Creating a variant style for Modal on chakra-ui - javascript

I want to create a Modal variant with and set the default width and background color (among other things). I can't find documentation that says exactly how to do it, but I figured using variants would be the way to go.
I've put my best attempt on Code Sandbox here: https://codesandbox.io/s/vigilant-germain-u3mkx?
Any suggestions would be welcome.

Add baseStyle in the Modal component instead of variants
import {
ChakraProvider,
Modal,
extendTheme,
Button,
useDisclosure,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalCloseButton,
ModalBody
} from "#chakra-ui/react";
import "./styles.css";
const theme = extendTheme({
components: {
Modal: {
baseStyle: (props) => ({
dialog: {
maxWidth: ["95%", "95%", "95%"],
minWidth: "95%",
bg: "#00ff00"
}
})
}
}
});
export default function App() {
const { isOpen, onOpen, onClose } = useDisclosure();
return (
<ChakraProvider theme={theme}>
<Button onClick={onOpen}>Open Modal</Button>
<Modal isOpen={isOpen} onClose={onClose} variant="wide">
<ModalOverlay />
<ModalContent>
<ModalHeader>Modal Title</ModalHeader>
<ModalCloseButton />
<ModalBody>
<p>Test</p>
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Close
</Button>
<Button variant="ghost">Secondary Action</Button>
</ModalFooter>
</ModalContent>
</Modal>
</ChakraProvider>
);
}

Related

How to clear state on Dialog close React?

I am using https://react-spectrum.adobe.com/react-spectrum/Dialog.html and whenever I close the dialog and reopen it the value I type does not default back to the initial state. How can I render Dialog on close to reset all states within the dialog?
import {
ActionButton,
Button,
ButtonGroup,
Content,
Dialog,
DialogTrigger,
Divider,
Header,
Heading,
Text,
TextField,
} from "#adobe/react-spectrum";
import { useState } from "react";
export const DialogBox = () => {
const [value, setValue] = useState("");
return (
<DialogTrigger>
<ActionButton>Check connectivity</ActionButton>
{(close) => (
<Dialog>
<Heading>Internet Speed Test</Heading>
<Header>Connection status: Connected</Header>
<Divider />
<Content>
<TextField value={value} onChange={setValue} />
</Content>
<ButtonGroup>
<Button variant="secondary" onPress={close}>
Cancel
</Button>
<Button variant="cta" onPress={close}>
Confirm
</Button>
</ButtonGroup>
</Dialog>
)}
</DialogTrigger>
);
};
Run setValue('') before closing
import {
ActionButton,
Button,
ButtonGroup,
Content,
Dialog,
DialogTrigger,
Divider,
Header,
Heading,
Text,
TextField,
} from "#adobe/react-spectrum";
import { useState } from "react";
export const DialogBox = () => {
const [value, setValue] = useState("");
return (
<DialogTrigger>
<ActionButton>Check connectivity</ActionButton>
{(close) => {
const onClose = () => {
setValue('')
close()
}
return (
<Dialog>
<Heading>Internet Speed Test</Heading>
<Header>Connection status: Connected</Header>
<Divider />
<Content>
<TextField value={value} onChange={setValue} />
</Content>
<ButtonGroup>
<Button variant="secondary" onPress={onClose }>
Cancel
</Button>
<Button variant="cta" onPress={onClose }>
Confirm
</Button>
</ButtonGroup>
</Dialog>
)
}
)}
</DialogTrigger>
);
};
#Konrad Linkowski 's is good,
but I would recommend a better structure.
You can read from their docs about: handling events.
In the event handling you can add the setValue(''):
const cancel = (close) => {
setValue('');
close();
};

Dialog box doen't occupy entire width of a browser

I have a dialog box which confirms ok or cancel.
The width of the dialog box is already 100% ie width:100%, but it still doesn't occupy entire width of the browser.
a backdrop occupies entire width though.
//App.js
import React from "react";
import ConfirmationDialog from "./ConfirmationDialog";
import { useState } from "react";
export default function App() {
const [confirm, setConfirm] = useState(false);
const handleClick = () => {
setConfirm(true);
};
const handleClose = () => {
setConfirm(false);
};
return (
<>
<button onClick={handleClick}>click</button>
<ConfirmationDialog open={confirm} handleClose={handleClose} />
</>
);
}
// ConfirmationDialog.js
import Box from "#mui/material/Box";
import Button from "#mui/material/Button";
import DialogTitle from "#mui/material/DialogTitle";
import DialogContent from "#mui/material/DialogContent";
import DialogActions from "#mui/material/DialogActions";
import Dialog from "#mui/material/Dialog";
function ConfirmationDialogRaw(props) {
const { onClose, open, ...other } = props;
const handleCancel = () => {
onClose();
};
const handleOk = () => {
onClose();
};
return (
<Dialog
sx={{ "& .MuiDialog-paper": { width: "100%", maxHeight: 435 } }} // This only occupies middle part of the browser, left and right side backdrop is visible.
maxWidth="xs"
open={open}
{...other}
>
<DialogTitle>Dialog Title</DialogTitle>
<DialogContent dividers>Hello World!</DialogContent>
<DialogActions>
<Button autoFocus onClick={handleCancel}>
Cancel
</Button>
<Button onClick={handleOk}>Ok</Button>
</DialogActions>
</Dialog>
);
}
function ConfirmationDialog({ open, handleClose }) {
return (
<Box sx={{ width: "100%", maxWidth: 400, bgcolor: "background.paper" }}>
<ConfirmationDialogRaw
id="confirmationId"
keepMounted
open={open}
onClose={handleClose}
/>
</Box>
);
}
export default ConfirmationDialog;
How to occupy entire browser width with the dialog box?
codeSandbox Demo
the maxWidth property is the problem
return (
<Dialog
sx={{ "& .MuiDialog-paper": { width: "100%", maxHeight: 435 } }} // This only occupies middle part of the browser, left and right side backdrop is visible.
maxWidth="xs"
open={open}
{...other}
>
remove
maxWidth="xs"
The rest not ocuppyed by the dialog it's the dialog margin

Open Modal in fullscreen

Is there a way to open a modal which will take entire screen just like in youtube video when you click on it's fullscreen it takes the entire screen view.
Right now this is what i have achieved so far
<Modal
title={false}
visible={visible}
footer={false}
centered
width="100vw"
onCancel={() => setVisible(false)}
>
<div style={{height: '100vh'}}>
some content
</div>
</Modal>
and this is how it looks like
i want it to look like this
With pure JavaScript you can do something like
const modal = document.querySelector('#myModalsClass')
modal.requestFullscreen()
If you look up the docs for the fullscreen API you will find other useful information about how to work with this.
If you're using React you need to use a ref to access the dom api
import React, { useRef } from "react";
const MyComponent = (props) => {
const myFullscreenComponent = useRef();
const openContentFullscreen = () => {
const element = myFullscreenComponent.current;
if (element && element.requestFullscreen) {
element.requestFullscreen();
}
};
return (
<div>
<button onClick={openContentFullscreen}>Full Screen</button>
<div className="modal" ref={myFullscreenComponent}>
content I want to be fullscreen
</div>
</div>
);
};
id recommend to use mui full-screen modal Here the link https://mui.com/material-ui/react-dialog/
let me know if you need any help
Check the following example
Note: set footer={null} if you want to hide OK and CANCEL buttons
App.js
import React, { useState } from 'react';
import 'antd/dist/antd.css';
import './index.css';
import { Button, Modal } from 'antd';
const App = () => {
const [visible, setVisible] = useState(false);
return (
<>
<Button type="primary" onClick={() => setVisible(true)}>
Open Full screen Modal
</Button>
<Modal
title="Full screen modal"
visible={visible}
//onOk={() => setVisible(false)}
onCancel={() => setVisible(false)}
footer={null} //If you want to hide OK and cancel buttons
>
<p>Full screen...</p>
<p>Full screen...</p>
<p>Full screen...</p>
<p>Full screen...</p>
<p>Full screen...</p>
</Modal>
</>
);
};
export default App;
index.css
.ant-modal,
.ant-modal-content {
height: 100vh;
width: 100vw;
top: 0;
margin: 0;
}
Screenshot
Demo

How to call dialog box from another file in React

I am very new to React so this may seem a little trivial. I have a delete icon in one file which when clicked, I am trying to program a confirmation dialog box. Using the source of their website: https://material-ui.com/components/dialogs/. My file is comprises of a listview:
ListView:
import React from 'react';
import PropTypes from 'prop-types';
import { List, ListItem, ListItemText, ListItemAvatar, Avatar, ListItemSecondaryAction, IconButton } from '#material-ui/core';
import DeleteIcon from '#material-ui/icons/Delete';
import AlertDialog from './AlertDialog'
// Import CSS
import './ListViewer.css'
export function ListViewer({ objects}) {
return (
<div className='list-viewer'>
<List>
<ListItem alignItems="center" divider key={obj.id}>
<ListItemText primary={objects.name} />
<ListItemSecondaryAction>
<IconButton edge="end" aria-label="delete" onClick={handleClickOpen()}>
<DeleteIcon />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
</List>
</div>
);
}
AlertDialog.js:
import React from 'react';
import Button from '#material-ui/core/Button';
import Dialog from '#material-ui/core/Dialog';
import DialogActions from '#material-ui/core/DialogActions';
import DialogContent from '#material-ui/core/DialogContent';
import DialogContentText from '#material-ui/core/DialogContentText';
import DialogTitle from '#material-ui/core/DialogTitle';
export default function AlertDialog() {
const [open, setOpen] = React.useState(false);
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
return (
<div>
{/* <Button variant="outlined" color="primary" onClick={handleClickOpen}>
Open alert dialog
</Button> */}
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">{"Are you sure you want to delete this object?"}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
Deleting this object will permanently remove it
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="primary">
Cancel
</Button>
<Button onClick={handleClose} color="primary" autoFocus>
Delete
</Button>
</DialogActions>
</Dialog>
</div>
);
}
As you can see in AlertDialog, there was initially a button which triggers the dialog to open. Instead from my other file, when the delete icon is clicked, I am trying to trigger the dialog. How can I do this? I have imported AlertDialog and AlertDialog.handleClickOpen but this does not work as handleClickOpen is not a function
You can pass open and onClose via props into AlertDialog.
function AlertDialog(props) {
const { open, onClose } = props
return (
<Dialog
open={open}
onClose={onClose}
>
{/* Dialog content */}
</Dialog>
Then, simply use it in ListView:
function ListView() {
const [dialogIsOpen, setDialogIsOpen] = React.useState(false)
const openDialog = () => setDialogIsOpen(true)
const closeDialog = () => setDialogIsOpen(false)
return (
<div className='list-viewer'>
<List>{/* Now you can set dialogIsOpen here */}</List>
<AlertDialog open={dialogIsOpen} onClose={closeDialog} />
</div>
)
}
There are a few steps how I would do it the first is that I would do instead of a open and close function I would do one as this:
const toggleDialog = useCallback(() => {
setOpen(!open);
}, [open]);
The useCallback function makes it that it only creates a new function when the parameter in the [] changes, means when open changes.
Sadly #Code-Apprentice was faster and metioned the rest to it.
<IconButton edge="end" aria-label="delete" onClick={handleClickOpen()}>
The onClick handler here must be in the same class that renders the <IconButton>. Also, remove the parentheses to set the onClick prop to the function instead of its return value:
onClick={handleClickOpen}

Open modal from another component click in react js

I am using the basic component modal component of react - https://github.com/reactjs/react-modal
What I am trying to achieve is that I want to open the modal from another parent that has the modal imported.
Parent.js
<button onClick={() => this.refs.setState({modalIsOpen: true})}> - THIS BUTTON ELEMENT IS IN ANOTHER COMPONENT
Modal.js
import React from 'react';
import ReactDOM from 'react-dom';
import Modal from 'react-modal';
const customStyles = {
content : {
top : '50%',
left : '50%',
right : 'auto',
bottom : 'auto',
marginRight : '-50%',
transform : 'translate(-50%, -50%)'
}
};
class App extends React.Component {
constructor() {
super();
this.state = {
modalIsOpen: false
};
this.openModal = this.openModal.bind(this);
this.afterOpenModal = this.afterOpenModal.bind(this);
this.closeModal = this.closeModal.bind(this);
}
openModal() {
this.setState({modalIsOpen: true});
}
afterOpenModal() {
// references are now sync'd and can be accessed.
this.subtitle.style.color = '#f00';
}
closeModal() {
this.setState({modalIsOpen: false});
}
render() {
return (
<div>
<button onClick={this.openModal}>Open Modal</button>
<Modal
isOpen={this.state.modalIsOpen}
onAfterOpen={this.afterOpenModal}
onRequestClose={this.closeModal}
style={customStyles}
contentLabel="Example Modal"
>
<h2 ref={subtitle => this.subtitle = subtitle}>Hello</h2>
<button onClick={this.closeModal}>close</button>
<div>I am a modal</div>
<form>
<input />
<button>tab navigation</button>
<button>stays</button>
<button>inside</button>
<button>the modal</button>
</form>
</Modal>
</div>
);
}
}
export default App
I have read that this can be done using refs and changing the state of the modal. What exactly am I doing wrong here?
Thanks!
Can you try below code in parent
<button onClick={() => this._modal.openModal()}>click</button>
when you call your modal component use ref attribute then can call like above code.
<Modal ref={(modal) => { this._modal = modal; }} />
easy way, do this via props:
modal.js
import ....
<Modal
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
className={classes.modal}
open={this.props.handleOpen}
onClose={this.props.handleClose}
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 1000
}}
>
in your component that has the modal imported.
///some code here
state = {
isOpen: Boolean(false)
};
<externalElement onClick={() => this.setState({ isOpen: true })}>title ... </externalElement>
<importedModal
handleOpen={this.state.isOpen}
handleClose={() => this.setState({ isOpen: false })}
/>

Categories

Resources