Skip to content

Commit

Permalink
Clarify how Modal and FormLayout can be composed together
Browse files Browse the repository at this point in the history
  • Loading branch information
adamkudrna committed Feb 28, 2023
1 parent d4ea296 commit ff6205b
Showing 1 changed file with 62 additions and 46 deletions.
108 changes: 62 additions & 46 deletions src/lib/components/Modal/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from 'docz'
import {
Button,
CheckboxField,
FormLayout,
Modal,
ModalBody,
Expand Down Expand Up @@ -666,57 +667,61 @@ On top of that, the modal can adjust to the width of its content.
}}
</Playground>

👉 Please note the auto width may not function correctly in combination with
other auto-layout mechanisms, e.g. the auto-width
[FormLayout](/components/form-layout#label-width). It's just too much
magic that doesn't work together (yet?) 🎩.
## Position

👉 Beware of horizontal FormLayout inside `small` modals. While automatic
overflow handling comes to the rescue in this kind of scenario, you will be
better off with the combination of auto-sized modal and horizontal FormLayout
with a fixed label width (i.e. any other than `auto`, see the previous note).
Modal can be aligned either to the top or center of the screen.

<Playground>
{() => {
const [modalOpen, setModalOpen] = React.useState(false);
const [modalPosition, setModalPosition] = React.useState('center');
const modalPrimaryButtonRef = React.useRef();
const modalCloseButtonRef = React.useRef();
return (
<>
<Button
label="Launch auto-with modal with a form"
onClick={() => setModalOpen(true)}
label="Launch modal at center"
onClick={() => {
setModalPosition('center');
setModalOpen(true);
}}
/>
<Button
label="Launch modal at top"
onClick={() => {
setModalPosition('top');
setModalOpen(true);
}}
/>
<div>
{modalOpen && (
<Modal
closeButtonRef={modalCloseButtonRef}
position={modalPosition}
primaryButtonRef={modalPrimaryButtonRef}
size="auto"
>
<ModalHeader>
<ModalTitle>Form inside modal</ModalTitle>
<ModalTitle>Delete the user?</ModalTitle>
<ModalCloseButton onClick={() => setModalOpen(false)} />
</ModalHeader>
<ModalBody>
<ModalContent>
<FormLayout fieldLayout="horizontal">
<TextField label="A form element" />
<TextField label="Another form element" />
<TextField label="Yet another one" />
</FormLayout>
<p>
Do you really want to delete the user <code>admin</code>?
This cannot be undone.
</p>
</ModalContent>
</ModalBody>
<ModalFooter>
<Button
color="primary"
label="Save"
color="danger"
label="Delete"
onClick={() => setModalOpen(false)}
ref={modalPrimaryButtonRef}
/>
<Button
color="secondary"
label="Cancel"
label="Close"
onClick={() => setModalOpen(false)}
priority="outline"
ref={modalCloseButtonRef}
Expand All @@ -730,61 +735,64 @@ with a fixed label width (i.e. any other than `auto`, see the previous note).
}}
</Playground>

## Position
## Forms in Modals

Modal can be aligned either to the top or center of the screen.
You can safely place a FormLayout into a Modal of any size, including the
auto-width Modal.

<Playground>
{() => {
const [modalOpen, setModalOpen] = React.useState(false);
const [modalPosition, setModalPosition] = React.useState('center');
const [agree, setAgree] = React.useState(true);
const modalPrimaryButtonRef = React.useRef();
const modalCloseButtonRef = React.useRef();
return (
<>
<Button
label="Launch modal at center"
onClick={() => {
setModalPosition('center');
setModalOpen(true);
}}
/>
<Button
label="Launch modal at top"
onClick={() => {
setModalPosition('top');
setModalOpen(true);
}}
label="Launch auto-width modal with auto-width form"
onClick={() => setModalOpen(true)}
/>
<div>
{modalOpen && (
<Modal
closeButtonRef={modalCloseButtonRef}
position={modalPosition}
primaryButtonRef={modalPrimaryButtonRef}
size="auto"
>
<ModalHeader>
<ModalTitle>Delete the user?</ModalTitle>
<ModalTitle>Auto-width form inside auto-width modal</ModalTitle>
<ModalCloseButton onClick={() => setModalOpen(false)} />
</ModalHeader>
<ModalBody>
<ModalContent>
<p>
Do you really want to delete the user <code>admin</code>?
This cannot be undone.
</p>
<FormLayout autoWidth fieldLayout="horizontal">
<TextField
label="A form element"
validationState="warning"
validationText={`Account with this name already exists,
pick a different one.`
}
/>
<TextField label="Another form element" />
<TextField label="Yet another one" />
<CheckboxField
checked={agree}
label="I agree"
onChange={() => setAgree(!agree)}
/>
</FormLayout>
</ModalContent>
</ModalBody>
<ModalFooter>
<Button
color="danger"
label="Delete"
color="primary"
label="Save"
onClick={() => setModalOpen(false)}
ref={modalPrimaryButtonRef}
/>
<Button
color="secondary"
label="Close"
label="Cancel"
onClick={() => setModalOpen(false)}
priority="outline"
ref={modalCloseButtonRef}
Expand All @@ -798,6 +806,14 @@ Modal can be aligned either to the top or center of the screen.
}}
</Playground>

👉 Inside Modal, we recommend using the `autoWidth` option of FormLayout. This
prevents the Modal from unwanted horizontal expansion when a long validation
text pops up during user's interaction with the form.

👉 Beware of horizontal FormLayout inside `small` modals. While automatic
overflow handling comes to the rescue in this kind of scenario, you will be
better off with the combination of auto-sized modal and horizontal FormLayout.

## Keyboard Control

Modal can be controlled either by mouse or keyboard. To enhance user
Expand All @@ -809,8 +825,8 @@ To enable it, you just need to pass a reference to the buttons using
a reference to the button is that if the button is disabled, the key press will
not fire the event.

👉 We strongly recommend using this feature together with Autofocus for a better
user experience.
👉 We strongly recommend using this feature together with
[Autofocus](#autofocus) for a better user experience.

## Autofocus

Expand Down

0 comments on commit ff6205b

Please sign in to comment.