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>
This commit is contained in:
Suzanne Aitchison 2022-05-05 14:32:35 +01:00 committed by GitHub
parent eeed96cf9c
commit 26af4d951a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 108 additions and 8 deletions

View file

@ -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;

View file

@ -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']),
};

View file

@ -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,
};

View file

@ -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
<iframe style="border: 1px solid rgba(0, 0, 0, 0.1);" width="100%" height="450" src="https://www.figma.com/embed?embed_host=share&url=https%3A%2F%2Fwww.figma.com%2Ffile%2FgHpwugeu9jFGW4d9u3ReuR%2FCrayons%3Fnode-id%3D456%253A215" allowfullscreen></iframe>
<iframe
style="border: 1px solid rgba(0, 0, 0, 0.1);"
width="100%"
height="450"
src="https://www.figma.com/embed?embed_host=share&url=https%3A%2F%2Fwww.figma.com%2Ffile%2FgHpwugeu9jFGW4d9u3ReuR%2FCrayons%3Fnode-id%3D456%253A215"
allowfullscreen
></iframe>