Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[Joy UI] Add Modal component #34043

Merged
merged 37 commits into from Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
60a1fe7
add Modal component
siriwatknp Aug 21, 2022
d4747e4
add ModalDialog
siriwatknp Aug 21, 2022
9ac5a30
init modal components
siriwatknp Aug 22, 2022
40169c0
add modal test
siriwatknp Aug 22, 2022
90c4373
add ModalDialog test
siriwatknp Aug 22, 2022
56ef068
remove instanceSize
siriwatknp Aug 23, 2022
00c78e2
add tests
siriwatknp Aug 23, 2022
3527d1e
fix tests
siriwatknp Aug 23, 2022
ef96bf7
create demos
siriwatknp Aug 23, 2022
f8f8150
run proptypes
siriwatknp Aug 23, 2022
666a4ae
Merge branch 'master' of https://github.com/mui/material-ui into joy/…
siriwatknp Aug 23, 2022
374f74e
reexport index and add styleOverrides types
siriwatknp Aug 23, 2022
f5cb4fe
copywriting tweaks
danilo-leal Aug 24, 2022
fbb77fd
a bit of demo customization
danilo-leal Aug 24, 2022
a1c9766
Merge branch 'master' of https://github.com/mui/material-ui into joy/…
siriwatknp Aug 24, 2022
09201d4
update styles and props
siriwatknp Aug 24, 2022
cfaacf6
add fade example
siriwatknp Aug 24, 2022
a4deaee
Merge branch 'joy/modal' of github.com:siriwatknp/material-ui into jo…
siriwatknp Aug 24, 2022
99616cd
remove Title and Description
siriwatknp Aug 31, 2022
7bc1471
remove ModalTitle and Description
siriwatknp Aug 31, 2022
e375b0a
Merge branch 'master' of https://github.com/mui/material-ui into joy/…
siriwatknp Aug 31, 2022
053f6db
add close modal demo
siriwatknp Aug 31, 2022
e16c348
remove all dead code
siriwatknp Aug 31, 2022
f8d9bd3
minor fixes
siriwatknp Aug 31, 2022
8be3ff7
Merge branch 'master' of https://github.com/mui/material-ui into joy/…
siriwatknp Sep 6, 2022
47c533d
add spec
siriwatknp Sep 6, 2022
85e6791
fix typo
siriwatknp Sep 6, 2022
1621472
move to feedback
siriwatknp Sep 6, 2022
a27d311
add ModalUsage
siriwatknp Sep 6, 2022
2774254
run proptypes
siriwatknp Sep 6, 2022
365d266
update
siriwatknp Sep 6, 2022
6a1287c
Merge branch 'master' of https://github.com/mui/material-ui into joy/…
siriwatknp Sep 6, 2022
823dea5
fix fade modal
siriwatknp Sep 6, 2022
032b01f
update content
siriwatknp Sep 6, 2022
bc6824e
remove 'top' layout
siriwatknp Sep 8, 2022
d1dcfae
Merge branch 'master' of https://github.com/mui/material-ui into joy/…
siriwatknp Sep 8, 2022
3063797
fix playground
siriwatknp Sep 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
55 changes: 55 additions & 0 deletions docs/data/joy/components/modal/AlertDialogModal.js
@@ -0,0 +1,55 @@
import * as React from 'react';
import Box from '@mui/joy/Box';
import Button from '@mui/joy/Button';
import Modal from '@mui/joy/Modal';
import ModalDialog from '@mui/joy/ModalDialog';
import ModalDialogTitle from '@mui/joy/ModalDialogTitle';
import ModalDialogDescription from '@mui/joy/ModalDialogDescription';
import DeleteForever from '@mui/icons-material/DeleteForever';
import WarningRoundedIcon from '@mui/icons-material/WarningRounded';
import Typography from '@mui/joy/Typography';

export default function BasicModalDialog() {
const [open, setOpen] = React.useState(false);
return (
<React.Fragment>
<Button
variant="outlined"
color="danger"
endIcon={<DeleteForever />}
onClick={() => setOpen(true)}
>
Discard
</Button>
<Modal open={open} onClose={() => setOpen(false)}>
<ModalDialog variant="outlined" role="alertdialog">
<ModalDialogTitle sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<WarningRoundedIcon />
<Typography
component="h2"
id="modal-title"
level="h5"
textColor="inherit"
fontWeight="lg"
>
Confirmation
</Typography>
</ModalDialogTitle>
<ModalDialogDescription sx={{ mb: 3 }}>
<Typography id="modal-desc" textColor="text.tertiary">
Are you sure you want to discard all of your notes?
</Typography>
</ModalDialogDescription>
<Box sx={{ display: 'flex', gap: 1, justifyContent: 'flex-end' }}>
<Button variant="plain" color="neutral" onClick={() => setOpen(false)}>
Cancel
</Button>
<Button variant="solid" color="danger" onClick={() => setOpen(false)}>
Discard notes
</Button>
</Box>
</ModalDialog>
</Modal>
</React.Fragment>
);
}
58 changes: 58 additions & 0 deletions docs/data/joy/components/modal/BasicModal.js
@@ -0,0 +1,58 @@
import * as React from 'react';
import Button from '@mui/joy/Button';
import Modal from '@mui/joy/Modal';
import ModalClose from '@mui/joy/ModalClose';
import Typography from '@mui/joy/Typography';
import Sheet from '@mui/joy/Sheet';

export default function BasicModalDialog() {
const [open, setOpen] = React.useState(false);
return (
<React.Fragment>
<Button variant="outlined" color="neutral" onClick={() => setOpen(true)}>
Open modal
</Button>
<Modal
open={open}
onClose={() => setOpen(false)}
sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}
>
<Sheet
aria-labelledby="modal-title"
aria-describedby="modal-desc"
variant="outlined"
sx={{
maxWidth: 500,
borderRadius: 'md',
p: 3,
boxShadow: 'lg',
}}
>
<ModalClose
variant="outlined"
sx={{
top: 'calc(-1/4 * var(--IconButton-size))',
right: 'calc(-1/4 * var(--IconButton-size))',
boxShadow: '0 2px 12px 0 rgba(0 0 0 / 0.2)',
borderRadius: '50%',
bgcolor: 'background.body',
}}
/>
<Typography
component="h2"
id="modal-title"
level="h4"
textColor="inherit"
fontWeight="lg"
>
This is the modal title
</Typography>
<Typography id="modal-desc" textColor="text.tertiary">
Make sure to use <code>aria-labelledby</code> on the modal dialog with an
optional <code>aria-describedby</code> attribute.
</Typography>
</Sheet>
</Modal>
</React.Fragment>
);
}
55 changes: 55 additions & 0 deletions docs/data/joy/components/modal/BasicModalDialog.js
@@ -0,0 +1,55 @@
import * as React from 'react';
import Button from '@mui/joy/Button';
import TextField from '@mui/joy/TextField';
import Modal from '@mui/joy/Modal';
import ModalDialog from '@mui/joy/ModalDialog';
import ModalDialogTitle from '@mui/joy/ModalDialogTitle';
import ModalDialogDescription from '@mui/joy/ModalDialogDescription';
import Stack from '@mui/joy/Stack';
import Add from '@mui/icons-material/Add';
import Typography from '@mui/joy/Typography';

export default function BasicModalDialog() {
const [open, setOpen] = React.useState(false);
return (
<React.Fragment>
<Button
variant="outlined"
color="neutral"
startIcon={<Add />}
onClick={() => setOpen(true)}
>
New project
</Button>
<Modal open={open} onClose={() => setOpen(false)}>
<ModalDialog
sx={{
maxWidth: 500,
borderRadius: 'md',
p: 3,
boxShadow: 'lg',
}}
>
<ModalDialogTitle>Create new project</ModalDialogTitle>
<ModalDialogDescription sx={{ mb: 2 }}>
<Typography id="modal-desc" textColor="text.tertiary">
Fill in the information of the project.
</Typography>
</ModalDialogDescription>
<form
onSubmit={(event) => {
event.preventDefault();
setOpen(false);
}}
>
<Stack spacing={2}>
<TextField label="Name" required />
<TextField label="Description" required />
<Button type="submit">Submit</Button>
</Stack>
</form>
</ModalDialog>
</Modal>
</React.Fragment>
);
}
25 changes: 25 additions & 0 deletions docs/data/joy/components/modal/KeepMountedModal.js
@@ -0,0 +1,25 @@
import * as React from 'react';
import Button from '@mui/joy/Button';
import Modal from '@mui/joy/Modal';
import ModalDialog from '@mui/joy/ModalDialog';
import ModalDialogTitle from '@mui/joy/ModalDialogTitle';
import ModalDialogDescription from '@mui/joy/ModalDialogDescription';

export default function BasicModalDialog() {
const [open, setOpen] = React.useState(false);
return (
<React.Fragment>
<Button variant="outlined" color="neutral" onClick={() => setOpen(true)}>
Open modal
</Button>
<Modal keepMounted open={open} onClose={() => setOpen(false)}>
<ModalDialog>
<ModalDialogTitle>Keep mounted modal</ModalDialogTitle>
<ModalDialogDescription>
This modal is still in the DOM event though it is closed.
</ModalDialogDescription>
</ModalDialog>
</Modal>
</React.Fragment>
);
}
36 changes: 36 additions & 0 deletions docs/data/joy/components/modal/LayoutModalDialog.js
@@ -0,0 +1,36 @@
import * as React from 'react';
import Button from '@mui/joy/Button';
import Stack from '@mui/joy/Stack';
import Modal from '@mui/joy/Modal';
import ModalDialog from '@mui/joy/ModalDialog';
import ModalDialogTitle from '@mui/joy/ModalDialogTitle';
import ModalDialogDescription from '@mui/joy/ModalDialogDescription';

export default function LayoutModalDialog() {
const [open, setOpen] = React.useState('');
return (
<React.Fragment>
<Stack direction="row" spacing={1}>
<Button
variant="outlined"
color="neutral"
onClick={() => setOpen('fullScreen')}
>
Full screen
</Button>
<Button variant="outlined" color="neutral" onClick={() => setOpen('center')}>
Center
</Button>
</Stack>
<Modal open={!!open} onClose={() => setOpen('')}>
<ModalDialog layout={open}>
<ModalDialogTitle>Modal dialog</ModalDialogTitle>
<ModalDialogDescription>
This is a <code>{open}</code> modal dialog. Press <code>esc</code> to
close it.
</ModalDialogDescription>
</ModalDialog>
</Modal>
</React.Fragment>
);
}
38 changes: 38 additions & 0 deletions docs/data/joy/components/modal/NestedModals.js
@@ -0,0 +1,38 @@
import * as React from 'react';
import Button from '@mui/joy/Button';
import Modal from '@mui/joy/Modal';
import ModalDialog from '@mui/joy/ModalDialog';
import ModalDialogTitle from '@mui/joy/ModalDialogTitle';
import ModalDialogDescription from '@mui/joy/ModalDialogDescription';

function randomBetween(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

export default function NestedModals({ random }) {
const [open, setOpen] = React.useState(false);
return (
<React.Fragment>
<Button variant="outlined" color="neutral" onClick={() => setOpen(true)}>
Open modal
</Button>
<Modal open={open} onClose={() => setOpen(false)}>
<ModalDialog
layout="center"
{...(random && {
sx: {
top: `${randomBetween(25, 75)}%`,
left: `${randomBetween(25, 75)}%`,
},
})}
>
<ModalDialogTitle>Infinite modals</ModalDialogTitle>
<ModalDialogDescription sx={{ mb: 1 }}>
Welcome to the infinite nested modals.
</ModalDialogDescription>
<NestedModals random />
</ModalDialog>
</Modal>
</React.Fragment>
);
}
42 changes: 42 additions & 0 deletions docs/data/joy/components/modal/ServerModal.js
@@ -0,0 +1,42 @@
import * as React from 'react';
import Box from '@mui/joy/Box';
import Modal from '@mui/joy/Modal';
import ModalDialog from '@mui/joy/ModalDialog';
import ModalDialogTitle from '@mui/joy/ModalDialogTitle';
import ModalDialogDescription from '@mui/joy/ModalDialogDescription';

export default function ServerModal() {
const rootRef = React.useRef(null);

return (
<Box
sx={{
height: 240,
flexGrow: 1,
minWidth: 300,
transform: 'translateZ(0)',
// The position fixed scoping doesn't work in IE11.
// Disable this demo to preserve the others.
'@media all and (-ms-high-contrast: none)': {
display: 'none',
},
}}
ref={rootRef}
>
<Modal
disablePortal
disableEnforceFocus
disableAutoFocus
open
container={() => rootRef.current}
>
<ModalDialog layout="center">
<ModalDialogTitle>Server-side modal</ModalDialogTitle>
<ModalDialogDescription>
If you disable JavaScript, you will still see me.
</ModalDialogDescription>
</ModalDialog>
</Modal>
</Box>
);
}
51 changes: 51 additions & 0 deletions docs/data/joy/components/modal/SizeModalDialog.js
@@ -0,0 +1,51 @@
import * as React from 'react';
import Button from '@mui/joy/Button';
import Stack from '@mui/joy/Stack';
import Modal from '@mui/joy/Modal';
import ModalClose from '@mui/joy/ModalClose';
import ModalDialog from '@mui/joy/ModalDialog';
import ModalDialogTitle from '@mui/joy/ModalDialogTitle';
import ModalDialogDescription from '@mui/joy/ModalDialogDescription';

export default function SizeModalDialog() {
const [open, setOpen] = React.useState('');
return (
<React.Fragment>
<Stack direction="row" alignItems="center" spacing={1}>
<Button
variant="outlined"
color="neutral"
size="sm"
onClick={() => setOpen('sm')}
>
Small
</Button>
<Button
variant="outlined"
color="neutral"
size="md"
onClick={() => setOpen('md')}
>
Medium
</Button>
<Button
variant="outlined"
color="neutral"
size="lg"
onClick={() => setOpen('lg')}
>
Large
</Button>
</Stack>
<Modal open={!!open} onClose={() => setOpen('')}>
<ModalDialog size={open}>
<ModalClose />
<ModalDialogTitle>Modal Dialog</ModalDialogTitle>
<ModalDialogDescription>
This is a `{open}` modal dialog.
</ModalDialogDescription>
</ModalDialog>
</Modal>
</React.Fragment>
);
}