Add Modal component guideline#1033
Conversation
- Add stories/modal.guideline.mdx with full usage documentation:
roles, close behavior, size rules, footer constraints, destructive
modal patterns, async handling, and forbidden patterns
- Rewrite stories/modal.stories.tsx with correct button labels,
proper footer alignment (flex-end), and a DestructiveModal story
- Update .storybook/preview.js storySort to display Guideline
before stories for all components
Hello cuervino,My role is to assist you with the merge of this Available options
Available commands
Status report is not available. |
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
Peer approvals must include at least 1 approval from the following list: |
| - `title` is always required and always text. It mirrors the verb of the action that triggered the modal: the button "Delete node" opens a modal titled "Delete node?". | ||
| - For standard modals, the title describes the action: "Edit settings", "Create bucket". | ||
| - For destructive or irreversible actions, the title is phrased as a question: "Delete node?", "Revoke access?". The question mark signals that a decision is required. | ||
| - `subTitle` is used for step indicators in multi-step modals only (e.g. `"Step 1/2"`). |
There was a problem hiding this comment.
This is opposed to:
❌ Do not use a modal for:
- Multi-step flows — use a full page or wizard instead
Are we missing some use case where we allow multi-steps modals ?
There was a problem hiding this comment.
I believe the subtitle attribute is shared by both the modal and the full-page form component.
However, I suspect the modal header might not actually use it for descriptive text (at least not in the standard sense). It’s possible it’s being only used for the '* indicates required fields' disclaimer.
I'll remove this mention to the multi-step modal. The Download modal is the only kind of multistep modal I can think of, but we don't display steps per say.
There was a problem hiding this comment.
Done — I've removed the multi-step reference from subTitle. The description now reflects its actual role: it occupies the header slot when no close button is present, and can be used for contextual information such as a step indicator or a required-fields disclaimer.
| ## Role: `dialog` vs `alertdialog` | ||
|
|
||
| The `role` prop controls how assistive technologies treat the modal and defines the dismissal behavior. | ||
|
|
||
| | `role` | When to use | ESC closes it | Close button | | ||
| |---|---|---|---| | ||
| | `dialog` (default) | Standard interaction — form, optional confirmation | Yes | Present | | ||
| | `alertdialog` | Critical or destructive action requiring a forced decision | No | Omit | | ||
|
|
||
| Use `alertdialog` when accidentally dismissing the modal would be dangerous or meaningless (e.g. a delete confirmation — ESC should not silently cancel the user's intent). | ||
|
|
||
| ## Close button and backdrop | ||
|
|
||
| - The **close button** (×) in the header is present by default via the `close` prop. Omit it only when using `role="alertdialog"` — the user must explicitly choose an action. | ||
| - **Clicking the backdrop never closes the modal.** This prevents accidental data loss, especially in forms. | ||
| - **ESC** closes `dialog`-role modals. It does not close `alertdialog`-role modals. |
There was a problem hiding this comment.
I'm unsure about those esc key rules. I'm afraid it can restricts accessibility.
There was a problem hiding this comment.
Do you mean you are pro or against it?
There was a problem hiding this comment.
I think I get the concern, but I don't think it's actually a trap -- WCAG 2.1.2 doesn't require ESC specifically, just that keyboard users can get out. And they can, via the footer buttons. The whole point of blocking ESC on an alertdialog is to force an explicit choice, not to trap anyone. Is that what you were talking about?
| ## Forbidden patterns | ||
|
|
||
| - **No modal on top of another modal.** If a flow requires a second modal, redesign as a full page or wizard. | ||
| - **No event-triggered modals** at the application level (login, WebSocket events, etc.) — race conditions between modals create an uncontrollable stacking experience. |
There was a problem hiding this comment.
We have the ISV exception case.
There was a problem hiding this comment.
Yeah, indeed, I'll say that we need to limit it, not to forbid it.
There was a problem hiding this comment.
Good point, I changed 'No' to 'Avoid' -- less absolute, leaves room for edge cases without making them a recommendation in the guideline.
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
Peer approvals must include at least 1 approval from the following list: |
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
Peer approvals must include at least 1 approval from the following list: |
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
Peer approvals must include at least 1 approval from the following list: |
|
/approve |
In the queueThe changeset has received all authorizations and has been added to the The changeset will be merged in:
There is no action required on your side. You will be notified here once IMPORTANT Please do not attempt to modify this pull request.
If you need this pull request to be removed from the queue, please contact a The following options are set: approve |
|
I have successfully merged the changeset of this pull request
Please check the status of the associated issue None. Goodbye cuervino. |
Description
This PR introduces the first complete design guideline for the Modal component in Storybook, along with a rewrite of the existing stories to match the documented
conventions.
The
modal.mdxfile that previously existed was a placeholder (a single Canvas and two story references with no documentation). It has been replaced bymodal.guideline.mdx, a full guideline covering all usage decisions for the component.The
modal.stories.tsxfile has been rewritten: the existing stories used"Yes"/"No"as button labels, which violates themodal-button-forbidden-labelvalalintrule. Footer alignment was also incorrect (
space-betweeninstead offlex-end). A newDestructiveModalstory has been added to illustrate thealertdialogpattern.Change list
stories/modal.guideline.mdxstories/modal.mdxstories/modal.stories.tsx.storybook/preview.jsDesign
Guideline covers:
dialogvsalertdialog: when to use each, ESC behavior, close button presencealertdialogrole,dangervariant, resource name mandatory in body if it existsisLoadingunder 3s, contextual message over 3s, no modal for long operationsBreaking Changes
No