From 26af4d951ac5e5bdeecc1478e82c2b955e0a68fe Mon Sep 17 00:00:00 2001 From: Suzanne Aitchison Date: Thu, 5 May 2022 14:32:35 +0100 Subject: [PATCH] Update crayons Modal to add sheet variant (#17576) * update Modal to add sheet variant * dont use prompt title for modal sheet stories, to better reflect intended purpose * Apply suggestions from code review Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com> Co-authored-by: Julianna Tetreault <32834804+juliannatetreault@users.noreply.github.com> --- app/assets/stylesheets/components/modals.scss | 24 +++++++ app/javascript/crayons/Modal/Modal.jsx | 6 ++ .../Modal/__stories__/Modal.stories.jsx | 62 ++++++++++++++++++- .../crayons/Modal/__stories__/modals.mdx | 24 ++++--- 4 files changed, 108 insertions(+), 8 deletions(-) diff --git a/app/assets/stylesheets/components/modals.scss b/app/assets/stylesheets/components/modals.scss index 0f4fc5ec3..0142ed830 100644 --- a/app/assets/stylesheets/components/modals.scss +++ b/app/assets/stylesheets/components/modals.scss @@ -124,6 +124,30 @@ } } + &--sheet { + height: 100%; + + .crayons-modal__box { + height: 100%; + max-height: 100%; + border-radius: 0; + } + + &.crayons-modal--left { + .crayons-modal__box { + position: absolute; + left: 0; + } + } + + &.crayons-modal--right { + .crayons-modal__box { + position: absolute; + right: 0; + } + } + } + &--prompt { @media (min-width: $breakpoint-s) { --modal-max-width: 480px; diff --git a/app/javascript/crayons/Modal/Modal.jsx b/app/javascript/crayons/Modal/Modal.jsx index 30c2717e4..98e8e8389 100644 --- a/app/javascript/crayons/Modal/Modal.jsx +++ b/app/javascript/crayons/Modal/Modal.jsx @@ -12,14 +12,18 @@ export const Modal = ({ className, title, prompt, + sheet, centered, noBackdrop, + sheetAlign = 'center', backdropDismissible = false, onClose = () => {}, focusTrapSelector = '.crayons-modal__box', }) => { const classes = classNames('crayons-modal', { [`crayons-modal--${size}`]: size && size !== 'medium', + [`crayons-modal--${sheetAlign}`]: sheet && sheetAlign !== 'center', + 'crayons-modal--sheet': sheet, 'crayons-modal--prompt': prompt, 'crayons-modal--centered': centered && prompt, 'crayons-modal--bg-dismissible': !noBackdrop && backdropDismissible, @@ -74,4 +78,6 @@ Modal.propTypes = { onClose: PropTypes.func, size: PropTypes.oneOf(['small', 'medium', 'large']), focusTrapSelector: PropTypes.string, + sheet: PropTypes.bool, + sheetAlign: PropTypes.oneOf(['center', 'left', 'right']), }; diff --git a/app/javascript/crayons/Modal/__stories__/Modal.stories.jsx b/app/javascript/crayons/Modal/__stories__/Modal.stories.jsx index 826690a85..5302c5c50 100644 --- a/app/javascript/crayons/Modal/__stories__/Modal.stories.jsx +++ b/app/javascript/crayons/Modal/__stories__/Modal.stories.jsx @@ -26,6 +26,19 @@ export default { defaultValue: { summary: 'default' }, }, }, + sheetAlign: { + type: 'select', + options: { + 'Center (default)': 'center', + Left: 'left', + Right: 'right', + }, + description: + 'Modals will default to showing in the center of the screen. When using the `sheet` variant, it is possible to position to left or right of screen', + table: { + defaultValue: { summary: 'center' }, + }, + }, noBackdrop: { description: 'Removes the default backdrop overlay.', table: { @@ -46,9 +59,16 @@ export default { defaultValue: { summary: false }, }, }, + sheet: { + description: + 'Special style to display the modal as full view height. Useful for larger chunks of content, and may be anchored to left or right of screen using the `align` prop', + table: { + defaultValue: { summary: false }, + }, + }, centered: { description: - 'In some cases it might be "nicer" to center Modals content. This will only work with `prompt` though.', + 'In some cases it might be "nicer" to center modal content. This will only work with `prompt` though.', table: { defaultValue: { summary: false }, }, @@ -104,6 +124,7 @@ Default.args = { backdropDismissible: false, prompt: false, centered: false, + sheet: false, }; export const Prompt = Template.bind({}); @@ -115,6 +136,7 @@ Prompt.args = { backdropDismissible: false, prompt: true, centered: false, + sheet: false, }; export const PromptCentered = Template.bind({}); @@ -126,6 +148,42 @@ PromptCentered.args = { backdropDismissible: false, prompt: true, centered: true, + sheet: false, +}; + +export const Sheet = Template.bind({}); +Sheet.args = { + size: undefined, + title: 'Modal title', + noBackdrop: false, + backdropDismissible: false, + prompt: false, + centered: false, + sheet: true, +}; + +export const SheetLeftAligned = Template.bind({}); +SheetLeftAligned.args = { + size: undefined, + title: 'Modal title', + noBackdrop: false, + backdropDismissible: false, + prompt: false, + centered: false, + sheet: true, + sheetAlign: 'left', +}; + +export const SheetRightAligned = Template.bind({}); +SheetRightAligned.args = { + size: undefined, + title: 'Modal title', + noBackdrop: false, + backdropDismissible: false, + prompt: false, + centered: false, + sheet: true, + sheetAlign: 'right', }; export const BackdropDismissible = Template.bind({}); @@ -136,6 +194,7 @@ BackdropDismissible.args = { backdropDismissible: true, prompt: false, centered: false, + sheet: false, }; export const NoBackdrop = Template.bind({}); @@ -146,4 +205,5 @@ NoBackdrop.args = { backdropDismissible: false, prompt: false, centered: false, + sheet: false, }; diff --git a/app/javascript/crayons/Modal/__stories__/modals.mdx b/app/javascript/crayons/Modal/__stories__/modals.mdx index f13fe82ed..ddfb7d6f7 100644 --- a/app/javascript/crayons/Modal/__stories__/modals.mdx +++ b/app/javascript/crayons/Modal/__stories__/modals.mdx @@ -11,14 +11,18 @@ We have 3 possible sizes to use: - Small - 480px - for displaying small amount of data/text. - Medium - 640px (this is default one) - you will probably want to use this one in most cases. -- Large - 768px - use for long and/or complex contnet. +- Large - 768px - use for long and/or complex content. + +## Sheets + +Sheets are a special variant of the modal, which will occupy the full height of the screen. Sheets may also be anchored to the left or right side of the page by using the `sheetAlign` prop. ## Prompts -Except classic Modals you can also use `prompt` style (prop) to apply _special styling_. +Classic modals excluded, you can also use the `prompt` style (prop) to apply _special styling_. It will work best with really short messages or some sort of confirmation prompts, for example: -> Are you sure you want to remove Ben's account? +> Are you sure you want to remove Ben's account? > > [YES] [NO] @@ -29,13 +33,13 @@ The "special styling" means it will: ### Centered prompt -Some prompts may visually benefit from centering the content. -Leave the decision to designers but keep it mind this is possible with `centered` prop +Some prompts may visually benefit from centering the content. +Leave the decision to designers but keep in mind this is possible with `centered` prop (and it will only work in combination with `prompt`). ## Backdrop -By default Modals come with dark backdrop (a layer overlaying underlaying content). +By default, Modals come with a dark backdrop (a layer overlaying underlaying content). It is possible to not show it but it should be used in some very rare scenarios, when underlaying content might still be important as additional context. @@ -56,4 +60,10 @@ The Preact Modal component utilises the `focus-trap` library to ensure that: ## Design - +