From fc267827f9976f904ce92a6f3f8871be938fc9e4 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Fri, 24 May 2024 11:41:30 +0200 Subject: [PATCH 01/36] Implement notofications/dialogs RFCs --- .../core/components/dialogs/AlertDialog.js | 28 ++ .../core/components/dialogs/AlertDialog.tsx | 28 ++ .../dialogs/AlertDialog.tsx.preview | 1 + .../core/components/dialogs/ConfirmDialog.js | 36 ++ .../core/components/dialogs/ConfirmDialog.tsx | 36 ++ .../dialogs/ConfirmDialog.tsx.preview | 9 + .../core/components/dialogs/CustomDialog.js | 50 +++ .../core/components/dialogs/CustomDialog.tsx | 44 +++ .../dialogs/CustomDialog.tsx.preview | 1 + .../dialogs/CustomDialogWithPayload.js | 59 ++++ .../dialogs/CustomDialogWithPayload.tsx | 52 +++ .../CustomDialogWithPayload.tsx.preview | 1 + .../dialogs/CustomDialogWithResult.js | 63 ++++ .../dialogs/CustomDialogWithResult.tsx | 57 ++++ .../CustomDialogWithResult.tsx.preview | 2 + .../core/components/dialogs/PromptDialog.js | 31 ++ .../core/components/dialogs/PromptDialog.tsx | 31 ++ .../dialogs/PromptDialog.tsx.preview | 4 + .../core/components/dialogs/StackedDialog.js | 60 ++++ .../core/components/dialogs/StackedDialog.tsx | 53 +++ .../dialogs/StackedDialog.tsx.preview | 1 + .../core/components/dialogs/dialogs.md | 94 ++++++ .../notifications/AlertNotification.js | 51 +++ .../notifications/AlertNotification.tsx | 53 +++ .../AlertNotification.tsx.preview | 4 + .../notifications/BasicNotification.js | 26 ++ .../notifications/BasicNotification.tsx | 26 ++ .../BasicNotification.tsx.preview | 3 + .../notifications/CloseNotification.js | 46 +++ .../notifications/CloseNotification.tsx | 46 +++ .../CloseNotification.tsx.preview | 12 + .../notifications/DedupeNotification.js | 28 ++ .../notifications/DedupeNotification.tsx | 28 ++ .../DedupeNotification.tsx.preview | 4 + .../notifications/MultipleNotifications.js | 25 ++ .../notifications/MultipleNotifications.tsx | 25 ++ .../MultipleNotifications.tsx.preview | 2 + .../components/notifications/notifications.md | 69 ++++ docs/data/toolpad/core/pages.ts | 24 +- docs/pages/toolpad/core/components/dialogs.js | 7 + .../toolpad/core/components/notifications.js | 7 + .../src/AppProvider/AppProvider.tsx | 11 +- .../src/DashboardLayout/DashboardLayout.tsx | 12 - packages/toolpad-core/src/index.ts | 9 +- packages/toolpad-core/src/useDialogs/index.ts | 1 + .../src/useDialogs/useDialogs.tsx | 317 ++++++++++++++++++ .../src/useNotifications/index.ts | 1 + .../src/useNotifications/useNotifications.tsx | 234 +++++++++++++ packages/toolpad-utils/src/react.tsx | 10 +- pnpm-lock.yaml | 45 +++ 50 files changed, 1830 insertions(+), 37 deletions(-) create mode 100644 docs/data/toolpad/core/components/dialogs/AlertDialog.js create mode 100644 docs/data/toolpad/core/components/dialogs/AlertDialog.tsx create mode 100644 docs/data/toolpad/core/components/dialogs/AlertDialog.tsx.preview create mode 100644 docs/data/toolpad/core/components/dialogs/ConfirmDialog.js create mode 100644 docs/data/toolpad/core/components/dialogs/ConfirmDialog.tsx create mode 100644 docs/data/toolpad/core/components/dialogs/ConfirmDialog.tsx.preview create mode 100644 docs/data/toolpad/core/components/dialogs/CustomDialog.js create mode 100644 docs/data/toolpad/core/components/dialogs/CustomDialog.tsx create mode 100644 docs/data/toolpad/core/components/dialogs/CustomDialog.tsx.preview create mode 100644 docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.js create mode 100644 docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.tsx create mode 100644 docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.tsx.preview create mode 100644 docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.js create mode 100644 docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.tsx create mode 100644 docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.tsx.preview create mode 100644 docs/data/toolpad/core/components/dialogs/PromptDialog.js create mode 100644 docs/data/toolpad/core/components/dialogs/PromptDialog.tsx create mode 100644 docs/data/toolpad/core/components/dialogs/PromptDialog.tsx.preview create mode 100644 docs/data/toolpad/core/components/dialogs/StackedDialog.js create mode 100644 docs/data/toolpad/core/components/dialogs/StackedDialog.tsx create mode 100644 docs/data/toolpad/core/components/dialogs/StackedDialog.tsx.preview create mode 100644 docs/data/toolpad/core/components/dialogs/dialogs.md create mode 100644 docs/data/toolpad/core/components/notifications/AlertNotification.js create mode 100644 docs/data/toolpad/core/components/notifications/AlertNotification.tsx create mode 100644 docs/data/toolpad/core/components/notifications/AlertNotification.tsx.preview create mode 100644 docs/data/toolpad/core/components/notifications/BasicNotification.js create mode 100644 docs/data/toolpad/core/components/notifications/BasicNotification.tsx create mode 100644 docs/data/toolpad/core/components/notifications/BasicNotification.tsx.preview create mode 100644 docs/data/toolpad/core/components/notifications/CloseNotification.js create mode 100644 docs/data/toolpad/core/components/notifications/CloseNotification.tsx create mode 100644 docs/data/toolpad/core/components/notifications/CloseNotification.tsx.preview create mode 100644 docs/data/toolpad/core/components/notifications/DedupeNotification.js create mode 100644 docs/data/toolpad/core/components/notifications/DedupeNotification.tsx create mode 100644 docs/data/toolpad/core/components/notifications/DedupeNotification.tsx.preview create mode 100644 docs/data/toolpad/core/components/notifications/MultipleNotifications.js create mode 100644 docs/data/toolpad/core/components/notifications/MultipleNotifications.tsx create mode 100644 docs/data/toolpad/core/components/notifications/MultipleNotifications.tsx.preview create mode 100644 docs/data/toolpad/core/components/notifications/notifications.md create mode 100644 docs/pages/toolpad/core/components/dialogs.js create mode 100644 docs/pages/toolpad/core/components/notifications.js create mode 100644 packages/toolpad-core/src/useDialogs/index.ts create mode 100644 packages/toolpad-core/src/useDialogs/useDialogs.tsx create mode 100644 packages/toolpad-core/src/useNotifications/index.ts create mode 100644 packages/toolpad-core/src/useNotifications/useNotifications.tsx diff --git a/docs/data/toolpad/core/components/dialogs/AlertDialog.js b/docs/data/toolpad/core/components/dialogs/AlertDialog.js new file mode 100644 index 00000000000..654b428f884 --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/AlertDialog.js @@ -0,0 +1,28 @@ +import * as React from 'react'; +import { DialogProvider, useDialogs } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; + +function DemoContent() { + const dialogs = useDialogs(); + return ( +
+ +
+ ); +} + +export default function AlertDialog() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/AlertDialog.tsx b/docs/data/toolpad/core/components/dialogs/AlertDialog.tsx new file mode 100644 index 00000000000..654b428f884 --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/AlertDialog.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import { DialogProvider, useDialogs } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; + +function DemoContent() { + const dialogs = useDialogs(); + return ( +
+ +
+ ); +} + +export default function AlertDialog() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/AlertDialog.tsx.preview b/docs/data/toolpad/core/components/dialogs/AlertDialog.tsx.preview new file mode 100644 index 00000000000..4f81c7d194c --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/AlertDialog.tsx.preview @@ -0,0 +1 @@ +await dialogs.alert('Hello World'); \ No newline at end of file diff --git a/docs/data/toolpad/core/components/dialogs/ConfirmDialog.js b/docs/data/toolpad/core/components/dialogs/ConfirmDialog.js new file mode 100644 index 00000000000..40591882e2e --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/ConfirmDialog.js @@ -0,0 +1,36 @@ +import * as React from 'react'; +import { DialogProvider, useDialogs } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; + +function DemoContent() { + const dialogs = useDialogs(); + return ( +
+ +
+ ); +} + +export default function ConfirmDialog() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/ConfirmDialog.tsx b/docs/data/toolpad/core/components/dialogs/ConfirmDialog.tsx new file mode 100644 index 00000000000..40591882e2e --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/ConfirmDialog.tsx @@ -0,0 +1,36 @@ +import * as React from 'react'; +import { DialogProvider, useDialogs } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; + +function DemoContent() { + const dialogs = useDialogs(); + return ( +
+ +
+ ); +} + +export default function ConfirmDialog() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/ConfirmDialog.tsx.preview b/docs/data/toolpad/core/components/dialogs/ConfirmDialog.tsx.preview new file mode 100644 index 00000000000..9500e780731 --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/ConfirmDialog.tsx.preview @@ -0,0 +1,9 @@ +const confirmed = await dialogs.confirm('Are you sure?', { + okText: 'Yes', + cancelText: 'No', +}); +if (confirmed) { + await dialogs.alert("Then let's do it!"); +} else { + await dialogs.alert('Ok, forget about it!'); +} \ No newline at end of file diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialog.js b/docs/data/toolpad/core/components/dialogs/CustomDialog.js new file mode 100644 index 00000000000..160ceb479cc --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/CustomDialog.js @@ -0,0 +1,50 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { DialogProvider, useDialogs } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogTitle from '@mui/material/DialogTitle'; +import DialogContent from '@mui/material/DialogContent'; +import DialogActions from '@mui/material/DialogActions'; + +function MyCustomDialog({ open, onClose }) { + return ( + onClose()}> + Custom dialog + I am a custom dialog + + + + + ); +} + +MyCustomDialog.propTypes = { + onClose: PropTypes.func.isRequired, + open: PropTypes.bool.isRequired, +}; + +function DemoContent() { + const dialogs = useDialogs(); + return ( +
+ +
+ ); +} + +export default function CustomDialog() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialog.tsx b/docs/data/toolpad/core/components/dialogs/CustomDialog.tsx new file mode 100644 index 00000000000..4a1bb09dcbd --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/CustomDialog.tsx @@ -0,0 +1,44 @@ +import * as React from 'react'; +import { DialogProvider, useDialogs, DialogProps } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogTitle from '@mui/material/DialogTitle'; +import DialogContent from '@mui/material/DialogContent'; +import DialogActions from '@mui/material/DialogActions'; + +function MyCustomDialog({ open, onClose }: DialogProps) { + return ( + onClose()}> + Custom dialog + I am a custom dialog + + + + + ); +} + +function DemoContent() { + const dialogs = useDialogs(); + return ( +
+ +
+ ); +} + +export default function CustomDialog() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialog.tsx.preview b/docs/data/toolpad/core/components/dialogs/CustomDialog.tsx.preview new file mode 100644 index 00000000000..3c31a5c7950 --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/CustomDialog.tsx.preview @@ -0,0 +1 @@ +await dialogs.open(MyCustomDialog); \ No newline at end of file diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.js b/docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.js new file mode 100644 index 00000000000..2e6e4238c83 --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.js @@ -0,0 +1,59 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { DialogProvider, useDialogs } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogTitle from '@mui/material/DialogTitle'; +import DialogContent from '@mui/material/DialogContent'; +import DialogActions from '@mui/material/DialogActions'; +import TextField from '@mui/material/TextField'; +import Stack from '@mui/material/Stack'; + +function MyCustomDialog({ payload, open, onClose }) { + return ( + onClose()}> + Dialog with payload + The payload is "{payload}" + + + + + ); +} + +MyCustomDialog.propTypes = { + onClose: PropTypes.func.isRequired, + open: PropTypes.bool.isRequired, + payload: PropTypes.string.isRequired, +}; + +function DemoContent() { + const dialogs = useDialogs(); + const [payload, setPayload] = React.useState('Some payload'); + return ( + + setPayload(event.currentTarget.value)} + /> + + + ); +} + +export default function CustomDialogWithPayload() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.tsx b/docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.tsx new file mode 100644 index 00000000000..931015b8f2b --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.tsx @@ -0,0 +1,52 @@ +import * as React from 'react'; +import { DialogProvider, useDialogs, DialogProps } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogTitle from '@mui/material/DialogTitle'; +import DialogContent from '@mui/material/DialogContent'; +import DialogActions from '@mui/material/DialogActions'; +import TextField from '@mui/material/TextField'; +import Stack from '@mui/material/Stack'; + +function MyCustomDialog({ payload, open, onClose }: DialogProps) { + return ( + onClose()}> + Dialog with payload + The payload is "{payload}" + + + + + ); +} + +function DemoContent() { + const dialogs = useDialogs(); + const [payload, setPayload] = React.useState('Some payload'); + return ( + + setPayload(event.currentTarget.value)} + /> + + + ); +} + +export default function CustomDialogWithPayload() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.tsx.preview b/docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.tsx.preview new file mode 100644 index 00000000000..1a23cecf043 --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.tsx.preview @@ -0,0 +1 @@ +await dialogs.open(MyCustomDialog, payload); \ No newline at end of file diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.js b/docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.js new file mode 100644 index 00000000000..7e79cfee872 --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.js @@ -0,0 +1,63 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { DialogProvider, useDialogs } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogTitle from '@mui/material/DialogTitle'; +import DialogContent from '@mui/material/DialogContent'; +import DialogActions from '@mui/material/DialogActions'; +import TextField from '@mui/material/TextField'; +import Stack from '@mui/material/Stack'; +import DialogContentText from '@mui/material/DialogContentText'; + +function MyCustomDialog({ open, onClose }) { + const [result, setResult] = React.useState('Jon Snow'); + return ( + onClose(null)}> + Dialog with payload + + What is your name? + setResult(event.currentTarget.value)} + /> + + + + + + ); +} + +MyCustomDialog.propTypes = { + onClose: PropTypes.func.isRequired, + open: PropTypes.bool.isRequired, +}; + +function DemoContent() { + const dialogs = useDialogs(); + return ( + + + + ); +} + +export default function CustomDialogWithResult() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.tsx b/docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.tsx new file mode 100644 index 00000000000..853b8cf32ea --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.tsx @@ -0,0 +1,57 @@ +import * as React from 'react'; +import { DialogProvider, useDialogs, DialogProps } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogTitle from '@mui/material/DialogTitle'; +import DialogContent from '@mui/material/DialogContent'; +import DialogActions from '@mui/material/DialogActions'; +import TextField from '@mui/material/TextField'; +import Stack from '@mui/material/Stack'; +import DialogContentText from '@mui/material/DialogContentText'; + +function MyCustomDialog({ open, onClose }: DialogProps) { + const [result, setResult] = React.useState('Jon Snow'); + return ( + onClose(null)}> + Dialog with payload + + What is your name? + setResult(event.currentTarget.value)} + /> + + + + + + ); +} + +function DemoContent() { + const dialogs = useDialogs(); + return ( + + + + ); +} + +export default function CustomDialogWithResult() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.tsx.preview b/docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.tsx.preview new file mode 100644 index 00000000000..7a20a35ab3e --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.tsx.preview @@ -0,0 +1,2 @@ +const result = await dialogs.open(MyCustomDialog); +await dialogs.alert(`Your name is "${result}"`); \ No newline at end of file diff --git a/docs/data/toolpad/core/components/dialogs/PromptDialog.js b/docs/data/toolpad/core/components/dialogs/PromptDialog.js new file mode 100644 index 00000000000..40e27491d35 --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/PromptDialog.js @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { DialogProvider, useDialogs } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; + +function DemoContent() { + const dialogs = useDialogs(); + return ( +
+ +
+ ); +} + +export default function PromptDialog() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/PromptDialog.tsx b/docs/data/toolpad/core/components/dialogs/PromptDialog.tsx new file mode 100644 index 00000000000..40e27491d35 --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/PromptDialog.tsx @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { DialogProvider, useDialogs } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; + +function DemoContent() { + const dialogs = useDialogs(); + return ( +
+ +
+ ); +} + +export default function PromptDialog() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/PromptDialog.tsx.preview b/docs/data/toolpad/core/components/dialogs/PromptDialog.tsx.preview new file mode 100644 index 00000000000..b20e0553547 --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/PromptDialog.tsx.preview @@ -0,0 +1,4 @@ +const name = await dialogs.prompt("What's your name?"); +if (name) { + await dialogs.alert(`Hi there, ${name}`); +} \ No newline at end of file diff --git a/docs/data/toolpad/core/components/dialogs/StackedDialog.js b/docs/data/toolpad/core/components/dialogs/StackedDialog.js new file mode 100644 index 00000000000..6a0132d29ca --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/StackedDialog.js @@ -0,0 +1,60 @@ +import * as React from 'react'; +import PropTypes from 'prop-types'; +import { DialogProvider, useDialogs } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogTitle from '@mui/material/DialogTitle'; +import DialogContent from '@mui/material/DialogContent'; +import DialogActions from '@mui/material/DialogActions'; + +function MyCustomDialog({ payload, open, onClose }) { + const dialogs = useDialogs(); + return ( + onClose()}> + Dialog {payload} + + + + + + + + ); +} + +MyCustomDialog.propTypes = { + onClose: PropTypes.func.isRequired, + open: PropTypes.bool.isRequired, + payload: PropTypes.number.isRequired, +}; + +function DemoContent() { + const dialogs = useDialogs(); + return ( +
+ +
+ ); +} + +export default function StackedDialog() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/StackedDialog.tsx b/docs/data/toolpad/core/components/dialogs/StackedDialog.tsx new file mode 100644 index 00000000000..60b0be49536 --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/StackedDialog.tsx @@ -0,0 +1,53 @@ +import * as React from 'react'; +import { DialogProvider, useDialogs, DialogProps } from '@toolpad/core/useDialogs'; +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogTitle from '@mui/material/DialogTitle'; +import DialogContent from '@mui/material/DialogContent'; +import DialogActions from '@mui/material/DialogActions'; + +function MyCustomDialog({ payload, open, onClose }: DialogProps) { + const dialogs = useDialogs(); + return ( + onClose()}> + Dialog {payload} + + + + + + + + ); +} + +function DemoContent() { + const dialogs = useDialogs(); + return ( +
+ +
+ ); +} + +export default function StackedDialog() { + return ( + + + + ); +} diff --git a/docs/data/toolpad/core/components/dialogs/StackedDialog.tsx.preview b/docs/data/toolpad/core/components/dialogs/StackedDialog.tsx.preview new file mode 100644 index 00000000000..45e7f84f761 --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/StackedDialog.tsx.preview @@ -0,0 +1 @@ +await dialogs.open(MyCustomDialog, payload + 1); \ No newline at end of file diff --git a/docs/data/toolpad/core/components/dialogs/dialogs.md b/docs/data/toolpad/core/components/dialogs/dialogs.md new file mode 100644 index 00000000000..d4c989f218c --- /dev/null +++ b/docs/data/toolpad/core/components/dialogs/dialogs.md @@ -0,0 +1,94 @@ +# Dialogs + +

Imperative APIs to open and interact with dialogs.

+ +Toolpad core offers a set of abstractions that makes interacting with dialogs simpler. It has an imperative API to open and close dialogs, and allows dialogs to be stacked on top of each other. + +First thing you need to do is install the DialogProvider at the root of your application. + +```tsx +import { DialogProvider } from '@toolpad/core/useDialogs'; + +function App({ children }) { + return {children}; +} +``` + +To get access to the dialogs API you first have to call the `useDialogs` hook. + +```js +import { useDialogs } from '@toolpad/core/useDialogs'; + +function MyApp() { + const dialogs = useDialogs(); + // ... +} +``` + +:::info +The Toolpad AppProvider automatically comes with dialogs enabled. You won't need to explicitly add the DialogProvider in Toolpad applications. +::: + +## Basic dialog + +Dialogs are React components that taken `open` and `onClose` properties and return a Dialog component. The `open` property reflects the open state of the dialog and you can call the `onClose` handler to close it. + +```js +function MyCustomDialog({ open, onClose }: DialogProps) { + return ( + onClose()}> + Custom dialog + I am a custom dialog + + + + + ); +} +``` + +Now you can call the `dialogs.open` function and pass the component as a first parameter. + +{{"demo": "CustomDialog.js"}} + +## With dialog payload + +You can pass a `payload` to the dialog with the second parameter. The payload stays constant for the lifetime of the dialog. + +{{"demo": "CustomDialogWithPayload.js"}} + +## With dialog result + +A dialog can return a value with the `onClose` handler. The promise returned by the `open` method is resolved with the value that was passed to `onClose`. + +{{"demo": "CustomDialogWithResult.js"}} + +## Stacked dialogs + +Dialogs can be stacked. A dialog can open other another dialog which comes to the foreground upon opening. Closing the latter reveals the former again. + +{{"demo": "StackedDialog.js"}} + +## System dialogs + +Toolpad comes with a set of system dialogs that improve on the native `window.alert`, `window.confirm`, and `window.prompt` APIs. These APIs are very similar, but they create dialogs that follow your application theme. + +### Alert + +Analog to [`window.alert`](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert) it opens a dialog with a message for the user. The only action to be taken is to acknowledge the message after which the dialog closes. +The dialog title and button text are customizable with the `title` and `okText` properties. + +{{"demo": "AlertDialog.js"}} + +### Confirm + +Analog to [`window.confirm`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm) it opens a dialog with a question for the user. The user can either confirm or cancel and the dialog result is a boolean which is `true` when the user confirmed. +The dialog title and button texts are customizable with the `title`, `okText`, and `cancelText` properties. + +{{"demo": "ConfirmDialog.js"}} + +### Prompt + +Analog to [`window.prompt`](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt) it opens a dialog inquiring the user for some input text. The user can fill the input box and upon confirmation the promise returned from the `prompt` call is resolved with its value. The dialog title and button texts are customizable with the `title`, `okText`, and `cancelText` properties. + +{{"demo": "PromptDialog.js"}} diff --git a/docs/data/toolpad/core/components/notifications/AlertNotification.js b/docs/data/toolpad/core/components/notifications/AlertNotification.js new file mode 100644 index 00000000000..5e285a068d0 --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/AlertNotification.js @@ -0,0 +1,51 @@ +import * as React from 'react'; +import { + NotificationsProvider, + useNotifications, +} from '@toolpad/core/useNotifications'; +import Button from '@mui/material/Button'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormControl from '@mui/material/FormControl'; +import FormLabel from '@mui/material/FormLabel'; +import RadioGroup from '@mui/material/RadioGroup'; +import Radio from '@mui/material/Radio'; +import Stack from '@mui/material/Stack'; + +export default function AlertNotification() { + const notifications = useNotifications(); + const [severity, setSeverity] = React.useState('info'); + return ( +
+ + + + Severity + setSeverity(event.target.value)} + aria-labelledby="alert-notification-severity" + name="severity" + > + } label="Info" /> + } label="Success" /> + } label="Warning" /> + } label="Error" /> + + + + +
+ ); +} diff --git a/docs/data/toolpad/core/components/notifications/AlertNotification.tsx b/docs/data/toolpad/core/components/notifications/AlertNotification.tsx new file mode 100644 index 00000000000..bd8289a20a7 --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/AlertNotification.tsx @@ -0,0 +1,53 @@ +import * as React from 'react'; +import { + NotificationsProvider, + useNotifications, +} from '@toolpad/core/useNotifications'; +import Button from '@mui/material/Button'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import FormControl from '@mui/material/FormControl'; +import FormLabel from '@mui/material/FormLabel'; +import RadioGroup from '@mui/material/RadioGroup'; +import Radio from '@mui/material/Radio'; +import Stack from '@mui/material/Stack'; + +export default function AlertNotification() { + const notifications = useNotifications(); + const [severity, setSeverity] = React.useState< + 'info' | 'success' | 'warning' | 'error' + >('info'); + return ( +
+ + + + Severity + setSeverity(event.target.value as any)} + aria-labelledby="alert-notification-severity" + name="severity" + > + } label="Info" /> + } label="Success" /> + } label="Warning" /> + } label="Error" /> + + + + +
+ ); +} diff --git a/docs/data/toolpad/core/components/notifications/AlertNotification.tsx.preview b/docs/data/toolpad/core/components/notifications/AlertNotification.tsx.preview new file mode 100644 index 00000000000..74a268b404e --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/AlertNotification.tsx.preview @@ -0,0 +1,4 @@ +await notifications.show('Consider yourself notified!', { + severity, + autoHideDuration: 3000, +}); \ No newline at end of file diff --git a/docs/data/toolpad/core/components/notifications/BasicNotification.js b/docs/data/toolpad/core/components/notifications/BasicNotification.js new file mode 100644 index 00000000000..832f96ab71f --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/BasicNotification.js @@ -0,0 +1,26 @@ +import * as React from 'react'; +import { + NotificationsProvider, + useNotifications, +} from '@toolpad/core/useNotifications'; +import Button from '@mui/material/Button'; + +export default function BasicNotification() { + const notifications = useNotifications(); + return ( +
+ + +
+ ); +} diff --git a/docs/data/toolpad/core/components/notifications/BasicNotification.tsx b/docs/data/toolpad/core/components/notifications/BasicNotification.tsx new file mode 100644 index 00000000000..832f96ab71f --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/BasicNotification.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import { + NotificationsProvider, + useNotifications, +} from '@toolpad/core/useNotifications'; +import Button from '@mui/material/Button'; + +export default function BasicNotification() { + const notifications = useNotifications(); + return ( +
+ + +
+ ); +} diff --git a/docs/data/toolpad/core/components/notifications/BasicNotification.tsx.preview b/docs/data/toolpad/core/components/notifications/BasicNotification.tsx.preview new file mode 100644 index 00000000000..7fac733f535 --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/BasicNotification.tsx.preview @@ -0,0 +1,3 @@ +await notifications.show('Consider yourself notified!', { + autoHideDuration: 3000, +}); \ No newline at end of file diff --git a/docs/data/toolpad/core/components/notifications/CloseNotification.js b/docs/data/toolpad/core/components/notifications/CloseNotification.js new file mode 100644 index 00000000000..b0f0ec5a685 --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/CloseNotification.js @@ -0,0 +1,46 @@ +import * as React from 'react'; +import { + NotificationsProvider, + useNotifications, +} from '@toolpad/core/useNotifications'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import Switch from '@mui/material/Switch'; + +export default function CloseNotification() { + const notifications = useNotifications(); + const [online, setOnline] = React.useState(true); + const prevOnline = React.useRef(online); + React.useEffect(() => { + if (prevOnline.current === online) { + return () => {}; + } + prevOnline.current = online; + + // preview-start + const key = online + ? notifications.show('You are now online', { + severity: 'success', + autoHideDuration: 3000, + }) + : notifications.show('You are now offline', { + severity: 'error', + }); + + return () => { + notifications.close(key); + }; + // preview-end + }, [notifications, online]); + + return ( +
+ + setOnline((prev) => !prev)} /> + } + label="Online" + /> +
+ ); +} diff --git a/docs/data/toolpad/core/components/notifications/CloseNotification.tsx b/docs/data/toolpad/core/components/notifications/CloseNotification.tsx new file mode 100644 index 00000000000..b0f0ec5a685 --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/CloseNotification.tsx @@ -0,0 +1,46 @@ +import * as React from 'react'; +import { + NotificationsProvider, + useNotifications, +} from '@toolpad/core/useNotifications'; +import FormControlLabel from '@mui/material/FormControlLabel'; +import Switch from '@mui/material/Switch'; + +export default function CloseNotification() { + const notifications = useNotifications(); + const [online, setOnline] = React.useState(true); + const prevOnline = React.useRef(online); + React.useEffect(() => { + if (prevOnline.current === online) { + return () => {}; + } + prevOnline.current = online; + + // preview-start + const key = online + ? notifications.show('You are now online', { + severity: 'success', + autoHideDuration: 3000, + }) + : notifications.show('You are now offline', { + severity: 'error', + }); + + return () => { + notifications.close(key); + }; + // preview-end + }, [notifications, online]); + + return ( +
+ + setOnline((prev) => !prev)} /> + } + label="Online" + /> +
+ ); +} diff --git a/docs/data/toolpad/core/components/notifications/CloseNotification.tsx.preview b/docs/data/toolpad/core/components/notifications/CloseNotification.tsx.preview new file mode 100644 index 00000000000..9d1eb56a00e --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/CloseNotification.tsx.preview @@ -0,0 +1,12 @@ +const key = online + ? notifications.show('You are now online', { + severity: 'success', + autoHideDuration: 3000, + }) + : notifications.show('You are now offline', { + severity: 'error', + }); + +return () => { + notifications.close(key); +}; \ No newline at end of file diff --git a/docs/data/toolpad/core/components/notifications/DedupeNotification.js b/docs/data/toolpad/core/components/notifications/DedupeNotification.js new file mode 100644 index 00000000000..4efbb0d01ff --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/DedupeNotification.js @@ -0,0 +1,28 @@ +import * as React from 'react'; +import { + NotificationsProvider, + useNotifications, +} from '@toolpad/core/useNotifications'; +import Button from '@mui/material/Button'; + +export default function DedupeNotification() { + const notifications = useNotifications(); + return ( + // preview +
+ + +
+ ); +} diff --git a/docs/data/toolpad/core/components/notifications/DedupeNotification.tsx b/docs/data/toolpad/core/components/notifications/DedupeNotification.tsx new file mode 100644 index 00000000000..4efbb0d01ff --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/DedupeNotification.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import { + NotificationsProvider, + useNotifications, +} from '@toolpad/core/useNotifications'; +import Button from '@mui/material/Button'; + +export default function DedupeNotification() { + const notifications = useNotifications(); + return ( + // preview +
+ + +
+ ); +} diff --git a/docs/data/toolpad/core/components/notifications/DedupeNotification.tsx.preview b/docs/data/toolpad/core/components/notifications/DedupeNotification.tsx.preview new file mode 100644 index 00000000000..8341c8be9db --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/DedupeNotification.tsx.preview @@ -0,0 +1,4 @@ +await notifications.show('Listen carefully, I will say this only once', { + key: 'dedupe-notification', + autoHideDuration: 5000, +}); \ No newline at end of file diff --git a/docs/data/toolpad/core/components/notifications/MultipleNotifications.js b/docs/data/toolpad/core/components/notifications/MultipleNotifications.js new file mode 100644 index 00000000000..82704cfb866 --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/MultipleNotifications.js @@ -0,0 +1,25 @@ +import * as React from 'react'; +import { + NotificationsProvider, + useNotifications, +} from '@toolpad/core/useNotifications'; +import Button from '@mui/material/Button'; + +export default function MultipleNotifications() { + const notifications = useNotifications(); + return ( +
+ + +
+ ); +} diff --git a/docs/data/toolpad/core/components/notifications/MultipleNotifications.tsx b/docs/data/toolpad/core/components/notifications/MultipleNotifications.tsx new file mode 100644 index 00000000000..82704cfb866 --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/MultipleNotifications.tsx @@ -0,0 +1,25 @@ +import * as React from 'react'; +import { + NotificationsProvider, + useNotifications, +} from '@toolpad/core/useNotifications'; +import Button from '@mui/material/Button'; + +export default function MultipleNotifications() { + const notifications = useNotifications(); + return ( +
+ + +
+ ); +} diff --git a/docs/data/toolpad/core/components/notifications/MultipleNotifications.tsx.preview b/docs/data/toolpad/core/components/notifications/MultipleNotifications.tsx.preview new file mode 100644 index 00000000000..91b054287d2 --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/MultipleNotifications.tsx.preview @@ -0,0 +1,2 @@ +await notifications.show('Hello', { autoHideDuration: 1000 }); +await notifications.show('Goodbye', { autoHideDuration: 1000 }); \ No newline at end of file diff --git a/docs/data/toolpad/core/components/notifications/notifications.md b/docs/data/toolpad/core/components/notifications/notifications.md new file mode 100644 index 00000000000..8c7ca1bd3ff --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/notifications.md @@ -0,0 +1,69 @@ +# Notifications + +

Imperative APIs to show and interact with application notifications

+ +Toolpad core offers a set of abstractions that make it easier to interact with notifications. Notifications are used to give short updates to the user about things that are happening during the application lifetime. They appear at the bottom of the screen. The Toolpad API allows for opening multiple notifications concurrenlty. + +First thing you need to do to get access to the notifications APIs is install the NotificationsProvider. + +```js +import { NotificationsProvider } from '@toolpad/core/useNotifications'; + +function App({ children }) { + return ( + + {children} + + + ); +} +``` + +To then get acess to the notifications APIs you need to call the `useNotifications` hook. + +```js +import { useNotifications } from '@toolpad/core/useNotifications'; + +function MyApp() { + const notifications = useNotifications(); + // ... +} +``` + +:::info +The Toolpad AppProvider automatically comes with notifications installed. You won't need to explicitly add the NotificationsProvider in Toolpad applications. +::: + +## Basic notification + +You can notify your users with a neutral message by calling `notifications.show`. To have the notification automatically hide, add the `autoHideDuration` option. This expresses the time in milliseconds after which to close the notification. + +{{"demo": "BasicNotification.js"}} + +## Alert notifications + +You can send notifications under the form of alerts with the `severity` property. It takes a value from `"info"`, `"success"`, `"warning"`, or `"error"`. + +{{"demo": "AlertNotification.js"}} + +## Multiple notifications + +Multiple concurrent notifications are stacked and when more than one notification is available, a badge is shown with the amount of open notification. Try it out with the following demo: + +{{"demo": "MultipleNotifications.js"}} + +## Close notifications + +You can programmatically close existing notifications. Each notification has an associated key. You can call the `notifications.close` method with this key to close the opened notification. + +{{"demo": "CloseNotification.js"}} + +## Dedupe notifications + +You can supply your own value for a key to shown notifications to associate them with this key. Notifications with the same key are deduplicated as long as one is already open. If you try to show a notification with the same key, the call is simply ignored. + +{{"demo": "DedupeNotification.js"}} + +## 🚧 Notification center + +When multiple notifications are available, click the badge to open the notification center to show a scrollable list of all available notifications. This feature is not available yet. diff --git a/docs/data/toolpad/core/pages.ts b/docs/data/toolpad/core/pages.ts index 85662776f49..080f4cb2728 100644 --- a/docs/data/toolpad/core/pages.ts +++ b/docs/data/toolpad/core/pages.ts @@ -1,4 +1,5 @@ import type { MuiPage } from '@mui/monorepo/docs/src/MuiPage'; +import pagesApi from './pagesApi'; const pages: MuiPage[] = [ { @@ -81,28 +82,27 @@ const pages: MuiPage[] = [ }, ], }, - ], - }, - { - pathname: '/toolpad/core/api-group', - title: 'APIs', - children: [ { - pathname: '/toolpad/core/api/components-group', - subheader: 'Components', + pathname: '/toolpad/core/components/filter-group', + subheader: 'Utils', children: [ { - pathname: '/toolpad/core/api/app-provider', - title: 'AppProvider', + pathname: '/toolpad/core/components/dialogs', + title: 'dialogs', }, { - pathname: '/toolpad/core/api/dashboard-layout', - title: 'DashboardLayout', + pathname: '/toolpad/core/components/notifications', + title: 'notifications', }, ], }, ], }, + { + pathname: '/toolpad/core/api-group', + title: 'APIs', + children: pagesApi, + }, { pathname: '/toolpad/core/customization', title: 'Customization', diff --git a/docs/pages/toolpad/core/components/dialogs.js b/docs/pages/toolpad/core/components/dialogs.js new file mode 100644 index 00000000000..cdf8d124f0c --- /dev/null +++ b/docs/pages/toolpad/core/components/dialogs.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docs-toolpad/data/toolpad/core/components/dialogs/dialogs.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/toolpad/core/components/notifications.js b/docs/pages/toolpad/core/components/notifications.js new file mode 100644 index 00000000000..1e208a61779 --- /dev/null +++ b/docs/pages/toolpad/core/components/notifications.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docs-toolpad/data/toolpad/core/components/notifications/notifications.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/packages/toolpad-core/src/AppProvider/AppProvider.tsx b/packages/toolpad-core/src/AppProvider/AppProvider.tsx index c39d602f3af..e64ddecbb42 100644 --- a/packages/toolpad-core/src/AppProvider/AppProvider.tsx +++ b/packages/toolpad-core/src/AppProvider/AppProvider.tsx @@ -3,6 +3,8 @@ import PropTypes from 'prop-types'; import { ThemeProvider, Theme } from '@mui/material/styles'; import CssBaseline from '@mui/material/CssBaseline'; import { baseTheme } from '../themes'; +import { NotificationsProvider } from '../useNotifications'; +import { DialogProvider } from '../useDialogs'; export interface Branding { title?: string; @@ -73,9 +75,12 @@ function AppProvider(props: AppProviderProps) { return ( - - {children} - + + + + {children} + + ); } diff --git a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx index 1d9348dcb50..93f7cd9dcf1 100644 --- a/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx +++ b/packages/toolpad-core/src/DashboardLayout/DashboardLayout.tsx @@ -274,18 +274,6 @@ function DashboardLayout(props: DashboardLayoutProps) { - {/* - `1px solid ${theme.palette.divider}`, - }} - > - - - */} { + onClose?: (result: R) => Promise; +} + +export interface AlertOptions extends SystemDialogBase { + title?: React.ReactNode; + okText?: React.ReactNode; +} + +export interface ConfirmOptions extends SystemDialogBase { + title?: React.ReactNode; + color?: 'error' | 'info' | 'success' | 'warning'; + defaultValue?: string; + okText?: React.ReactNode; + severity?: 'error' | 'info' | 'success' | 'warning'; + cancelText?: React.ReactNode; +} + +export interface PromptOptions extends SystemDialogBase { + title?: React.ReactNode; + okText?: React.ReactNode; + cancelText?: React.ReactNode; +} + +export interface DialogProps

{ + payload: P; + open: boolean; + onClose: (result: R) => Promise; +} + +export interface OpenAlertDialog { + (msg: React.ReactNode, options?: AlertOptions): Promise; +} + +export interface OpenConfirmDialog { + (msg: React.ReactNode, options?: ConfirmOptions): Promise; +} + +export interface OpenPromptDialog { + (msg: React.ReactNode, options?: PromptOptions): Promise; +} + +type DialogComponent = React.ComponentType>; + +export interface OpenDialogOptions { + onClose?: (result: R) => Promise; +} + +export interface OpenDialog { +

( + Component: DialogComponent, + payload?: P, + options?: OpenDialogOptions, + ): Promise; + (Component: DialogComponent, payload: P, options?: OpenDialogOptions): Promise; +} + +export interface CloseDialog { + (dialog: Promise, result: R): Promise; +} + +export interface DialogHook { + alert: OpenAlertDialog; + confirm: OpenConfirmDialog; + prompt: OpenPromptDialog; + open: OpenDialog; + close: CloseDialog; +} + +interface DialogStackEntry { + key: string; + open: boolean; + promise: Promise; + Component: DialogComponent; + payload: P; + onClose: (result: R) => Promise; + resolve: (result: R) => void; +} + +const OpenDialogContext = React.createContext(async () => { + throw new Error('No DialogProvider found'); +}); + +const CloseDialogContext = React.createContext(async () => { + throw new Error('No DialogProvider found'); +}); + +export interface DialogProviderprops { + children?: React.ReactNode; +} + +export function DialogProvider({ children }: DialogProviderprops) { + const [stack, setStack] = React.useState[]>([]); + const keyPrefix = React.useId(); + const nextId = React.useRef(0); + + const requestDialog = React.useCallback( + function open( + Component: DialogComponent, + payload: P, + options: OpenDialogOptions = {}, + ) { + const { onClose = async () => {} } = options; + let resolve: ((result: R) => void) | undefined; + const promise = new Promise((resolveImpl) => { + resolve = resolveImpl; + }); + invariant(resolve, 'resolve not set'); + + const key = `${keyPrefix}-${nextId.current}`; + nextId.current += 1; + + const newEntry: DialogStackEntry = { + key, + open: true, + promise, + Component, + payload, + onClose, + resolve, + }; + + setStack((prevStack) => [...prevStack, newEntry]); + return promise; + }, + [keyPrefix], + ); + + const closeDialogUi = React.useCallback(function closeDialogUi(dialog: Promise) { + setStack((prevStack) => + prevStack.map((entry) => (entry.promise === dialog ? { ...entry, open: false } : entry)), + ); + setTimeout(() => { + // wait for closing animation + setStack((prevStack) => prevStack.filter((entry) => entry.promise !== dialog)); + }, 1000); + }, []); + + const closeDialog = React.useCallback( + async function closeDialog(dialog: Promise, result: R) { + const entryToClose = stack.find((entry) => entry.promise === dialog); + invariant(entryToClose, 'dialog not found'); + await entryToClose.onClose(result); + entryToClose.resolve(result); + closeDialogUi(dialog); + return dialog; + }, + [stack, closeDialogUi], + ); + + return ( + + + {children} + {stack.map(({ key, open, Component, payload, promise }) => ( + { + await closeDialog(promise, result); + }} + /> + ))} + + + ); +} + +function useDialogLoadingButton(onClose: () => Promise) { + const [loading, setLoading] = React.useState(false); + const handleClick = async () => { + try { + setLoading(true); + await onClose(); + } finally { + setLoading(false); + } + }; + return { + onClick: handleClick, + loading, + }; +} + +export interface AlertDialogPayload extends AlertOptions { + msg: React.ReactNode; +} + +export interface AlertDialogProps extends DialogProps {} + +export function AlertDialog({ open, payload, onClose }: AlertDialogProps) { + const okButtonProps = useDialogLoadingButton(() => onClose()); + return ( +

onClose()}> + {payload.title ?? 'Alert'} + {payload.msg} + + + {payload.okText ?? 'Ok'} + + + + ); +} + +export interface ConfirmDialogPayload extends ConfirmOptions { + msg: React.ReactNode; +} + +export interface ConfirmDialogProps extends DialogProps {} + +export function ConfirmDialog({ open, payload, onClose }: ConfirmDialogProps) { + const cancelButtonProps = useDialogLoadingButton(() => onClose(false)); + const okButtonProps = useDialogLoadingButton(() => onClose(true)); + return ( + onClose(false)}> + {payload.title ?? 'Confirm'} + {payload.msg} + + + {payload.cancelText ?? 'Cancel'} + + + {payload.okText ?? 'Ok'} + + + + ); +} + +export interface PromptDialogPayload extends PromptOptions { + msg: React.ReactNode; +} + +export interface PromptDialogProps extends DialogProps {} + +export function PromptDialog({ open, payload, onClose }: PromptDialogProps) { + const [input, setInput] = React.useState(''); + const cancelButtonProps = useDialogLoadingButton(() => onClose(null)); + const okButtonProps = useDialogLoadingButton(() => onClose(input)); + return ( + onClose(null)}> + {payload.title ?? 'Confirm'} + + {payload.msg} + setInput(e.target.value)} + /> + + + + {payload.cancelText ?? 'Cancel'} + + + {payload.okText ?? 'Ok'} + + + + ); +} + +export function useDialogs(): DialogHook { + const open = React.useContext(OpenDialogContext); + + const close = React.useContext(CloseDialogContext); + + const alert = React.useCallback( + async (msg, { onClose, ...options } = {}) => + open(AlertDialog, { ...options, msg }, { onClose }), + [open], + ); + + const confirm = React.useCallback( + async (msg, { onClose, ...options } = {}) => + open(ConfirmDialog, { ...options, msg }, { onClose }), + [open], + ); + + const prompt = React.useCallback( + async (msg, { onClose, ...options } = {}) => + open(PromptDialog, { ...options, msg }, { onClose }), + [open], + ); + + return React.useMemo( + () => ({ + alert, + confirm, + prompt, + open, + close, + }), + [alert, close, confirm, open, prompt], + ); +} diff --git a/packages/toolpad-core/src/useNotifications/index.ts b/packages/toolpad-core/src/useNotifications/index.ts new file mode 100644 index 00000000000..0435a4c45c0 --- /dev/null +++ b/packages/toolpad-core/src/useNotifications/index.ts @@ -0,0 +1 @@ +export * from './useNotifications'; diff --git a/packages/toolpad-core/src/useNotifications/useNotifications.tsx b/packages/toolpad-core/src/useNotifications/useNotifications.tsx new file mode 100644 index 00000000000..53e490d5e6c --- /dev/null +++ b/packages/toolpad-core/src/useNotifications/useNotifications.tsx @@ -0,0 +1,234 @@ +import { + Alert, + Badge, + Button, + CloseReason, + IconButton, + Snackbar, + SnackbarCloseReason, + SnackbarContent, +} from '@mui/material'; +import CloseIcon from '@mui/icons-material/Close'; +import * as React from 'react'; +import { createGlobalState, useNonNullableContext } from '@toolpad/utils/react'; + +const closeText = 'Close'; + +export interface ShowNotificationOptions { + key?: string; // To dedupe snackbars + severity?: 'info' | 'warning' | 'error' | 'success'; + autoHideDuration?: number; + actionText?: React.ReactNode; + onAction?: () => void; +} + +export interface ShowNotification { + (message: React.ReactNode, options?: ShowNotificationOptions): string; +} + +export interface CloseNotification { + (key: string): void; +} + +interface NotificationQueueEntry { + notificationKey: string; + options: ShowNotificationOptions; + open: boolean; + message: React.ReactNode; +} + +interface NotificationsState { + queue: NotificationQueueEntry[]; +} + +interface NotificationsContextValue { + getState: () => NotificationsState; + subscribe: (cb: () => void) => () => void; + show: ShowNotification; + close: CloseNotification; +} + +function createNotificationsContext(): NotificationsContextValue | null { + if (typeof window === 'undefined') { + return null; + } + + let nextId = 1; + let state: NotificationsState = { queue: [] }; + // Only one subscriber allowed, last one wins + const subscribers = new Set<() => void>(); + + const setState: React.Dispatch> = (newState) => { + state = typeof newState === 'function' ? newState(state) : newState; + Array.from(subscribers).forEach((cb) => cb()); + }; + + return { + getState: () => state, + subscribe: (cb) => { + subscribers.add(cb); + return () => { + subscribers.delete(cb); + }; + }, + show: (message, options = {}) => { + const notificationKey = options.key ?? `::toolpad-internal::notification::${nextId}`; + nextId += 1; + setState((prev) => { + if (prev.queue.some((n) => n.notificationKey === notificationKey)) { + // deduplicate by key + return prev; + } + return { + ...prev, + queue: [...prev.queue, { message, options, notificationKey, open: true }], + }; + }); + return notificationKey; + }, + close: (key) => { + setState((prev) => ({ + ...prev, + queue: prev.queue.filter((n) => n.notificationKey !== key), + })); + }, + }; +} + +const NotificationsContext = React.createContext(createNotificationsContext()); + +interface NotificationProps { + notificationKey: string; + badge: string | null; + open: boolean; + message: React.ReactNode; + options: ShowNotificationOptions; +} + +function Notification({ notificationKey, open, message, options, badge }: NotificationProps) { + const { close } = useNonNullableContext(NotificationsContext); + + const { severity, actionText, onAction, autoHideDuration } = options; + + const handleClose = React.useCallback( + (event: unknown, reason?: CloseReason | SnackbarCloseReason) => { + if (reason === 'clickaway') { + return; + } + close(notificationKey); + }, + [notificationKey, close], + ); + + const action = ( + + {onAction ? ( + + ) : null} + + + + + ); + + return ( + + + {severity ? ( + + {message} + + ) : ( + + )} + + + ); +} + +interface UseNotifications { + show: ShowNotification; + close: CloseNotification; +} + +const serverNotifications: UseNotifications = { + show: () => { + throw new Error('Not supported on server side'); + }, + close: () => { + throw new Error('Not supported on server side'); + }, +}; + +export function useNotifications(): UseNotifications { + const context = React.useContext(NotificationsContext); + + if (context) { + const { show, close } = context; + return { show, close }; + } + + return serverNotifications; +} + +interface NotificationsUiProps { + context: NotificationsContextValue; +} + +function Notifications({ context }: NotificationsUiProps) { + const getServerState = React.useCallback(() => ({ queue: [] }), []); + const state: NotificationsState = React.useSyncExternalStore( + context.subscribe, + context.getState, + getServerState, + ); + + const currentNotification = state.queue[0] ?? null; + + return currentNotification ? ( + 1 ? String(state.queue.length) : null} + /> + ) : null; +} + +const master = createGlobalState(null); + +export interface NotificationsProviderProps { + children?: React.ReactNode; +} + +export function NotificationsProvider() { + const context = React.useContext(NotificationsContext); + + const id = React.useId(); + const [masterId] = master.useState(); + + React.useEffect(() => { + master.setState((prev) => (prev === null ? id : prev)); + return () => { + master.setState((prev) => (prev === id ? null : prev)); + }; + }, [id]); + + if (!context || masterId !== id) { + return null; + } + + return ; +} diff --git a/packages/toolpad-utils/src/react.tsx b/packages/toolpad-utils/src/react.tsx index e18d700e3f2..ecd918fa9d8 100644 --- a/packages/toolpad-utils/src/react.tsx +++ b/packages/toolpad-utils/src/react.tsx @@ -101,20 +101,16 @@ export function createGlobalState(initialState: T) { }; }; - const getState = () => { - return state; - }; + const getState = () => state; const setState = (newState: T | ((oldValue: T) => T)) => { state = typeof newState === 'function' ? (newState as Function)(state) : newState; listeners.forEach((cb) => cb(state)); }; - const useValue = () => { - return React.useSyncExternalStore(subscribe, getState); - }; + const useValue = () => React.useSyncExternalStore(subscribe, getState, getState); - const useState = () => { + const useState = (): [T, React.Dispatch>] => { const value = useValue(); return [value, setState]; }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6e0664f24bc..30524451dac 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -561,6 +561,15 @@ importers: packages/toolpad-core: dependencies: + '@mui/lab': + specifier: 5.0.0-alpha.170 + version: 5.0.0-alpha.170(@mui/material@5.15.18)(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0) + '@mui/x-data-grid': + specifier: 7.4.0 + version: 7.4.0(@mui/material@5.15.18)(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0) + '@tanstack/react-query': + specifier: 5.36.0 + version: 5.36.0(react@18.2.0) '@toolpad/utils': specifier: workspace:* version: link:../toolpad-utils @@ -4583,6 +4592,29 @@ packages: - '@types/react' dev: false + /@mui/x-data-grid@7.4.0(@mui/material@5.15.18)(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-ILu0AVqqHQf4wN/nblsJ/k7PkvlB115vQ/FEiYk7neZlc/kOJOUyst3MWMVClAecZ8+JEs476q40xd4r1CtMfw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@mui/material': ^5.15.14 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + dependencies: + '@babel/runtime': 7.24.5 + '@mui/material': 5.15.18(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0) + '@mui/system': 5.15.15(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.3.1)(react@18.2.0) + '@mui/utils': 5.15.14(@types/react@18.3.1)(react@18.2.0) + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + reselect: 4.1.8 + transitivePeerDependencies: + - '@emotion/react' + - '@emotion/styled' + - '@types/react' + dev: false + /@mui/x-data-grid@7.5.1(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@5.15.18)(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-5GuHg95UcphQ3O4LftUEFkNPP00YKUDZoSxmsNJ2+o6pwhHH4f8XIuuXEZJCyEMUiVYQk6/iYZwxJL6CpvbNCw==} engines: {node: '>=14.0.0'} @@ -5809,6 +5841,10 @@ packages: tslib: 2.6.2 dev: false + /@tanstack/query-core@5.36.0: + resolution: {integrity: sha512-B5BD3pg/mztDR36i77hGcyySKKeYrbM5mnogOROTBi1SUml5ByRK7PGUUl16vvubvQC+mSnqziFG/VIy/DE3FQ==} + dev: false + /@tanstack/query-core@5.36.1: resolution: {integrity: sha512-BteWYEPUcucEu3NBcDAgKuI4U25R9aPrHSP6YSf2NvaD2pSlIQTdqOfLRsxH9WdRYg7k0Uom35Uacb6nvbIMJg==} dev: false @@ -5828,6 +5864,15 @@ packages: react: 18.2.0 dev: false + /@tanstack/react-query@5.36.0(react@18.2.0): + resolution: {integrity: sha512-BATvtM0rohwg7pRHUnxgeDiwLWRGZ8OM/4y8LImHVpecQWoH6Uhytu3Z8YV6V7hQ1sMQBFcUrGE1/e4MxR6YiA==} + peerDependencies: + react: ^18.0.0 + dependencies: + '@tanstack/query-core': 5.36.0 + react: 18.2.0 + dev: false + /@tanstack/react-query@5.37.1(react@18.2.0): resolution: {integrity: sha512-EhtBNA8GL3XFeSx6VYUjXQ96n44xe3JGKZCzBINrCYlxbZP6UwBafv7ti4eSRWc2Fy+fybQre0w17gR6lMzULA==} peerDependencies: From 97343b9f09a332b44bf56ed798ba4309e2f818b5 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Fri, 24 May 2024 11:59:15 +0200 Subject: [PATCH 02/36] Update pnpm-lock.yaml --- pnpm-lock.yaml | 45 --------------------------------------------- 1 file changed, 45 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 30524451dac..6e0664f24bc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -561,15 +561,6 @@ importers: packages/toolpad-core: dependencies: - '@mui/lab': - specifier: 5.0.0-alpha.170 - version: 5.0.0-alpha.170(@mui/material@5.15.18)(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0) - '@mui/x-data-grid': - specifier: 7.4.0 - version: 7.4.0(@mui/material@5.15.18)(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0) - '@tanstack/react-query': - specifier: 5.36.0 - version: 5.36.0(react@18.2.0) '@toolpad/utils': specifier: workspace:* version: link:../toolpad-utils @@ -4592,29 +4583,6 @@ packages: - '@types/react' dev: false - /@mui/x-data-grid@7.4.0(@mui/material@5.15.18)(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-ILu0AVqqHQf4wN/nblsJ/k7PkvlB115vQ/FEiYk7neZlc/kOJOUyst3MWMVClAecZ8+JEs476q40xd4r1CtMfw==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@mui/material': ^5.15.14 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - dependencies: - '@babel/runtime': 7.24.5 - '@mui/material': 5.15.18(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0) - '@mui/system': 5.15.15(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.3.1)(react@18.2.0) - '@mui/utils': 5.15.14(@types/react@18.3.1)(react@18.2.0) - clsx: 2.1.1 - prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - reselect: 4.1.8 - transitivePeerDependencies: - - '@emotion/react' - - '@emotion/styled' - - '@types/react' - dev: false - /@mui/x-data-grid@7.5.1(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@mui/material@5.15.18)(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-5GuHg95UcphQ3O4LftUEFkNPP00YKUDZoSxmsNJ2+o6pwhHH4f8XIuuXEZJCyEMUiVYQk6/iYZwxJL6CpvbNCw==} engines: {node: '>=14.0.0'} @@ -5841,10 +5809,6 @@ packages: tslib: 2.6.2 dev: false - /@tanstack/query-core@5.36.0: - resolution: {integrity: sha512-B5BD3pg/mztDR36i77hGcyySKKeYrbM5mnogOROTBi1SUml5ByRK7PGUUl16vvubvQC+mSnqziFG/VIy/DE3FQ==} - dev: false - /@tanstack/query-core@5.36.1: resolution: {integrity: sha512-BteWYEPUcucEu3NBcDAgKuI4U25R9aPrHSP6YSf2NvaD2pSlIQTdqOfLRsxH9WdRYg7k0Uom35Uacb6nvbIMJg==} dev: false @@ -5864,15 +5828,6 @@ packages: react: 18.2.0 dev: false - /@tanstack/react-query@5.36.0(react@18.2.0): - resolution: {integrity: sha512-BATvtM0rohwg7pRHUnxgeDiwLWRGZ8OM/4y8LImHVpecQWoH6Uhytu3Z8YV6V7hQ1sMQBFcUrGE1/e4MxR6YiA==} - peerDependencies: - react: ^18.0.0 - dependencies: - '@tanstack/query-core': 5.36.0 - react: 18.2.0 - dev: false - /@tanstack/react-query@5.37.1(react@18.2.0): resolution: {integrity: sha512-EhtBNA8GL3XFeSx6VYUjXQ96n44xe3JGKZCzBINrCYlxbZP6UwBafv7ti4eSRWc2Fy+fybQre0w17gR6lMzULA==} peerDependencies: From 6cc74ec4c9b8f0361f8c82c42f0e9fb3f5f6de7e Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Fri, 24 May 2024 12:11:40 +0200 Subject: [PATCH 03/36] frwt --- packages/toolpad-core/package.json | 1 + pnpm-lock.yaml | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/toolpad-core/package.json b/packages/toolpad-core/package.json index 150b091d2d2..7505ca4a316 100644 --- a/packages/toolpad-core/package.json +++ b/packages/toolpad-core/package.json @@ -46,6 +46,7 @@ "test": "vitest run" }, "dependencies": { + "@mui/lab": "5.0.0-alpha.170", "@toolpad/utils": "workspace:*", "client-only": "^0.0.1", "invariant": "2.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6e0664f24bc..e1f8e5fd426 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -561,6 +561,9 @@ importers: packages/toolpad-core: dependencies: + '@mui/lab': + specifier: 5.0.0-alpha.170 + version: 5.0.0-alpha.170(@mui/material@5.15.18)(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0) '@toolpad/utils': specifier: workspace:* version: link:../toolpad-utils @@ -3869,7 +3872,7 @@ packages: optional: true dependencies: '@babel/runtime': 7.24.5 - '@mui/material': 5.15.18(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0) + '@mui/material': 5.15.18(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0) '@types/react': 18.3.1 react: 18.2.0 @@ -4095,7 +4098,6 @@ packages: react-dom: 18.2.0(react@18.2.0) react-is: 18.2.0 react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) - dev: false /@mui/material@5.15.18(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-n+/dsiqux74fFfcRUJjok+ieNQ7+BEk6/OwX9cLcLvriZrZb+/7Y8+Fd2HlUUbn5N0CDurgAHm0VH1DqyJ9HAw==} From 7170702dd55a77f94bb5964a166bed2efdba5655 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Fri, 24 May 2024 12:37:08 +0200 Subject: [PATCH 04/36] Update pnpm-lock.yaml --- pnpm-lock.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e1f8e5fd426..45447f4075d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3872,7 +3872,7 @@ packages: optional: true dependencies: '@babel/runtime': 7.24.5 - '@mui/material': 5.15.18(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0) + '@mui/material': 5.15.18(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.3.1)(react-dom@18.2.0)(react@18.2.0) '@types/react': 18.3.1 react: 18.2.0 @@ -4098,6 +4098,7 @@ packages: react-dom: 18.2.0(react@18.2.0) react-is: 18.2.0 react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) + dev: false /@mui/material@5.15.18(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-n+/dsiqux74fFfcRUJjok+ieNQ7+BEk6/OwX9cLcLvriZrZb+/7Y8+Fd2HlUUbn5N0CDurgAHm0VH1DqyJ9HAw==} From 5b437a6959013939934fb9a1dc07749e5f51f8e1 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 11:11:53 +0200 Subject: [PATCH 05/36] Update notifications --- .../notifications/AlertNotification.js | 6 +- .../notifications/AlertNotification.tsx | 6 +- .../notifications/BasicNotification.js | 6 +- .../notifications/BasicNotification.tsx | 6 +- .../notifications/CloseNotification.js | 6 +- .../notifications/CloseNotification.tsx | 6 +- .../notifications/DedupeNotification.js | 6 +- .../notifications/DedupeNotification.tsx | 6 +- .../notifications/MultipleNotifications.js | 6 +- .../notifications/MultipleNotifications.tsx | 6 +- .../notifications/ScopedNotification.js | 40 ++++++ .../notifications/ScopedNotification.tsx | 40 ++++++ .../ScopedNotification.tsx.preview | 3 + .../components/notifications/notifications.md | 19 +-- docs/data/toolpad/core/pages.ts | 4 +- .../toolpad/core/components/notifications.js | 7 - .../dialogs.js => react-dialogs/index.js} | 0 .../toolpad/core/react-notifications/index.js | 29 ++++ .../src/AppProvider/AppProvider.tsx | 15 +- packages/toolpad-core/src/index.ts | 2 +- .../toolpad-core/src/notifications/index.ts | 1 + .../notifications.tsx} | 135 ++++++++---------- .../src/useNotifications/index.ts | 1 - 23 files changed, 201 insertions(+), 155 deletions(-) create mode 100644 docs/data/toolpad/core/components/notifications/ScopedNotification.js create mode 100644 docs/data/toolpad/core/components/notifications/ScopedNotification.tsx create mode 100644 docs/data/toolpad/core/components/notifications/ScopedNotification.tsx.preview delete mode 100644 docs/pages/toolpad/core/components/notifications.js rename docs/pages/toolpad/core/{components/dialogs.js => react-dialogs/index.js} (100%) create mode 100644 docs/pages/toolpad/core/react-notifications/index.js create mode 100644 packages/toolpad-core/src/notifications/index.ts rename packages/toolpad-core/src/{useNotifications/useNotifications.tsx => notifications/notifications.tsx} (58%) delete mode 100644 packages/toolpad-core/src/useNotifications/index.ts diff --git a/docs/data/toolpad/core/components/notifications/AlertNotification.js b/docs/data/toolpad/core/components/notifications/AlertNotification.js index 5e285a068d0..bdd1b0377fd 100644 --- a/docs/data/toolpad/core/components/notifications/AlertNotification.js +++ b/docs/data/toolpad/core/components/notifications/AlertNotification.js @@ -1,8 +1,5 @@ import * as React from 'react'; -import { - NotificationsProvider, - useNotifications, -} from '@toolpad/core/useNotifications'; +import { useNotifications } from '@toolpad/core/notifications'; import Button from '@mui/material/Button'; import FormControlLabel from '@mui/material/FormControlLabel'; import FormControl from '@mui/material/FormControl'; @@ -16,7 +13,6 @@ export default function AlertNotification() { const [severity, setSeverity] = React.useState('info'); return (
- Severity diff --git a/docs/data/toolpad/core/components/notifications/AlertNotification.tsx b/docs/data/toolpad/core/components/notifications/AlertNotification.tsx index bd8289a20a7..1e37e3e9864 100644 --- a/docs/data/toolpad/core/components/notifications/AlertNotification.tsx +++ b/docs/data/toolpad/core/components/notifications/AlertNotification.tsx @@ -1,8 +1,5 @@ import * as React from 'react'; -import { - NotificationsProvider, - useNotifications, -} from '@toolpad/core/useNotifications'; +import { useNotifications } from '@toolpad/core/notifications'; import Button from '@mui/material/Button'; import FormControlLabel from '@mui/material/FormControlLabel'; import FormControl from '@mui/material/FormControl'; @@ -18,7 +15,6 @@ export default function AlertNotification() { >('info'); return (
- Severity diff --git a/docs/data/toolpad/core/components/notifications/BasicNotification.js b/docs/data/toolpad/core/components/notifications/BasicNotification.js index 832f96ab71f..a5be51c396c 100644 --- a/docs/data/toolpad/core/components/notifications/BasicNotification.js +++ b/docs/data/toolpad/core/components/notifications/BasicNotification.js @@ -1,15 +1,11 @@ import * as React from 'react'; -import { - NotificationsProvider, - useNotifications, -} from '@toolpad/core/useNotifications'; +import { useNotifications } from '@toolpad/core/notifications'; import Button from '@mui/material/Button'; export default function BasicNotification() { const notifications = useNotifications(); return (
- + + ); +} + +export default function ScopedNotification() { + return ( + + + + + + ); +} diff --git a/docs/data/toolpad/core/components/notifications/ScopedNotification.tsx b/docs/data/toolpad/core/components/notifications/ScopedNotification.tsx new file mode 100644 index 00000000000..53bf07eeb82 --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/ScopedNotification.tsx @@ -0,0 +1,40 @@ +import * as React from 'react'; +import { + NotificationsProvider, + useNotifications, +} from '@toolpad/core/notifications'; +import Button from '@mui/material/Button'; +import { Box, Snackbar, styled } from '@mui/material'; + +const ScopedSnackbar = styled(Snackbar)({ position: 'absolute' }); + +const notificationsProviderSlots = { + snackbar: ScopedSnackbar, +}; + +function ScopedContent() { + const notifications = useNotifications(); + return ( + + + + ); +} + +export default function ScopedNotification() { + return ( + + + + + + ); +} diff --git a/docs/data/toolpad/core/components/notifications/ScopedNotification.tsx.preview b/docs/data/toolpad/core/components/notifications/ScopedNotification.tsx.preview new file mode 100644 index 00000000000..63b153cf7dd --- /dev/null +++ b/docs/data/toolpad/core/components/notifications/ScopedNotification.tsx.preview @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/docs/data/toolpad/core/components/notifications/notifications.md b/docs/data/toolpad/core/components/notifications/notifications.md index 8c7ca1bd3ff..2ca6d747375 100644 --- a/docs/data/toolpad/core/components/notifications/notifications.md +++ b/docs/data/toolpad/core/components/notifications/notifications.md @@ -7,22 +7,17 @@ Toolpad core offers a set of abstractions that make it easier to interact with n First thing you need to do to get access to the notifications APIs is install the NotificationsProvider. ```js -import { NotificationsProvider } from '@toolpad/core/useNotifications'; +import { NotificationsProvider } from '@toolpad/core/notifications'; function App({ children }) { - return ( - - {children} - - - ); + return {children}; } ``` -To then get acess to the notifications APIs you need to call the `useNotifications` hook. +Now you can get acess to the notifications APIs through the `useNotifications` hook. ```js -import { useNotifications } from '@toolpad/core/useNotifications'; +import { useNotifications } from '@toolpad/core/notifications'; function MyApp() { const notifications = useNotifications(); @@ -64,6 +59,12 @@ You can supply your own value for a key to shown notifications to associate them {{"demo": "DedupeNotification.js"}} +## Scoped notifications + +Notifcation providers can be nested. That way you can scope the notifications to a subset of the page. Use the slots to position the snackbar relative to a specific element on the page. + +{{"demo": "ScopedNotification.js"}} + ## 🚧 Notification center When multiple notifications are available, click the badge to open the notification center to show a scrollable list of all available notifications. This feature is not available yet. diff --git a/docs/data/toolpad/core/pages.ts b/docs/data/toolpad/core/pages.ts index 3a4bac81223..e1b79b8b161 100644 --- a/docs/data/toolpad/core/pages.ts +++ b/docs/data/toolpad/core/pages.ts @@ -92,11 +92,11 @@ const pages: MuiPage[] = [ subheader: 'Utils', children: [ { - pathname: '/toolpad/core/components/dialogs', + pathname: '/toolpad/core/react-dialogs', title: 'dialogs', }, { - pathname: '/toolpad/core/components/notifications', + pathname: '/toolpad/core/react-notifications', title: 'notifications', }, ], diff --git a/docs/pages/toolpad/core/components/notifications.js b/docs/pages/toolpad/core/components/notifications.js deleted file mode 100644 index 1e208a61779..00000000000 --- a/docs/pages/toolpad/core/components/notifications.js +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import * as pageProps from 'docs-toolpad/data/toolpad/core/components/notifications/notifications.md?muiMarkdown'; - -export default function Page() { - return ; -} diff --git a/docs/pages/toolpad/core/components/dialogs.js b/docs/pages/toolpad/core/react-dialogs/index.js similarity index 100% rename from docs/pages/toolpad/core/components/dialogs.js rename to docs/pages/toolpad/core/react-dialogs/index.js diff --git a/docs/pages/toolpad/core/react-notifications/index.js b/docs/pages/toolpad/core/react-notifications/index.js new file mode 100644 index 00000000000..58a43b6a66c --- /dev/null +++ b/docs/pages/toolpad/core/react-notifications/index.js @@ -0,0 +1,29 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docs-toolpad/data/toolpad/core/components/notifications/notifications.md?muiMarkdown'; +import { NotificationsProvider } from '@toolpad/core/notifications'; +import { Snackbar, createTheme, useTheme, ThemeProvider } from '@mui/material'; + +function DemoThemedSnackbar(props) { + const outerTheme = useTheme(); + const paletteMode = outerTheme.palette.mode; + const demoTheme = React.useMemo( + () => createTheme({ palette: { mode: paletteMode } }), + [paletteMode], + ); + return ( + + + + ); +} + +const notificationsProviderSlots = { snackbar: DemoThemedSnackbar }; + +export default function Page() { + return ( + + + + ); +} diff --git a/packages/toolpad-core/src/AppProvider/AppProvider.tsx b/packages/toolpad-core/src/AppProvider/AppProvider.tsx index 9e6b048a9fe..f19f3b91fc7 100644 --- a/packages/toolpad-core/src/AppProvider/AppProvider.tsx +++ b/packages/toolpad-core/src/AppProvider/AppProvider.tsx @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; import { ThemeProvider, Theme } from '@mui/material/styles'; import CssBaseline from '@mui/material/CssBaseline'; import { baseTheme } from '../themes'; -import { NotificationsProvider } from '../useNotifications'; +import { NotificationsProvider } from '../notifications'; import { DialogProvider } from '../useDialogs'; export interface NavigateOptions { @@ -103,12 +103,13 @@ function AppProvider(props: AppProviderProps) { - - - - {children} - - + + + + {children} + + + ); diff --git a/packages/toolpad-core/src/index.ts b/packages/toolpad-core/src/index.ts index 6257db47151..8377e1a1b53 100644 --- a/packages/toolpad-core/src/index.ts +++ b/packages/toolpad-core/src/index.ts @@ -10,4 +10,4 @@ export * from './LineChart'; export * from './useDialogs'; -export * from './useNotifications'; +export * from './notifications'; diff --git a/packages/toolpad-core/src/notifications/index.ts b/packages/toolpad-core/src/notifications/index.ts new file mode 100644 index 00000000000..9ea5ce778c9 --- /dev/null +++ b/packages/toolpad-core/src/notifications/index.ts @@ -0,0 +1 @@ +export * from './notifications'; diff --git a/packages/toolpad-core/src/useNotifications/useNotifications.tsx b/packages/toolpad-core/src/notifications/notifications.tsx similarity index 58% rename from packages/toolpad-core/src/useNotifications/useNotifications.tsx rename to packages/toolpad-core/src/notifications/notifications.tsx index 53e490d5e6c..f1012688dba 100644 --- a/packages/toolpad-core/src/useNotifications/useNotifications.tsx +++ b/packages/toolpad-core/src/notifications/notifications.tsx @@ -7,10 +7,11 @@ import { Snackbar, SnackbarCloseReason, SnackbarContent, + SnackbarProps, } from '@mui/material'; import CloseIcon from '@mui/icons-material/Close'; import * as React from 'react'; -import { createGlobalState, useNonNullableContext } from '@toolpad/utils/react'; +import { useNonNullableContext } from '@toolpad/utils/react'; const closeText = 'Close'; @@ -42,60 +43,19 @@ interface NotificationsState { } interface NotificationsContextValue { - getState: () => NotificationsState; - subscribe: (cb: () => void) => () => void; show: ShowNotification; close: CloseNotification; } -function createNotificationsContext(): NotificationsContextValue | null { - if (typeof window === 'undefined') { - return null; - } +const NotificationsContext = React.createContext(null); - let nextId = 1; - let state: NotificationsState = { queue: [] }; - // Only one subscriber allowed, last one wins - const subscribers = new Set<() => void>(); - - const setState: React.Dispatch> = (newState) => { - state = typeof newState === 'function' ? newState(state) : newState; - Array.from(subscribers).forEach((cb) => cb()); - }; - - return { - getState: () => state, - subscribe: (cb) => { - subscribers.add(cb); - return () => { - subscribers.delete(cb); - }; - }, - show: (message, options = {}) => { - const notificationKey = options.key ?? `::toolpad-internal::notification::${nextId}`; - nextId += 1; - setState((prev) => { - if (prev.queue.some((n) => n.notificationKey === notificationKey)) { - // deduplicate by key - return prev; - } - return { - ...prev, - queue: [...prev.queue, { message, options, notificationKey, open: true }], - }; - }); - return notificationKey; - }, - close: (key) => { - setState((prev) => ({ - ...prev, - queue: prev.queue.filter((n) => n.notificationKey !== key), - })); - }, - }; -} +const SlotsContext = React.createContext({ + snackbar: Snackbar, +}); -const NotificationsContext = React.createContext(createNotificationsContext()); +export interface NotificationsProviderSlots { + snackbar: React.ComponentType; +} interface NotificationProps { notificationKey: string; @@ -139,8 +99,10 @@ function Notification({ notificationKey, open, message, options, badge }: Notifi ); + const { snackbar: SnackbarComponent } = React.useContext(SlotsContext); + return ( - )} - + ); } @@ -186,17 +148,10 @@ export function useNotifications(): UseNotifications { } interface NotificationsUiProps { - context: NotificationsContextValue; + state: NotificationsState; } -function Notifications({ context }: NotificationsUiProps) { - const getServerState = React.useCallback(() => ({ queue: [] }), []); - const state: NotificationsState = React.useSyncExternalStore( - context.subscribe, - context.getState, - getServerState, - ); - +function Notifications({ state }: NotificationsUiProps) { const currentNotification = state.queue[0] ?? null; return currentNotification ? ( @@ -206,29 +161,53 @@ function Notifications({ context }: NotificationsUiProps) { /> ) : null; } - -const master = createGlobalState(null); - export interface NotificationsProviderProps { children?: React.ReactNode; + slots?: Partial; } -export function NotificationsProvider() { - const context = React.useContext(NotificationsContext); - - const id = React.useId(); - const [masterId] = master.useState(); +let nextId = 1; - React.useEffect(() => { - master.setState((prev) => (prev === null ? id : prev)); - return () => { - master.setState((prev) => (prev === id ? null : prev)); - }; - }, [id]); +export function NotificationsProvider({ children, slots }: NotificationsProviderProps) { + const [state, setState] = React.useState({ queue: [] }); - if (!context || masterId !== id) { - return null; - } + const show = React.useCallback((message, options = {}) => { + const notificationKey = options.key ?? `::toolpad-internal::notification::${nextId}`; + nextId += 1; + setState((prev) => { + if (prev.queue.some((n) => n.notificationKey === notificationKey)) { + // deduplicate by key + return prev; + } + return { + ...prev, + queue: [...prev.queue, { message, options, notificationKey, open: true }], + }; + }); + return notificationKey; + }, []); + + const close = React.useCallback((key) => { + setState((prev) => ({ + ...prev, + queue: prev.queue.filter((n) => n.notificationKey !== key), + })); + }, []); + + const contextValue = React.useMemo(() => ({ show, close }), [show, close]); + + const outerSlots = React.useContext(SlotsContext); + const slotsContextValue = React.useMemo( + () => (slots ? { ...outerSlots, ...slots } : outerSlots), + [outerSlots, slots], + ); - return ; + return ( + + + {children} + + + + ); } diff --git a/packages/toolpad-core/src/useNotifications/index.ts b/packages/toolpad-core/src/useNotifications/index.ts deleted file mode 100644 index 0435a4c45c0..00000000000 --- a/packages/toolpad-core/src/useNotifications/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './useNotifications'; From 910a9d3cda94d3c903e7e4901eeb55c741c9d5a3 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 11:16:35 +0200 Subject: [PATCH 06/36] revert --- .../components/{dialogs => use-dialogs}/AlertDialog.js | 0 .../components/{dialogs => use-dialogs}/AlertDialog.tsx | 0 .../{dialogs => use-dialogs}/AlertDialog.tsx.preview | 0 .../components/{dialogs => use-dialogs}/ConfirmDialog.js | 0 .../components/{dialogs => use-dialogs}/ConfirmDialog.tsx | 0 .../{dialogs => use-dialogs}/ConfirmDialog.tsx.preview | 0 .../components/{dialogs => use-dialogs}/CustomDialog.js | 0 .../components/{dialogs => use-dialogs}/CustomDialog.tsx | 0 .../{dialogs => use-dialogs}/CustomDialog.tsx.preview | 0 .../{dialogs => use-dialogs}/CustomDialogWithPayload.js | 0 .../{dialogs => use-dialogs}/CustomDialogWithPayload.tsx | 0 .../CustomDialogWithPayload.tsx.preview | 0 .../{dialogs => use-dialogs}/CustomDialogWithResult.js | 0 .../{dialogs => use-dialogs}/CustomDialogWithResult.tsx | 0 .../CustomDialogWithResult.tsx.preview | 0 .../components/{dialogs => use-dialogs}/PromptDialog.js | 0 .../components/{dialogs => use-dialogs}/PromptDialog.tsx | 0 .../{dialogs => use-dialogs}/PromptDialog.tsx.preview | 0 .../components/{dialogs => use-dialogs}/StackedDialog.js | 0 .../components/{dialogs => use-dialogs}/StackedDialog.tsx | 0 .../{dialogs => use-dialogs}/StackedDialog.tsx.preview | 0 .../{dialogs/dialogs.md => use-dialogs/use-dialogs.md} | 0 .../AlertNotification.js | 2 +- .../AlertNotification.tsx | 2 +- .../AlertNotification.tsx.preview | 0 .../BasicNotification.js | 2 +- .../BasicNotification.tsx | 2 +- .../BasicNotification.tsx.preview | 0 .../CloseNotification.js | 2 +- .../CloseNotification.tsx | 2 +- .../CloseNotification.tsx.preview | 0 .../DedupeNotification.js | 2 +- .../DedupeNotification.tsx | 2 +- .../DedupeNotification.tsx.preview | 0 .../MultipleNotifications.js | 2 +- .../MultipleNotifications.tsx | 2 +- .../MultipleNotifications.tsx.preview | 0 .../ScopedNotification.js | 2 +- .../ScopedNotification.tsx | 2 +- .../ScopedNotification.tsx.preview | 0 .../use-notifications.md} | 4 ++-- docs/data/toolpad/core/pages.ts | 8 ++++---- .../core/{react-dialogs => react-use-dialogs}/index.js | 2 +- .../index.js | 4 ++-- packages/toolpad-core/src/AppProvider/AppProvider.tsx | 2 +- packages/toolpad-core/src/index.ts | 2 +- packages/toolpad-core/src/notifications/index.ts | 1 - packages/toolpad-core/src/useNotifications/index.ts | 1 + .../useNotifications.tsx} | 0 49 files changed, 24 insertions(+), 24 deletions(-) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/AlertDialog.js (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/AlertDialog.tsx (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/AlertDialog.tsx.preview (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/ConfirmDialog.js (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/ConfirmDialog.tsx (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/ConfirmDialog.tsx.preview (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/CustomDialog.js (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/CustomDialog.tsx (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/CustomDialog.tsx.preview (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/CustomDialogWithPayload.js (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/CustomDialogWithPayload.tsx (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/CustomDialogWithPayload.tsx.preview (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/CustomDialogWithResult.js (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/CustomDialogWithResult.tsx (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/CustomDialogWithResult.tsx.preview (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/PromptDialog.js (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/PromptDialog.tsx (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/PromptDialog.tsx.preview (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/StackedDialog.js (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/StackedDialog.tsx (100%) rename docs/data/toolpad/core/components/{dialogs => use-dialogs}/StackedDialog.tsx.preview (100%) rename docs/data/toolpad/core/components/{dialogs/dialogs.md => use-dialogs/use-dialogs.md} (100%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/AlertNotification.js (96%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/AlertNotification.tsx (96%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/AlertNotification.tsx.preview (100%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/BasicNotification.js (87%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/BasicNotification.tsx (87%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/BasicNotification.tsx.preview (100%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/CloseNotification.js (93%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/CloseNotification.tsx (93%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/CloseNotification.tsx.preview (100%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/DedupeNotification.js (89%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/DedupeNotification.tsx (89%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/DedupeNotification.tsx.preview (100%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/MultipleNotifications.js (88%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/MultipleNotifications.tsx (88%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/MultipleNotifications.tsx.preview (100%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/ScopedNotification.js (95%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/ScopedNotification.tsx (95%) rename docs/data/toolpad/core/components/{notifications => use-notifications}/ScopedNotification.tsx.preview (100%) rename docs/data/toolpad/core/components/{notifications/notifications.md => use-notifications/use-notifications.md} (95%) rename docs/pages/toolpad/core/{react-dialogs => react-use-dialogs}/index.js (84%) rename docs/pages/toolpad/core/{react-notifications => react-use-notifications}/index.js (86%) delete mode 100644 packages/toolpad-core/src/notifications/index.ts create mode 100644 packages/toolpad-core/src/useNotifications/index.ts rename packages/toolpad-core/src/{notifications/notifications.tsx => useNotifications/useNotifications.tsx} (100%) diff --git a/docs/data/toolpad/core/components/dialogs/AlertDialog.js b/docs/data/toolpad/core/components/use-dialogs/AlertDialog.js similarity index 100% rename from docs/data/toolpad/core/components/dialogs/AlertDialog.js rename to docs/data/toolpad/core/components/use-dialogs/AlertDialog.js diff --git a/docs/data/toolpad/core/components/dialogs/AlertDialog.tsx b/docs/data/toolpad/core/components/use-dialogs/AlertDialog.tsx similarity index 100% rename from docs/data/toolpad/core/components/dialogs/AlertDialog.tsx rename to docs/data/toolpad/core/components/use-dialogs/AlertDialog.tsx diff --git a/docs/data/toolpad/core/components/dialogs/AlertDialog.tsx.preview b/docs/data/toolpad/core/components/use-dialogs/AlertDialog.tsx.preview similarity index 100% rename from docs/data/toolpad/core/components/dialogs/AlertDialog.tsx.preview rename to docs/data/toolpad/core/components/use-dialogs/AlertDialog.tsx.preview diff --git a/docs/data/toolpad/core/components/dialogs/ConfirmDialog.js b/docs/data/toolpad/core/components/use-dialogs/ConfirmDialog.js similarity index 100% rename from docs/data/toolpad/core/components/dialogs/ConfirmDialog.js rename to docs/data/toolpad/core/components/use-dialogs/ConfirmDialog.js diff --git a/docs/data/toolpad/core/components/dialogs/ConfirmDialog.tsx b/docs/data/toolpad/core/components/use-dialogs/ConfirmDialog.tsx similarity index 100% rename from docs/data/toolpad/core/components/dialogs/ConfirmDialog.tsx rename to docs/data/toolpad/core/components/use-dialogs/ConfirmDialog.tsx diff --git a/docs/data/toolpad/core/components/dialogs/ConfirmDialog.tsx.preview b/docs/data/toolpad/core/components/use-dialogs/ConfirmDialog.tsx.preview similarity index 100% rename from docs/data/toolpad/core/components/dialogs/ConfirmDialog.tsx.preview rename to docs/data/toolpad/core/components/use-dialogs/ConfirmDialog.tsx.preview diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialog.js b/docs/data/toolpad/core/components/use-dialogs/CustomDialog.js similarity index 100% rename from docs/data/toolpad/core/components/dialogs/CustomDialog.js rename to docs/data/toolpad/core/components/use-dialogs/CustomDialog.js diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialog.tsx b/docs/data/toolpad/core/components/use-dialogs/CustomDialog.tsx similarity index 100% rename from docs/data/toolpad/core/components/dialogs/CustomDialog.tsx rename to docs/data/toolpad/core/components/use-dialogs/CustomDialog.tsx diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialog.tsx.preview b/docs/data/toolpad/core/components/use-dialogs/CustomDialog.tsx.preview similarity index 100% rename from docs/data/toolpad/core/components/dialogs/CustomDialog.tsx.preview rename to docs/data/toolpad/core/components/use-dialogs/CustomDialog.tsx.preview diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.js b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.js similarity index 100% rename from docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.js rename to docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.js diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.tsx b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.tsx similarity index 100% rename from docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.tsx rename to docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.tsx diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.tsx.preview b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.tsx.preview similarity index 100% rename from docs/data/toolpad/core/components/dialogs/CustomDialogWithPayload.tsx.preview rename to docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.tsx.preview diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.js b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.js similarity index 100% rename from docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.js rename to docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.js diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.tsx b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.tsx similarity index 100% rename from docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.tsx rename to docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.tsx diff --git a/docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.tsx.preview b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.tsx.preview similarity index 100% rename from docs/data/toolpad/core/components/dialogs/CustomDialogWithResult.tsx.preview rename to docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.tsx.preview diff --git a/docs/data/toolpad/core/components/dialogs/PromptDialog.js b/docs/data/toolpad/core/components/use-dialogs/PromptDialog.js similarity index 100% rename from docs/data/toolpad/core/components/dialogs/PromptDialog.js rename to docs/data/toolpad/core/components/use-dialogs/PromptDialog.js diff --git a/docs/data/toolpad/core/components/dialogs/PromptDialog.tsx b/docs/data/toolpad/core/components/use-dialogs/PromptDialog.tsx similarity index 100% rename from docs/data/toolpad/core/components/dialogs/PromptDialog.tsx rename to docs/data/toolpad/core/components/use-dialogs/PromptDialog.tsx diff --git a/docs/data/toolpad/core/components/dialogs/PromptDialog.tsx.preview b/docs/data/toolpad/core/components/use-dialogs/PromptDialog.tsx.preview similarity index 100% rename from docs/data/toolpad/core/components/dialogs/PromptDialog.tsx.preview rename to docs/data/toolpad/core/components/use-dialogs/PromptDialog.tsx.preview diff --git a/docs/data/toolpad/core/components/dialogs/StackedDialog.js b/docs/data/toolpad/core/components/use-dialogs/StackedDialog.js similarity index 100% rename from docs/data/toolpad/core/components/dialogs/StackedDialog.js rename to docs/data/toolpad/core/components/use-dialogs/StackedDialog.js diff --git a/docs/data/toolpad/core/components/dialogs/StackedDialog.tsx b/docs/data/toolpad/core/components/use-dialogs/StackedDialog.tsx similarity index 100% rename from docs/data/toolpad/core/components/dialogs/StackedDialog.tsx rename to docs/data/toolpad/core/components/use-dialogs/StackedDialog.tsx diff --git a/docs/data/toolpad/core/components/dialogs/StackedDialog.tsx.preview b/docs/data/toolpad/core/components/use-dialogs/StackedDialog.tsx.preview similarity index 100% rename from docs/data/toolpad/core/components/dialogs/StackedDialog.tsx.preview rename to docs/data/toolpad/core/components/use-dialogs/StackedDialog.tsx.preview diff --git a/docs/data/toolpad/core/components/dialogs/dialogs.md b/docs/data/toolpad/core/components/use-dialogs/use-dialogs.md similarity index 100% rename from docs/data/toolpad/core/components/dialogs/dialogs.md rename to docs/data/toolpad/core/components/use-dialogs/use-dialogs.md diff --git a/docs/data/toolpad/core/components/notifications/AlertNotification.js b/docs/data/toolpad/core/components/use-notifications/AlertNotification.js similarity index 96% rename from docs/data/toolpad/core/components/notifications/AlertNotification.js rename to docs/data/toolpad/core/components/use-notifications/AlertNotification.js index bdd1b0377fd..a00e3f97bf5 100644 --- a/docs/data/toolpad/core/components/notifications/AlertNotification.js +++ b/docs/data/toolpad/core/components/use-notifications/AlertNotification.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useNotifications } from '@toolpad/core/notifications'; +import { useNotifications } from '@toolpad/core/useNotifications'; import Button from '@mui/material/Button'; import FormControlLabel from '@mui/material/FormControlLabel'; import FormControl from '@mui/material/FormControl'; diff --git a/docs/data/toolpad/core/components/notifications/AlertNotification.tsx b/docs/data/toolpad/core/components/use-notifications/AlertNotification.tsx similarity index 96% rename from docs/data/toolpad/core/components/notifications/AlertNotification.tsx rename to docs/data/toolpad/core/components/use-notifications/AlertNotification.tsx index 1e37e3e9864..68741c87b4b 100644 --- a/docs/data/toolpad/core/components/notifications/AlertNotification.tsx +++ b/docs/data/toolpad/core/components/use-notifications/AlertNotification.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useNotifications } from '@toolpad/core/notifications'; +import { useNotifications } from '@toolpad/core/useNotifications'; import Button from '@mui/material/Button'; import FormControlLabel from '@mui/material/FormControlLabel'; import FormControl from '@mui/material/FormControl'; diff --git a/docs/data/toolpad/core/components/notifications/AlertNotification.tsx.preview b/docs/data/toolpad/core/components/use-notifications/AlertNotification.tsx.preview similarity index 100% rename from docs/data/toolpad/core/components/notifications/AlertNotification.tsx.preview rename to docs/data/toolpad/core/components/use-notifications/AlertNotification.tsx.preview diff --git a/docs/data/toolpad/core/components/notifications/BasicNotification.js b/docs/data/toolpad/core/components/use-notifications/BasicNotification.js similarity index 87% rename from docs/data/toolpad/core/components/notifications/BasicNotification.js rename to docs/data/toolpad/core/components/use-notifications/BasicNotification.js index a5be51c396c..5e5fa525acc 100644 --- a/docs/data/toolpad/core/components/notifications/BasicNotification.js +++ b/docs/data/toolpad/core/components/use-notifications/BasicNotification.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useNotifications } from '@toolpad/core/notifications'; +import { useNotifications } from '@toolpad/core/useNotifications'; import Button from '@mui/material/Button'; export default function BasicNotification() { diff --git a/docs/data/toolpad/core/components/notifications/BasicNotification.tsx b/docs/data/toolpad/core/components/use-notifications/BasicNotification.tsx similarity index 87% rename from docs/data/toolpad/core/components/notifications/BasicNotification.tsx rename to docs/data/toolpad/core/components/use-notifications/BasicNotification.tsx index a5be51c396c..5e5fa525acc 100644 --- a/docs/data/toolpad/core/components/notifications/BasicNotification.tsx +++ b/docs/data/toolpad/core/components/use-notifications/BasicNotification.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useNotifications } from '@toolpad/core/notifications'; +import { useNotifications } from '@toolpad/core/useNotifications'; import Button from '@mui/material/Button'; export default function BasicNotification() { diff --git a/docs/data/toolpad/core/components/notifications/BasicNotification.tsx.preview b/docs/data/toolpad/core/components/use-notifications/BasicNotification.tsx.preview similarity index 100% rename from docs/data/toolpad/core/components/notifications/BasicNotification.tsx.preview rename to docs/data/toolpad/core/components/use-notifications/BasicNotification.tsx.preview diff --git a/docs/data/toolpad/core/components/notifications/CloseNotification.js b/docs/data/toolpad/core/components/use-notifications/CloseNotification.js similarity index 93% rename from docs/data/toolpad/core/components/notifications/CloseNotification.js rename to docs/data/toolpad/core/components/use-notifications/CloseNotification.js index 66ab0338b7b..a8a0402e77a 100644 --- a/docs/data/toolpad/core/components/notifications/CloseNotification.js +++ b/docs/data/toolpad/core/components/use-notifications/CloseNotification.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useNotifications } from '@toolpad/core/notifications'; +import { useNotifications } from '@toolpad/core/useNotifications'; import FormControlLabel from '@mui/material/FormControlLabel'; import Switch from '@mui/material/Switch'; diff --git a/docs/data/toolpad/core/components/notifications/CloseNotification.tsx b/docs/data/toolpad/core/components/use-notifications/CloseNotification.tsx similarity index 93% rename from docs/data/toolpad/core/components/notifications/CloseNotification.tsx rename to docs/data/toolpad/core/components/use-notifications/CloseNotification.tsx index 66ab0338b7b..a8a0402e77a 100644 --- a/docs/data/toolpad/core/components/notifications/CloseNotification.tsx +++ b/docs/data/toolpad/core/components/use-notifications/CloseNotification.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useNotifications } from '@toolpad/core/notifications'; +import { useNotifications } from '@toolpad/core/useNotifications'; import FormControlLabel from '@mui/material/FormControlLabel'; import Switch from '@mui/material/Switch'; diff --git a/docs/data/toolpad/core/components/notifications/CloseNotification.tsx.preview b/docs/data/toolpad/core/components/use-notifications/CloseNotification.tsx.preview similarity index 100% rename from docs/data/toolpad/core/components/notifications/CloseNotification.tsx.preview rename to docs/data/toolpad/core/components/use-notifications/CloseNotification.tsx.preview diff --git a/docs/data/toolpad/core/components/notifications/DedupeNotification.js b/docs/data/toolpad/core/components/use-notifications/DedupeNotification.js similarity index 89% rename from docs/data/toolpad/core/components/notifications/DedupeNotification.js rename to docs/data/toolpad/core/components/use-notifications/DedupeNotification.js index 5f54e9e8758..08a9704da3d 100644 --- a/docs/data/toolpad/core/components/notifications/DedupeNotification.js +++ b/docs/data/toolpad/core/components/use-notifications/DedupeNotification.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useNotifications } from '@toolpad/core/notifications'; +import { useNotifications } from '@toolpad/core/useNotifications'; import Button from '@mui/material/Button'; export default function DedupeNotification() { diff --git a/docs/data/toolpad/core/components/notifications/DedupeNotification.tsx b/docs/data/toolpad/core/components/use-notifications/DedupeNotification.tsx similarity index 89% rename from docs/data/toolpad/core/components/notifications/DedupeNotification.tsx rename to docs/data/toolpad/core/components/use-notifications/DedupeNotification.tsx index 5f54e9e8758..08a9704da3d 100644 --- a/docs/data/toolpad/core/components/notifications/DedupeNotification.tsx +++ b/docs/data/toolpad/core/components/use-notifications/DedupeNotification.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useNotifications } from '@toolpad/core/notifications'; +import { useNotifications } from '@toolpad/core/useNotifications'; import Button from '@mui/material/Button'; export default function DedupeNotification() { diff --git a/docs/data/toolpad/core/components/notifications/DedupeNotification.tsx.preview b/docs/data/toolpad/core/components/use-notifications/DedupeNotification.tsx.preview similarity index 100% rename from docs/data/toolpad/core/components/notifications/DedupeNotification.tsx.preview rename to docs/data/toolpad/core/components/use-notifications/DedupeNotification.tsx.preview diff --git a/docs/data/toolpad/core/components/notifications/MultipleNotifications.js b/docs/data/toolpad/core/components/use-notifications/MultipleNotifications.js similarity index 88% rename from docs/data/toolpad/core/components/notifications/MultipleNotifications.js rename to docs/data/toolpad/core/components/use-notifications/MultipleNotifications.js index aea8a4e35eb..cab319417ec 100644 --- a/docs/data/toolpad/core/components/notifications/MultipleNotifications.js +++ b/docs/data/toolpad/core/components/use-notifications/MultipleNotifications.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useNotifications } from '@toolpad/core/notifications'; +import { useNotifications } from '@toolpad/core/useNotifications'; import Button from '@mui/material/Button'; export default function MultipleNotifications() { diff --git a/docs/data/toolpad/core/components/notifications/MultipleNotifications.tsx b/docs/data/toolpad/core/components/use-notifications/MultipleNotifications.tsx similarity index 88% rename from docs/data/toolpad/core/components/notifications/MultipleNotifications.tsx rename to docs/data/toolpad/core/components/use-notifications/MultipleNotifications.tsx index aea8a4e35eb..cab319417ec 100644 --- a/docs/data/toolpad/core/components/notifications/MultipleNotifications.tsx +++ b/docs/data/toolpad/core/components/use-notifications/MultipleNotifications.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { useNotifications } from '@toolpad/core/notifications'; +import { useNotifications } from '@toolpad/core/useNotifications'; import Button from '@mui/material/Button'; export default function MultipleNotifications() { diff --git a/docs/data/toolpad/core/components/notifications/MultipleNotifications.tsx.preview b/docs/data/toolpad/core/components/use-notifications/MultipleNotifications.tsx.preview similarity index 100% rename from docs/data/toolpad/core/components/notifications/MultipleNotifications.tsx.preview rename to docs/data/toolpad/core/components/use-notifications/MultipleNotifications.tsx.preview diff --git a/docs/data/toolpad/core/components/notifications/ScopedNotification.js b/docs/data/toolpad/core/components/use-notifications/ScopedNotification.js similarity index 95% rename from docs/data/toolpad/core/components/notifications/ScopedNotification.js rename to docs/data/toolpad/core/components/use-notifications/ScopedNotification.js index 53bf07eeb82..5d2d4dae2f3 100644 --- a/docs/data/toolpad/core/components/notifications/ScopedNotification.js +++ b/docs/data/toolpad/core/components/use-notifications/ScopedNotification.js @@ -2,7 +2,7 @@ import * as React from 'react'; import { NotificationsProvider, useNotifications, -} from '@toolpad/core/notifications'; +} from '@toolpad/core/useNotifications'; import Button from '@mui/material/Button'; import { Box, Snackbar, styled } from '@mui/material'; diff --git a/docs/data/toolpad/core/components/notifications/ScopedNotification.tsx b/docs/data/toolpad/core/components/use-notifications/ScopedNotification.tsx similarity index 95% rename from docs/data/toolpad/core/components/notifications/ScopedNotification.tsx rename to docs/data/toolpad/core/components/use-notifications/ScopedNotification.tsx index 53bf07eeb82..5d2d4dae2f3 100644 --- a/docs/data/toolpad/core/components/notifications/ScopedNotification.tsx +++ b/docs/data/toolpad/core/components/use-notifications/ScopedNotification.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { NotificationsProvider, useNotifications, -} from '@toolpad/core/notifications'; +} from '@toolpad/core/useNotifications'; import Button from '@mui/material/Button'; import { Box, Snackbar, styled } from '@mui/material'; diff --git a/docs/data/toolpad/core/components/notifications/ScopedNotification.tsx.preview b/docs/data/toolpad/core/components/use-notifications/ScopedNotification.tsx.preview similarity index 100% rename from docs/data/toolpad/core/components/notifications/ScopedNotification.tsx.preview rename to docs/data/toolpad/core/components/use-notifications/ScopedNotification.tsx.preview diff --git a/docs/data/toolpad/core/components/notifications/notifications.md b/docs/data/toolpad/core/components/use-notifications/use-notifications.md similarity index 95% rename from docs/data/toolpad/core/components/notifications/notifications.md rename to docs/data/toolpad/core/components/use-notifications/use-notifications.md index 2ca6d747375..36085c57866 100644 --- a/docs/data/toolpad/core/components/notifications/notifications.md +++ b/docs/data/toolpad/core/components/use-notifications/use-notifications.md @@ -7,7 +7,7 @@ Toolpad core offers a set of abstractions that make it easier to interact with n First thing you need to do to get access to the notifications APIs is install the NotificationsProvider. ```js -import { NotificationsProvider } from '@toolpad/core/notifications'; +import { NotificationsProvider } from '@toolpad/core/useNotifications'; function App({ children }) { return {children}; @@ -17,7 +17,7 @@ function App({ children }) { Now you can get acess to the notifications APIs through the `useNotifications` hook. ```js -import { useNotifications } from '@toolpad/core/notifications'; +import { useNotifications } from '@toolpad/core/useNotifications'; function MyApp() { const notifications = useNotifications(); diff --git a/docs/data/toolpad/core/pages.ts b/docs/data/toolpad/core/pages.ts index e1b79b8b161..d2806c38d7a 100644 --- a/docs/data/toolpad/core/pages.ts +++ b/docs/data/toolpad/core/pages.ts @@ -92,12 +92,12 @@ const pages: MuiPage[] = [ subheader: 'Utils', children: [ { - pathname: '/toolpad/core/react-dialogs', - title: 'dialogs', + pathname: '/toolpad/core/react-use-dialogs', + title: 'useDialogs', }, { - pathname: '/toolpad/core/react-notifications', - title: 'notifications', + pathname: '/toolpad/core/react-use-notifications', + title: 'useNotifications', }, ], }, diff --git a/docs/pages/toolpad/core/react-dialogs/index.js b/docs/pages/toolpad/core/react-use-dialogs/index.js similarity index 84% rename from docs/pages/toolpad/core/react-dialogs/index.js rename to docs/pages/toolpad/core/react-use-dialogs/index.js index cdf8d124f0c..3181d8c0420 100644 --- a/docs/pages/toolpad/core/react-dialogs/index.js +++ b/docs/pages/toolpad/core/react-use-dialogs/index.js @@ -1,6 +1,6 @@ import * as React from 'react'; import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import * as pageProps from 'docs-toolpad/data/toolpad/core/components/dialogs/dialogs.md?muiMarkdown'; +import * as pageProps from 'docs-toolpad/data/toolpad/core/components/use-dialogs/use-dialogs.md?muiMarkdown'; export default function Page() { return ; diff --git a/docs/pages/toolpad/core/react-notifications/index.js b/docs/pages/toolpad/core/react-use-notifications/index.js similarity index 86% rename from docs/pages/toolpad/core/react-notifications/index.js rename to docs/pages/toolpad/core/react-use-notifications/index.js index 58a43b6a66c..62e976cbd79 100644 --- a/docs/pages/toolpad/core/react-notifications/index.js +++ b/docs/pages/toolpad/core/react-use-notifications/index.js @@ -1,7 +1,7 @@ import * as React from 'react'; import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import * as pageProps from 'docs-toolpad/data/toolpad/core/components/notifications/notifications.md?muiMarkdown'; -import { NotificationsProvider } from '@toolpad/core/notifications'; +import * as pageProps from 'docs-toolpad/data/toolpad/core/components/use-notifications/use-notifications.md?muiMarkdown'; +import { NotificationsProvider } from '@toolpad/core/useNotifications'; import { Snackbar, createTheme, useTheme, ThemeProvider } from '@mui/material'; function DemoThemedSnackbar(props) { diff --git a/packages/toolpad-core/src/AppProvider/AppProvider.tsx b/packages/toolpad-core/src/AppProvider/AppProvider.tsx index f19f3b91fc7..d3f065806f4 100644 --- a/packages/toolpad-core/src/AppProvider/AppProvider.tsx +++ b/packages/toolpad-core/src/AppProvider/AppProvider.tsx @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; import { ThemeProvider, Theme } from '@mui/material/styles'; import CssBaseline from '@mui/material/CssBaseline'; import { baseTheme } from '../themes'; -import { NotificationsProvider } from '../notifications'; +import { NotificationsProvider } from '../useNotifications'; import { DialogProvider } from '../useDialogs'; export interface NavigateOptions { diff --git a/packages/toolpad-core/src/index.ts b/packages/toolpad-core/src/index.ts index 8377e1a1b53..6257db47151 100644 --- a/packages/toolpad-core/src/index.ts +++ b/packages/toolpad-core/src/index.ts @@ -10,4 +10,4 @@ export * from './LineChart'; export * from './useDialogs'; -export * from './notifications'; +export * from './useNotifications'; diff --git a/packages/toolpad-core/src/notifications/index.ts b/packages/toolpad-core/src/notifications/index.ts deleted file mode 100644 index 9ea5ce778c9..00000000000 --- a/packages/toolpad-core/src/notifications/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './notifications'; diff --git a/packages/toolpad-core/src/useNotifications/index.ts b/packages/toolpad-core/src/useNotifications/index.ts new file mode 100644 index 00000000000..0435a4c45c0 --- /dev/null +++ b/packages/toolpad-core/src/useNotifications/index.ts @@ -0,0 +1 @@ +export * from './useNotifications'; diff --git a/packages/toolpad-core/src/notifications/notifications.tsx b/packages/toolpad-core/src/useNotifications/useNotifications.tsx similarity index 100% rename from packages/toolpad-core/src/notifications/notifications.tsx rename to packages/toolpad-core/src/useNotifications/useNotifications.tsx From 2cbe54b88edbbfeca52baf6e570bb166a0ff6c70 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 12:08:26 +0200 Subject: [PATCH 07/36] fsrf --- .../use-notifications/ScopedNotification.tsx | 7 +++---- .../useNotifications/useNotifications.test.tsx | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 packages/toolpad-core/src/useNotifications/useNotifications.test.tsx diff --git a/docs/data/toolpad/core/components/use-notifications/ScopedNotification.tsx b/docs/data/toolpad/core/components/use-notifications/ScopedNotification.tsx index 5d2d4dae2f3..cee2c174454 100644 --- a/docs/data/toolpad/core/components/use-notifications/ScopedNotification.tsx +++ b/docs/data/toolpad/core/components/use-notifications/ScopedNotification.tsx @@ -2,14 +2,13 @@ import * as React from 'react'; import { NotificationsProvider, useNotifications, + NotificationsProviderSlots, } from '@toolpad/core/useNotifications'; import Button from '@mui/material/Button'; import { Box, Snackbar, styled } from '@mui/material'; -const ScopedSnackbar = styled(Snackbar)({ position: 'absolute' }); - -const notificationsProviderSlots = { - snackbar: ScopedSnackbar, +const notificationsProviderSlots: NotificationsProviderSlots = { + snackbar: styled(Snackbar)({ position: 'absolute' }), }; function ScopedContent() { diff --git a/packages/toolpad-core/src/useNotifications/useNotifications.test.tsx b/packages/toolpad-core/src/useNotifications/useNotifications.test.tsx new file mode 100644 index 00000000000..1d485f55aa0 --- /dev/null +++ b/packages/toolpad-core/src/useNotifications/useNotifications.test.tsx @@ -0,0 +1,15 @@ +/** + * @vitest-environment jsdom + */ + +import * as React from 'react'; +import { describe, test, expect, vi } from 'vitest'; +import { render, waitFor, within, screen } from '@testing-library/react'; +import { userEvent } from '@testing-library/user-event'; +import { useNotifications } from './useNotifications'; + +describe('useNotifications', () => { + test('notifies', async () => { + console.log('stub'); + }); +}); From 89b884810be184cad652c0bfbb1a6246340daaf5 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 12:19:48 +0200 Subject: [PATCH 08/36] ferg --- .../use-notifications/ScopedNotification.tsx | 3 +- docs/package.json | 14 +- pnpm-lock.yaml | 175 ++++-------------- 3 files changed, 44 insertions(+), 148 deletions(-) diff --git a/docs/data/toolpad/core/components/use-notifications/ScopedNotification.tsx b/docs/data/toolpad/core/components/use-notifications/ScopedNotification.tsx index cee2c174454..20e02096e29 100644 --- a/docs/data/toolpad/core/components/use-notifications/ScopedNotification.tsx +++ b/docs/data/toolpad/core/components/use-notifications/ScopedNotification.tsx @@ -2,12 +2,11 @@ import * as React from 'react'; import { NotificationsProvider, useNotifications, - NotificationsProviderSlots, } from '@toolpad/core/useNotifications'; import Button from '@mui/material/Button'; import { Box, Snackbar, styled } from '@mui/material'; -const notificationsProviderSlots: NotificationsProviderSlots = { +const notificationsProviderSlots = { snackbar: styled(Snackbar)({ position: 'absolute' }), }; diff --git a/docs/package.json b/docs/package.json index edb03627e88..588da3a6b04 100644 --- a/docs/package.json +++ b/docs/package.json @@ -26,14 +26,14 @@ "@emotion/styled": "11.11.5", "@mui/base": "5.0.0-beta.40", "@mui/docs": "6.0.0-dev.240424162023-9968b4889d", - "@mui/icons-material": "next", + "@mui/icons-material": "^5.15.19", "@mui/internal-markdown": "^1.0.1", - "@mui/joy": "next", - "@mui/lab": "next", - "@mui/material": "next", - "@mui/material-nextjs": "next", - "@mui/styles": "next", - "@mui/utils": "next", + "@mui/joy": "5.0.0-beta.32", + "@mui/lab": "^5.0.0-alpha.170", + "@mui/material": "^5.15.19", + "@mui/material-nextjs": "^5.15.11", + "@mui/styles": "^5.15.19", + "@mui/system": "^5.15.15", "@mui/x-license": "7.6.1", "@toolpad/core": "workspace:*", "@toolpad/studio": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 99575a48e0a..76c564ac867 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -284,31 +284,31 @@ importers: version: 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/docs': specifier: 6.0.0-dev.240424162023-9968b4889d - version: 6.0.0-dev.240424162023-9968b4889d(@mui/base@5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/icons-material@6.0.0-alpha.10(@mui/material@6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@6.0.0-dev.240424162023-9968b4889d(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 6.0.0-dev.240424162023-9968b4889d(@mui/base@5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/icons-material@5.15.19(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@mui/icons-material': - specifier: next - version: 6.0.0-alpha.10(@mui/material@6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + specifier: ^5.15.19 + version: 5.15.19(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@mui/internal-markdown': specifier: ^1.0.1 version: 1.0.4 '@mui/joy': - specifier: next - version: 5.0.0-beta.43(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 5.0.0-beta.32 + version: 5.0.0-beta.32(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/lab': - specifier: next - version: 6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^5.0.0-alpha.170 + version: 5.0.0-alpha.170(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/material': - specifier: next - version: 6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: ^5.15.19 + version: 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/material-nextjs': - specifier: next - version: 6.0.0-alpha.1(@emotion/cache@11.11.0)(@emotion/server@11.11.0)(@mui/material@6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + specifier: ^5.15.11 + version: 5.15.11(@emotion/cache@11.11.0)(@emotion/server@11.11.0)(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@mui/styles': - specifier: next - version: 6.0.0-alpha.10(@types/react@18.3.3)(react@18.3.1) - '@mui/utils': - specifier: next - version: 6.0.0-alpha.9(@types/react@18.3.3)(react@18.3.1) + specifier: ^5.15.19 + version: 5.15.19(@types/react@18.3.3)(react@18.3.1) + '@mui/system': + specifier: ^5.15.15 + version: 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@mui/x-license': specifier: 7.6.1 version: 7.6.1(@types/react@18.3.3)(react@18.3.1) @@ -2009,7 +2009,7 @@ packages: resolution: {integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.24.7 '@babel/register@7.24.6': resolution: {integrity: sha512-WSuFCc2wCqMeXkz/i3yfAAsxwWflEgbVkZzivgAmXl/MxrXeoYFZOOPllbC8R8WTF7u61wSRQtDVZ1879cdu6w==} @@ -2718,17 +2718,6 @@ packages: '@types/react': optional: true - '@mui/icons-material@6.0.0-alpha.10': - resolution: {integrity: sha512-j9vDpwXVp4xMOxcW7dVquNSGgEFZIb3seCq+VBCkyRcXlC5vYqiEVemFhvM6qiSx0i0fOWB+T+nAYK8vOCFF4w==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@mui/material': ^6.0.0-alpha.10 - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@mui/internal-docs-utils@1.0.7': resolution: {integrity: sha512-vHplixLKu17U7Wa3RDbGv9C3FmXniJKywyZEIeJaTG4ikvl+iWI+BuZPCNniJwj0HSxu3thbyPIrBXijh7j+Xg==} @@ -2738,8 +2727,8 @@ packages: '@mui/internal-scripts@1.0.9': resolution: {integrity: sha512-HI4HTTBhrVUJlys6UirkbovcDKDR/qR/mZ7dyOE7lNa9PzxQam2V907kJdypWKAs/aPxGApl0wQufcrC9rwRRQ==} - '@mui/joy@5.0.0-beta.43': - resolution: {integrity: sha512-c9nVUEpAfXzvxSkIZ+4uzV5zXhTMCODgciBBaPMLwOpeJf/6MiYchp1/nLtgm9RzWdsPR9AdYG+DkKmcS0JzTA==} + '@mui/joy@5.0.0-beta.32': + resolution: {integrity: sha512-QJW5Mu2GTJUX4sXjxt4nQBugpJAiSkUT49S/bwoKCCWx8bCfsEyplTzZPK+FraweiGhGgZWExWOTAPpxH83RUQ==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -2773,24 +2762,6 @@ packages: '@types/react': optional: true - '@mui/lab@6.0.0-alpha.10': - resolution: {integrity: sha512-xd0AFj3VzSb7SYqP5OotMR4l6Os7lwuhbNHlcKp51tho68gcI3yiAI7NAjihHc7B34DyxNW2wm2RY9y+xAjxuw==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@emotion/react': ^11.5.0 - '@emotion/styled': ^11.3.0 - '@mui/material': ^6.0.0-alpha.10 - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@emotion/react': - optional: true - '@emotion/styled': - optional: true - '@types/react': - optional: true - '@mui/material-nextjs@5.15.11': resolution: {integrity: sha512-cp5RWYbBngyi7NKP91R9QITllfxumCVPFjqe4AKzNROVuCot0VpgkafxXqfbv0uFsyUU0ROs0O2M3r17q604Aw==} engines: {node: '>=12.0.0'} @@ -2809,24 +2780,6 @@ packages: '@types/react': optional: true - '@mui/material-nextjs@6.0.0-alpha.1': - resolution: {integrity: sha512-HDUS+GOv/R9k++bnJvIVfWXIWDvP3xzMM5eQB9lxnKbqeJq66VkoIuNTKaCrcHk5Im8bsEoPRrBWbA94X86isA==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@emotion/cache': ^11.11.0 - '@emotion/server': ^11.11.0 - '@mui/material': ^6.0.0-alpha.7 - '@types/react': ^17.0.0 || ^18.0.0 - next: ^13.0.0 || ^14.0.0 - react: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@emotion/cache': - optional: true - '@emotion/server': - optional: true - '@types/react': - optional: true - '@mui/material@5.15.19': resolution: {integrity: sha512-lp5xQBbcRuxNtjpWU0BWZgIrv2XLUz4RJ0RqFXBdESIsKoGCQZ6P3wwU5ZPuj5TjssNiKv9AlM+vHopRxZhvVQ==} engines: {node: '>=12.0.0'} @@ -2912,8 +2865,8 @@ packages: '@emotion/styled': optional: true - '@mui/styles@6.0.0-alpha.10': - resolution: {integrity: sha512-AFZUSqX0fPZy3C2Az05mDzWPaCJaiE6ySs1tDXZNdC1a6/uvCV/Z4MLNqWVn3zdAQn9azSR5mq4VwLLiSqPD3g==} + '@mui/styles@5.15.19': + resolution: {integrity: sha512-WOYjZT6DL/StJv/vFR/tJPJuHC98lwWza7Gzj2RWZk123eCcSJ+3ruc62/ZyXaCx4PKCbE849mVl+CWhA2ecmw==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -2972,16 +2925,6 @@ packages: '@types/react': optional: true - '@mui/utils@6.0.0-alpha.9': - resolution: {integrity: sha512-fie2VEiVzpHCbcUIwgWx5lQT+SYjL3uHDCfutXzr7hTbnqDu9KSVEBPgADitFqZOGCIcBXfs4aE4LIn1FmmKjg==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@mui/utils@6.0.0-dev.20240529-082515-213b5e33ab': resolution: {integrity: sha512-jyNcB0drDhYcoq5MHNTiEc63GfVE1GZK+CVUd8tlLzk5q631RPYJ5jONSOszLiUOXBmI8Uu1SBJUwrG3j2YG2A==} engines: {node: '>=12.0.0'} @@ -11546,7 +11489,7 @@ snapshots: '@babel/runtime': 7.24.6 '@floating-ui/react-dom': 2.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/types': 7.2.14(@types/react@18.3.3) - '@mui/utils': 6.0.0-alpha.9(@types/react@18.3.3)(react@18.3.1) + '@mui/utils': 6.0.0-dev.20240529-082515-213b5e33ab(@types/react@18.3.3)(react@18.3.1) '@popperjs/core': 2.11.8 clsx: 2.1.1 prop-types: 15.8.1 @@ -11559,14 +11502,14 @@ snapshots: '@mui/core-downloads-tracker@6.0.0-dev.240424162023-9968b4889d': {} - ? '@mui/docs@6.0.0-dev.240424162023-9968b4889d(@mui/base@5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/icons-material@6.0.0-alpha.10(@mui/material@6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@6.0.0-dev.240424162023-9968b4889d(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)' + ? '@mui/docs@6.0.0-dev.240424162023-9968b4889d(@mui/base@5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/icons-material@5.15.19(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)' : dependencies: '@babel/runtime': 7.24.6 '@mui/base': 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/icons-material': 6.0.0-alpha.10(@mui/material@6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/icons-material': 5.15.19(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@mui/internal-markdown': 1.0.4 - '@mui/material': 6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': 6.0.0-dev.240424162023-9968b4889d(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/material': 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) clipboard-copy: 4.0.1 clsx: 2.1.1 next: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -11584,14 +11527,6 @@ snapshots: optionalDependencies: '@types/react': 18.3.3 - '@mui/icons-material@6.0.0-alpha.10(@mui/material@6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.24.6 - '@mui/material': 6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@types/react': 18.3.3 - '@mui/internal-docs-utils@1.0.7': dependencies: rimraf: 5.0.7 @@ -11619,14 +11554,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@mui/joy@5.0.0-beta.43(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mui/joy@5.0.0-beta.32(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.6 - '@mui/base': 5.0.0-beta.48(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/core-downloads-tracker': 6.0.0-dev.240424162023-9968b4889d - '@mui/system': 6.0.0-dev.240424162023-9968b4889d(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/base': 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/core-downloads-tracker': 5.15.19 + '@mui/system': 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@mui/types': 7.2.14(@types/react@18.3.3) - '@mui/utils': 6.0.0-alpha.9(@types/react@18.3.3)(react@18.3.1) + '@mui/utils': 5.15.14(@types/react@18.3.3)(react@18.3.1) clsx: 2.1.1 prop-types: 15.8.1 react: 18.3.1 @@ -11653,23 +11588,6 @@ snapshots: '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@types/react': 18.3.3 - '@mui/lab@6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.24.6 - '@mui/base': 5.0.0-beta.48(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/material': 6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': 6.0.0-dev.240424162023-9968b4889d(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) - '@mui/types': 7.2.14(@types/react@18.3.3) - '@mui/utils': 6.0.0-alpha.9(@types/react@18.3.3)(react@18.3.1) - clsx: 2.1.1 - prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - optionalDependencies: - '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) - '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) - '@types/react': 18.3.3 - '@mui/material-nextjs@5.15.11(@emotion/cache@11.11.0)(@emotion/server@11.11.0)(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.6 @@ -11681,17 +11599,6 @@ snapshots: '@emotion/server': 11.11.0 '@types/react': 18.3.3 - '@mui/material-nextjs@6.0.0-alpha.1(@emotion/cache@11.11.0)(@emotion/server@11.11.0)(@mui/material@6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': - dependencies: - '@babel/runtime': 7.24.6 - '@mui/material': 6.0.0-alpha.10(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - optionalDependencies: - '@emotion/cache': 11.11.0 - '@emotion/server': 11.11.0 - '@types/react': 18.3.3 - '@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.6 @@ -11720,7 +11627,7 @@ snapshots: '@mui/core-downloads-tracker': 6.0.0-dev.240424162023-9968b4889d '@mui/system': 6.0.0-dev.240424162023-9968b4889d(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@mui/types': 7.2.14(@types/react@18.3.3) - '@mui/utils': 6.0.0-alpha.9(@types/react@18.3.3)(react@18.3.1) + '@mui/utils': 6.0.0-dev.20240529-082515-213b5e33ab(@types/react@18.3.3)(react@18.3.1) '@types/react-transition-group': 4.4.10 clsx: 2.1.1 csstype: 3.1.3 @@ -11789,13 +11696,13 @@ snapshots: '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) - '@mui/styles@6.0.0-alpha.10(@types/react@18.3.3)(react@18.3.1)': + '@mui/styles@5.15.19(@types/react@18.3.3)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.6 '@emotion/hash': 0.9.1 - '@mui/private-theming': 6.0.0-dev.20240529-082515-213b5e33ab(@types/react@18.3.3)(react@18.3.1) + '@mui/private-theming': 5.15.14(@types/react@18.3.3)(react@18.3.1) '@mui/types': 7.2.14(@types/react@18.3.3) - '@mui/utils': 6.0.0-alpha.9(@types/react@18.3.3)(react@18.3.1) + '@mui/utils': 5.15.14(@types/react@18.3.3)(react@18.3.1) clsx: 2.1.1 csstype: 3.1.3 hoist-non-react-statics: 3.3.2 @@ -11834,7 +11741,7 @@ snapshots: '@mui/private-theming': 6.0.0-dev.20240529-082515-213b5e33ab(@types/react@18.3.3)(react@18.3.1) '@mui/styled-engine': 6.0.0-dev.20240529-082515-213b5e33ab(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(react@18.3.1) '@mui/types': 7.2.14(@types/react@18.3.3) - '@mui/utils': 6.0.0-alpha.9(@types/react@18.3.3)(react@18.3.1) + '@mui/utils': 6.0.0-dev.20240529-082515-213b5e33ab(@types/react@18.3.3)(react@18.3.1) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 @@ -11858,16 +11765,6 @@ snapshots: optionalDependencies: '@types/react': 18.3.3 - '@mui/utils@6.0.0-alpha.9(@types/react@18.3.3)(react@18.3.1)': - dependencies: - '@babel/runtime': 7.24.6 - '@types/prop-types': 15.7.12 - prop-types: 15.8.1 - react: 18.3.1 - react-is: 18.3.1 - optionalDependencies: - '@types/react': 18.3.3 - '@mui/utils@6.0.0-dev.20240529-082515-213b5e33ab(@types/react@18.3.3)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.6 From e8ee153d4ec243597ccd403d638b323591b72f4c Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 13:39:10 +0200 Subject: [PATCH 09/36] slotprops --- packages/toolpad-core/package.json | 1 + .../src/useNotifications/useNotifications.tsx | 54 +++++++++++-------- pnpm-lock.yaml | 5 +- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/packages/toolpad-core/package.json b/packages/toolpad-core/package.json index d404a8c0cb6..7d384fbfc7c 100644 --- a/packages/toolpad-core/package.json +++ b/packages/toolpad-core/package.json @@ -48,6 +48,7 @@ "test:browser:dev": "vitest --browser.enabled" }, "dependencies": { + "@mui/base": "5.0.0-beta.40", "@mui/lab": "5.0.0-alpha.170", "@mui/utils": "5.15.14", "@mui/x-charts": "7.6.2", diff --git a/packages/toolpad-core/src/useNotifications/useNotifications.tsx b/packages/toolpad-core/src/useNotifications/useNotifications.tsx index f1012688dba..fc1a17a3b64 100644 --- a/packages/toolpad-core/src/useNotifications/useNotifications.tsx +++ b/packages/toolpad-core/src/useNotifications/useNotifications.tsx @@ -12,6 +12,7 @@ import { import CloseIcon from '@mui/icons-material/Close'; import * as React from 'react'; import { useNonNullableContext } from '@toolpad/utils/react'; +import { useSlotProps } from '@mui/base/utils'; const closeText = 'Close'; @@ -49,14 +50,16 @@ interface NotificationsContextValue { const NotificationsContext = React.createContext(null); -const SlotsContext = React.createContext({ - snackbar: Snackbar, -}); - -export interface NotificationsProviderSlots { - snackbar: React.ComponentType; +export interface NotificationsProviderSlotProps { + snackbar: SnackbarProps; } +type Slots = { [K in keyof T]: React.ComponentType }; + +export type NotificationsProviderSlots = Slots; + +const RootPropsContext = React.createContext(null); + interface NotificationProps { notificationKey: string; badge: string | null; @@ -99,16 +102,22 @@ function Notification({ notificationKey, open, message, options, badge }: Notifi ); - const { snackbar: SnackbarComponent } = React.useContext(SlotsContext); + const props = React.useContext(RootPropsContext); + const SnackbarComponent = props?.slots?.snackbar ?? Snackbar; + const snackbarSlotProps = useSlotProps({ + elementType: SnackbarComponent, + ownerState: props, + externalSlotProps: props?.slotProps?.snackbar, + additionalProps: { + open, + autoHideDuration, + onClose: handleClose, + action, + }, + }); return ( - + {severity ? ( @@ -161,14 +170,19 @@ function Notifications({ state }: NotificationsUiProps) { /> ) : null; } + export interface NotificationsProviderProps { children?: React.ReactNode; + // eslint-disable-next-line react/no-unused-prop-types slots?: Partial; + // eslint-disable-next-line react/no-unused-prop-types + slotProps?: Partial; } let nextId = 1; -export function NotificationsProvider({ children, slots }: NotificationsProviderProps) { +export function NotificationsProvider(props: NotificationsProviderProps) { + const { children } = props; const [state, setState] = React.useState({ queue: [] }); const show = React.useCallback((message, options = {}) => { @@ -196,18 +210,12 @@ export function NotificationsProvider({ children, slots }: NotificationsProvider const contextValue = React.useMemo(() => ({ show, close }), [show, close]); - const outerSlots = React.useContext(SlotsContext); - const slotsContextValue = React.useMemo( - () => (slots ? { ...outerSlots, ...slots } : outerSlots), - [outerSlots, slots], - ); - return ( - + {children} - + ); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76c564ac867..22cc20fd53b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -570,6 +570,9 @@ importers: packages/toolpad-core: dependencies: + '@mui/base': + specifier: 5.0.0-beta.40 + version: 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/lab': specifier: 5.0.0-alpha.170 version: 5.0.0-alpha.170(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -2009,7 +2012,7 @@ packages: resolution: {integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.24.7 + '@babel/core': ^7.0.0-0 '@babel/register@7.24.6': resolution: {integrity: sha512-WSuFCc2wCqMeXkz/i3yfAAsxwWflEgbVkZzivgAmXl/MxrXeoYFZOOPllbC8R8WTF7u61wSRQtDVZ1879cdu6w==} From 04bc70df29fd411d6e6e5ff31d55985290ee0174 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:05:17 +0200 Subject: [PATCH 10/36] dew --- docs/package.json | 1 + packages/toolpad-core/package.json | 1 + .../useNotifications.test.tsx | 34 ++++++++++++++++--- pnpm-lock.yaml | 3 ++ 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/docs/package.json b/docs/package.json index 588da3a6b04..ecda90a9d0a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -34,6 +34,7 @@ "@mui/material-nextjs": "^5.15.11", "@mui/styles": "^5.15.19", "@mui/system": "^5.15.15", + "@mui/utils": "5.15.14", "@mui/x-license": "7.6.1", "@toolpad/core": "workspace:*", "@toolpad/studio": "workspace:*", diff --git a/packages/toolpad-core/package.json b/packages/toolpad-core/package.json index 7d384fbfc7c..fd08fd579b7 100644 --- a/packages/toolpad-core/package.json +++ b/packages/toolpad-core/package.json @@ -44,6 +44,7 @@ "dev": "concurrently \"pnpm build:stable --watch\" \"pnpm build:types --watch --preserveWatchOutput\"", "check-types": "tsc --noEmit", "test": "vitest run", + "test:dev": "vitest", "test:browser": "vitest run --browser.enabled", "test:browser:dev": "vitest --browser.enabled" }, diff --git a/packages/toolpad-core/src/useNotifications/useNotifications.test.tsx b/packages/toolpad-core/src/useNotifications/useNotifications.test.tsx index 1d485f55aa0..45013f1e19c 100644 --- a/packages/toolpad-core/src/useNotifications/useNotifications.test.tsx +++ b/packages/toolpad-core/src/useNotifications/useNotifications.test.tsx @@ -3,13 +3,37 @@ */ import * as React from 'react'; -import { describe, test, expect, vi } from 'vitest'; -import { render, waitFor, within, screen } from '@testing-library/react'; +import { describe, test, expect } from 'vitest'; +import { renderHook, within, screen } from '@testing-library/react'; import { userEvent } from '@testing-library/user-event'; -import { useNotifications } from './useNotifications'; +import { NotificationsProvider, useNotifications } from './useNotifications'; + +interface TestWrapperProps { + children: React.ReactNode; +} + +function TestWrapper({ children }: TestWrapperProps) { + return {children}; +} describe('useNotifications', () => { - test('notifies', async () => { - console.log('stub'); + test('can do basic notifications', async () => { + const { result, rerender } = renderHook(() => useNotifications(), { wrapper: TestWrapper }); + + expect(screen.queryByRole('alert')).toBeNull(); + + const key = result.current.show('Hello'); + expect(key).toBeTypeOf('string'); + + rerender(); + + const snackbar = screen.getByRole('alert'); + expect(snackbar.textContent).toBe('Hello'); + + await userEvent.click(within(snackbar).getByRole('button', { name: 'Close' })); + + rerender(); + + expect(screen.queryByRole('alert')).toBeNull(); }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0443b1480f0..1f6e0883da3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -309,6 +309,9 @@ importers: '@mui/system': specifier: ^5.15.15 version: 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/utils': + specifier: 5.15.14 + version: 5.15.14(@types/react@18.3.3)(react@18.3.1) '@mui/x-license': specifier: 7.6.1 version: 7.6.1(@types/react@18.3.3)(react@18.3.1) From 45cd1f0e7119e5524b51493a9e5df02be1da3461 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:24:00 +0200 Subject: [PATCH 11/36] extra tests --- .../use-notifications/ScopedNotification.js | 4 +- .../src/useDialogs/useDialog.test.tsx | 129 ++++++++++++++++++ .../src/useDialogs/useDialogs.tsx | 6 +- 3 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 packages/toolpad-core/src/useDialogs/useDialog.test.tsx diff --git a/docs/data/toolpad/core/components/use-notifications/ScopedNotification.js b/docs/data/toolpad/core/components/use-notifications/ScopedNotification.js index 5d2d4dae2f3..20e02096e29 100644 --- a/docs/data/toolpad/core/components/use-notifications/ScopedNotification.js +++ b/docs/data/toolpad/core/components/use-notifications/ScopedNotification.js @@ -6,10 +6,8 @@ import { import Button from '@mui/material/Button'; import { Box, Snackbar, styled } from '@mui/material'; -const ScopedSnackbar = styled(Snackbar)({ position: 'absolute' }); - const notificationsProviderSlots = { - snackbar: ScopedSnackbar, + snackbar: styled(Snackbar)({ position: 'absolute' }), }; function ScopedContent() { diff --git a/packages/toolpad-core/src/useDialogs/useDialog.test.tsx b/packages/toolpad-core/src/useDialogs/useDialog.test.tsx new file mode 100644 index 00000000000..6bfa273bd02 --- /dev/null +++ b/packages/toolpad-core/src/useDialogs/useDialog.test.tsx @@ -0,0 +1,129 @@ +/** + * @vitest-environment jsdom + */ + +import * as React from 'react'; +import { describe, test, expect } from 'vitest'; +import { renderHook, within, screen, act } from '@testing-library/react'; +import { userEvent } from '@testing-library/user-event'; +import { DialogProvider, useDialogs } from './useDialogs'; + +interface TestWrapperProps { + children: React.ReactNode; +} + +function TestWrapper({ children }: TestWrapperProps) { + return {children}; +} + +describe('useDialogs', () => { + describe('alert', () => { + test('can show and hide', async () => { + const { result, rerender } = renderHook(() => useDialogs(), { wrapper: TestWrapper }); + + const dialogResult = result.current.alert('Hello'); + + rerender(); + + const dialog = screen.getByRole('dialog'); + + expect(within(dialog).getByText('Hello')).toBeTruthy(); + + await userEvent.click(within(dialog).getByRole('button', { name: 'Ok' })); + + rerender(); + + expect(await dialogResult).toBeUndefined(); + + expect(screen.queryByRole('dialog')).toBeFalsy(); + }); + }); + + describe('confirm', () => { + test('can show and confirm', async () => { + const { result, rerender } = renderHook(() => useDialogs(), { wrapper: TestWrapper }); + + const dialogResult = result.current.confirm('Hello'); + + rerender(); + + const dialog = screen.getByRole('dialog'); + + expect(within(dialog).getByText('Hello')).toBeTruthy(); + + await userEvent.click(within(dialog).getByRole('button', { name: 'Ok' })); + + rerender(); + + expect(await dialogResult).toBe(true); + + expect(screen.queryByRole('dialog')).toBeFalsy(); + }); + + test('can show and cancel', async () => { + const { result, rerender } = renderHook(() => useDialogs(), { wrapper: TestWrapper }); + + const dialogResult = result.current.confirm('Hello'); + + rerender(); + + const dialog = screen.getByRole('dialog'); + + expect(within(dialog).getByText('Hello')).toBeTruthy(); + + await userEvent.click(within(dialog).getByRole('button', { name: 'Cancel' })); + + rerender(); + + expect(await dialogResult).toBe(false); + + expect(screen.queryByRole('dialog')).toBeFalsy(); + }); + }); + + describe('prompt', () => { + test('can show and take input', async () => { + const { result, rerender } = renderHook(() => useDialogs(), { wrapper: TestWrapper }); + + const dialogResult = result.current.prompt('Hello'); + + rerender(); + + const dialog = screen.getByRole('dialog'); + + expect(within(dialog).getByText('Hello')).toBeTruthy(); + + await userEvent.keyboard('Hello, World!'); + + await userEvent.click(within(dialog).getByRole('button', { name: 'Ok' })); + + rerender(); + + expect(await dialogResult).toBe('Hello, World!'); + + expect(screen.queryByRole('dialog')).toBeFalsy(); + }); + + test('can show and cancel', async () => { + const { result, rerender } = renderHook(() => useDialogs(), { wrapper: TestWrapper }); + + const dialogResult = result.current.prompt('Hello'); + + rerender(); + + const dialog = screen.getByRole('dialog'); + + expect(within(dialog).getByText('Hello')).toBeTruthy(); + + await userEvent.keyboard('Hello, World!'); + + await userEvent.click(within(dialog).getByRole('button', { name: 'Cancel' })); + + rerender(); + + expect(await dialogResult).toBe(null); + + expect(screen.queryByRole('dialog')).toBeFalsy(); + }); + }); +}); diff --git a/packages/toolpad-core/src/useDialogs/useDialogs.tsx b/packages/toolpad-core/src/useDialogs/useDialogs.tsx index 5789e49fbfd..4c5797897cb 100644 --- a/packages/toolpad-core/src/useDialogs/useDialogs.tsx +++ b/packages/toolpad-core/src/useDialogs/useDialogs.tsx @@ -99,9 +99,11 @@ const CloseDialogContext = React.createContext(async () => { export interface DialogProviderprops { children?: React.ReactNode; + unmountAfter?: number; } -export function DialogProvider({ children }: DialogProviderprops) { +export function DialogProvider(props: DialogProviderprops) { + const { children, unmountAfter = 1000 } = props; const [stack, setStack] = React.useState[]>([]); const keyPrefix = React.useId(); const nextId = React.useRef(0); @@ -145,7 +147,7 @@ export function DialogProvider({ children }: DialogProviderprops) { setTimeout(() => { // wait for closing animation setStack((prevStack) => prevStack.filter((entry) => entry.promise !== dialog)); - }, 1000); + }, unmountAfter); }, []); const closeDialog = React.useCallback( From 948f457658bf6720b4f9c31d5c4f9d3f6da3e451 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:30:24 +0200 Subject: [PATCH 12/36] dedupe --- pnpm-lock.yaml | 344 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 240 insertions(+), 104 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1f6e0883da3..648475811b7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,7 +16,7 @@ importers: version: 4.17.5 '@vitest/browser': specifier: beta - version: 2.0.0-beta.9(playwright@1.44.1)(vitest@2.0.0-beta.9) + version: 2.0.0-beta.10(playwright@1.44.1)(typescript@5.4.5)(vitest@2.0.0-beta.10) archiver: specifier: 7.0.1 version: 7.0.1 @@ -52,7 +52,7 @@ importers: version: 4.14.1 vitest: specifier: beta - version: 2.0.0-beta.9(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.9)(jsdom@24.1.0)(terser@5.31.0) + version: 2.0.0-beta.10(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.10)(jsdom@24.1.0)(terser@5.31.0) yargs: specifier: 17.7.2 version: 17.7.2 @@ -113,10 +113,10 @@ importers: version: 1.44.1 '@testing-library/react': specifier: 16.0.0 - version: 16.0.0(@testing-library/dom@9.3.4)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 16.0.0(@testing-library/dom@10.1.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@testing-library/user-event': specifier: 14.5.2 - version: 14.5.2(@testing-library/dom@9.3.4) + version: 14.5.2(@testing-library/dom@10.1.0) '@types/archiver': specifier: 6.0.2 version: 6.0.2 @@ -248,10 +248,10 @@ importers: version: 2.0.3 vitest-dom: specifier: 0.1.1 - version: 0.1.1(vitest@2.0.0-beta.9(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.9)(jsdom@24.1.0)(terser@5.31.0)) + version: 0.1.1(vitest@2.0.0-beta.10(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.10)(jsdom@24.1.0)(terser@5.31.0)) vitest-fail-on-console: specifier: 0.7.0 - version: 0.7.0(vite@5.2.13(@types/node@20.14.2)(terser@5.31.0))(vitest@2.0.0-beta.9(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.9)(jsdom@24.1.0)(terser@5.31.0)) + version: 0.7.0(vite@5.2.13(@types/node@20.14.2)(terser@5.31.0))(vitest@2.0.0-beta.10(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.10)(jsdom@24.1.0)(terser@5.31.0)) docs: dependencies: @@ -630,7 +630,7 @@ importers: version: 17.0.3 '@vitest/browser': specifier: beta - version: 2.0.0-beta.9(playwright@1.44.1)(vitest@2.0.0-beta.9) + version: 2.0.0-beta.10(playwright@1.44.1)(typescript@5.4.5)(vitest@2.0.0-beta.10) next: specifier: ^14.2.3 version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -645,7 +645,7 @@ importers: version: 18.0.0 vitest: specifier: beta - version: 2.0.0-beta.9(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.9)(jsdom@24.1.0)(terser@5.31.0) + version: 2.0.0-beta.10(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.10)(jsdom@24.1.0)(terser@5.31.0) packages/toolpad-studio: dependencies: @@ -2015,7 +2015,7 @@ packages: resolution: {integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.24.7 + '@babel/core': ^7.0.0-0 '@babel/register@7.24.6': resolution: {integrity: sha512-WSuFCc2wCqMeXkz/i3yfAAsxwWflEgbVkZzivgAmXl/MxrXeoYFZOOPllbC8R8WTF7u61wSRQtDVZ1879cdu6w==} @@ -2049,6 +2049,12 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@bundled-es-modules/cookie@2.0.0': + resolution: {integrity: sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==} + + '@bundled-es-modules/statuses@1.0.1': + resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} + '@date-io/core@3.0.0': resolution: {integrity: sha512-S3j+IAQVBYNkQzchVVhX40eBkGDreBpScy9RXwTS5j2+k07+62pMVPisQ44Gq76Rqy5AOG/EZXCwBpY/jbemvA==} @@ -2606,10 +2612,22 @@ packages: cpu: [x64] os: [win32] + '@inquirer/confirm@3.1.9': + resolution: {integrity: sha512-UF09aejxCi4Xqm6N/jJAiFXArXfi9al52AFaSD+2uIHnhZGtd1d6lIGTRMPouVSJxbGEi+HkOWSYaiEY/+szUw==} + engines: {node: '>=18'} + + '@inquirer/core@8.2.2': + resolution: {integrity: sha512-K8SuNX45jEFlX3EBJpu9B+S2TISzMPGXZIuJ9ME924SqbdW6Pt6fIkKvXg7mOEOKJ4WxpQsxj0UTfcL/A434Ww==} + engines: {node: '>=18'} + '@inquirer/figures@1.0.3': resolution: {integrity: sha512-ErXXzENMH5pJt5/ssXV0DfWUZqly8nGzf0UcBV9xTnP+KyffE2mqyxIMBrZ8ijQck2nU0TQm40EQB53YreyWHw==} engines: {node: '>=18'} + '@inquirer/type@1.3.3': + resolution: {integrity: sha512-xTUt0NulylX27/zMx04ZYar/kr1raaiFTVvQ5feljQsiAgdm0WPj4S73/ye0fbslh+15QrIuDvfCXTek7pMY5A==} + engines: {node: '>=18'} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -2670,6 +2688,14 @@ packages: resolution: {integrity: sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==} engines: {node: '>= 0.4'} + '@mswjs/cookies@1.1.0': + resolution: {integrity: sha512-0ZcCVQxifZmhwNBoQIrystCb+2sWBY2Zw8lpfJBPCHGCA/HWqehITeCRVIv4VMy8MPlaHo2w2pTHFV2pFfqKPw==} + engines: {node: '>=18'} + + '@mswjs/interceptors@0.29.1': + resolution: {integrity: sha512-3rDakgJZ77+RiQUuSK69t1F0m8BQKA8Vh5DCS5V0DWvNY67zob2JhhQrhCO0AKLGINTRSFd1tBaHcJTkhefoSw==} + engines: {node: '>=18'} + '@mui/base@5.0.0-beta.40': resolution: {integrity: sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==} engines: {node: '>=12.0.0'} @@ -3320,6 +3346,15 @@ packages: '@octokit/types@9.3.2': resolution: {integrity: sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==} + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + '@opentelemetry/api-logs@0.50.0': resolution: {integrity: sha512-JdZuKrhOYggqOpUljAq4WWNi5nB10PmgoF0y2CvedLGXd0kSawb/UBnWT8gg1ND3bHCNHStAIVT0ELlxJJRqrA==} engines: {node: '>=14'} @@ -3655,9 +3690,9 @@ packages: peerDependencies: react: ^18.0.0 - '@testing-library/dom@9.3.4': - resolution: {integrity: sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==} - engines: {node: '>=14'} + '@testing-library/dom@10.1.0': + resolution: {integrity: sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==} + engines: {node: '>=18'} '@testing-library/react@16.0.0': resolution: {integrity: sha512-guuxUKRWQ+FgNX0h0NS0FIq3Q3uLtWVpBzcLOggmfMoUpgBnzBzvLLd4fbm6yS8ydJd94cIfY4yP9qUQjM2KwQ==} @@ -3870,6 +3905,9 @@ packages: '@types/minimist@1.2.5': resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} + '@types/mute-stream@0.0.4': + resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} + '@types/node-fetch@2.6.11': resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} @@ -3954,6 +3992,9 @@ packages: '@types/source-list-map@0.1.6': resolution: {integrity: sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g==} + '@types/statuses@2.0.5': + resolution: {integrity: sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==} + '@types/stylis@4.2.5': resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==} @@ -3993,6 +4034,9 @@ packages: '@types/whatwg-url@11.0.5': resolution: {integrity: sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==} + '@types/wrap-ansi@3.0.0': + resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} + '@types/ws@7.4.7': resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} @@ -4136,12 +4180,12 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 - '@vitest/browser@2.0.0-beta.9': - resolution: {integrity: sha512-+jJAf+lGcU69gIIwn0klNA/imViOGlnULTfGoqkOmtmCP7CotD6XN8aVLJ8S9MJulJsXxVz6JHk3Yb1+AysHkg==} + '@vitest/browser@2.0.0-beta.10': + resolution: {integrity: sha512-9rnX+kxRz1cEJ8B19DE9NYwYmwvSYV/BNL6oRXiC6lFkE9BnxB+ezzokav9K+A2tMaK+Q2n+rtGyT4jdJBJCdw==} peerDependencies: playwright: '*' safaridriver: '*' - vitest: 2.0.0-beta.9 + vitest: 2.0.0-beta.10 webdriverio: '*' peerDependenciesMeta: playwright: @@ -4151,20 +4195,20 @@ packages: webdriverio: optional: true - '@vitest/expect@2.0.0-beta.9': - resolution: {integrity: sha512-bYvI/JTVe0KuN0JtkIq+ka2r4A9Mu9+vwx0mzpnc/nnzj1UEBNj7UAjeRF858aaQYLw72gvEior7jh4VSGDVJg==} + '@vitest/expect@2.0.0-beta.10': + resolution: {integrity: sha512-/i2m9rj/Hzd+PcJYZo47dFDcrUnU0T4LbdCguugJZ0bvFLtU1oWmn6PxCUTYcwj4TgBWNU9r7f1ngZQId2j5Mw==} - '@vitest/runner@2.0.0-beta.9': - resolution: {integrity: sha512-ZwmBOfg8Fl/dl66/ds7WnHqM5m+f6HacgPxbvHgZHRaE7F9YRwjfraJx3MJTrI02I+fuftKLNr/1obnthyePeQ==} + '@vitest/runner@2.0.0-beta.10': + resolution: {integrity: sha512-OYqqCCOWoD0jJCJuAr5mNqlI98b1IUUw4o57JgoJ3sU1FRvgeb2fJX6n3/EFFGz9vkCBshiqkICZsEVy8AxUbQ==} - '@vitest/snapshot@2.0.0-beta.9': - resolution: {integrity: sha512-ZVyTIN4WnflZs5GEoWdU7/24zRNbzgLH+mAVvANs4wNRMAcDhdn+MkqXTQlKSzARN3WhGrMfvx7KXwO8pK1pxw==} + '@vitest/snapshot@2.0.0-beta.10': + resolution: {integrity: sha512-SvvnBwcGsxI++T0WF8Py5LGCzJE2s5x2Bs6hCTiGVZPqmCrmCLVPeRQCLzYyX3LVRUHgkqgfmP7grUHDKusMJg==} - '@vitest/spy@2.0.0-beta.9': - resolution: {integrity: sha512-zh7pZfMvCmyF13zuf+FWIZQvCE5v+El5M07asLuwk0xPhStZhXc+4GwMYb3sesm3eE4KpAP8xkQxjcrWC45Qdg==} + '@vitest/spy@2.0.0-beta.10': + resolution: {integrity: sha512-vqkBBxQr5F+ufquHPMMpwfe/aPDWgHx7f6WyL7w6tIswZuCa9QSdwARldr8i2lEpCQC7htWA3UnmxQz5faYLxw==} - '@vitest/utils@2.0.0-beta.9': - resolution: {integrity: sha512-NcY+BtAy+ChZGYen+Y+hNBAxYSEro/gA38kAbArnr6Yw1QSpyhKUe4Vdv1iG7djke+Zz/5Y1uVum8JAzlzEevQ==} + '@vitest/utils@2.0.0-beta.10': + resolution: {integrity: sha512-QfkMTsHtNCav0ejxmJsRloUa1VT46vK0xJFQIA9hpA7rGnuUS3QZmKcbi9NrBRbCgPxk7TrXc2sJu2dk13Uifg==} '@webassemblyjs/ast@1.12.1': resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} @@ -4386,9 +4430,6 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - aria-query@5.1.3: - resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} - aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} @@ -4974,6 +5015,10 @@ packages: resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} engines: {node: '>= 0.6'} + cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + cookie@0.6.0: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} @@ -5218,10 +5263,6 @@ packages: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} - deep-equal@2.2.3: - resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} - engines: {node: '>= 0.4'} - deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -6163,6 +6204,10 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + graphql@16.8.1: + resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + gtoken@7.1.0: resolution: {integrity: sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==} engines: {node: '>=14.0.0'} @@ -6220,6 +6265,9 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + headers-polyfill@4.0.3: + resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + hexoid@1.0.0: resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} engines: {node: '>=8'} @@ -6518,6 +6566,9 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + is-number-object@1.0.7: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} @@ -7389,6 +7440,16 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + msw@2.3.1: + resolution: {integrity: sha512-ocgvBCLn/5l3jpl1lssIb3cniuACJLoOfZu01e3n5dbJrpA5PeeWn28jCLgQDNt6d7QT8tF2fYRzm9JoEHtiig==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + typescript: '>= 4.7.x' + peerDependenciesMeta: + typescript: + optional: true + multimatch@5.0.0: resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} engines: {node: '>=10'} @@ -7648,10 +7709,6 @@ packages: object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} - object-is@1.1.6: - resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} - engines: {node: '>= 0.4'} - object-keys@0.4.0: resolution: {integrity: sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==} @@ -7737,6 +7794,9 @@ packages: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} + outvariant@1.4.2: + resolution: {integrity: sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==} + p-event@5.0.1: resolution: {integrity: sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -8922,6 +8982,9 @@ packages: streamx@2.18.0: resolution: {integrity: sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==} + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + string-at@1.1.0: resolution: {integrity: sha512-jCpPowWKBn0NFdvtmK2qxK40Ol4jPcgCt8qYnKpPx6B5eDwHMDhRvq9MCsDEgsOTNtbXY6beAMHMRT2qPJXllA==} engines: {node: '>= 0.4'} @@ -9354,6 +9417,10 @@ packages: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} + type-fest@4.20.0: + resolution: {integrity: sha512-MBh+PHUHHisjXf4tlx0CFWoMdjx8zCMLJHOjnV1prABYZFHqtFOyauCIK2/7w4oIfwkF8iNhLtnJEfVY2vn3iw==} + engines: {node: '>=16'} + type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -9534,8 +9601,8 @@ packages: victory-vendor@36.9.2: resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} - vite-node@2.0.0-beta.9: - resolution: {integrity: sha512-mtNz0n2hcgBNZu2yhD7ooLcTdFcn09zRPfDgNDgdG/Y4K5boMu8yVGh3tSqC37Ihc1iEDmDytIXmq73ZxojS8g==} + vite-node@2.0.0-beta.10: + resolution: {integrity: sha512-+QvNhWLzDnK58qUHUloUZsk5ECy32+fMwSv3boeXXPFVlBpJDonw7dOeEgXAPa3+vXTTFszUCJnPrZwWBBuxIQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -9578,15 +9645,15 @@ packages: vite: '>=4.5.2' vitest: '>=0.26.2' - vitest@2.0.0-beta.9: - resolution: {integrity: sha512-3oFHS324DKUVbYDkrdAs29+MH2opXSGkdldc5VBPQYYShpS+NCRbI01XOBIpiJi2UYNt0/GhwnIAAsDxwmuhQQ==} + vitest@2.0.0-beta.10: + resolution: {integrity: sha512-Mv8WjiuhQGC1QRySkVnVc0XS2jfwv3vwu6uSt2LZexldWYi13S4W83yH621VDEmrH1hJ+oOT0/eGBIYRaggGRg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.0.0-beta.9 - '@vitest/ui': 2.0.0-beta.9 + '@vitest/browser': 2.0.0-beta.10 + '@vitest/ui': 2.0.0-beta.10 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -10908,6 +10975,14 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} + '@bundled-es-modules/cookie@2.0.0': + dependencies: + cookie: 0.5.0 + + '@bundled-es-modules/statuses@1.0.1': + dependencies: + statuses: 2.0.1 + '@date-io/core@3.0.0': {} '@date-io/date-fns-jalali@3.0.0(date-fns-jalali@2.29.3-0)': @@ -11336,8 +11411,31 @@ snapshots: '@img/sharp-win32-x64@0.33.4': optional: true + '@inquirer/confirm@3.1.9': + dependencies: + '@inquirer/core': 8.2.2 + '@inquirer/type': 1.3.3 + + '@inquirer/core@8.2.2': + dependencies: + '@inquirer/figures': 1.0.3 + '@inquirer/type': 1.3.3 + '@types/mute-stream': 0.0.4 + '@types/node': 20.14.2 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-spinners: 2.9.2 + cli-width: 4.1.0 + mute-stream: 1.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + '@inquirer/figures@1.0.3': {} + '@inquirer/type@1.3.3': {} + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -11476,6 +11574,17 @@ snapshots: dependencies: call-bind: 1.0.7 + '@mswjs/cookies@1.1.0': {} + + '@mswjs/interceptors@0.29.1': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.2 + strict-event-emitter: 0.5.1 + '@mui/base@5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -12213,6 +12322,15 @@ snapshots: dependencies: '@octokit/openapi-types': 18.1.1 + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.2 + + '@open-draft/until@2.1.0': {} + '@opentelemetry/api-logs@0.50.0': dependencies: '@opentelemetry/api': 1.8.0 @@ -12568,30 +12686,30 @@ snapshots: '@tanstack/query-core': 5.40.0 react: 18.3.1 - '@testing-library/dom@9.3.4': + '@testing-library/dom@10.1.0': dependencies: '@babel/code-frame': 7.24.7 '@babel/runtime': 7.24.7 '@types/aria-query': 5.0.4 - aria-query: 5.1.3 + aria-query: 5.3.0 chalk: 4.1.2 dom-accessibility-api: 0.5.16 lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/react@16.0.0(@testing-library/dom@9.3.4)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@testing-library/react@16.0.0(@testing-library/dom@10.1.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 - '@testing-library/dom': 9.3.4 + '@testing-library/dom': 10.1.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.3 '@types/react-dom': 18.3.0 - '@testing-library/user-event@14.5.2(@testing-library/dom@9.3.4)': + '@testing-library/user-event@14.5.2(@testing-library/dom@10.1.0)': dependencies: - '@testing-library/dom': 9.3.4 + '@testing-library/dom': 10.1.0 '@tootallnate/once@2.0.0': {} @@ -12806,6 +12924,10 @@ snapshots: '@types/minimist@1.2.5': {} + '@types/mute-stream@0.0.4': + dependencies: + '@types/node': 20.14.2 + '@types/node-fetch@2.6.11': dependencies: '@types/node': 20.14.2 @@ -12907,6 +13029,8 @@ snapshots: '@types/source-list-map@0.1.6': {} + '@types/statuses@2.0.5': {} + '@types/stylis@4.2.5': {} '@types/tapable@1.0.12': {} @@ -12961,6 +13085,8 @@ snapshots: dependencies: '@types/webidl-conversions': 7.0.3 + '@types/wrap-ansi@3.0.0': {} + '@types/ws@7.4.7': dependencies: '@types/node': 20.14.2 @@ -13158,40 +13284,43 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitest/browser@2.0.0-beta.9(playwright@1.44.1)(vitest@2.0.0-beta.9)': + '@vitest/browser@2.0.0-beta.10(playwright@1.44.1)(typescript@5.4.5)(vitest@2.0.0-beta.10)': dependencies: - '@testing-library/dom': 9.3.4 - '@testing-library/user-event': 14.5.2(@testing-library/dom@9.3.4) - '@vitest/utils': 2.0.0-beta.9 + '@testing-library/dom': 10.1.0 + '@testing-library/user-event': 14.5.2(@testing-library/dom@10.1.0) + '@vitest/utils': 2.0.0-beta.10 magic-string: 0.30.10 + msw: 2.3.1(typescript@5.4.5) sirv: 2.0.4 - vitest: 2.0.0-beta.9(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.9)(jsdom@24.1.0)(terser@5.31.0) + vitest: 2.0.0-beta.10(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.10)(jsdom@24.1.0)(terser@5.31.0) optionalDependencies: playwright: 1.44.1 + transitivePeerDependencies: + - typescript - '@vitest/expect@2.0.0-beta.9': + '@vitest/expect@2.0.0-beta.10': dependencies: - '@vitest/spy': 2.0.0-beta.9 - '@vitest/utils': 2.0.0-beta.9 + '@vitest/spy': 2.0.0-beta.10 + '@vitest/utils': 2.0.0-beta.10 chai: 5.1.1 - '@vitest/runner@2.0.0-beta.9': + '@vitest/runner@2.0.0-beta.10': dependencies: - '@vitest/utils': 2.0.0-beta.9 + '@vitest/utils': 2.0.0-beta.10 p-limit: 5.0.0 pathe: 1.1.2 - '@vitest/snapshot@2.0.0-beta.9': + '@vitest/snapshot@2.0.0-beta.10': dependencies: magic-string: 0.30.10 pathe: 1.1.2 pretty-format: 29.7.0 - '@vitest/spy@2.0.0-beta.9': + '@vitest/spy@2.0.0-beta.10': dependencies: tinyspy: 3.0.0 - '@vitest/utils@2.0.0-beta.9': + '@vitest/utils@2.0.0-beta.10': dependencies: diff-sequences: 29.6.3 estree-walker: 3.0.3 @@ -13487,10 +13616,6 @@ snapshots: argparse@2.0.1: {} - aria-query@5.1.3: - dependencies: - deep-equal: 2.2.3 - aria-query@5.3.0: dependencies: dequal: 2.0.3 @@ -14188,6 +14313,8 @@ snapshots: cookie@0.4.2: {} + cookie@0.5.0: {} + cookie@0.6.0: {} copy-anything@3.0.5: @@ -14426,27 +14553,6 @@ snapshots: deep-eql@5.0.2: {} - deep-equal@2.2.3: - dependencies: - array-buffer-byte-length: 1.0.1 - call-bind: 1.0.7 - es-get-iterator: 1.1.3 - get-intrinsic: 1.2.4 - is-arguments: 1.1.1 - is-array-buffer: 3.0.4 - is-date-object: 1.0.5 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.3 - isarray: 2.0.5 - object-is: 1.1.6 - object-keys: 1.1.1 - object.assign: 4.1.5 - regexp.prototype.flags: 1.5.2 - side-channel: 1.0.6 - which-boxed-primitive: 1.0.2 - which-collection: 1.0.2 - which-typed-array: 1.1.15 - deep-extend@0.6.0: {} deep-is@0.1.4: {} @@ -15753,6 +15859,8 @@ snapshots: graphemer@1.4.0: {} + graphql@16.8.1: {} + gtoken@7.1.0(encoding@0.1.13): dependencies: gaxios: 6.6.0(encoding@0.1.13) @@ -15807,6 +15915,8 @@ snapshots: dependencies: function-bind: 1.1.2 + headers-polyfill@4.0.3: {} + hexoid@1.0.0: {} hoist-non-react-statics@3.3.2: @@ -16137,6 +16247,8 @@ snapshots: is-negative-zero@2.0.3: {} + is-node-process@1.2.0: {} + is-number-object@1.0.7: dependencies: has-tostringtag: 1.0.2 @@ -17089,6 +17201,28 @@ snapshots: ms@2.1.3: {} + msw@2.3.1(typescript@5.4.5): + dependencies: + '@bundled-es-modules/cookie': 2.0.0 + '@bundled-es-modules/statuses': 1.0.1 + '@inquirer/confirm': 3.1.9 + '@mswjs/cookies': 1.1.0 + '@mswjs/interceptors': 0.29.1 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.5 + chalk: 4.1.2 + graphql: 16.8.1 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.2 + path-to-regexp: 6.2.2 + strict-event-emitter: 0.5.1 + type-fest: 4.20.0 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.4.5 + multimatch@5.0.0: dependencies: '@types/minimatch': 3.0.5 @@ -17435,11 +17569,6 @@ snapshots: object-inspect@1.13.1: {} - object-is@1.1.6: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - object-keys@0.4.0: {} object-keys@1.1.1: {} @@ -17563,6 +17692,8 @@ snapshots: os-tmpdir@1.0.2: {} + outvariant@1.4.2: {} + p-event@5.0.1: dependencies: p-timeout: 5.1.0 @@ -18845,6 +18976,8 @@ snapshots: optionalDependencies: bare-events: 2.3.1 + strict-event-emitter@0.5.1: {} + string-at@1.1.0: dependencies: define-properties: 1.2.1 @@ -19286,6 +19419,8 @@ snapshots: type-fest@2.19.0: {} + type-fest@4.20.0: {} + type-is@1.6.18: dependencies: media-typer: 0.3.0 @@ -19509,7 +19644,7 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 - vite-node@2.0.0-beta.9(@types/node@20.14.2)(terser@5.31.0): + vite-node@2.0.0-beta.10(@types/node@20.14.2)(terser@5.31.0): dependencies: cac: 6.7.14 debug: 4.3.5 @@ -19536,7 +19671,7 @@ snapshots: fsevents: 2.3.3 terser: 5.31.0 - vitest-dom@0.1.1(vitest@2.0.0-beta.9(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.9)(jsdom@24.1.0)(terser@5.31.0)): + vitest-dom@0.1.1(vitest@2.0.0-beta.10(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.10)(jsdom@24.1.0)(terser@5.31.0)): dependencies: aria-query: 5.3.0 chalk: 5.3.0 @@ -19544,21 +19679,22 @@ snapshots: dom-accessibility-api: 0.6.3 lodash-es: 4.17.21 redent: 4.0.0 - vitest: 2.0.0-beta.9(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.9)(jsdom@24.1.0)(terser@5.31.0) + vitest: 2.0.0-beta.10(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.10)(jsdom@24.1.0)(terser@5.31.0) - vitest-fail-on-console@0.7.0(vite@5.2.13(@types/node@20.14.2)(terser@5.31.0))(vitest@2.0.0-beta.9(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.9)(jsdom@24.1.0)(terser@5.31.0)): + vitest-fail-on-console@0.7.0(vite@5.2.13(@types/node@20.14.2)(terser@5.31.0))(vitest@2.0.0-beta.10(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.10)(jsdom@24.1.0)(terser@5.31.0)): dependencies: chalk: 5.3.0 vite: 5.2.13(@types/node@20.14.2)(terser@5.31.0) - vitest: 2.0.0-beta.9(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.9)(jsdom@24.1.0)(terser@5.31.0) + vitest: 2.0.0-beta.10(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.10)(jsdom@24.1.0)(terser@5.31.0) - vitest@2.0.0-beta.9(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.9)(jsdom@24.1.0)(terser@5.31.0): + vitest@2.0.0-beta.10(@types/node@20.14.2)(@vitest/browser@2.0.0-beta.10)(jsdom@24.1.0)(terser@5.31.0): dependencies: - '@vitest/expect': 2.0.0-beta.9 - '@vitest/runner': 2.0.0-beta.9 - '@vitest/snapshot': 2.0.0-beta.9 - '@vitest/spy': 2.0.0-beta.9 - '@vitest/utils': 2.0.0-beta.9 + '@ampproject/remapping': 2.3.0 + '@vitest/expect': 2.0.0-beta.10 + '@vitest/runner': 2.0.0-beta.10 + '@vitest/snapshot': 2.0.0-beta.10 + '@vitest/spy': 2.0.0-beta.10 + '@vitest/utils': 2.0.0-beta.10 chai: 5.1.1 debug: 4.3.5 execa: 8.0.1 @@ -19569,11 +19705,11 @@ snapshots: tinybench: 2.8.0 tinypool: 1.0.0 vite: 5.2.13(@types/node@20.14.2)(terser@5.31.0) - vite-node: 2.0.0-beta.9(@types/node@20.14.2)(terser@5.31.0) + vite-node: 2.0.0-beta.10(@types/node@20.14.2)(terser@5.31.0) why-is-node-running: 2.2.2 optionalDependencies: '@types/node': 20.14.2 - '@vitest/browser': 2.0.0-beta.9(playwright@1.44.1)(vitest@2.0.0-beta.9) + '@vitest/browser': 2.0.0-beta.10(playwright@1.44.1)(typescript@5.4.5)(vitest@2.0.0-beta.10) jsdom: 24.1.0 transitivePeerDependencies: - less From 24c01ddb3deeb04d94c305bfdbe459a4845ff243 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:37:34 +0200 Subject: [PATCH 13/36] lint --- .../src/useDialogs/useDialog.test.tsx | 2 +- .../src/useDialogs/useDialogs.tsx | 21 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/toolpad-core/src/useDialogs/useDialog.test.tsx b/packages/toolpad-core/src/useDialogs/useDialog.test.tsx index 6bfa273bd02..1ba17085926 100644 --- a/packages/toolpad-core/src/useDialogs/useDialog.test.tsx +++ b/packages/toolpad-core/src/useDialogs/useDialog.test.tsx @@ -4,7 +4,7 @@ import * as React from 'react'; import { describe, test, expect } from 'vitest'; -import { renderHook, within, screen, act } from '@testing-library/react'; +import { renderHook, within, screen } from '@testing-library/react'; import { userEvent } from '@testing-library/user-event'; import { DialogProvider, useDialogs } from './useDialogs'; diff --git a/packages/toolpad-core/src/useDialogs/useDialogs.tsx b/packages/toolpad-core/src/useDialogs/useDialogs.tsx index 4c5797897cb..87da7a61d84 100644 --- a/packages/toolpad-core/src/useDialogs/useDialogs.tsx +++ b/packages/toolpad-core/src/useDialogs/useDialogs.tsx @@ -140,15 +140,18 @@ export function DialogProvider(props: DialogProviderprops) { [keyPrefix], ); - const closeDialogUi = React.useCallback(function closeDialogUi(dialog: Promise) { - setStack((prevStack) => - prevStack.map((entry) => (entry.promise === dialog ? { ...entry, open: false } : entry)), - ); - setTimeout(() => { - // wait for closing animation - setStack((prevStack) => prevStack.filter((entry) => entry.promise !== dialog)); - }, unmountAfter); - }, []); + const closeDialogUi = React.useCallback( + function closeDialogUi(dialog: Promise) { + setStack((prevStack) => + prevStack.map((entry) => (entry.promise === dialog ? { ...entry, open: false } : entry)), + ); + setTimeout(() => { + // wait for closing animation + setStack((prevStack) => prevStack.filter((entry) => entry.promise !== dialog)); + }, unmountAfter); + }, + [unmountAfter], + ); const closeDialog = React.useCallback( async function closeDialog(dialog: Promise, result: R) { From 05afa96dda7bc9d3cc72f1417bf79a3599ef4d97 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:41:10 +0200 Subject: [PATCH 14/36] tests --- .../src/useDialogs/useDialog.test.tsx | 81 +++++++++++++++++-- 1 file changed, 75 insertions(+), 6 deletions(-) diff --git a/packages/toolpad-core/src/useDialogs/useDialog.test.tsx b/packages/toolpad-core/src/useDialogs/useDialog.test.tsx index 1ba17085926..53e152f8f60 100644 --- a/packages/toolpad-core/src/useDialogs/useDialog.test.tsx +++ b/packages/toolpad-core/src/useDialogs/useDialog.test.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { describe, test, expect } from 'vitest'; import { renderHook, within, screen } from '@testing-library/react'; import { userEvent } from '@testing-library/user-event'; -import { DialogProvider, useDialogs } from './useDialogs'; +import { DialogProps, DialogProvider, useDialogs } from './useDialogs'; interface TestWrapperProps { children: React.ReactNode; @@ -25,7 +25,7 @@ describe('useDialogs', () => { rerender(); - const dialog = screen.getByRole('dialog'); + const dialog = await screen.findByRole('dialog'); expect(within(dialog).getByText('Hello')).toBeTruthy(); @@ -47,7 +47,7 @@ describe('useDialogs', () => { rerender(); - const dialog = screen.getByRole('dialog'); + const dialog = await screen.findByRole('dialog'); expect(within(dialog).getByText('Hello')).toBeTruthy(); @@ -67,7 +67,7 @@ describe('useDialogs', () => { rerender(); - const dialog = screen.getByRole('dialog'); + const dialog = await screen.findByRole('dialog'); expect(within(dialog).getByText('Hello')).toBeTruthy(); @@ -89,7 +89,7 @@ describe('useDialogs', () => { rerender(); - const dialog = screen.getByRole('dialog'); + const dialog = await screen.findByRole('dialog'); expect(within(dialog).getByText('Hello')).toBeTruthy(); @@ -111,7 +111,7 @@ describe('useDialogs', () => { rerender(); - const dialog = screen.getByRole('dialog'); + const dialog = await screen.findByRole('dialog'); expect(within(dialog).getByText('Hello')).toBeTruthy(); @@ -126,4 +126,73 @@ describe('useDialogs', () => { expect(screen.queryByRole('dialog')).toBeFalsy(); }); }); + + describe('custom dialog', () => { + test('can show and hide', async () => { + function CustomDialog({ open, onClose }: DialogProps) { + return open ? ( +
+ Hello +
+ ) : null; + } + const { result, rerender } = renderHook(() => useDialogs(), { wrapper: TestWrapper }); + + result.current.open(CustomDialog); + + const dialog = await screen.findByRole('dialog'); + + rerender(); + + expect(within(dialog).getByText('Hello')).toBeTruthy(); + + await userEvent.click(within(dialog).getByRole('button', { name: 'Close me' })); + + rerender(); + + expect(screen.queryByRole('dialog')).toBeFalsy(); + }); + }); + + test('can pass a payload', async () => { + function CustomDialog({ open, onClose, payload }: DialogProps) { + return open ? ( +
+ {payload} +
+ ) : null; + } + const { result, rerender } = renderHook(() => useDialogs(), { wrapper: TestWrapper }); + + result.current.open(CustomDialog, 'I am content'); + + const dialog = await screen.findByRole('dialog'); + + rerender(); + + expect(within(dialog).getByText('I am content')).toBeTruthy(); + }); + + test('can receive result', async () => { + function CustomDialog({ open, onClose }: DialogProps) { + return open ? ( +
+ Hello +
+ ) : null; + } + const { result, rerender } = renderHook(() => useDialogs(), { wrapper: TestWrapper }); + + const dialogResult = result.current.open(CustomDialog); + + const dialog = await screen.findByRole('dialog'); + + rerender(); + + await userEvent.click(within(dialog).getByRole('button', { name: 'Close me' })); + + rerender(); + + expect(await dialogResult).toBe('I am result'); + }); }); From f0874a209ccc28bcc27ca9b9bb405005de03f0ac Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 14:52:15 +0200 Subject: [PATCH 15/36] ferger --- .../src/useDialogs/useDialog.test.tsx | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/toolpad-core/src/useDialogs/useDialog.test.tsx b/packages/toolpad-core/src/useDialogs/useDialog.test.tsx index 53e152f8f60..c037a58d8fe 100644 --- a/packages/toolpad-core/src/useDialogs/useDialog.test.tsx +++ b/packages/toolpad-core/src/useDialogs/useDialog.test.tsx @@ -152,47 +152,47 @@ describe('useDialogs', () => { expect(screen.queryByRole('dialog')).toBeFalsy(); }); - }); - test('can pass a payload', async () => { - function CustomDialog({ open, onClose, payload }: DialogProps) { - return open ? ( -
- {payload} -
- ) : null; - } - const { result, rerender } = renderHook(() => useDialogs(), { wrapper: TestWrapper }); + test('can pass a payload', async () => { + function CustomDialog({ open, onClose, payload }: DialogProps) { + return open ? ( +
+ {payload} +
+ ) : null; + } + const { result, rerender } = renderHook(() => useDialogs(), { wrapper: TestWrapper }); - result.current.open(CustomDialog, 'I am content'); + result.current.open(CustomDialog, 'I am content'); - const dialog = await screen.findByRole('dialog'); + const dialog = await screen.findByRole('dialog'); - rerender(); + rerender(); - expect(within(dialog).getByText('I am content')).toBeTruthy(); - }); + expect(within(dialog).getByText('I am content')).toBeTruthy(); + }); - test('can receive result', async () => { - function CustomDialog({ open, onClose }: DialogProps) { - return open ? ( -
- Hello -
- ) : null; - } - const { result, rerender } = renderHook(() => useDialogs(), { wrapper: TestWrapper }); + test('can receive result', async () => { + function CustomDialog({ open, onClose }: DialogProps) { + return open ? ( +
+ Hello +
+ ) : null; + } + const { result, rerender } = renderHook(() => useDialogs(), { wrapper: TestWrapper }); - const dialogResult = result.current.open(CustomDialog); + const dialogResult = result.current.open(CustomDialog); - const dialog = await screen.findByRole('dialog'); + const dialog = await screen.findByRole('dialog'); - rerender(); + rerender(); - await userEvent.click(within(dialog).getByRole('button', { name: 'Close me' })); + await userEvent.click(within(dialog).getByRole('button', { name: 'Close me' })); - rerender(); + rerender(); - expect(await dialogResult).toBe('I am result'); + expect(await dialogResult).toBe('I am result'); + }); }); }); From 4bcbe1d3db9173b91d7303628cd9060a6aee2e97 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 16:14:19 +0200 Subject: [PATCH 16/36] let's go --- docs/package.json | 16 ++-- pnpm-lock.yaml | 183 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 151 insertions(+), 48 deletions(-) diff --git a/docs/package.json b/docs/package.json index ecda90a9d0a..4b0b58dcc01 100644 --- a/docs/package.json +++ b/docs/package.json @@ -26,15 +26,15 @@ "@emotion/styled": "11.11.5", "@mui/base": "5.0.0-beta.40", "@mui/docs": "6.0.0-dev.240424162023-9968b4889d", - "@mui/icons-material": "^5.15.19", + "@mui/icons-material": "next", "@mui/internal-markdown": "^1.0.1", - "@mui/joy": "5.0.0-beta.32", - "@mui/lab": "^5.0.0-alpha.170", - "@mui/material": "^5.15.19", - "@mui/material-nextjs": "^5.15.11", - "@mui/styles": "^5.15.19", - "@mui/system": "^5.15.15", - "@mui/utils": "5.15.14", + "@mui/joy": "next", + "@mui/lab": "next", + "@mui/material": "next", + "@mui/material-nextjs": "next", + "@mui/styles": "next", + "@mui/system": "next", + "@mui/utils": "next", "@mui/x-license": "7.6.1", "@toolpad/core": "workspace:*", "@toolpad/studio": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 648475811b7..47efc114fc2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -284,34 +284,34 @@ importers: version: 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/docs': specifier: 6.0.0-dev.240424162023-9968b4889d - version: 6.0.0-dev.240424162023-9968b4889d(@mui/base@5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/icons-material@5.15.19(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 6.0.0-dev.240424162023-9968b4889d(@mui/base@5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/icons-material@6.0.0-alpha.11(@mui/material@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@mui/icons-material': - specifier: ^5.15.19 - version: 5.15.19(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + specifier: next + version: 6.0.0-alpha.11(@mui/material@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@mui/internal-markdown': specifier: ^1.0.1 version: 1.0.5 '@mui/joy': - specifier: 5.0.0-beta.32 - version: 5.0.0-beta.32(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: next + version: 5.0.0-beta.44(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/lab': - specifier: ^5.0.0-alpha.170 - version: 5.0.0-alpha.170(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: next + version: 6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/material': - specifier: ^5.15.19 - version: 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: next + version: 6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/material-nextjs': - specifier: ^5.15.11 - version: 5.15.11(@emotion/cache@11.11.0)(@emotion/server@11.11.0)(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + specifier: next + version: 6.0.0-alpha.11(@emotion/cache@11.11.0)(@emotion/server@11.11.0)(@mui/material@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@mui/styles': - specifier: ^5.15.19 - version: 5.15.19(@types/react@18.3.3)(react@18.3.1) + specifier: next + version: 6.0.0-alpha.11(@types/react@18.3.3)(react@18.3.1) '@mui/system': - specifier: ^5.15.15 - version: 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + specifier: next + version: 6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@mui/utils': - specifier: 5.15.14 - version: 5.15.14(@types/react@18.3.3)(react@18.3.1) + specifier: next + version: 6.0.0-alpha.11(@types/react@18.3.3)(react@18.3.1) '@mui/x-license': specifier: 7.6.1 version: 7.6.1(@types/react@18.3.3)(react@18.3.1) @@ -2750,6 +2750,17 @@ packages: '@types/react': optional: true + '@mui/icons-material@6.0.0-alpha.11': + resolution: {integrity: sha512-4UEQJHgss0D0F4GPGe2m7ZMmIdlYnPYISMn+VoODFflLPPSFsWh+yLcpYalmXPep961rOb2Vjbnx4lE1sb4J8Q==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@mui/material': ^6.0.0-alpha.11 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@mui/internal-docs-utils@1.0.7': resolution: {integrity: sha512-vHplixLKu17U7Wa3RDbGv9C3FmXniJKywyZEIeJaTG4ikvl+iWI+BuZPCNniJwj0HSxu3thbyPIrBXijh7j+Xg==} @@ -2759,8 +2770,8 @@ packages: '@mui/internal-scripts@1.0.10': resolution: {integrity: sha512-Cj07lzcM2ozjTF7BYIhSaCwy6MYzAUB7HxC3d7lex46dE9N6zsG/48S0Hs5qSMrWOyUnNXI/5Y/SypgL/Ss8ng==} - '@mui/joy@5.0.0-beta.32': - resolution: {integrity: sha512-QJW5Mu2GTJUX4sXjxt4nQBugpJAiSkUT49S/bwoKCCWx8bCfsEyplTzZPK+FraweiGhGgZWExWOTAPpxH83RUQ==} + '@mui/joy@5.0.0-beta.44': + resolution: {integrity: sha512-U0LxmLXoqrBxr9lJf7RQbqaO7SXYAwhnNrsEFQqJBTQ9gk7iL2viIsQUcYVhb2ckmbsi0qWu51dw7BQE6w6/4w==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -2794,6 +2805,24 @@ packages: '@types/react': optional: true + '@mui/lab@6.0.0-alpha.11': + resolution: {integrity: sha512-iN0+GtxoFDZ2k+eSSQ0nxpxc3b9J2YA6/NKegj0EoJT80h5omuFZtguqsaAXRbmY3UDCfrmrSDof6ynn0cenTA==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@mui/material': ^6.0.0-alpha.11 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + '@mui/material-nextjs@5.15.11': resolution: {integrity: sha512-cp5RWYbBngyi7NKP91R9QITllfxumCVPFjqe4AKzNROVuCot0VpgkafxXqfbv0uFsyUU0ROs0O2M3r17q604Aw==} engines: {node: '>=12.0.0'} @@ -2812,6 +2841,24 @@ packages: '@types/react': optional: true + '@mui/material-nextjs@6.0.0-alpha.11': + resolution: {integrity: sha512-4bLqUA7Gxq8LYAtxBsxd56tFOTVVlhS9bgA67hmIoQmk/h/ST6jo58mGLitMIDMg1IwRjJuIK1uuHmRzIOBNMw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/cache': ^11.11.0 + '@emotion/server': ^11.11.0 + '@mui/material': ^6.0.0-alpha.11 + '@types/react': ^17.0.0 || ^18.0.0 + next: ^13.0.0 || ^14.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/cache': + optional: true + '@emotion/server': + optional: true + '@types/react': + optional: true + '@mui/material@5.15.19': resolution: {integrity: sha512-lp5xQBbcRuxNtjpWU0BWZgIrv2XLUz4RJ0RqFXBdESIsKoGCQZ6P3wwU5ZPuj5TjssNiKv9AlM+vHopRxZhvVQ==} engines: {node: '>=12.0.0'} @@ -2897,8 +2944,8 @@ packages: '@emotion/styled': optional: true - '@mui/styles@5.15.19': - resolution: {integrity: sha512-WOYjZT6DL/StJv/vFR/tJPJuHC98lwWza7Gzj2RWZk123eCcSJ+3ruc62/ZyXaCx4PKCbE849mVl+CWhA2ecmw==} + '@mui/styles@6.0.0-alpha.11': + resolution: {integrity: sha512-0dXPE9aImKi6ACD9ZT7CSBli1rpbCMBJPL7Wk05I1YagK9LPZzN5lZv8VqHgBGq4ynVY9tEzn8TDQ1z0aUiJsw==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -2923,8 +2970,8 @@ packages: '@types/react': optional: true - '@mui/system@6.0.0-dev.240424162023-9968b4889d': - resolution: {integrity: sha512-Y3yCFUHN1xMK62hJJBqzZb1YQvHNaHc7JUX01eU6QTPojtIbGMF2jCOP/EQw77/byahNbxeLoAIQx10F0IR3Rw==} + '@mui/system@6.0.0-alpha.11': + resolution: {integrity: sha512-RceH1GU0M7aKNFIaQ92n5uR0moRbsuPfWh08F2Z9jz0k/y/59Tj/IVsdSYnjncnoGxhS3HfL3qJM8gRIkbdF1Q==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -2957,6 +3004,16 @@ packages: '@types/react': optional: true + '@mui/utils@6.0.0-alpha.11': + resolution: {integrity: sha512-L4GpoTSWH6lVmMghR4a8j5SYOcXwR1jRSvKD6CEs42SOkdYH9lYdDumR6xOzrR+ROV97oB6sh44pVc2GWNLxhg==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@mui/utils@6.0.0-dev.20240529-082515-213b5e33ab': resolution: {integrity: sha512-jyNcB0drDhYcoq5MHNTiEc63GfVE1GZK+CVUd8tlLzk5q631RPYJ5jONSOszLiUOXBmI8Uu1SBJUwrG3j2YG2A==} engines: {node: '>=12.0.0'} @@ -11604,7 +11661,7 @@ snapshots: '@babel/runtime': 7.24.7 '@floating-ui/react-dom': 2.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/types': 7.2.14(@types/react@18.3.3) - '@mui/utils': 6.0.0-dev.20240529-082515-213b5e33ab(@types/react@18.3.3)(react@18.3.1) + '@mui/utils': 6.0.0-alpha.11(@types/react@18.3.3)(react@18.3.1) '@popperjs/core': 2.11.8 clsx: 2.1.1 prop-types: 15.8.1 @@ -11617,14 +11674,14 @@ snapshots: '@mui/core-downloads-tracker@6.0.0-dev.240424162023-9968b4889d': {} - ? '@mui/docs@6.0.0-dev.240424162023-9968b4889d(@mui/base@5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/icons-material@5.15.19(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)' + ? '@mui/docs@6.0.0-dev.240424162023-9968b4889d(@mui/base@5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/icons-material@6.0.0-alpha.11(@mui/material@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)' : dependencies: '@babel/runtime': 7.24.7 '@mui/base': 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/icons-material': 5.15.19(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/icons-material': 6.0.0-alpha.11(@mui/material@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@mui/internal-markdown': 1.0.5 - '@mui/material': 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/material': 6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': 6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) clipboard-copy: 4.0.1 clsx: 2.1.1 next: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -11642,6 +11699,14 @@ snapshots: optionalDependencies: '@types/react': 18.3.3 + '@mui/icons-material@6.0.0-alpha.11(@mui/material@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@mui/material': 6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + '@mui/internal-docs-utils@1.0.7': dependencies: rimraf: 5.0.7 @@ -11669,14 +11734,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@mui/joy@5.0.0-beta.32(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mui/joy@5.0.0-beta.44(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 - '@mui/base': 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/core-downloads-tracker': 5.15.19 - '@mui/system': 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/base': 5.0.0-beta.49(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/core-downloads-tracker': 6.0.0-dev.240424162023-9968b4889d + '@mui/system': 6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@mui/types': 7.2.14(@types/react@18.3.3) - '@mui/utils': 5.15.14(@types/react@18.3.3)(react@18.3.1) + '@mui/utils': 6.0.0-alpha.11(@types/react@18.3.3)(react@18.3.1) clsx: 2.1.1 prop-types: 15.8.1 react: 18.3.1 @@ -11703,6 +11768,23 @@ snapshots: '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@types/react': 18.3.3 + '@mui/lab@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@mui/base': 5.0.0-beta.49(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': 6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': 6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/types': 7.2.14(@types/react@18.3.3) + '@mui/utils': 6.0.0-alpha.11(@types/react@18.3.3)(react@18.3.1) + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@types/react': 18.3.3 + '@mui/material-nextjs@5.15.11(@emotion/cache@11.11.0)(@emotion/server@11.11.0)(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -11714,6 +11796,17 @@ snapshots: '@emotion/server': 11.11.0 '@types/react': 18.3.3 + '@mui/material-nextjs@6.0.0-alpha.11(@emotion/cache@11.11.0)(@emotion/server@11.11.0)(@mui/material@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@mui/material': 6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.8.0)(@playwright/test@1.44.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@emotion/cache': 11.11.0 + '@emotion/server': 11.11.0 + '@types/react': 18.3.3 + '@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 @@ -11740,9 +11833,9 @@ snapshots: '@babel/runtime': 7.24.7 '@mui/base': 5.0.0-beta.49(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/core-downloads-tracker': 6.0.0-dev.240424162023-9968b4889d - '@mui/system': 6.0.0-dev.240424162023-9968b4889d(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/system': 6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@mui/types': 7.2.14(@types/react@18.3.3) - '@mui/utils': 6.0.0-dev.20240529-082515-213b5e33ab(@types/react@18.3.3)(react@18.3.1) + '@mui/utils': 6.0.0-alpha.11(@types/react@18.3.3)(react@18.3.1) '@types/react-transition-group': 4.4.10 clsx: 2.1.1 csstype: 3.1.3 @@ -11811,13 +11904,13 @@ snapshots: '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) - '@mui/styles@5.15.19(@types/react@18.3.3)(react@18.3.1)': + '@mui/styles@6.0.0-alpha.11(@types/react@18.3.3)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 '@emotion/hash': 0.9.1 - '@mui/private-theming': 5.15.14(@types/react@18.3.3)(react@18.3.1) + '@mui/private-theming': 6.0.0-dev.20240529-082515-213b5e33ab(@types/react@18.3.3)(react@18.3.1) '@mui/types': 7.2.14(@types/react@18.3.3) - '@mui/utils': 5.15.14(@types/react@18.3.3)(react@18.3.1) + '@mui/utils': 6.0.0-alpha.11(@types/react@18.3.3)(react@18.3.1) clsx: 2.1.1 csstype: 3.1.3 hoist-non-react-statics: 3.3.2 @@ -11850,13 +11943,13 @@ snapshots: '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) '@types/react': 18.3.3 - '@mui/system@6.0.0-dev.240424162023-9968b4889d(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)': + '@mui/system@6.0.0-alpha.11(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 '@mui/private-theming': 6.0.0-dev.20240529-082515-213b5e33ab(@types/react@18.3.3)(react@18.3.1) '@mui/styled-engine': 6.0.0-dev.20240529-082515-213b5e33ab(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(react@18.3.1) '@mui/types': 7.2.14(@types/react@18.3.3) - '@mui/utils': 6.0.0-dev.20240529-082515-213b5e33ab(@types/react@18.3.3)(react@18.3.1) + '@mui/utils': 6.0.0-alpha.11(@types/react@18.3.3)(react@18.3.1) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 @@ -11880,6 +11973,16 @@ snapshots: optionalDependencies: '@types/react': 18.3.3 + '@mui/utils@6.0.0-alpha.11(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@types/prop-types': 15.7.12 + prop-types: 15.8.1 + react: 18.3.1 + react-is: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + '@mui/utils@6.0.0-dev.20240529-082515-213b5e33ab(@types/react@18.3.3)(react@18.3.1)': dependencies: '@babel/runtime': 7.24.7 From 4cf476d103804a7237f9ab59afa6edae088ff608 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 16:42:24 +0200 Subject: [PATCH 17/36] Update useDialogs.tsx --- .../src/useDialogs/useDialogs.tsx | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/packages/toolpad-core/src/useDialogs/useDialogs.tsx b/packages/toolpad-core/src/useDialogs/useDialogs.tsx index 87da7a61d84..008200d1ecb 100644 --- a/packages/toolpad-core/src/useDialogs/useDialogs.tsx +++ b/packages/toolpad-core/src/useDialogs/useDialogs.tsx @@ -255,9 +255,32 @@ export interface PromptDialogProps extends DialogProps onClose(null)); - const okButtonProps = useDialogLoadingButton(() => onClose(input)); + + const [loading, setLoading] = React.useState(false); + + const name = 'input'; return ( - onClose(null)}> + onClose(null)} + PaperProps={{ + component: 'form', + onSubmit: async (event: React.FormEvent) => { + event.preventDefault(); + try { + setLoading(true); + const formData = new FormData(event.currentTarget); + const value = formData.get(name) ?? ''; + invariant(typeof value === 'string', 'Value must come from a text input'); + await onClose(value); + } finally { + setLoading(false); + } + }, + }} + > {payload.title ?? 'Confirm'} {payload.msg} @@ -266,7 +289,7 @@ export function PromptDialog({ open, payload, onClose }: PromptDialogProps) { required margin="dense" id="name" - name="input" + name={name} type="text" fullWidth variant="standard" @@ -278,7 +301,7 @@ export function PromptDialog({ open, payload, onClose }: PromptDialogProps) { {payload.cancelText ?? 'Cancel'} - + {payload.okText ?? 'Ok'} From 25b6af95fb0fdef7fb03cf901be6f2754d66259e Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Wed, 12 Jun 2024 18:14:07 +0200 Subject: [PATCH 18/36] Delete dashboard-layout.js --- docs/pages/toolpad/core/components/dashboard-layout.js | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 docs/pages/toolpad/core/components/dashboard-layout.js diff --git a/docs/pages/toolpad/core/components/dashboard-layout.js b/docs/pages/toolpad/core/components/dashboard-layout.js deleted file mode 100644 index 928b679bea5..00000000000 --- a/docs/pages/toolpad/core/components/dashboard-layout.js +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from 'react'; -import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; -import * as pageProps from '../../../../data/toolpad/core/components/dashboard-layout/dashboard-layout.md?muiMarkdown'; - -export default function Page() { - return ; -} From c136a86deef7bc9faccb094322b8a248ba40a446 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:55:20 +0200 Subject: [PATCH 19/36] Dialogs API reference --- .../components/use-dialogs/use-dialogs-api.md | 138 ++++++++++++++++++ .../components/use-dialogs/use-dialogs.md | 5 + .../use-notifications-api.md | 13 ++ .../toolpad/core/react-use-dialogs/api.js | 7 + .../core/react-use-notifications/api.js | 7 + .../src/useDialogs/useDialogs.tsx | 108 ++++++++++++-- .../src/useNotifications/useNotifications.tsx | 3 +- 7 files changed, 269 insertions(+), 12 deletions(-) create mode 100644 docs/data/toolpad/core/components/use-dialogs/use-dialogs-api.md create mode 100644 docs/data/toolpad/core/components/use-notifications/use-notifications-api.md create mode 100644 docs/pages/toolpad/core/react-use-dialogs/api.js create mode 100644 docs/pages/toolpad/core/react-use-notifications/api.js diff --git a/docs/data/toolpad/core/components/use-dialogs/use-dialogs-api.md b/docs/data/toolpad/core/components/use-dialogs/use-dialogs-api.md new file mode 100644 index 00000000000..6fa71f9348f --- /dev/null +++ b/docs/data/toolpad/core/components/use-dialogs/use-dialogs-api.md @@ -0,0 +1,138 @@ +# useDialogs API + +

API reference for the useDialogs hook.

+ +## Import + +```js +import useDialogs from '@toolpad/core/useDialogs'; +// or +import { useDialogs } from '@toolpad/core'; +``` + +Learn about the difference by reading this [guide](https://mui.com/material-ui/guides/minimizing-bundle-size/) on minimizing bundle size. + +## usage + +Get access to the dialogs API by invoking the hook. + +```js +const dialogs = useDialogs(); +``` + +## Reference + +### `dialogs.alert(message, options?)` + +Open an alert dialog, returns a promise that resolves when the user closes the dialog. + +```js +await dialogs.alert('Something went wrong', { + title: 'Attention!', +}); +``` + +**Parameters:** + +- `message`: `React.ReactNode` The message to display in the alert dialog. +- `options?`: `object` Extra configuration for the alert dialog. + - `onClose?`: `() => Promise` A function that is called before closing the dialog closes. The dialog stays open as long as the returned promise is not resolved. Use this if you want to perform an async action on close and show a loading state. + - `title?`: `React.ReactNode` A title for the dialog. Defaults to `'Alert'`. + - `okText?`: `React.ReactNode` The text to show in the "Ok" button. Defaults to `'Ok'`. + +**Returns:** + +`Promise` A promise that resolves once the user has dismissed the dialog. + +### `dialogs.confirm(message, options?)` + +Open a confirmation dialog. Returns a promise that resolves to true if the user confirms, false if the user cancels. + +```js +const confirmed = await dialogs.confirm('Are you sure?', { + okText: 'Yes', + cancelText: 'No', +}); +``` + +**Parameters:** + +- `message`: `React.ReactNode` The message to display in the confirmation dialog. +- `options?`: `object` Extra configuration for the confirmation dialog. + - `onClose?`: `(result: boolean) => Promise` A function that is called before closing the dialog closes. The dialog stays open as long as the returned promise is not resolved. Use this if you want to perform an async action on close and show a loading state. + - `title?`: `React.ReactNode` A title for the dialog. Defaults to `'Confirm'`. + - `okText?`: `React.ReactNode` The text to show in the "Ok" button. Defaults to `'Ok'`. + - `severity?`: `'error' | 'info' | 'success' | 'warning'` Denotes the purpose of the dialog. This will affect the color of the "Ok" button. Defaults to `undefined`. + - `cancelText?`: `React.ReactNode` The text to show in the "Cancel" button. Defaults to `'Cancel'`. + +**Returns:** + +`Promise` A promise that resolves to true if the user confirms, false if the user cancels. + +### `dialogs.prompt(message, options?)` + +Open a prompt dialog to request user input. Returns a promise that resolves to the input if the user confirms, null if the user cancels. + +```js +const input = await dialogs.prompt('What is your name?', { + canceltext: 'Leave me alone', +}); +``` + +**Parameters:** + +- `message`: `React.ReactNode` The message to display in the prompt dialog. +- `options?`: `object` Extra configuration for the prompt dialog. + - `onClose?`: `(result: string) => Promise` A function that is called before closing the dialog closes. The dialog stays open as long as the returned promise is not resolved. Use this if you want to perform an async action on close and show a loading state. + - `title?`: `React.ReactNode` A title for the dialog. Defaults to `'Prompt'`. + - `okText?`: `React.ReactNode` The text to show in the "Ok" button. Defaults to `'Ok'`. + - `cancelText?`: `React.ReactNode` The text to show in the "Cancel" button. Defaults to `'Cancel'`. + +**Returns:** + +`Promise` A promise that resolves to the user input if the user confirms, null if the user cancels. + +### `dialogs.open(component, payload, options?)` + +Open a custom dialog. The dialog is a React component that optionally takes a payload and optionally returns a result in its `onClose` property. + +```js +function MyDialog({ open, onClose, payload }) { + // ... +} + +const result = await dialogs.open(MyDialog, 123, { + onClose: async (result) => callApi(result), +}); +``` + +**Parameters:** + +- `component`: `React.ComponentType<{ open: boolean, onClose: (result: R) => Promise, payload: P }>` The dialog component to display. +- `payload?`: `P` The optional payload passed to the dialog. Useful if you want to parametrize the dialog, or use instance specific data. This value will be kept constant during the lifetime of the dialog. +- `options?`: `object` Extra configuration for the dialog. + - `onClose?`: `(result: R) => Promise` A function that is called before closing the dialog closes. The dialog stays open as long as the returned promise is not resolved. Use this if you want to perform an async action on close and show a loading state. + +**Returns:** + +`Promise` A promise that resolves to the user input if the user confirms, null if the user cancels. + +### `dialogs.close(dialog, result)` + +Programmatically close a dialog that was previously opened with `dialogs.open`. If the dialog returns a result, `close` must also be called with a result. The original dialog promise will be resolved with this result. This promise is also returned from the `close` function. + +```js +const myDialog = dialogs.open(/* ... */); + +// ... + +const result = await dialogs.close(myDialog, 123); +``` + +**Parameters:** + +- `dialog`: `Promise` The dialog to close. This should be a promise that was previously returned by `dialogs.open`. +- `result?`: `R` The result to return from the dialog. + **Returns:** + +`Promise` A promise that resolves with the dialog result when the dialog is fully closed. diff --git a/docs/data/toolpad/core/components/use-dialogs/use-dialogs.md b/docs/data/toolpad/core/components/use-dialogs/use-dialogs.md index d4c989f218c..51f65ca6836 100644 --- a/docs/data/toolpad/core/components/use-dialogs/use-dialogs.md +++ b/docs/data/toolpad/core/components/use-dialogs/use-dialogs.md @@ -92,3 +92,8 @@ The dialog title and button texts are customizable with the `title`, `okText`, a Analog to [`window.prompt`](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt) it opens a dialog inquiring the user for some input text. The user can fill the input box and upon confirmation the promise returned from the `prompt` call is resolved with its value. The dialog title and button texts are customizable with the `title`, `okText`, and `cancelText` properties. {{"demo": "PromptDialog.js"}} + +## API + +- [`useDialog`](/toolpad/core/react-use-dialogs/api/) +- `DialogsProvider` diff --git a/docs/data/toolpad/core/components/use-notifications/use-notifications-api.md b/docs/data/toolpad/core/components/use-notifications/use-notifications-api.md new file mode 100644 index 00000000000..157a97a74a6 --- /dev/null +++ b/docs/data/toolpad/core/components/use-notifications/use-notifications-api.md @@ -0,0 +1,13 @@ +# useNotifications API + +

API reference for the useNotifications hook.

+ +## Import + +```js +import useNotifications from '@toolpad/core/useNotifications'; +// or +import { useNotifications } from '@toolpad/core'; +``` + +Learn about the difference by reading this [guide](https://mui.com/material-ui/guides/minimizing-bundle-size/) on minimizing bundle size. diff --git a/docs/pages/toolpad/core/react-use-dialogs/api.js b/docs/pages/toolpad/core/react-use-dialogs/api.js new file mode 100644 index 00000000000..4b7eaff25b9 --- /dev/null +++ b/docs/pages/toolpad/core/react-use-dialogs/api.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docs-toolpad/data/toolpad/core/components/use-dialogs/use-dialogs-api.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/docs/pages/toolpad/core/react-use-notifications/api.js b/docs/pages/toolpad/core/react-use-notifications/api.js new file mode 100644 index 00000000000..fdf8eea12c5 --- /dev/null +++ b/docs/pages/toolpad/core/react-use-notifications/api.js @@ -0,0 +1,7 @@ +import * as React from 'react'; +import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs'; +import * as pageProps from 'docs-toolpad/data/toolpad/core/components/use-notifications/use-notifications-api.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/packages/toolpad-core/src/useDialogs/useDialogs.tsx b/packages/toolpad-core/src/useDialogs/useDialogs.tsx index 008200d1ecb..de431e60c37 100644 --- a/packages/toolpad-core/src/useDialogs/useDialogs.tsx +++ b/packages/toolpad-core/src/useDialogs/useDialogs.tsx @@ -10,64 +10,152 @@ import { import invariant from 'invariant'; import * as React from 'react'; -export interface SystemDialogBase { +export interface OpenDialogOptions { + /** + * A function that is called before closing the dialog closes. The dialog + * stays open as long as the returned promise is not resolved. Use this if + * you want to perform an async action on close and show a loading state. + * + * @param result The result that the dialog will return after closing. + * @returns A promise that resolves when the dialog can be closed. + */ onClose?: (result: R) => Promise; } -export interface AlertOptions extends SystemDialogBase { +export interface AlertOptions extends OpenDialogOptions { + /** + * A title for the dialog. Defaults to `'Alert'`. + */ title?: React.ReactNode; + /** + * The text to show in the "Ok" button. Defaults to `'Ok'`. + */ okText?: React.ReactNode; } -export interface ConfirmOptions extends SystemDialogBase { +export interface ConfirmOptions extends OpenDialogOptions { + /** + * A title for the dialog. Defaults to `'Confirm'`. + */ title?: React.ReactNode; - color?: 'error' | 'info' | 'success' | 'warning'; - defaultValue?: string; + /** + * The text to show in the "Ok" button. Defaults to `'Ok'`. + */ okText?: React.ReactNode; + /** + * Denotes the purpose of the dialog. This will affect the color of the + * "Ok" button. Defaults to `undefined`. + */ severity?: 'error' | 'info' | 'success' | 'warning'; + /** + * The text to show in the "Cancel" button. Defaults to `'Cancel'`. + */ cancelText?: React.ReactNode; } -export interface PromptOptions extends SystemDialogBase { +export interface PromptOptions extends OpenDialogOptions { + /** + * A title for the dialog. Defaults to `'Prompt'`. + */ title?: React.ReactNode; + /** + * The text to show in the "Ok" button. Defaults to `'Ok'`. + */ okText?: React.ReactNode; + /** + * The text to show in the "Cancel" button. Defaults to `'Cancel'`. + */ cancelText?: React.ReactNode; } +/** + * The props that are passed to a dialog component. + */ export interface DialogProps

{ + /** + * The payload that was passed when the dialog was opened. + */ payload: P; + /** + * Whether the dialog is open. + */ open: boolean; + /** + * A function to call when the dialog should be closed. If the dialog has a return + * value, it should be apssed as an argument to this function. You should use the promise + * that is returned to show a loading state while the dialog is performing async actions + * on close. + * @param result The result to return from the dialog. + * @returns A promise that resolves when the dialog can be fully closed. + */ onClose: (result: R) => Promise; } export interface OpenAlertDialog { + /** + * Open an alert dialog. Returns a promise that resolves when the user + * closes the dialog. + * + * @param msg The message to show in the dialog. + * @param options Additional options for the dialog. + * @returns A promise that resolves when the dialog is closed. + */ (msg: React.ReactNode, options?: AlertOptions): Promise; } export interface OpenConfirmDialog { + /** + * Open a confirmation dialog. Returns a promise that resolves to true if + * the user confirms, false if the user cancels. + * + * @param msg The message to show in the dialog. + * @param options Additional options for the dialog. + * @returns A promise that resolves to true if the user confirms, false if the user cancels. + */ (msg: React.ReactNode, options?: ConfirmOptions): Promise; } export interface OpenPromptDialog { + /** + * Open a prompt dialog to request user input. Returns a promise that resolves to the input + * if the user confirms, null if the user cancels. + * + * @param msg The message to show in the dialog. + * @param options Additional options for the dialog. + * @returns A promise that resolves to the user input if the user confirms, null if the user cancels. + */ (msg: React.ReactNode, options?: PromptOptions): Promise; } type DialogComponent = React.ComponentType>; -export interface OpenDialogOptions { - onClose?: (result: R) => Promise; -} - export interface OpenDialog { + /** + * Open a dialog without payload. + * @param Component The dialog component to open. + * @param options Additional options for the dialog. + */

( Component: DialogComponent, payload?: P, options?: OpenDialogOptions, ): Promise; + /** + * Open a dialog and pass a payload. + * @param Component The dialog component to open. + * @param payload The payload to pass to the dialog. + * @param options Additional options for the dialog. + */ (Component: DialogComponent, payload: P, options?: OpenDialogOptions): Promise; } export interface CloseDialog { + /** + * Close a dialog and return a result. + * @param dialog The dialog to close. The promise returned by `open`. + * @param result The result to return from the dialog. + * @returns A promise that resolves when the dialog is fully closed. + */ (dialog: Promise, result: R): Promise; } diff --git a/packages/toolpad-core/src/useNotifications/useNotifications.tsx b/packages/toolpad-core/src/useNotifications/useNotifications.tsx index fc1a17a3b64..524ea5ee20a 100644 --- a/packages/toolpad-core/src/useNotifications/useNotifications.tsx +++ b/packages/toolpad-core/src/useNotifications/useNotifications.tsx @@ -149,8 +149,7 @@ export function useNotifications(): UseNotifications { const context = React.useContext(NotificationsContext); if (context) { - const { show, close } = context; - return { show, close }; + return context; } return serverNotifications; From 231815fbad19580009ff2d0b68e3c4d9467b76aa Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Thu, 13 Jun 2024 11:19:49 +0200 Subject: [PATCH 20/36] start --- .../components/use-dialogs/CustomDialog.js | 11 ++++++++++ .../use-dialogs/CustomDialogWithPayload.js | 14 +++++++++++++ .../use-dialogs/CustomDialogWithResult.js | 11 ++++++++++ .../components/use-dialogs/StackedDialog.js | 14 +++++++++++++ .../components/use-dialogs/use-dialogs-api.md | 2 +- .../use-notifications/AlertNotification.js | 4 ++-- .../use-notifications/AlertNotification.tsx | 4 ++-- .../AlertNotification.tsx.preview | 2 +- .../use-notifications/BasicNotification.js | 4 ++-- .../use-notifications/BasicNotification.tsx | 4 ++-- .../BasicNotification.tsx.preview | 2 +- .../use-notifications/DedupeNotification.js | 4 ++-- .../use-notifications/DedupeNotification.tsx | 4 ++-- .../DedupeNotification.tsx.preview | 2 +- .../MultipleNotifications.js | 6 +++--- .../MultipleNotifications.tsx | 6 +++--- .../MultipleNotifications.tsx.preview | 4 ++-- .../use-notifications/ScopedNotification.js | 4 ++-- .../use-notifications/ScopedNotification.tsx | 4 ++-- .../use-notifications-api.md | 20 +++++++++++++++++++ .../src/useNotifications/useNotifications.tsx | 7 +++++++ 21 files changed, 105 insertions(+), 28 deletions(-) diff --git a/docs/data/toolpad/core/components/use-dialogs/CustomDialog.js b/docs/data/toolpad/core/components/use-dialogs/CustomDialog.js index 160ceb479cc..0a09cd30aa7 100644 --- a/docs/data/toolpad/core/components/use-dialogs/CustomDialog.js +++ b/docs/data/toolpad/core/components/use-dialogs/CustomDialog.js @@ -20,7 +20,18 @@ function MyCustomDialog({ open, onClose }) { } MyCustomDialog.propTypes = { + /** + * A function to call when the dialog should be closed. If the dialog has a return + * value, it should be apssed as an argument to this function. You should use the promise + * that is returned to show a loading state while the dialog is performing async actions + * on close. + * @param result The result to return from the dialog. + * @returns A promise that resolves when the dialog can be fully closed. + */ onClose: PropTypes.func.isRequired, + /** + * Whether the dialog is open. + */ open: PropTypes.bool.isRequired, }; diff --git a/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.js b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.js index 2e6e4238c83..0749e1d7fc3 100644 --- a/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.js +++ b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.js @@ -22,8 +22,22 @@ function MyCustomDialog({ payload, open, onClose }) { } MyCustomDialog.propTypes = { + /** + * A function to call when the dialog should be closed. If the dialog has a return + * value, it should be apssed as an argument to this function. You should use the promise + * that is returned to show a loading state while the dialog is performing async actions + * on close. + * @param result The result to return from the dialog. + * @returns A promise that resolves when the dialog can be fully closed. + */ onClose: PropTypes.func.isRequired, + /** + * Whether the dialog is open. + */ open: PropTypes.bool.isRequired, + /** + * The payload that was passed when the dialog was opened. + */ payload: PropTypes.string.isRequired, }; diff --git a/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.js b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.js index 7e79cfee872..93f57429505 100644 --- a/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.js +++ b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.js @@ -32,7 +32,18 @@ function MyCustomDialog({ open, onClose }) { } MyCustomDialog.propTypes = { + /** + * A function to call when the dialog should be closed. If the dialog has a return + * value, it should be apssed as an argument to this function. You should use the promise + * that is returned to show a loading state while the dialog is performing async actions + * on close. + * @param result The result to return from the dialog. + * @returns A promise that resolves when the dialog can be fully closed. + */ onClose: PropTypes.func.isRequired, + /** + * Whether the dialog is open. + */ open: PropTypes.bool.isRequired, }; diff --git a/docs/data/toolpad/core/components/use-dialogs/StackedDialog.js b/docs/data/toolpad/core/components/use-dialogs/StackedDialog.js index 6a0132d29ca..2172adcf196 100644 --- a/docs/data/toolpad/core/components/use-dialogs/StackedDialog.js +++ b/docs/data/toolpad/core/components/use-dialogs/StackedDialog.js @@ -31,8 +31,22 @@ function MyCustomDialog({ payload, open, onClose }) { } MyCustomDialog.propTypes = { + /** + * A function to call when the dialog should be closed. If the dialog has a return + * value, it should be apssed as an argument to this function. You should use the promise + * that is returned to show a loading state while the dialog is performing async actions + * on close. + * @param result The result to return from the dialog. + * @returns A promise that resolves when the dialog can be fully closed. + */ onClose: PropTypes.func.isRequired, + /** + * Whether the dialog is open. + */ open: PropTypes.bool.isRequired, + /** + * The payload that was passed when the dialog was opened. + */ payload: PropTypes.number.isRequired, }; diff --git a/docs/data/toolpad/core/components/use-dialogs/use-dialogs-api.md b/docs/data/toolpad/core/components/use-dialogs/use-dialogs-api.md index 6fa71f9348f..ee024b57e79 100644 --- a/docs/data/toolpad/core/components/use-dialogs/use-dialogs-api.md +++ b/docs/data/toolpad/core/components/use-dialogs/use-dialogs-api.md @@ -12,7 +12,7 @@ import { useDialogs } from '@toolpad/core'; Learn about the difference by reading this [guide](https://mui.com/material-ui/guides/minimizing-bundle-size/) on minimizing bundle size. -## usage +## Usage Get access to the dialogs API by invoking the hook. diff --git a/docs/data/toolpad/core/components/use-notifications/AlertNotification.js b/docs/data/toolpad/core/components/use-notifications/AlertNotification.js index a00e3f97bf5..06da677b18d 100644 --- a/docs/data/toolpad/core/components/use-notifications/AlertNotification.js +++ b/docs/data/toolpad/core/components/use-notifications/AlertNotification.js @@ -30,9 +30,9 @@ export default function AlertNotification() { + ) : null} + + + + + ); + + const props = React.useContext(RootPropsContext); + const SnackbarComponent = props?.slots?.snackbar ?? Snackbar; + const snackbarSlotProps = useSlotProps({ + elementType: SnackbarComponent, + ownerState: props, + externalSlotProps: props?.slotProps?.snackbar, + additionalProps: { + open, + autoHideDuration, + onClose: handleClose, + action, + }, + }); + + return ( + + + {severity ? ( + + {message} + + ) : ( + + )} + + + ); +} + +interface NotificationQueueEntry { + notificationKey: string; + options: ShowNotificationOptions; + open: boolean; + message: React.ReactNode; +} + +interface NotificationsState { + queue: NotificationQueueEntry[]; +} + +interface NotificationsProps { + state: NotificationsState; +} + +function Notifications({ state }: NotificationsProps) { + const currentNotification = state.queue[0] ?? null; + + return currentNotification ? ( + 1 ? String(state.queue.length) : null} + /> + ) : null; +} + +export interface NotificationsProviderProps { + children?: React.ReactNode; + // eslint-disable-next-line react/no-unused-prop-types + slots?: Partial; + // eslint-disable-next-line react/no-unused-prop-types + slotProps?: Partial; +} + +let nextId = 1; + +function NotificationsProvider(props: NotificationsProviderProps) { + const { children } = props; + const [state, setState] = React.useState({ queue: [] }); + + const show = React.useCallback((message, options = {}) => { + const notificationKey = options.key ?? `::toolpad-internal::notification::${nextId}`; + nextId += 1; + setState((prev) => { + if (prev.queue.some((n) => n.notificationKey === notificationKey)) { + // deduplicate by key + return prev; + } + return { + ...prev, + queue: [...prev.queue, { message, options, notificationKey, open: true }], + }; + }); + return notificationKey; + }, []); + + const close = React.useCallback((key) => { + setState((prev) => ({ + ...prev, + queue: prev.queue.filter((n) => n.notificationKey !== key), + })); + }, []); + + const contextValue = React.useMemo(() => ({ show, close }), [show, close]); + + return ( + + + {children} + + + + ); +} + +export { NotificationsProvider }; diff --git a/packages/toolpad-core/src/useNotifications/index.ts b/packages/toolpad-core/src/useNotifications/index.ts index 0435a4c45c0..38ae998b741 100644 --- a/packages/toolpad-core/src/useNotifications/index.ts +++ b/packages/toolpad-core/src/useNotifications/index.ts @@ -1 +1,2 @@ export * from './useNotifications'; +export * from './NotificationsProvider'; diff --git a/packages/toolpad-core/src/useNotifications/useNotifications.tsx b/packages/toolpad-core/src/useNotifications/useNotifications.tsx index 38d83c30d76..91dcb340aec 100644 --- a/packages/toolpad-core/src/useNotifications/useNotifications.tsx +++ b/packages/toolpad-core/src/useNotifications/useNotifications.tsx @@ -1,20 +1,5 @@ -import { - Alert, - Badge, - Button, - CloseReason, - IconButton, - Snackbar, - SnackbarCloseReason, - SnackbarContent, - SnackbarProps, -} from '@mui/material'; -import CloseIcon from '@mui/icons-material/Close'; import * as React from 'react'; -import { useNonNullableContext } from '@toolpad/utils/react'; -import { useSlotProps } from '@mui/base/utils'; - -const closeText = 'Close'; +import { NotificationsContext } from './NotificationsContext'; export interface ShowNotificationOptions { /** @@ -61,105 +46,6 @@ export interface CloseNotification { (key: string): void; } -interface NotificationQueueEntry { - notificationKey: string; - options: ShowNotificationOptions; - open: boolean; - message: React.ReactNode; -} - -interface NotificationsState { - queue: NotificationQueueEntry[]; -} - -interface NotificationsContextValue { - show: ShowNotification; - close: CloseNotification; -} - -const NotificationsContext = React.createContext(null); - -export interface NotificationsProviderSlotProps { - snackbar: SnackbarProps; -} - -export interface NotificationsProviderSlots { - snackbar: React.ElementType; -} - -const RootPropsContext = React.createContext(null); - -interface NotificationProps { - notificationKey: string; - badge: string | null; - open: boolean; - message: React.ReactNode; - options: ShowNotificationOptions; -} - -function Notification({ notificationKey, open, message, options, badge }: NotificationProps) { - const { close } = useNonNullableContext(NotificationsContext); - - const { severity, actionText, onAction, autoHideDuration } = options; - - const handleClose = React.useCallback( - (event: unknown, reason?: CloseReason | SnackbarCloseReason) => { - if (reason === 'clickaway') { - return; - } - close(notificationKey); - }, - [notificationKey, close], - ); - - const action = ( - - {onAction ? ( - - ) : null} - - - - - ); - - const props = React.useContext(RootPropsContext); - const SnackbarComponent = props?.slots?.snackbar ?? Snackbar; - const snackbarSlotProps = useSlotProps({ - elementType: SnackbarComponent, - ownerState: props, - externalSlotProps: props?.slotProps?.snackbar, - additionalProps: { - open, - autoHideDuration, - onClose: handleClose, - action, - }, - }); - - return ( - - - {severity ? ( - - {message} - - ) : ( - - )} - - - ); -} - interface UseNotifications { show: ShowNotification; close: CloseNotification; @@ -183,68 +69,3 @@ export function useNotifications(): UseNotifications { return serverNotifications; } - -interface NotificationsUiProps { - state: NotificationsState; -} - -function Notifications({ state }: NotificationsUiProps) { - const currentNotification = state.queue[0] ?? null; - - return currentNotification ? ( - 1 ? String(state.queue.length) : null} - /> - ) : null; -} - -export interface NotificationsProviderProps { - children?: React.ReactNode; - - // eslint-disable-next-line react/no-unused-prop-types - slots?: Partial; - // eslint-disable-next-line react/no-unused-prop-types - slotProps?: Partial; -} - -let nextId = 1; - -export function NotificationsProvider(props: NotificationsProviderProps) { - const { children } = props; - const [state, setState] = React.useState({ queue: [] }); - - const show = React.useCallback((message, options = {}) => { - const notificationKey = options.key ?? `::toolpad-internal::notification::${nextId}`; - nextId += 1; - setState((prev) => { - if (prev.queue.some((n) => n.notificationKey === notificationKey)) { - // deduplicate by key - return prev; - } - return { - ...prev, - queue: [...prev.queue, { message, options, notificationKey, open: true }], - }; - }); - return notificationKey; - }, []); - - const close = React.useCallback((key) => { - setState((prev) => ({ - ...prev, - queue: prev.queue.filter((n) => n.notificationKey !== key), - })); - }, []); - - const contextValue = React.useMemo(() => ({ show, close }), [show, close]); - - return ( - - - {children} - - - - ); -} From be94e8856072a0c13106efbda5e91a7f5334358c Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:19:07 +0200 Subject: [PATCH 27/36] wip --- docs/data/toolpad/core/pagesApi.js | 1 + .../core/api/notifications-provider.js | 23 +++++++++++++++++++ .../core/api/notifications-provider.json | 13 +++++++++++ .../notifications-provider.json | 1 + .../src/useDialogs/DialogsProvider.test.tsx | 3 --- .../NotificationsProvider.test.tsx | 17 ++++++++++++++ .../NotificationsProvider.tsx | 10 ++++++++ 7 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 docs/pages/toolpad/core/api/notifications-provider.js create mode 100644 docs/pages/toolpad/core/api/notifications-provider.json create mode 100644 docs/translations/api-docs/notifications-provider/notifications-provider.json create mode 100644 packages/toolpad-core/src/useNotifications/NotificationsProvider.test.tsx diff --git a/docs/data/toolpad/core/pagesApi.js b/docs/data/toolpad/core/pagesApi.js index 7ba118e5829..360899799b6 100644 --- a/docs/data/toolpad/core/pagesApi.js +++ b/docs/data/toolpad/core/pagesApi.js @@ -4,4 +4,5 @@ module.exports = [ { pathname: '/toolpad/core/api/data-grid' }, { pathname: '/toolpad/core/api/dialogs-provider' }, { pathname: '/toolpad/core/api/line-chart' }, + { pathname: '/toolpad/core/api/notifications-provider' }, ]; diff --git a/docs/pages/toolpad/core/api/notifications-provider.js b/docs/pages/toolpad/core/api/notifications-provider.js new file mode 100644 index 00000000000..1867f26371a --- /dev/null +++ b/docs/pages/toolpad/core/api/notifications-provider.js @@ -0,0 +1,23 @@ +import * as React from 'react'; +import ApiPage from 'docs/src/modules/components/ApiPage'; +import mapApiPageTranslations from 'docs/src/modules/utils/mapApiPageTranslations'; +import jsonPageContent from './notifications-provider.json'; + +export default function Page(props) { + const { descriptions, pageContent } = props; + return ; +} + +Page.getInitialProps = () => { + const req = require.context( + 'docs-toolpad/translations/api-docs/notifications-provider', + false, + /\.\/notifications-provider.*.json$/, + ); + const descriptions = mapApiPageTranslations(req); + + return { + descriptions, + pageContent: jsonPageContent, + }; +}; diff --git a/docs/pages/toolpad/core/api/notifications-provider.json b/docs/pages/toolpad/core/api/notifications-provider.json new file mode 100644 index 00000000000..5b3ecdf4146 --- /dev/null +++ b/docs/pages/toolpad/core/api/notifications-provider.json @@ -0,0 +1,13 @@ +{ + "props": {}, + "name": "NotificationsProvider", + "imports": ["import { NotificationsProvider } from '@toolpad-core/useNotifications';"], + "classes": [], + "spread": true, + "themeDefaultProps": false, + "muiName": "NotificationsProvider", + "filename": "/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx", + "inheritance": null, + "demos": "

", + "cssComponent": false +} diff --git a/docs/translations/api-docs/notifications-provider/notifications-provider.json b/docs/translations/api-docs/notifications-provider/notifications-provider.json new file mode 100644 index 00000000000..f93d4cbd8c7 --- /dev/null +++ b/docs/translations/api-docs/notifications-provider/notifications-provider.json @@ -0,0 +1 @@ +{ "componentDescription": "", "propDescriptions": {}, "classDescriptions": {} } diff --git a/packages/toolpad-core/src/useDialogs/DialogsProvider.test.tsx b/packages/toolpad-core/src/useDialogs/DialogsProvider.test.tsx index b542f5fb79a..06ebfadb9a6 100644 --- a/packages/toolpad-core/src/useDialogs/DialogsProvider.test.tsx +++ b/packages/toolpad-core/src/useDialogs/DialogsProvider.test.tsx @@ -10,8 +10,5 @@ import { DialogsProvider } from './DialogsProvider'; describe('DialogsProvider', () => { describeConformance(, () => ({ skip: ['themeDefaultProps'], - slots: { - snackbar: {}, - }, })); }); diff --git a/packages/toolpad-core/src/useNotifications/NotificationsProvider.test.tsx b/packages/toolpad-core/src/useNotifications/NotificationsProvider.test.tsx new file mode 100644 index 00000000000..e1a96543a71 --- /dev/null +++ b/packages/toolpad-core/src/useNotifications/NotificationsProvider.test.tsx @@ -0,0 +1,17 @@ +/** + * @vitest-environment jsdom + */ + +import * as React from 'react'; +import { describe } from 'vitest'; +import describeConformance from '@toolpad/utils/describeConformance'; +import { NotificationsProvider } from './NotificationsProvider'; + +describe('NotificationsProvider', () => { + describeConformance(, () => ({ + skip: ['themeDefaultProps'], + slots: { + snackbar: {}, + }, + })); +}); diff --git a/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx b/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx index 8e53b087a39..ca595620381 100644 --- a/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx +++ b/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx @@ -139,6 +139,16 @@ export interface NotificationsProviderProps { let nextId = 1; +/** + * + * Demos: + * + * - [Notifications](https://mui.com/toolpad/core/react-use-notifications/) + * + * API: + * + * - [NotificationsProvider API](https://mui.com/toolpad/core/api/notifications-provider) + */ function NotificationsProvider(props: NotificationsProviderProps) { const { children } = props; const [state, setState] = React.useState({ queue: [] }); From c12d09c91cbb05bba6e17c595529ea8119d4e698 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:25:00 +0200 Subject: [PATCH 28/36] Add slot --- docs/pages/toolpad/core/api/data-grid.json | 833 +++++++++++++++++- .../core/api/notifications-provider.json | 8 + .../api-docs/data-grid/data-grid.json | 570 +++++++++++- .../notifications-provider.json | 7 +- .../NotificationsProvider.tsx | 4 + .../config/projectSettings.ts | 3 +- 6 files changed, 1420 insertions(+), 5 deletions(-) diff --git a/docs/pages/toolpad/core/api/data-grid.json b/docs/pages/toolpad/core/api/data-grid.json index 54797238575..724b85b8453 100644 --- a/docs/pages/toolpad/core/api/data-grid.json +++ b/docs/pages/toolpad/core/api/data-grid.json @@ -13,7 +13,838 @@ "import { DataGrid } from '@toolpad-core/DataGrid';", "import { DataGrid } from '@toolpad-core';" ], - "classes": [], + "classes": [ + { + "key": "actionsCell", + "className": "", + "description": "Styles applied to the root element of the cell with type=\"actions\".", + "isGlobal": false + }, + { + "key": "aggregationColumnHeader", + "className": "", + "description": "Styles applied to the root element of the column header when aggregated.", + "isGlobal": false + }, + { + "key": "aggregationColumnHeader--alignCenter", + "className": "", + "description": "Styles applied to the root element of the header when aggregation if `headerAlign=\"center\"`.", + "isGlobal": false + }, + { + "key": "aggregationColumnHeader--alignLeft", + "className": "", + "description": "Styles applied to the root element of the header when aggregation if `headerAlign=\"left\"`.", + "isGlobal": false + }, + { + "key": "aggregationColumnHeader--alignRight", + "className": "", + "description": "Styles applied to the root element of the header when aggregation if `headerAlign=\"right\"`.", + "isGlobal": false + }, + { + "key": "aggregationColumnHeaderLabel", + "className": "", + "description": "Styles applied to the aggregation label in the column header when aggregated.", + "isGlobal": false + }, + { + "key": "autoHeight", + "className": "", + "description": "Styles applied to the root element if `autoHeight={true}`.", + "isGlobal": false + }, + { + "key": "autosizing", + "className": "", + "description": "Styles applied to the root element while it is being autosized.", + "isGlobal": false + }, + { + "key": "booleanCell", + "className": "", + "description": "Styles applied to the icon of the boolean cell.", + "isGlobal": false + }, + { + "key": "cell", + "className": "", + "description": "Styles applied to the cell element.", + "isGlobal": false + }, + { + "key": "cell--editable", + "className": "", + "description": "Styles applied to the cell element if the cell is editable.", + "isGlobal": false + }, + { + "key": "cell--editing", + "className": "", + "description": "Styles applied to the cell element if the cell is in edit mode.", + "isGlobal": false + }, + { + "key": "cell--flex", + "className": "", + "description": "Styles applied to the cell element in flex display mode.", + "isGlobal": false + }, + { + "key": "cell--pinnedLeft", + "className": "", + "description": "Styles applied to the cell element if it is pinned to the left.", + "isGlobal": false + }, + { + "key": "cell--pinnedRight", + "className": "", + "description": "Styles applied to the cell element if it is pinned to the right.", + "isGlobal": false + }, + { + "key": "cell--rangeBottom", + "className": "", + "description": "Styles applied to the cell element if it is at the bottom edge of a cell selection range.", + "isGlobal": false + }, + { + "key": "cell--rangeLeft", + "className": "", + "description": "Styles applied to the cell element if it is at the left edge of a cell selection range.", + "isGlobal": false + }, + { + "key": "cell--rangeRight", + "className": "", + "description": "Styles applied to the cell element if it is at the right edge of a cell selection range.", + "isGlobal": false + }, + { + "key": "cell--rangeTop", + "className": "", + "description": "Styles applied to the cell element if it is at the top edge of a cell selection range.", + "isGlobal": false + }, + { + "key": "cell--selectionMode", + "className": "", + "description": "Styles applied to the cell element if it is in a cell selection range.", + "isGlobal": false + }, + { + "key": "cell--textCenter", + "className": "", + "description": "Styles applied to the cell element if `align=\"center\"`.", + "isGlobal": false + }, + { + "key": "cell--textLeft", + "className": "", + "description": "Styles applied to the cell element if `align=\"left\"`.", + "isGlobal": false + }, + { + "key": "cell--textRight", + "className": "", + "description": "Styles applied to the cell element if `align=\"right\"`.", + "isGlobal": false + }, + { + "key": "cell--withLeftBorder", + "className": "", + "description": "Styles applied the cell if `showColumnVerticalBorder={true}`.", + "isGlobal": false + }, + { + "key": "cell--withRightBorder", + "className": "", + "description": "Styles applied the cell if `showColumnVerticalBorder={true}`.", + "isGlobal": false + }, + { + "key": "cellCheckbox", + "className": "", + "description": "Styles applied to the cell checkbox element.", + "isGlobal": false + }, + { + "key": "cellEmpty", + "className": "", + "description": "Styles applied to the empty cell element.", + "isGlobal": false + }, + { + "key": "cellSkeleton", + "className": "", + "description": "Styles applied to the skeleton cell element.", + "isGlobal": false + }, + { + "key": "checkboxInput", + "className": "", + "description": "Styles applied to the selection checkbox element.", + "isGlobal": false + }, + { + "key": "columnHeader", + "className": "", + "description": "Styles applied to the column header element.", + "isGlobal": false + }, + { + "key": "columnHeader--alignCenter", + "className": "", + "description": "Styles applied to the column header if `headerAlign=\"center\"`.", + "isGlobal": false + }, + { + "key": "columnHeader--alignLeft", + "className": "", + "description": "Styles applied to the column header if `headerAlign=\"left\"`.", + "isGlobal": false + }, + { + "key": "columnHeader--alignRight", + "className": "", + "description": "Styles applied to the column header if `headerAlign=\"right\"`.", + "isGlobal": false + }, + { + "key": "columnHeader--dragging", + "className": "", + "description": "Styles applied to the floating column header element when it is dragged.", + "isGlobal": false + }, + { + "key": "columnHeader--emptyGroup", + "className": "", + "description": "Styles applied to the empty column group header cell.", + "isGlobal": false + }, + { + "key": "columnHeader--filledGroup", + "className": "", + "description": "Styles applied to the column group header cell if not empty.", + "isGlobal": false + }, + { + "key": "columnHeader--filtered", + "className": "", + "description": "Styles applied to the column header if the column has a filter applied to it.", + "isGlobal": false + }, + { + "key": "columnHeader--last", + "className": "", + "description": "Styles applied to the last column header element.", + "isGlobal": false + }, + { + "key": "columnHeader--moving", + "className": "", + "description": "Styles applied to the column header if it is being dragged.", + "isGlobal": false + }, + { + "key": "columnHeader--numeric", + "className": "", + "description": "Styles applied to the column header if the type of the column is `number`.", + "isGlobal": false + }, + { "key": "columnHeader--pinnedLeft", "className": "", "description": "", "isGlobal": false }, + { "key": "columnHeader--pinnedRight", "className": "", "description": "", "isGlobal": false }, + { + "key": "columnHeader--sortable", + "className": "", + "description": "Styles applied to the column header if the column is sortable.", + "isGlobal": false + }, + { + "key": "columnHeader--sorted", + "className": "", + "description": "Styles applied to the column header if the column is sorted.", + "isGlobal": false + }, + { + "key": "columnHeader--withLeftBorder", + "className": "", + "description": "", + "isGlobal": false + }, + { + "key": "columnHeader--withRightBorder", + "className": "", + "description": "Styles applied the column header if `showColumnVerticalBorder={true}`.", + "isGlobal": false + }, + { + "key": "columnHeaderCheckbox", + "className": "", + "description": "Styles applied to the header checkbox cell element.", + "isGlobal": false + }, + { + "key": "columnHeaderDraggableContainer", + "className": "", + "description": "Styles applied to the column header's draggable container element.", + "isGlobal": false + }, + { + "key": "columnHeaders", + "className": "", + "description": "Styles applied to the column headers.", + "isGlobal": false + }, + { + "key": "columnHeaderTitle", + "className": "", + "description": "Styles applied to the column header's title element;", + "isGlobal": false + }, + { + "key": "columnHeaderTitleContainer", + "className": "", + "description": "Styles applied to the column header's title container element.", + "isGlobal": false + }, + { + "key": "columnHeaderTitleContainerContent", + "className": "", + "description": "Styles applied to the column header's title excepted buttons.", + "isGlobal": false + }, + { + "key": "columnSeparator", + "className": "", + "description": "Styles applied to the column header separator element.", + "isGlobal": false + }, + { + "key": "columnSeparator--resizable", + "className": "", + "description": "Styles applied to the column header separator if the column is resizable.", + "isGlobal": false + }, + { + "key": "columnSeparator--resizing", + "className": "", + "description": "Styles applied to the column header separator if the column is being resized.", + "isGlobal": false + }, + { + "key": "columnSeparator--sideLeft", + "className": "", + "description": "Styles applied to the column header separator if the side is \"left\".", + "isGlobal": false + }, + { + "key": "columnSeparator--sideRight", + "className": "", + "description": "Styles applied to the column header separator if the side is \"right\".", + "isGlobal": false + }, + { + "key": "columnsManagement", + "className": "", + "description": "Styles applied to the columns management body.", + "isGlobal": false + }, + { + "key": "columnsManagementFooter", + "className": "", + "description": "Styles applied to the columns management footer element.", + "isGlobal": false + }, + { + "key": "columnsManagementHeader", + "className": "", + "description": "Styles applied to the columns management header element.", + "isGlobal": false + }, + { + "key": "columnsManagementRow", + "className": "", + "description": "Styles applied to the columns management row element.", + "isGlobal": false + }, + { + "key": "container--bottom", + "className": "", + "description": "Styles applied to the bottom container.", + "isGlobal": false + }, + { + "key": "container--top", + "className": "", + "description": "Styles applied to the top container.", + "isGlobal": false + }, + { + "key": "detailPanel", + "className": "", + "description": "Styles applied to the detail panel element.", + "isGlobal": false + }, + { + "key": "detailPanels", + "className": "", + "description": "Styles applied to the detail panels wrapper element.", + "isGlobal": false + }, + { + "key": "detailPanelToggleCell", + "className": "", + "description": "Styles applied to the detail panel toggle cell element.", + "isGlobal": false + }, + { + "key": "detailPanelToggleCell--expanded", + "className": "", + "description": "Styles applied to the detail panel toggle cell element if expanded.", + "isGlobal": false + }, + { + "key": "editBooleanCell", + "className": "", + "description": "Styles applied to root of the boolean edit component.", + "isGlobal": false + }, + { + "key": "editInputCell", + "className": "", + "description": "Styles applied to the root of the input component.", + "isGlobal": false + }, + { + "key": "filterForm", + "className": "", + "description": "Styles applied to the root of the filter form component.", + "isGlobal": false + }, + { + "key": "filterFormColumnInput", + "className": "", + "description": "Styles applied to the column input of the filter form component.", + "isGlobal": false + }, + { + "key": "filterFormDeleteIcon", + "className": "", + "description": "Styles applied to the delete icon of the filter form component.", + "isGlobal": false + }, + { + "key": "filterFormLogicOperatorInput", + "className": "", + "description": "Styles applied to the link operator input of the filter form component.", + "isGlobal": false + }, + { + "key": "filterFormOperatorInput", + "className": "", + "description": "Styles applied to the operator input of the filter form component.", + "isGlobal": false + }, + { + "key": "filterFormValueInput", + "className": "", + "description": "Styles applied to the value input of the filter form component.", + "isGlobal": false + }, + { + "key": "filterIcon", + "className": "", + "description": "Styles applied to the filter icon element.", + "isGlobal": false + }, + { + "key": "footerCell", + "className": "", + "description": "Styles applied to the root element of the cell inside a footer row.", + "isGlobal": false + }, + { + "key": "footerContainer", + "className": "", + "description": "Styles applied to the footer container element.", + "isGlobal": false + }, + { + "key": "groupingCriteriaCell", + "className": "", + "description": "Styles applied to the root element of the grouping criteria cell", + "isGlobal": false + }, + { + "key": "groupingCriteriaCellToggle", + "className": "", + "description": "Styles applied to the toggle of the grouping criteria cell", + "isGlobal": false + }, + { + "key": "headerFilterRow", + "className": "", + "description": "Styles applied to the column header filter row.", + "isGlobal": false + }, + { + "key": "iconButtonContainer", + "className": "", + "description": "Styles applied to the column header icon's container.", + "isGlobal": false + }, + { + "key": "iconSeparator", + "className": "", + "description": "Styles applied to the column header separator icon element.", + "isGlobal": false + }, + { + "key": "main", + "className": "", + "description": "Styles applied to the main container element.", + "isGlobal": false + }, + { + "key": "main--hasPinnedRight", + "className": "", + "description": "Styles applied to the main container element when it has right pinned columns.", + "isGlobal": false + }, + { + "key": "menu", + "className": "", + "description": "Styles applied to the menu element.", + "isGlobal": false + }, + { + "key": "menuIcon", + "className": "", + "description": "Styles applied to the menu icon element.", + "isGlobal": false + }, + { + "key": "menuIconButton", + "className": "", + "description": "Styles applied to the menu icon button element.", + "isGlobal": false + }, + { + "key": "menuList", + "className": "", + "description": "Styles applied to the menu list element.", + "isGlobal": false + }, + { + "key": "menuOpen", + "className": "", + "description": "Styles applied to the menu icon element if the menu is open.", + "isGlobal": false + }, + { + "key": "overlay", + "className": "", + "description": "Styles applied to the overlay element.", + "isGlobal": false + }, + { + "key": "overlayWrapper", + "className": "", + "description": "Styles applied to the overlay wrapper element.", + "isGlobal": false + }, + { + "key": "overlayWrapperInner", + "className": "", + "description": "Styles applied to the overlay wrapper inner element.", + "isGlobal": false + }, + { + "key": "panel", + "className": "", + "description": "Styles applied to the panel element.", + "isGlobal": false + }, + { + "key": "panelContent", + "className": "", + "description": "Styles applied to the panel content element.", + "isGlobal": false + }, + { + "key": "panelFooter", + "className": "", + "description": "Styles applied to the panel footer element.", + "isGlobal": false + }, + { + "key": "panelHeader", + "className": "", + "description": "Styles applied to the panel header element.", + "isGlobal": false + }, + { + "key": "panelWrapper", + "className": "", + "description": "Styles applied to the panel wrapper element.", + "isGlobal": false + }, + { + "key": "paper", + "className": "", + "description": "Styles applied to the paper element.", + "isGlobal": false + }, + { + "key": "pinnedColumns", + "className": "", + "description": "Styles applied to the pinned columns.", + "isGlobal": false + }, + { + "key": "pinnedRows", + "className": "", + "description": "Styles applied to the pinned rows container.", + "isGlobal": false + }, + { + "key": "pinnedRows--bottom", + "className": "", + "description": "Styles applied to the bottom pinned rows container.", + "isGlobal": false + }, + { + "key": "pinnedRows--top", + "className": "", + "description": "Styles applied to the top pinned rows container.", + "isGlobal": false + }, + { + "key": "pinnedRowsRenderZone", + "className": "", + "description": "Styles applied to pinned rows render zones.", + "isGlobal": false + }, + { + "key": "root", + "className": "", + "description": "Styles applied to the root element.", + "isGlobal": false + }, + { + "key": "root--densityComfortable", + "className": "", + "description": "Styles applied to the root element if density is \"comfortable\".", + "isGlobal": false + }, + { + "key": "root--densityCompact", + "className": "", + "description": "Styles applied to the root element if density is \"compact\".", + "isGlobal": false + }, + { + "key": "root--densityStandard", + "className": "", + "description": "Styles applied to the root element if density is \"standard\" (default).", + "isGlobal": false + }, + { + "key": "root--disableUserSelection", + "className": "", + "description": "Styles applied to the root element when user selection is disabled.", + "isGlobal": false + }, + { + "key": "row", + "className": "", + "description": "Styles applied to the row element.", + "isGlobal": false + }, + { + "key": "row--detailPanelExpanded", + "className": "", + "description": "Styles applied to the row if its detail panel is open.", + "isGlobal": false + }, + { + "key": "row--dragging", + "className": "", + "description": "Styles applied to the floating special row reorder cell element when it is dragged.", + "isGlobal": false + }, + { + "key": "row--dynamicHeight", + "className": "", + "description": "Styles applied to the row if it has dynamic row height.", + "isGlobal": false + }, + { + "key": "row--editable", + "className": "", + "description": "Styles applied to the row element if the row is editable.", + "isGlobal": false + }, + { + "key": "row--editing", + "className": "", + "description": "Styles applied to the row element if the row is in edit mode.", + "isGlobal": false + }, + { + "key": "row--firstVisible", + "className": "", + "description": "Styles applied to the first visible row element on every page of the grid.", + "isGlobal": false + }, + { + "key": "row--lastVisible", + "className": "", + "description": "Styles applied to the last visible row element on every page of the grid.", + "isGlobal": false + }, + { + "key": "rowCount", + "className": "", + "description": "Styles applied to the footer row count element to show the total number of rows.\nOnly works when pagination is disabled.", + "isGlobal": false + }, + { + "key": "rowReorderCell", + "className": "", + "description": "Styles applied to the root element of the row reorder cell", + "isGlobal": false + }, + { + "key": "rowReorderCell--draggable", + "className": "", + "description": "Styles applied to the root element of the row reorder cell when dragging is allowed", + "isGlobal": false + }, + { + "key": "rowReorderCellContainer", + "className": "", + "description": "Styles applied to the row reorder cell container element.", + "isGlobal": false + }, + { + "key": "rowReorderCellPlaceholder", + "className": "", + "description": "Styles applied to the row's draggable placeholder element inside the special row reorder cell.", + "isGlobal": false + }, + { + "key": "scrollArea", + "className": "", + "description": "Styles applied to both scroll area elements.", + "isGlobal": false + }, + { + "key": "scrollArea--left", + "className": "", + "description": "Styles applied to the left scroll area element.", + "isGlobal": false + }, + { + "key": "scrollArea--right", + "className": "", + "description": "Styles applied to the right scroll area element.", + "isGlobal": false + }, + { + "key": "scrollbar", + "className": "", + "description": "Styles applied to the scrollbars.", + "isGlobal": false + }, + { + "key": "scrollbar--horizontal", + "className": "", + "description": "Styles applied to the horizontal scrollbar.", + "isGlobal": false + }, + { + "key": "scrollbar--vertical", + "className": "", + "description": "Styles applied to the horizontal scrollbar.", + "isGlobal": false + }, + { + "key": "selectedRowCount", + "className": "", + "description": "Styles applied to the footer selected row count element.", + "isGlobal": false + }, + { + "key": "sortIcon", + "className": "", + "description": "Styles applied to the sort icon element.", + "isGlobal": false + }, + { + "key": "toolbarContainer", + "className": "", + "description": "Styles applied to the toolbar container element.", + "isGlobal": false + }, + { + "key": "toolbarFilterList", + "className": "", + "description": "Styles applied to the toolbar filter list element.", + "isGlobal": false + }, + { + "key": "treeDataGroupingCell", + "className": "", + "description": "Styles applied to the root of the grouping column of the tree data.", + "isGlobal": false + }, + { + "key": "treeDataGroupingCellToggle", + "className": "", + "description": "Styles applied to the toggle of the grouping cell of the tree data.", + "isGlobal": false + }, + { + "key": "virtualScroller", + "className": "", + "description": "Styles applied to the virtualization container.", + "isGlobal": false + }, + { + "key": "virtualScrollerContent", + "className": "", + "description": "Styles applied to the virtualization content.", + "isGlobal": false + }, + { + "key": "virtualScrollerContent--overflowed", + "className": "", + "description": "Styles applied to the virtualization content when its height is bigger than the virtualization container.", + "isGlobal": false + }, + { + "key": "virtualScrollerRenderZone", + "className": "", + "description": "Styles applied to the virtualization render zone.", + "isGlobal": false + }, + { + "key": "withBorderColor", + "className": "", + "description": "Styles applied to cells, column header and other elements that have border.\nSets border color only.", + "isGlobal": false + }, + { + "key": "withVerticalBorder", + "className": "", + "description": "Styles applied the grid if `showColumnVerticalBorder={true}`.", + "isGlobal": false + } + ], "spread": true, "themeDefaultProps": false, "muiName": "DataGrid", diff --git a/docs/pages/toolpad/core/api/notifications-provider.json b/docs/pages/toolpad/core/api/notifications-provider.json index 5b3ecdf4146..29c1fdff962 100644 --- a/docs/pages/toolpad/core/api/notifications-provider.json +++ b/docs/pages/toolpad/core/api/notifications-provider.json @@ -2,6 +2,14 @@ "props": {}, "name": "NotificationsProvider", "imports": ["import { NotificationsProvider } from '@toolpad-core/useNotifications';"], + "slots": [ + { + "name": "snackbar", + "description": "The component that renders the snackbar.", + "default": "Snackbar", + "class": null + } + ], "classes": [], "spread": true, "themeDefaultProps": false, diff --git a/docs/translations/api-docs/data-grid/data-grid.json b/docs/translations/api-docs/data-grid/data-grid.json index 994401fdf15..7f867e41d8a 100644 --- a/docs/translations/api-docs/data-grid/data-grid.json +++ b/docs/translations/api-docs/data-grid/data-grid.json @@ -8,5 +8,573 @@ "description": "The height of the datagrid in pixels. If left undefined, it adopts the height of its parent." } }, - "classDescriptions": {} + "classDescriptions": { + "actionsCell": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the root element of the cell with type="actions"" + }, + "aggregationColumnHeader": { + "description": "Styles applied to {{nodeName}} when {{conditions}}.", + "nodeName": "the root element of the column header", + "conditions": "aggregated" + }, + "aggregationColumnHeader--alignCenter": { + "description": "Styles applied to {{nodeName}} when {{conditions}}.", + "nodeName": "the root element of the header", + "conditions": "aggregation if headerAlign=\"center\"" + }, + "aggregationColumnHeader--alignLeft": { + "description": "Styles applied to {{nodeName}} when {{conditions}}.", + "nodeName": "the root element of the header", + "conditions": "aggregation if headerAlign=\"left\"" + }, + "aggregationColumnHeader--alignRight": { + "description": "Styles applied to {{nodeName}} when {{conditions}}.", + "nodeName": "the root element of the header", + "conditions": "aggregation if headerAlign=\"right\"" + }, + "aggregationColumnHeaderLabel": { + "description": "Styles applied to {{nodeName}} when {{conditions}}.", + "nodeName": "the aggregation label in the column header", + "conditions": "aggregated" + }, + "autoHeight": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "autoHeight={true}" + }, + "autosizing": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the root element while it is being autosized" + }, + "booleanCell": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the icon of the boolean cell" + }, + "cell": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the cell element" }, + "cell--editable": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the cell element", + "conditions": "the cell is editable" + }, + "cell--editing": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the cell element", + "conditions": "the cell is in edit mode" + }, + "cell--flex": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the cell element in flex display mode" + }, + "cell--pinnedLeft": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the cell element", + "conditions": "it is pinned to the left" + }, + "cell--pinnedRight": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the cell element", + "conditions": "it is pinned to the right" + }, + "cell--rangeBottom": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the cell element", + "conditions": "it is at the bottom edge of a cell selection range" + }, + "cell--rangeLeft": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the cell element", + "conditions": "it is at the left edge of a cell selection range" + }, + "cell--rangeRight": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the cell element", + "conditions": "it is at the right edge of a cell selection range" + }, + "cell--rangeTop": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the cell element", + "conditions": "it is at the top edge of a cell selection range" + }, + "cell--selectionMode": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the cell element", + "conditions": "it is in a cell selection range" + }, + "cell--textCenter": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the cell element", + "conditions": "align=\"center\"" + }, + "cell--textLeft": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the cell element", + "conditions": "align=\"left\"" + }, + "cell--textRight": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the cell element", + "conditions": "align=\"right\"" + }, + "cell--withLeftBorder": { + "description": "Styles applied the cell if showColumnVerticalBorder={true}." + }, + "cell--withRightBorder": { + "description": "Styles applied the cell if showColumnVerticalBorder={true}." + }, + "cellCheckbox": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the cell checkbox element" + }, + "cellEmpty": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the empty cell element" + }, + "cellSkeleton": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the skeleton cell element" + }, + "checkboxInput": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the selection checkbox element" + }, + "columnHeader": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the column header element" + }, + "columnHeader--alignCenter": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the column header", + "conditions": "headerAlign=\"center\"" + }, + "columnHeader--alignLeft": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the column header", + "conditions": "headerAlign=\"left\"" + }, + "columnHeader--alignRight": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the column header", + "conditions": "headerAlign=\"right\"" + }, + "columnHeader--dragging": { + "description": "Styles applied to {{nodeName}} when {{conditions}}.", + "nodeName": "the floating column header element", + "conditions": "it is dragged" + }, + "columnHeader--emptyGroup": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the empty column group header cell" + }, + "columnHeader--filledGroup": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the column group header cell", + "conditions": "not empty" + }, + "columnHeader--filtered": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the column header", + "conditions": "the column has a filter applied to it" + }, + "columnHeader--last": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the last column header element" + }, + "columnHeader--moving": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the column header", + "conditions": "it is being dragged" + }, + "columnHeader--numeric": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the column header", + "conditions": "the type of the column is number" + }, + "columnHeader--pinnedLeft": { "description": "" }, + "columnHeader--pinnedRight": { "description": "" }, + "columnHeader--sortable": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the column header", + "conditions": "the column is sortable" + }, + "columnHeader--sorted": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the column header", + "conditions": "the column is sorted" + }, + "columnHeader--withLeftBorder": { "description": "" }, + "columnHeader--withRightBorder": { + "description": "Styles applied the column header if showColumnVerticalBorder={true}." + }, + "columnHeaderCheckbox": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the header checkbox cell element" + }, + "columnHeaderDraggableContainer": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the column header's draggable container element" + }, + "columnHeaders": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the column headers" + }, + "columnHeaderTitle": { + "description": "Styles applied to the column header's title element;" + }, + "columnHeaderTitleContainer": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the column header's title container element" + }, + "columnHeaderTitleContainerContent": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the column header's title excepted buttons" + }, + "columnSeparator": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the column header separator element" + }, + "columnSeparator--resizable": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the column header separator", + "conditions": "the column is resizable" + }, + "columnSeparator--resizing": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the column header separator", + "conditions": "the column is being resized" + }, + "columnSeparator--sideLeft": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the column header separator", + "conditions": "the side is "left"" + }, + "columnSeparator--sideRight": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the column header separator", + "conditions": "the side is "right"" + }, + "columnsManagement": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the columns management body" + }, + "columnsManagementFooter": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the columns management footer element" + }, + "columnsManagementHeader": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the columns management header element" + }, + "columnsManagementRow": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the columns management row element" + }, + "container--bottom": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the bottom container" + }, + "container--top": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the top container" + }, + "detailPanel": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the detail panel element" + }, + "detailPanels": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the detail panels wrapper element" + }, + "detailPanelToggleCell": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the detail panel toggle cell element" + }, + "detailPanelToggleCell--expanded": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the detail panel toggle cell element", + "conditions": "expanded" + }, + "editBooleanCell": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "root of the boolean edit component" + }, + "editInputCell": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the root of the input component" + }, + "filterForm": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the root of the filter form component" + }, + "filterFormColumnInput": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the column input of the filter form component" + }, + "filterFormDeleteIcon": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the delete icon of the filter form component" + }, + "filterFormLogicOperatorInput": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the link operator input of the filter form component" + }, + "filterFormOperatorInput": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the operator input of the filter form component" + }, + "filterFormValueInput": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the value input of the filter form component" + }, + "filterIcon": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the filter icon element" + }, + "footerCell": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the root element of the cell inside a footer row" + }, + "footerContainer": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the footer container element" + }, + "groupingCriteriaCell": { + "description": "Styles applied to the root element of the grouping criteria cell" + }, + "groupingCriteriaCellToggle": { + "description": "Styles applied to the toggle of the grouping criteria cell" + }, + "headerFilterRow": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the column header filter row" + }, + "iconButtonContainer": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the column header icon's container" + }, + "iconSeparator": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the column header separator icon element" + }, + "main": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the main container element" + }, + "main--hasPinnedRight": { + "description": "Styles applied to {{nodeName}} when {{conditions}}.", + "nodeName": "the main container element", + "conditions": "it has right pinned columns" + }, + "menu": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the menu element" }, + "menuIcon": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the menu icon element" + }, + "menuIconButton": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the menu icon button element" + }, + "menuList": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the menu list element" + }, + "menuOpen": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the menu icon element", + "conditions": "the menu is open" + }, + "overlay": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the overlay element" + }, + "overlayWrapper": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the overlay wrapper element" + }, + "overlayWrapperInner": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the overlay wrapper inner element" + }, + "panel": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the panel element" }, + "panelContent": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the panel content element" + }, + "panelFooter": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the panel footer element" + }, + "panelHeader": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the panel header element" + }, + "panelWrapper": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the panel wrapper element" + }, + "paper": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the paper element" }, + "pinnedColumns": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the pinned columns" + }, + "pinnedRows": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the pinned rows container" + }, + "pinnedRows--bottom": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the bottom pinned rows container" + }, + "pinnedRows--top": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the top pinned rows container" + }, + "pinnedRowsRenderZone": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "pinned rows render zones" + }, + "root": { "description": "Styles applied to the root element." }, + "root--densityComfortable": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "density is "comfortable"" + }, + "root--densityCompact": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "density is "compact"" + }, + "root--densityStandard": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the root element", + "conditions": "density is "standard" (default)" + }, + "root--disableUserSelection": { + "description": "Styles applied to {{nodeName}} when {{conditions}}.", + "nodeName": "the root element", + "conditions": "user selection is disabled" + }, + "row": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the row element" }, + "row--detailPanelExpanded": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the row", + "conditions": "its detail panel is open" + }, + "row--dragging": { + "description": "Styles applied to {{nodeName}} when {{conditions}}.", + "nodeName": "the floating special row reorder cell element", + "conditions": "it is dragged" + }, + "row--dynamicHeight": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the row", + "conditions": "it has dynamic row height" + }, + "row--editable": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the row element", + "conditions": "the row is editable" + }, + "row--editing": { + "description": "Styles applied to {{nodeName}} if {{conditions}}.", + "nodeName": "the row element", + "conditions": "the row is in edit mode" + }, + "row--firstVisible": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the first visible row element on every page of the grid" + }, + "row--lastVisible": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the last visible row element on every page of the grid" + }, + "rowCount": { + "description": "Styles applied to {{nodeName}}. Only works when pagination is disabled.", + "nodeName": "the footer row count element to show the total number of rows" + }, + "rowReorderCell": { + "description": "Styles applied to the root element of the row reorder cell" + }, + "rowReorderCell--draggable": { + "description": "Styles applied to the root element of the row reorder cell when dragging is allowed" + }, + "rowReorderCellContainer": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the row reorder cell container element" + }, + "rowReorderCellPlaceholder": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the row's draggable placeholder element inside the special row reorder cell" + }, + "scrollArea": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "both scroll area elements" + }, + "scrollArea--left": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the left scroll area element" + }, + "scrollArea--right": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the right scroll area element" + }, + "scrollbar": { "description": "Styles applied to {{nodeName}}.", "nodeName": "the scrollbars" }, + "scrollbar--horizontal": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the horizontal scrollbar" + }, + "scrollbar--vertical": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the horizontal scrollbar" + }, + "selectedRowCount": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the footer selected row count element" + }, + "sortIcon": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the sort icon element" + }, + "toolbarContainer": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the toolbar container element" + }, + "toolbarFilterList": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the toolbar filter list element" + }, + "treeDataGroupingCell": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the root of the grouping column of the tree data" + }, + "treeDataGroupingCellToggle": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the toggle of the grouping cell of the tree data" + }, + "virtualScroller": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the virtualization container" + }, + "virtualScrollerContent": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the virtualization content" + }, + "virtualScrollerContent--overflowed": { + "description": "Styles applied to {{nodeName}} when {{conditions}}.", + "nodeName": "the virtualization content", + "conditions": "its height is bigger than the virtualization container" + }, + "virtualScrollerRenderZone": { + "description": "Styles applied to {{nodeName}}.", + "nodeName": "the virtualization render zone" + }, + "withBorderColor": { + "description": "Styles applied to {{nodeName}}, {{conditions}}. Sets border color only.", + "nodeName": "cells", + "conditions": "column header and other elements that have border" + }, + "withVerticalBorder": { + "description": "Styles applied the grid if showColumnVerticalBorder={true}." + } + } } diff --git a/docs/translations/api-docs/notifications-provider/notifications-provider.json b/docs/translations/api-docs/notifications-provider/notifications-provider.json index f93d4cbd8c7..28d6825203f 100644 --- a/docs/translations/api-docs/notifications-provider/notifications-provider.json +++ b/docs/translations/api-docs/notifications-provider/notifications-provider.json @@ -1 +1,6 @@ -{ "componentDescription": "", "propDescriptions": {}, "classDescriptions": {} } +{ + "componentDescription": "", + "propDescriptions": {}, + "classDescriptions": {}, + "slotDescriptions": { "snackbar": "The component that renders the snackbar." } +} diff --git a/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx b/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx index ca595620381..a66c68bf1cc 100644 --- a/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx +++ b/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx @@ -27,6 +27,10 @@ export interface NotificationsProviderSlotProps { } export interface NotificationsProviderSlots { + /** + * The component that renders the snackbar. + * @default Snackbar + */ snackbar: React.ElementType; } diff --git a/scripts/docs/buildCoreApiDocs/config/projectSettings.ts b/scripts/docs/buildCoreApiDocs/config/projectSettings.ts index bf0497e4c38..5d952eec674 100644 --- a/scripts/docs/buildCoreApiDocs/config/projectSettings.ts +++ b/scripts/docs/buildCoreApiDocs/config/projectSettings.ts @@ -23,13 +23,12 @@ export const projectSettings: ProjectSettings = { getComponentImports, translationLanguages: LANGUAGES, skipComponent: (filename: string) => { - console.log(filename); const relativePath = path.relative(repositoryRoot, filename); const directories = path.dirname(relativePath).split(path.sep); return directories[3] === 'nextjs'; }, - skipSlotsAndClasses: true, + skipSlotsAndClasses: false, translationPagesDirectory: 'docs/translations/api-docs', importTranslationPagesDirectory: 'docs-toolpad/translations/api-docs', generateClassName: () => '', From 6466ac34198ddbec61cc6dfe709770e891b62ecb Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:28:06 +0200 Subject: [PATCH 29/36] finish --- .../src/useDialogs/{useDialog.test.tsx => useDialogs.test.tsx} | 3 ++- .../src/useNotifications/useNotifications.test.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) rename packages/toolpad-core/src/useDialogs/{useDialog.test.tsx => useDialogs.test.tsx} (98%) diff --git a/packages/toolpad-core/src/useDialogs/useDialog.test.tsx b/packages/toolpad-core/src/useDialogs/useDialogs.test.tsx similarity index 98% rename from packages/toolpad-core/src/useDialogs/useDialog.test.tsx rename to packages/toolpad-core/src/useDialogs/useDialogs.test.tsx index 366dac461a0..66f6dc51bdc 100644 --- a/packages/toolpad-core/src/useDialogs/useDialog.test.tsx +++ b/packages/toolpad-core/src/useDialogs/useDialogs.test.tsx @@ -6,7 +6,8 @@ import * as React from 'react'; import { describe, test, expect } from 'vitest'; import { renderHook, within, screen } from '@testing-library/react'; import { userEvent } from '@testing-library/user-event'; -import { DialogProps, DialogsProvider, useDialogs } from './useDialogs'; +import { DialogProps, useDialogs } from './useDialogs'; +import { DialogsProvider } from './DialogsProvider'; interface TestWrapperProps { children: React.ReactNode; diff --git a/packages/toolpad-core/src/useNotifications/useNotifications.test.tsx b/packages/toolpad-core/src/useNotifications/useNotifications.test.tsx index 45013f1e19c..9c3d719200d 100644 --- a/packages/toolpad-core/src/useNotifications/useNotifications.test.tsx +++ b/packages/toolpad-core/src/useNotifications/useNotifications.test.tsx @@ -6,7 +6,8 @@ import * as React from 'react'; import { describe, test, expect } from 'vitest'; import { renderHook, within, screen } from '@testing-library/react'; import { userEvent } from '@testing-library/user-event'; -import { NotificationsProvider, useNotifications } from './useNotifications'; +import { useNotifications } from './useNotifications'; +import { NotificationsProvider } from './NotificationsProvider'; interface TestWrapperProps { children: React.ReactNode; From 3d74b14dbdb995d47039b51074bbfa1e8a725038 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:33:09 +0200 Subject: [PATCH 30/36] Update ScopedNotification.js --- .../core/components/use-notifications/ScopedNotification.js | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/data/toolpad/core/components/use-notifications/ScopedNotification.js b/docs/data/toolpad/core/components/use-notifications/ScopedNotification.js index edda9e9752d..0116e791617 100644 --- a/docs/data/toolpad/core/components/use-notifications/ScopedNotification.js +++ b/docs/data/toolpad/core/components/use-notifications/ScopedNotification.js @@ -7,7 +7,6 @@ import Button from '@mui/material/Button'; import { Box, Snackbar, styled } from '@mui/material'; const notificationsProviderSlots = { - // @ts-expect-error snackbar: styled(Snackbar)({ position: 'absolute' }), }; From 8caecda7e77236da8c17153aa3187948f2842fb3 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:44:15 +0200 Subject: [PATCH 31/36] dummy tests --- packages/toolpad-core/src/useDialogs/DialogsProvider.test.tsx | 4 +++- .../src/useNotifications/NotificationsProvider.test.tsx | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/toolpad-core/src/useDialogs/DialogsProvider.test.tsx b/packages/toolpad-core/src/useDialogs/DialogsProvider.test.tsx index 06ebfadb9a6..14a1e3cb822 100644 --- a/packages/toolpad-core/src/useDialogs/DialogsProvider.test.tsx +++ b/packages/toolpad-core/src/useDialogs/DialogsProvider.test.tsx @@ -3,7 +3,7 @@ */ import * as React from 'react'; -import { describe } from 'vitest'; +import { describe, test } from 'vitest'; import describeConformance from '@toolpad/utils/describeConformance'; import { DialogsProvider } from './DialogsProvider'; @@ -11,4 +11,6 @@ describe('DialogsProvider', () => { describeConformance(, () => ({ skip: ['themeDefaultProps'], })); + + test('dummy test', () => {}); }); diff --git a/packages/toolpad-core/src/useNotifications/NotificationsProvider.test.tsx b/packages/toolpad-core/src/useNotifications/NotificationsProvider.test.tsx index e1a96543a71..3aa3f618cad 100644 --- a/packages/toolpad-core/src/useNotifications/NotificationsProvider.test.tsx +++ b/packages/toolpad-core/src/useNotifications/NotificationsProvider.test.tsx @@ -3,7 +3,7 @@ */ import * as React from 'react'; -import { describe } from 'vitest'; +import { describe, test } from 'vitest'; import describeConformance from '@toolpad/utils/describeConformance'; import { NotificationsProvider } from './NotificationsProvider'; @@ -14,4 +14,6 @@ describe('NotificationsProvider', () => { snackbar: {}, }, })); + + test('dummy test', () => {}); }); From 34de819f6338c15677139eab6912b697f4aa6dcf Mon Sep 17 00:00:00 2001 From: Jan Potoms <2109932+Janpot@users.noreply.github.com> Date: Fri, 14 Jun 2024 19:01:04 +0200 Subject: [PATCH 32/36] Update docs/data/toolpad/core/components/use-dialogs/CustomDialog.js Co-authored-by: Pedro Ferreira <10789765+apedroferreira@users.noreply.github.com> Signed-off-by: Jan Potoms <2109932+Janpot@users.noreply.github.com> --- docs/data/toolpad/core/components/use-dialogs/CustomDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/toolpad/core/components/use-dialogs/CustomDialog.js b/docs/data/toolpad/core/components/use-dialogs/CustomDialog.js index 9547b821c8a..cd1b47cd5a8 100644 --- a/docs/data/toolpad/core/components/use-dialogs/CustomDialog.js +++ b/docs/data/toolpad/core/components/use-dialogs/CustomDialog.js @@ -22,7 +22,7 @@ function MyCustomDialog({ open, onClose }) { MyCustomDialog.propTypes = { /** * A function to call when the dialog should be closed. If the dialog has a return - * value, it should be apssed as an argument to this function. You should use the promise + * value, it should be passed as an argument to this function. You should use the promise * that is returned to show a loading state while the dialog is performing async actions * on close. * @param result The result to return from the dialog. From 7feadb9b3f1bfaf031a4ae8651611ae7a22853f3 Mon Sep 17 00:00:00 2001 From: Jan Potoms <2109932+Janpot@users.noreply.github.com> Date: Fri, 14 Jun 2024 19:01:12 +0200 Subject: [PATCH 33/36] Update docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.js Co-authored-by: Pedro Ferreira <10789765+apedroferreira@users.noreply.github.com> Signed-off-by: Jan Potoms <2109932+Janpot@users.noreply.github.com> --- .../core/components/use-dialogs/CustomDialogWithPayload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.js b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.js index 1da89f019f7..c53ce5083e7 100644 --- a/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.js +++ b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithPayload.js @@ -24,7 +24,7 @@ function MyCustomDialog({ payload, open, onClose }) { MyCustomDialog.propTypes = { /** * A function to call when the dialog should be closed. If the dialog has a return - * value, it should be apssed as an argument to this function. You should use the promise + * value, it should be passed as an argument to this function. You should use the promise * that is returned to show a loading state while the dialog is performing async actions * on close. * @param result The result to return from the dialog. From fb5728079e21152bbcbb2c5a69e08324abbbaabd Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Sat, 15 Jun 2024 00:59:47 +0200 Subject: [PATCH 34/36] typos --- .../core/components/use-dialogs/CustomDialogWithResult.js | 2 +- .../data/toolpad/core/components/use-dialogs/StackedDialog.js | 2 +- .../toolpad/core/components/use-dialogs/use-dialogs-api.md | 2 +- .../core/components/use-notifications/use-notifications.md | 2 +- packages/toolpad-core/src/useDialogs/DialogsProvider.tsx | 4 ++-- packages/toolpad-core/src/useDialogs/useDialogs.tsx | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.js b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.js index d54be91c1e4..f224de43d21 100644 --- a/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.js +++ b/docs/data/toolpad/core/components/use-dialogs/CustomDialogWithResult.js @@ -34,7 +34,7 @@ function MyCustomDialog({ open, onClose }) { MyCustomDialog.propTypes = { /** * A function to call when the dialog should be closed. If the dialog has a return - * value, it should be apssed as an argument to this function. You should use the promise + * value, it should be passed as an argument to this function. You should use the promise * that is returned to show a loading state while the dialog is performing async actions * on close. * @param result The result to return from the dialog. diff --git a/docs/data/toolpad/core/components/use-dialogs/StackedDialog.js b/docs/data/toolpad/core/components/use-dialogs/StackedDialog.js index 6aa55529589..86aec23eb80 100644 --- a/docs/data/toolpad/core/components/use-dialogs/StackedDialog.js +++ b/docs/data/toolpad/core/components/use-dialogs/StackedDialog.js @@ -33,7 +33,7 @@ function MyCustomDialog({ payload, open, onClose }) { MyCustomDialog.propTypes = { /** * A function to call when the dialog should be closed. If the dialog has a return - * value, it should be apssed as an argument to this function. You should use the promise + * value, it should be passed as an argument to this function. You should use the promise * that is returned to show a loading state while the dialog is performing async actions * on close. * @param result The result to return from the dialog. diff --git a/docs/data/toolpad/core/components/use-dialogs/use-dialogs-api.md b/docs/data/toolpad/core/components/use-dialogs/use-dialogs-api.md index d89b17e71b4..de5b34176ac 100644 --- a/docs/data/toolpad/core/components/use-dialogs/use-dialogs-api.md +++ b/docs/data/toolpad/core/components/use-dialogs/use-dialogs-api.md @@ -94,7 +94,7 @@ Open a prompt dialog to request user input. Returns a promise that resolves to t ```js const input = await dialogs.prompt('What is your name?', { - canceltext: 'Leave me alone', + cancelText: 'Leave me alone', }); ``` diff --git a/docs/data/toolpad/core/components/use-notifications/use-notifications.md b/docs/data/toolpad/core/components/use-notifications/use-notifications.md index 2f81939a66a..c500eadfec3 100644 --- a/docs/data/toolpad/core/components/use-notifications/use-notifications.md +++ b/docs/data/toolpad/core/components/use-notifications/use-notifications.md @@ -67,7 +67,7 @@ You can supply your own value for a key to shown notifications to associate them ## Scoped notifications -Notifcation providers can be nested. That way you can scope the notifications to a subset of the page. Use the slots to position the snackbar relative to a specific element on the page. +Notification providers can be nested. That way you can scope the notifications to a subset of the page. Use the slots to position the snackbar relative to a specific element on the page. {{"demo": "ScopedNotification.js"}} diff --git a/packages/toolpad-core/src/useDialogs/DialogsProvider.tsx b/packages/toolpad-core/src/useDialogs/DialogsProvider.tsx index 33230c46eb6..a739ce2b549 100644 --- a/packages/toolpad-core/src/useDialogs/DialogsProvider.tsx +++ b/packages/toolpad-core/src/useDialogs/DialogsProvider.tsx @@ -13,7 +13,7 @@ interface DialogStackEntry { resolve: (result: R) => void; } -export interface DialogProviderprops { +export interface DialogProviderProps { children?: React.ReactNode; unmountAfter?: number; } @@ -28,7 +28,7 @@ export interface DialogProviderprops { * * - [DialogsProvider API](https://mui.com/toolpad/core/api/dialogs-provider) */ -function DialogsProvider(props: DialogProviderprops) { +function DialogsProvider(props: DialogProviderProps) { const { children, unmountAfter = 1000 } = props; const [stack, setStack] = React.useState[]>([]); const keyPrefix = React.useId(); diff --git a/packages/toolpad-core/src/useDialogs/useDialogs.tsx b/packages/toolpad-core/src/useDialogs/useDialogs.tsx index 42fcec40e43..c73fe77ff58 100644 --- a/packages/toolpad-core/src/useDialogs/useDialogs.tsx +++ b/packages/toolpad-core/src/useDialogs/useDialogs.tsx @@ -84,7 +84,7 @@ export interface DialogProps

{ open: boolean; /** * A function to call when the dialog should be closed. If the dialog has a return - * value, it should be apssed as an argument to this function. You should use the promise + * value, it should be passed as an argument to this function. You should use the promise * that is returned to show a loading state while the dialog is performing async actions * on close. * @param result The result to return from the dialog. From be6fc7a7eb3868b14bb5bac7c85e28bcaecded15 Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Tue, 18 Jun 2024 10:28:38 +0200 Subject: [PATCH 35/36] some comments --- packages/toolpad-core/src/useDialogs/DialogsProvider.tsx | 2 ++ .../toolpad-core/src/useNotifications/NotificationsProvider.tsx | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packages/toolpad-core/src/useDialogs/DialogsProvider.tsx b/packages/toolpad-core/src/useDialogs/DialogsProvider.tsx index a739ce2b549..6d83266848a 100644 --- a/packages/toolpad-core/src/useDialogs/DialogsProvider.tsx +++ b/packages/toolpad-core/src/useDialogs/DialogsProvider.tsx @@ -19,6 +19,8 @@ export interface DialogProviderProps { } /** + * Provider for Dialog stacks. The subtree of this component can use the `useDialogs` hook to + * access the dialogs API. The dialogs are rendered in the order they are requested. * * Demos: * diff --git a/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx b/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx index a66c68bf1cc..5eef825b99d 100644 --- a/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx +++ b/packages/toolpad-core/src/useNotifications/NotificationsProvider.tsx @@ -144,6 +144,8 @@ export interface NotificationsProviderProps { let nextId = 1; /** + * Provider for Notifications. The subtree of this component can use the `useNotifications` hook to + * access the notifications API. The notifications are shown in the same order they are requested. * * Demos: * From d5a8405d7a7a0f45a3eb622e926aad6c959f8dee Mon Sep 17 00:00:00 2001 From: MUI bot <2109932+Janpot@users.noreply.github.com> Date: Tue, 18 Jun 2024 11:03:21 +0200 Subject: [PATCH 36/36] re --- .../api-docs/dialogs-provider/dialogs-provider.json | 6 +++++- .../notifications-provider/notifications-provider.json | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/translations/api-docs/dialogs-provider/dialogs-provider.json b/docs/translations/api-docs/dialogs-provider/dialogs-provider.json index f93d4cbd8c7..bc8924646fd 100644 --- a/docs/translations/api-docs/dialogs-provider/dialogs-provider.json +++ b/docs/translations/api-docs/dialogs-provider/dialogs-provider.json @@ -1 +1,5 @@ -{ "componentDescription": "", "propDescriptions": {}, "classDescriptions": {} } +{ + "componentDescription": "Provider for Dialog stacks. The subtree of this component can use the `useDialogs` hook to\naccess the dialogs API. The dialogs are rendered in the order they are requested.", + "propDescriptions": {}, + "classDescriptions": {} +} diff --git a/docs/translations/api-docs/notifications-provider/notifications-provider.json b/docs/translations/api-docs/notifications-provider/notifications-provider.json index 28d6825203f..d0aababd27a 100644 --- a/docs/translations/api-docs/notifications-provider/notifications-provider.json +++ b/docs/translations/api-docs/notifications-provider/notifications-provider.json @@ -1,5 +1,5 @@ { - "componentDescription": "", + "componentDescription": "Provider for Notifications. The subtree of this component can use the `useNotifications` hook to\naccess the notifications API. The notifications are shown in the same order they are requested.", "propDescriptions": {}, "classDescriptions": {}, "slotDescriptions": { "snackbar": "The component that renders the snackbar." }