Skip to content

Commit

Permalink
[added] Added custom overlayElement and contentElement.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack Allen authored and diasbruno committed Aug 19, 2020
1 parent fa98fcc commit c797e9a
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 34 deletions.
11 changes: 10 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,16 @@ import ReactModal from 'react-modal';

contentRef={
setContentRef
/* Content ref callback. */}>
/* Content ref callback. */}

overlayElement={
(props, contentElement) => <div {...props}>{contentElement}</div>
/* Custom Overlay element. */}

contentElement={
(props, children) => <div {...props}>{children}</div>
/* Custom Content element. */}
>
<p>Modal Content</p>
</ReactModal>
```
Expand Down
31 changes: 29 additions & 2 deletions specs/Modal.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ export default () => {
it("supports id prop", () => {
const modal = renderModal({ isOpen: true, id: "id" });
mcontent(modal)
.id.includes("id")
.should.be.ok();
.id
.should.be.eql("id");
});

it("supports portalClassName", () => {
Expand All @@ -256,6 +256,33 @@ export default () => {
.should.be.ok();
});

it("supports custom overlayElement", () => {
const overlayElement = (props, contentElement) => (
<div {...props} id="custom">
{contentElement}
</div>
);

const modal = renderModal({ isOpen: true, overlayElement });
const modalOverlay = moverlay(modal);

modalOverlay.id.should.eql("custom");
});

it("supports custom contentElement", () => {
const contentElement = (props, children) => (
<div {...props} id="custom">
{children}
</div>
);

const modal = renderModal({ isOpen: true, contentElement }, "hello");
const modalContent = mcontent(modal);

modalContent.id.should.eql("custom");
modalContent.textContent.should.be.eql("hello");
});

it("supports overlayClassName", () => {
const modal = renderModal({
isOpen: true,
Expand Down
9 changes: 7 additions & 2 deletions src/components/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ class Modal extends Component {
contentLabel: PropTypes.string,
shouldCloseOnEsc: PropTypes.bool,
overlayRef: PropTypes.func,
contentRef: PropTypes.func
contentRef: PropTypes.func,
id: PropTypes.string,
overlayElement: PropTypes.func,
contentElement: PropTypes.func
};
/* eslint-enable react/no-unused-prop-types */

Expand All @@ -84,7 +87,9 @@ class Modal extends Component {
shouldCloseOnOverlayClick: true,
shouldReturnFocusAfterClose: true,
preventScroll: false,
parentSelector: () => document.body
parentSelector: () => document.body,
overlayElement: (props, contentEl) => <div {...props}>{contentEl}</div>,
contentElement: (props, children) => <div {...props}>{children}</div>
};

static defaultStyles = {
Expand Down
63 changes: 34 additions & 29 deletions src/components/ModalPortal.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ export default class ModalPortal extends Component {
overlayRef: PropTypes.func,
contentRef: PropTypes.func,
id: PropTypes.string,
overlayElement: PropTypes.func,
contentElement: PropTypes.func,
testId: PropTypes.string
};

Expand Down Expand Up @@ -343,37 +345,40 @@ export default class ModalPortal extends Component {
}, {});

render() {
const { id, className, overlayClassName, defaultStyles } = this.props;
const { id, className, overlayClassName, defaultStyles, children } = this.props;
const contentStyles = className ? {} : defaultStyles.content;
const overlayStyles = overlayClassName ? {} : defaultStyles.overlay;

return this.shouldBeClosed() ? null : (
<div
ref={this.setOverlayRef}
className={this.buildClassName("overlay", overlayClassName)}
style={{ ...overlayStyles, ...this.props.style.overlay }}
onClick={this.handleOverlayOnClick}
onMouseDown={this.handleOverlayOnMouseDown}
>
<div
id={id}
ref={this.setContentRef}
style={{ ...contentStyles, ...this.props.style.content }}
className={this.buildClassName("content", className)}
tabIndex="-1"
onKeyDown={this.handleKeyDown}
onMouseDown={this.handleContentOnMouseDown}
onMouseUp={this.handleContentOnMouseUp}
onClick={this.handleContentOnClick}
role={this.props.role}
aria-label={this.props.contentLabel}
{...this.attributesFromObject("aria", this.props.aria || {})}
{...this.attributesFromObject("data", this.props.data || {})}
data-testid={this.props.testId}
>
{this.props.children}
</div>
</div>
);
if (this.shouldBeClosed()) {
return null;
}

const overlayProps = {
ref: this.setOverlayRef,
className: this.buildClassName("overlay", overlayClassName),
style: { ...overlayStyles, ...this.props.style.overlay },
onClick: this.handleOverlayOnClick,
onMouseDown: this.handleOverlayOnMouseDown
};

const contentProps = {
id,
ref: this.setContentRef,
style: { ...contentStyles, ...this.props.style.content },
className: this.buildClassName("content", className),
tabIndex: "-1",
onKeyDown: this.handleKeyDown,
onMouseDown: this.handleContentOnMouseDown,
onMouseUp: this.handleContentOnMouseUp,
onClick: this.handleContentOnClick,
role: this.props.role,
"aria-label": this.props.contentLabel,
...this.attributesFromObject("aria", this.props.aria || {}),
...this.attributesFromObject("data", this.props.data || {}),
"data-testid": this.props.testId
};

const contentElement = this.props.contentElement(contentProps, children);
return this.props.overlayElement(overlayProps, contentElement);
}
}

0 comments on commit c797e9a

Please sign in to comment.