Skip to content

Commit

Permalink
Merge pull request #415 from dcos-labs/mp/portal-modals-anywhere
Browse files Browse the repository at this point in the history
Allow modals to choose which node they mount in
  • Loading branch information
mperrotti authored Oct 11, 2019
2 parents 189903f + 25b07e7 commit 4a9c7d0
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 4 deletions.
5 changes: 3 additions & 2 deletions packages/modal/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Modals can be dismissed by:

### Do

Disable primary actions until user can proceed
Disable primary actions until user can proceed.
Use `DangerButton` to indicate destructive actions.
Focus on the first input field.
Bind the return key to the primary action.
Expand All @@ -34,4 +34,5 @@ Use primary action labels that enforce what taking the action does.
Display an error message at the bottom of the modal body.
Center align text in the modal body.
Have sidebars in modals (use the tabbed navigation).
Use use labels that are ambiguous at first glance e.g. use “Delete user” instead of “Are you sure?" and “Delete”
Use labels that are ambiguous at first glance e.g. use “Delete user” instead of “Are you sure?" and “Delete”.
Put a dialog modal inside of a dialog modal.
22 changes: 20 additions & 2 deletions packages/modal/components/ModalBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ export interface ModalBaseProps {
* human-readable selector used for writing tests
*/
dataCy?: string;
/**
* which DOM node the modal will attach to
*/
overlayRoot?: HTMLElement;
/**
* the ID attribute that is passed to the modal dialog box
*/
id?: string;
}

const animationDuration = 250;
Expand All @@ -63,11 +71,20 @@ class ModalBase extends React.PureComponent<ModalBaseProps, {}> {
public onKeyDown(e) {
if (e.key === "Escape") {
this.props.onClose(e);
e.stopPropagation();
}
}

public render() {
const { children, isAnimated, size, isOpen, dataCy } = this.props;
const {
children,
isAnimated,
size,
isOpen,
dataCy,
overlayRoot,
id
} = this.props;
const modalSize = size || ModalSizes.M;

return (
Expand All @@ -78,7 +95,7 @@ class ModalBase extends React.PureComponent<ModalBaseProps, {}> {
>
{state => {
return (
<Overlay>
<Overlay overlayRoot={overlayRoot}>
<FocusLock>
<div
role="button"
Expand All @@ -97,6 +114,7 @@ class ModalBase extends React.PureComponent<ModalBaseProps, {}> {
role="dialog"
onKeyDown={this.onKeyDown}
tabIndex={-1}
id={id}
>
<ModalContents
isOpen={isOpen}
Expand Down
45 changes: 45 additions & 0 deletions packages/modal/stories/Modal.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,51 @@ storiesOf("Modal", module)
}
}
)
.add(
"FullscreenModal w/ dialog modal",
() => {
return (
<ModalStoryContainer>
{({ isOpen, onClose }) => (
<FullscreenModal
isOpen={isOpen}
onClose={onClose}
title="I am modal"
subtitle="Optional subtitle"
closeText="Dismiss"
ctaButton={
<PrimaryButton
onClick={action("handling CTA")}
aria-haspopup={true}
>
Continue
</PrimaryButton>
}
id="testId"
>
<ModalStoryContainer>
{({ isOpen, onClose }) => (
<DialogModal
isOpen={isOpen}
onClose={onClose}
title="I am modal"
overlayRoot={document.querySelector("#testId")}
>
<ModalContent />
</DialogModal>
)}
</ModalStoryContainer>
</FullscreenModal>
)}
</ModalStoryContainer>
);
},
{
info: {
propTables: [FullscreenModal]
}
}
)
.add(
"custom focused element",
() => (
Expand Down

0 comments on commit 4a9c7d0

Please sign in to comment.