Modal
See React Bootstrap/Modals for full documentation and props.
The Modal component can have many possible variations. The most basic usage is to render a Modal with all content in the body and an optional Modal.Icon.
The Modal.Icon component can by styled by providing a variant prop. The default variant is 'info'.
function Example() {const [show, setShow] = React.useState(false);return (<><Button onClick={() => setShow(true)}>Show modal</Button><Modal show={show} onHide={() => setShow(false)} size="lg"><Modal.Body><div className="d-flex"><div className="me-3"><Modal.Icon><span className="icon-message-circle-02" /></Modal.Icon></div><div><strong className="fs-xxl">Title</strong><br />Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temporincididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrudexercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div></div></Modal.Body><Modal.Footer><Button variant="primary" onClick={() => setShow(false)}>Dismiss</Button></Modal.Footer></Modal></>);}
Modal with header
When using the Modal.Header component the Modal.Icon should be placed within the header to the left of the Modal.Title.
function Example() {const [show, setShow] = React.useState(false);return (<><Button onClick={() => setShow(true)}>Show modal</Button><Modal show={show} onHide={() => setShow(false)} size="lg"><Modal.Header closeButton><div className="d-flex"><div className="me-3"><Modal.Icon><span className="icon-message-circle-02" /></Modal.Icon></div><Modal.Title>Title</Modal.Title></div></Modal.Header><Modal.Body>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididuntut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitationullamco laboris nisi ut aliquip ex ea commodo consequat.</Modal.Body><Modal.Footer><span className="text-gray-500 me-3">Line of context for the buttons</span><Button variant="outline-secondary" onClick={() => setShow(false)}>Cancel</Button><Button variant="primary" onClick={() => setShow(false)}>Save</Button></Modal.Footer></Modal></>);}
Centered and stacked
This variation of the Modal moves the content of the footer into the body and centers all content vertically. Using the d-grid
utility class around Buttons will force them to take the full width of their container.
function Example() {const [show, setShow] = React.useState(false);return (<><Button onClick={() => setShow(true)}>Show modal</Button><Modal show={show} onHide={() => setShow(false)} centered><Modal.Body><div className="d-flex flex-column align-items-center"><div className="mb-3"><Modal.Icon variant="danger"><span className="icon-alert-triangle" /></Modal.Icon></div><div className="mb-3"><strong className="fs-xxl">Deactivate account</strong></div></div><div className="text-center mb-5">Are you sure you want to deactivate your account? All of your data will be permanentlyremoved from our servers forever. This action cannot be undone.</div><div className="d-grid"><Button variant="outline-secondary" className="mb-3" onClick={() => setShow(false)}>Cancel</Button><Button variant="primary" onClick={() => setShow(false)}>Deactivate</Button></div></Modal.Body></Modal></>);}
Other footer configurations
Interactive footer content (checkboxes or links) should be positioned to the start of the footer. The buttons should be remain positioned to the end of the footer.
function Example() {const [show, setShow] = React.useState(false);return (<><Button onClick={() => setShow(true)}>Show modal</Button><Modal show={show} onHide={() => setShow(false)} size="lg"><Modal.Header closeButton><div className="d-flex"><div className="me-3"><Modal.Icon><span className="icon-user-circle" /></Modal.Icon></div><Modal.Title>Save account</Modal.Title></div></Modal.Header><Modal.Body>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididuntut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitationullamco laboris nisi ut aliquip ex ea commodo consequat.</Modal.Body><Modal.Footer className="d-flex justify-content-between"><div><Checkbox label="Remember me" /></div><div><Button variant="outline-secondary" onClick={() => setShow(false)}>Cancel</Button><Button variant="primary" onClick={() => setShow(false)}>Save</Button></div></Modal.Footer></Modal></>);}
Modal with a form
Using a form ref in Modal.Footer
To make sure there are not duplicate footers when using a Form inside a Modal, pass a function that returns null into the Form's footerRenderer
prop. A ref to the Form can be used to call submit when one of the buttons in the Modal's footer is pressed.
function Example() {const formRef = React.useRef(null);const [show, setShow] = React.useState(false);const schema = object().shape({awesomeField: string().required(),});return (<><Button onClick={() => setShow(true)}>Show modal</Button><Modal show={show} onHide={() => setShow(false)} size="lg"><Modal.Header closeButton><div className="d-flex"><div className="me-3"><Modal.Icon><span className="icon-pencil-01" /></Modal.Icon></div><Modal.Title>Modal Form</Modal.Title></div></Modal.Header><Modal.Body><Formref={formRef}onSubmit={(values, helpers) => {console.log({ values, helpers });setShow(false);}}footerRenderer={() => null}validationSchema={schema}><FormField><TextField name="awesomeField" label="Awesome Field" /></FormField></Form></Modal.Body><Modal.Footer><Button variant="primary" onClick={() => formRef.current.submitForm()}>Submit</Button></Modal.Footer></Modal></>);}
Using a custom footer renderer
It's also possible to wrap the contents of the modal in a Form and use the footerRenderer
prop to render the buttons in the footer. This way, the form can be submitted by calling the onSubmit
function passed to the footerRenderer
prop.
function Example() {const [show, setShow] = React.useState(false);const schema = object().shape({awesomeField: string().required(),});return (<><Button onClick={() => setShow(true)}>Show modal</Button><Modal show={show} onHide={() => setShow(false)} size="lg"><FormonSubmit={(values, helpers) => {console.log({ values, helpers });setShow(false);}}footerRenderer={(form) => (<Modal.Footer><Button variant="primary" onClick={() => form.onSubmit()}>Submit</Button></Modal.Footer>)}validationSchema={schema}><Modal.Header closeButton><div className="d-flex"><div className="me-3"><Modal.Icon><span className="icon-pencil-01" /></Modal.Icon></div><Modal.Title>Modal Form</Modal.Title></div></Modal.Header><Modal.Body><FormField><TextField name="awesomeField" label="Awesome Field" /></FormField></Modal.Body></Form></Modal></>);}
Using Tabs
function Example() {const [show, setShow] = useState(false);const [activeTabId, setActiveTabId] = useState('Ownership');const handleClose = () => setShow(false);const handleShow = () => setShow(true);const tabsList = [<Tab key="Ownership" id="Ownership">Ownership</Tab>,<Tab key="Fees" id="Fees">Fees</Tab>,<Tab key="Realization" id="Realization">Realization</Tab>,<Tab key="Holdings" id="Holdings">Holdings</Tab>,];const tabContents = useMemo(() => {switch (activeTabId) {case 'Ownership':return 'Ownership Content';case 'Fees':return 'Fees Content';case 'Realization':return 'Realization Content';case 'Holdings':return 'Holdings Content';default:return null;}}, [activeTabId]);return (<><Button variant="primary" onClick={handleShow}>Toggle</Button><Modal show={show} onHide={handleClose}><Modal.Header className="border-0" closeButton><div className="d-flex"><div className="me-3"><Modal.Icon><span className="icon-placeholder" /></Modal.Icon></div><Modal.Title>Modal With Tabs</Modal.Title></div></Modal.Header><Modal.Body className="px-0 pt-0"><Tabsvariant="tabs"tabs={tabsList}activeTabId={activeTabId}onTabClick={(event, id) => {setActiveTabId(id);}}className="px-4"></Tabs><div className="border-top px-4 py-3" style={{ marginTop: 1 }}>{tabContents}</div></Modal.Body><Modal.Footer><Button onClick={handleClose} variant="outline-secondary">Cancel</Button><Button onClick={handleClose}>Save</Button></Modal.Footer></Modal></>);}
Analytics
The Modal component is trackable through Kyber Analytics. This is the default analytics config.
export default {
value: 'Modal',
actions: {
onHide: { type: 'MODAL_ON_HIDE', payload: 'Hide' },
},
};