Skip to content

Commit c797e9a

Browse files
Jack Allendiasbruno
Jack Allen
authored andcommitted
[added] Added custom overlayElement and contentElement.
1 parent fa98fcc commit c797e9a

File tree

4 files changed

+80
-34
lines changed

4 files changed

+80
-34
lines changed

Diff for: docs/index.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,16 @@ import ReactModal from 'react-modal';
153153

154154
contentRef={
155155
setContentRef
156-
/* Content ref callback. */}>
156+
/* Content ref callback. */}
157+
158+
overlayElement={
159+
(props, contentElement) => <div {...props}>{contentElement}</div>
160+
/* Custom Overlay element. */}
161+
162+
contentElement={
163+
(props, children) => <div {...props}>{children}</div>
164+
/* Custom Content element. */}
165+
>
157166
<p>Modal Content</p>
158167
</ReactModal>
159168
```

Diff for: specs/Modal.spec.js

+29-2
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,8 @@ export default () => {
237237
it("supports id prop", () => {
238238
const modal = renderModal({ isOpen: true, id: "id" });
239239
mcontent(modal)
240-
.id.includes("id")
241-
.should.be.ok();
240+
.id
241+
.should.be.eql("id");
242242
});
243243

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

259+
it("supports custom overlayElement", () => {
260+
const overlayElement = (props, contentElement) => (
261+
<div {...props} id="custom">
262+
{contentElement}
263+
</div>
264+
);
265+
266+
const modal = renderModal({ isOpen: true, overlayElement });
267+
const modalOverlay = moverlay(modal);
268+
269+
modalOverlay.id.should.eql("custom");
270+
});
271+
272+
it("supports custom contentElement", () => {
273+
const contentElement = (props, children) => (
274+
<div {...props} id="custom">
275+
{children}
276+
</div>
277+
);
278+
279+
const modal = renderModal({ isOpen: true, contentElement }, "hello");
280+
const modalContent = mcontent(modal);
281+
282+
modalContent.id.should.eql("custom");
283+
modalContent.textContent.should.be.eql("hello");
284+
});
285+
259286
it("supports overlayClassName", () => {
260287
const modal = renderModal({
261288
isOpen: true,

Diff for: src/components/Modal.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ class Modal extends Component {
6868
contentLabel: PropTypes.string,
6969
shouldCloseOnEsc: PropTypes.bool,
7070
overlayRef: PropTypes.func,
71-
contentRef: PropTypes.func
71+
contentRef: PropTypes.func,
72+
id: PropTypes.string,
73+
overlayElement: PropTypes.func,
74+
contentElement: PropTypes.func
7275
};
7376
/* eslint-enable react/no-unused-prop-types */
7477

@@ -84,7 +87,9 @@ class Modal extends Component {
8487
shouldCloseOnOverlayClick: true,
8588
shouldReturnFocusAfterClose: true,
8689
preventScroll: false,
87-
parentSelector: () => document.body
90+
parentSelector: () => document.body,
91+
overlayElement: (props, contentEl) => <div {...props}>{contentEl}</div>,
92+
contentElement: (props, children) => <div {...props}>{children}</div>
8893
};
8994

9095
static defaultStyles = {

Diff for: src/components/ModalPortal.js

+34-29
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ export default class ModalPortal extends Component {
6161
overlayRef: PropTypes.func,
6262
contentRef: PropTypes.func,
6363
id: PropTypes.string,
64+
overlayElement: PropTypes.func,
65+
contentElement: PropTypes.func,
6466
testId: PropTypes.string
6567
};
6668

@@ -343,37 +345,40 @@ export default class ModalPortal extends Component {
343345
}, {});
344346

345347
render() {
346-
const { id, className, overlayClassName, defaultStyles } = this.props;
348+
const { id, className, overlayClassName, defaultStyles, children } = this.props;
347349
const contentStyles = className ? {} : defaultStyles.content;
348350
const overlayStyles = overlayClassName ? {} : defaultStyles.overlay;
349351

350-
return this.shouldBeClosed() ? null : (
351-
<div
352-
ref={this.setOverlayRef}
353-
className={this.buildClassName("overlay", overlayClassName)}
354-
style={{ ...overlayStyles, ...this.props.style.overlay }}
355-
onClick={this.handleOverlayOnClick}
356-
onMouseDown={this.handleOverlayOnMouseDown}
357-
>
358-
<div
359-
id={id}
360-
ref={this.setContentRef}
361-
style={{ ...contentStyles, ...this.props.style.content }}
362-
className={this.buildClassName("content", className)}
363-
tabIndex="-1"
364-
onKeyDown={this.handleKeyDown}
365-
onMouseDown={this.handleContentOnMouseDown}
366-
onMouseUp={this.handleContentOnMouseUp}
367-
onClick={this.handleContentOnClick}
368-
role={this.props.role}
369-
aria-label={this.props.contentLabel}
370-
{...this.attributesFromObject("aria", this.props.aria || {})}
371-
{...this.attributesFromObject("data", this.props.data || {})}
372-
data-testid={this.props.testId}
373-
>
374-
{this.props.children}
375-
</div>
376-
</div>
377-
);
352+
if (this.shouldBeClosed()) {
353+
return null;
354+
}
355+
356+
const overlayProps = {
357+
ref: this.setOverlayRef,
358+
className: this.buildClassName("overlay", overlayClassName),
359+
style: { ...overlayStyles, ...this.props.style.overlay },
360+
onClick: this.handleOverlayOnClick,
361+
onMouseDown: this.handleOverlayOnMouseDown
362+
};
363+
364+
const contentProps = {
365+
id,
366+
ref: this.setContentRef,
367+
style: { ...contentStyles, ...this.props.style.content },
368+
className: this.buildClassName("content", className),
369+
tabIndex: "-1",
370+
onKeyDown: this.handleKeyDown,
371+
onMouseDown: this.handleContentOnMouseDown,
372+
onMouseUp: this.handleContentOnMouseUp,
373+
onClick: this.handleContentOnClick,
374+
role: this.props.role,
375+
"aria-label": this.props.contentLabel,
376+
...this.attributesFromObject("aria", this.props.aria || {}),
377+
...this.attributesFromObject("data", this.props.data || {}),
378+
"data-testid": this.props.testId
379+
};
380+
381+
const contentElement = this.props.contentElement(contentProps, children);
382+
return this.props.overlayElement(overlayProps, contentElement);
378383
}
379384
}

0 commit comments

Comments
 (0)