UNPKG

@wix/design-system

Version:

@wix/design-system

486 lines (425 loc) 14.8 kB
## Feature Examples ### Structure - description: <p><code>FullScreenModalLayout</code> is built from three components:</p><li><code>FullScreenModalLayout.Header</code></li><li><code>FullScreenModalLayout.Content</code></li><li><code>FullScreenModalLayout.Footer</code></li> - example: ```jsx () => { const [isOpen, setIsOpen] = React.useState(false); const closeModal = () => setIsOpen(false); return ( <Box padding="20px" gap="20px" direction="vertical"> <Button onClick={() => setIsOpen(true)}>Open Modal</Button> <Modal isOpen={isOpen} onRequestClose={closeModal}> <FullScreenModalLayout> <FullScreenModalLayout.Header startNode={ <Box border="1px dashed" padding="SP2"> 1 Node slot </Box> } endNode={ <Box border="1px dashed" padding="SP2"> 2 Node slot </Box> } > <Box direction="vertical" gap="SP1"> <Text>Modal title goes here</Text> <Text size="small" secondary> Subtitle goes here </Text> </Box> </FullScreenModalLayout.Header> <FullScreenModalLayout.Content padding> <Box border="1px dashed" height="240px" padding="SP4" direction="vertical" align="space-between" > <Box direction="vertical" align="center" gap="SP2"> <Text>Modal content starts here</Text> <TextButton onClick={closeModal}>Close modal</TextButton> </Box> <Text>Modal content ends here</Text> </Box> </FullScreenModalLayout.Content> <FullScreenModalLayout.Footer> <Box border="1px dashed" padding="SP3"> <Text>Footer is sticky</Text> </Box> </FullScreenModalLayout.Footer> </FullScreenModalLayout> </Modal> </Box> ); }; ``` ### Animation - description: <p>Control <code>FullScreenModalLayout</code> animation styles using <code>Modal</code> transition property:</p><p><code>zoomIn</code> (default) - the modal appears from the middle of the screen</p><li><code>moveVertical</code> - the modal slides in from the bottom </li><li><code>moveHorizontal</code> - the modal slides in from the right side of the screen</li> - example: ```jsx () => { const ModalWithButton = ({ isOpen: isOpenProp = false, buttonLabel, transition, children, }: { isOpen?: boolean; buttonLabel: string; transition: 'moveHorizontal' | 'moveVertical'; children: ({ isOpen, close, }: { isOpen: boolean; close: () => void; }) => React.ReactNode; }) => { const [isOpen, setIsOpen] = React.useState(isOpenProp); const close = React.useCallback(() => setIsOpen(false), []); return ( <> <Button onClick={() => setIsOpen(true)}>{buttonLabel}</Button> <Modal transition={transition} isOpen={isOpen} onRequestClose={close}> {children({ isOpen, close })} </Modal> </> ); }; return ( <StorybookComponents.Stack> <ModalWithButton buttonLabel="Horizontal transition" transition="moveHorizontal" > {({ close }) => ( <FullScreenModalLayout> <FullScreenModalLayout.Header startNode={ <CloseButton skin="dark" size="large" onClick={close} /> } endNode={ <TextButton size="small" onClick={close}> Save </TextButton> } > <Text size="small" weight="normal" ellipsis> Modal Title </Text> </FullScreenModalLayout.Header> <FullScreenModalLayout.Content padding> <Text>This is the main content area with padding.</Text> </FullScreenModalLayout.Content> <FullScreenModalLayout.Footer> <Text>Footer</Text> </FullScreenModalLayout.Footer> </FullScreenModalLayout> )} </ModalWithButton> <ModalWithButton buttonLabel="Vertical transition" transition="moveVertical" > {({ close }) => ( <FullScreenModalLayout> <FullScreenModalLayout.Header startNode={ <CloseButton skin="dark" size="large" onClick={close} /> } endNode={ <TextButton size="small" onClick={close}> Save </TextButton> } > <Text size="small" weight="normal" ellipsis> Modal Title </Text> </FullScreenModalLayout.Header> <FullScreenModalLayout.Content padding> <Text>This is the main content area with padding.</Text> </FullScreenModalLayout.Content> <FullScreenModalLayout.Footer> <Text>Footer</Text> </FullScreenModalLayout.Footer> </FullScreenModalLayout> )} </ModalWithButton> </StorybookComponents.Stack> ); }; ``` ## Common Use Case Examples ### Long forms - description: <p>It is recommended to use <code>FullScreenModalLayout.Footer</code> for modals that are longer. This way the main actions are always visible to users</p> - example: ```jsx () => { const [isOpen, setIsOpen] = React.useState(false); const openModal = () => setIsOpen(true); const closeModal = () => setIsOpen(false); return ( <StorybookComponents.Stack> <Button onClick={openModal} prefixIcon={<Icons.Add />}> New dish </Button> <Modal isOpen={isOpen} onRequestClose={closeModal} transition="moveVertical" > <FullScreenModalLayout> {/* HEADER */} <FullScreenModalLayout.Header startNode={ <CloseButton skin="dark" size="large" onClick={closeModal} /> } endNode={ <TextButton size="small" onClick={closeModal}> Save </TextButton> } > <Text size="small" weight="normal"> New dish </Text> </FullScreenModalLayout.Header> {/* CONTENT */} <FullScreenModalLayout.Content padding> <Box direction="vertical" gap="24px"> <FormField label="Image"> <ImageViewer width="100%" height="176px" /> </FormField> <FormField label="Name"> <Input value="My New Dish" /> </FormField> <FormField label="Price"> <Input value="0" prefix={<Input.Affix>$</Input.Affix>} /> </FormField> <FormField label="Description"> <InputArea placeholder="Describe your dish in a few sentences." resizable rows={3} /> </FormField> <FormField label="Dietary preferences" infoContent="Choose which dietary preferences your dish is appropriate for." > <Box direction="vertical" gap="12px"> <Checkbox>No salt</Checkbox> <Checkbox>Vegan</Checkbox> <Checkbox>Vegetarian</Checkbox> <Checkbox>Gluten free</Checkbox> <Checkbox>Organic</Checkbox> <Checkbox>Spicy</Checkbox> </Box> </FormField> <FormField label="Visibility"> <Checkbox checked>Visible on site</Checkbox> </FormField> <FormField label="Availability"> <Checkbox checked>In stock</Checkbox> </FormField> </Box> </FullScreenModalLayout.Content> {/* FOOTER */} <FullScreenModalLayout.Footer> <StorybookComponents.Stack spacing="12px" width="100%"> <Button fullWidth priority="secondary" onClick={closeModal}> Cancel </Button> <Button fullWidth onClick={closeModal}> Create dish </Button> </StorybookComponents.Stack> </FullScreenModalLayout.Footer> </FullScreenModalLayout> </Modal> </StorybookComponents.Stack> ); }; ``` ### Push screens - description: <p>You can use <code>FullScreenModalLayout</code> as push screens</p> - example: ```jsx () => { const [isOpen, setIsOpen] = React.useState(false); const [newsletter, setNewsletter] = React.useState(true); const open = () => setIsOpen(true); const close = () => setIsOpen(false); return ( <StorybookComponents.Stack> <Button onClick={open}>Show upgrade message</Button> <Modal isOpen={isOpen} onRequestClose={close} transition="moveHorizontal" > <FullScreenModalLayout> {/* Header */} <FullScreenModalLayout.Header startNode={ <CloseButton skin="dark" size="large" onClick={close} /> } > <Text size="small" weight="normal"> Upgrade to accept payments </Text> </FullScreenModalLayout.Header> {/* Content */} <FullScreenModalLayout.Content padding> <Layout cols={1} alignItems="vertical" gap="24px"> {/* Intro text */} <Text size="small"> Unlock secure online payments and help your business grow with a Business Basic plan. </Text> {/* Benefits list */} <Box direction="vertical" gap="12px"> <Text weight="bold">What you get:</Text> <Box direction="vertical" gap="6px"> <Text size="small">• Accept credit and debit card payments</Text> <Text size="small">• Automated invoice and tax handling</Text> <Text size="small">• Faster payouts to your bank</Text> </Box> </Box> {/* Optional settings */} <FormField label="Notifications"> <ToggleSwitch checked={newsletter} onChange={() => setNewsletter(!newsletter)} /> </FormField> <Box> <Text size="small" secondary> Enabling notifications helps you stay updated on payouts and payment changes. </Text> </Box> </Layout> </FullScreenModalLayout.Content> {/* Footer */} <FullScreenModalLayout.Footer> <StorybookComponents.Stack spacing="12px" width="100%"> <Button fullWidth priority="secondary" onClick={close} > Not now </Button> <Button fullWidth skin="premium" onClick={close} > Upgrade </Button> </StorybookComponents.Stack> </FullScreenModalLayout.Footer> </FullScreenModalLayout> </Modal> </StorybookComponents.Stack> ); }; ``` ### Multiple actions - description: <p></p> - example: ```jsx () => { const [shown, setShown] = React.useState(false); const openModal = () => setShown(true); const closeModal = () => setShown(false); return ( <Layout> <Cell span={6}> <Card> <Box direction="vertical" gap="1" paddingTop="2" paddingLeft="4" paddingRight="4" paddingBottom="2" > <Text secondary>From name:</Text> <Text weight="bold">User 1</Text> <Text secondary>Reply-to email:</Text> <Text weight="bold">user1@mail.com</Text> </Box> <Divider /> <Box padding="12px" align="center"> <TextButton onClick={openModal}>Confirm Email</TextButton> </Box> {/* Full Screen Modal */} <Modal isOpen={shown} onRequestClose={closeModal} transition="moveVertical" > <FullScreenModalLayout> {/* HEADER */} <FullScreenModalLayout.Header startNode={ <CloseButton skin="dark" size="large" onClick={closeModal} /> } endNode={ <TextButton size="small" onClick={closeModal}> Change Details </TextButton> } > <Text size="small" weight="normal"> Confirm your email address </Text> </FullScreenModalLayout.Header> {/* CONTENT */} <FullScreenModalLayout.Content padding> <StorybookComponents.Stack flexDirection="column" spacing="24px"> <Text> To make changes to your sender details, please confirm your email address. <br /> A confirmation code was sent to <b>user1@mail.com</b>. </Text> <FormField label="Confirmation Code"> <Input placeholder="XX-XXX-XX" /> </FormField> <Text> Didn’t get the code? <a>Send again</a> </Text> </StorybookComponents.Stack> </FullScreenModalLayout.Content> {/* FOOTER */} <FullScreenModalLayout.Footer> <StorybookComponents.Stack spacing="12px" width="100%"> <Button fullWidth onClick={closeModal}> Confirm </Button> <Button fullWidth priority="secondary" onClick={closeModal} > Cancel </Button> </StorybookComponents.Stack> </FullScreenModalLayout.Footer> </FullScreenModalLayout> </Modal> </Card> </Cell> </Layout> ); }; ```