-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Modal component and integrate Mailchimp form #96
Changes from all commits
7670e6d
2059d40
5eed696
f2a578d
3a34ba0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import PropTypes from "prop-types"; | ||
import React from "react"; | ||
import ReactModal from "react-modal"; | ||
|
||
import s from "./Modal.module.css"; | ||
import closeIcon from "./close-icon.svg"; | ||
|
||
const Modal = ({ children, isOpen, setIsOpen, ariaHideApp, contentLabel }) => ( | ||
<ReactModal | ||
className={s.content} | ||
overlayClassName={s.overlay} | ||
isOpen={isOpen} | ||
onRequestClose={() => setIsOpen(false)} | ||
ariaHideApp={ariaHideApp} | ||
contentLabel={contentLabel} | ||
> | ||
<button | ||
className={s.closeButton} | ||
onClick={() => setIsOpen(false)} | ||
type="button" | ||
> | ||
<img src={closeIcon} alt="Close" /> | ||
</button> | ||
{children} | ||
</ReactModal> | ||
); | ||
|
||
Modal.propTypes = { | ||
children: PropTypes.node.isRequired, | ||
isOpen: PropTypes.bool.isRequired, | ||
setIsOpen: PropTypes.func.isRequired, | ||
ariaHideApp: PropTypes.bool, | ||
contentLabel: PropTypes.string.isRequired, | ||
}; | ||
|
||
Modal.defaultProps = { | ||
ariaHideApp: true, | ||
}; | ||
|
||
export default Modal; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
.overlay { | ||
background-color: rgba(0, 0, 0, 0.5); | ||
bottom: 0; | ||
left: 0; | ||
overflow: auto; | ||
position: fixed; | ||
right: 0; | ||
top: 0; | ||
} | ||
|
||
.content { | ||
background: var(--color-white); | ||
border-radius: 16px; | ||
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.2); | ||
box-sizing: border-box; | ||
margin: 80px auto 40px; | ||
max-width: 850px; | ||
outline: none; | ||
padding: 50px; | ||
position: relative; | ||
} | ||
|
||
.closeButton { | ||
background: none; | ||
border: 0; | ||
cursor: pointer; | ||
display: inline-block; | ||
padding: 0; | ||
position: absolute; | ||
right: 30px; | ||
top: 30px; | ||
} | ||
|
||
@media (--tablet-and-down) { | ||
.content { | ||
margin-left: 20px; | ||
margin-right: 20px; | ||
Comment on lines
+36
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Possible shorthand can be used? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't want to override the top and bottom margin settings from the non-media-query version of this, which are set to 80px and 40px respectively. |
||
padding: 35px 25px; | ||
} | ||
|
||
.closeButton { | ||
right: 25px; | ||
top: 25px; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import React, { useState } from "react"; | ||
|
||
import Modal from "./Modal"; | ||
|
||
export default { | ||
title: "Grid-Aware/Modal", | ||
component: Modal, | ||
}; | ||
|
||
const Template = () => { | ||
const [modalIsOpen, setModalIsOpen] = useState(true); | ||
return ( | ||
<div> | ||
<Modal | ||
isOpen={modalIsOpen} | ||
setIsOpen={setModalIsOpen} | ||
/* Disable ariaHideApp in Storybook to suppress warning about not | ||
* setting the app element. | ||
* https://github.com/reactjs/react-modal/issues/576 | ||
*/ | ||
ariaHideApp={false} | ||
contentLabel="Example Modal" | ||
> | ||
<div style={{ font: "var(--font-body-medium)" }}> | ||
<h1 style={{ font: "var(--font-headline)" }}>Work with Us</h1> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do | ||
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim | ||
ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut | ||
aliquip ex ea commodo consequat. Duis aute irure dolor in | ||
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla | ||
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in | ||
culpa qui officia deserunt mollit anim id est laborum. | ||
</p> | ||
</div> | ||
</Modal> | ||
<div> | ||
<button type="button" onClick={() => setModalIsOpen(!modalIsOpen)}> | ||
Toggle Modal | ||
</button> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export const DefaultModal = Template.bind({}); | ||
DefaultModal.args = {}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from "./Modal"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* This file contains global styles because we are overriding the default styles | ||
* that come from Mailchimp. */ | ||
/* stylelint-disable selector-max-id */ | ||
|
||
#mc_embed_signup form { | ||
padding: 0 !important; | ||
} | ||
|
||
#mc_embed_signup .mc-field-group { | ||
margin-bottom: 39px; | ||
padding-bottom: 0 !important; | ||
} | ||
|
||
#mc_embed_signup .mc-field-group label { | ||
font: var(--font-caption); | ||
margin-bottom: 10px !important; | ||
} | ||
|
||
#mc_embed_signup .mc-field-group input { | ||
border: 1px solid var(--color-gray-400); | ||
border-radius: 0; | ||
font: var(--font-body-small); | ||
padding: 16px 17px 15px !important; | ||
} | ||
|
||
#mc_embed_signup .button { | ||
background-color: var(--color-sheltertech-blue) !important; | ||
border-radius: 0 !important; | ||
color: var(--color-white) !important; | ||
font: var(--font-action) !important; | ||
height: auto !important; | ||
padding: 16px 40px !important; | ||
text-transform: uppercase; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import React from "react"; | ||
|
||
import "./VolunteerSignupForm.css"; | ||
import s from "./VolunteerSignupForm.module.css"; | ||
|
||
/* eslint-disable react/no-danger */ | ||
// This entire file is just about embedding an external form | ||
|
||
const rawInnerHtml = { | ||
__html: ` | ||
<!-- Begin Mailchimp Signup Form --> | ||
<link href="//cdn-images.mailchimp.com/embedcode/classic-10_7.css" rel="stylesheet" type="text/css"> | ||
<style type="text/css"> | ||
#mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; } | ||
/* Add your own Mailchimp form style overrides in your site stylesheet or in this style block. | ||
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */ | ||
</style> | ||
<div id="mc_embed_signup"> | ||
<form action="https://sheltertech.us19.list-manage.com/subscribe/post?u=c47829732a0bea5c8e8a94604&id=08f60e42ef" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate> | ||
<div id="mc_embed_signup_scroll"> | ||
|
||
<div class="mc-field-group"> | ||
<label for="mce-EMAIL">Email Address </label> | ||
<input type="email" value="" name="EMAIL" class="required email" id="mce-EMAIL"> | ||
</div> | ||
<div class="mc-field-group"> | ||
<label for="mce-FNAME">First Name </label> | ||
<input type="text" value="" name="FNAME" class="" id="mce-FNAME"> | ||
</div> | ||
<div class="mc-field-group"> | ||
<label for="mce-LNAME">Last Name </label> | ||
<input type="text" value="" name="LNAME" class="" id="mce-LNAME"> | ||
</div> | ||
<div class="mc-field-group"> | ||
<label for="mce-MMERGE12">Volunteer Interests </label> | ||
<input type="text" value="" name="MMERGE12" class="" id="mce-MMERGE12"> | ||
</div> | ||
<div id="mce-responses" class="clear"> | ||
<div class="response" id="mce-error-response" style="display:none"></div> | ||
<div class="response" id="mce-success-response" style="display:none"></div> | ||
</div> <!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups--> | ||
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_c47829732a0bea5c8e8a94604_08f60e42ef" tabindex="-1" value=""></div> | ||
<div class="clear"><input type="submit" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button"></div> | ||
</div> | ||
</form> | ||
</div> | ||
<script type='text/javascript' src='//s3.amazonaws.com/downloads.mailchimp.com/js/mc-validate.js'></script><script type='text/javascript'>(function($) {window.fnames = new Array(); window.ftypes = new Array();fnames[0]='EMAIL';ftypes[0]='email';fnames[1]='FNAME';ftypes[1]='text';fnames[2]='LNAME';ftypes[2]='text';fnames[3]='ADDRESS';ftypes[3]='address';fnames[4]='PHONE';ftypes[4]='phone';fnames[5]='BIRTHDAY';ftypes[5]='birthday';fnames[6]='MMERGE6';ftypes[6]='text';fnames[7]='MMERGE7';ftypes[7]='number';fnames[8]='MMERGE8';ftypes[8]='date';fnames[9]='MMERGE9';ftypes[9]='text';fnames[10]='LGL_SAL';ftypes[10]='text';fnames[11]='LGL_ID';ftypes[11]='text';fnames[12]='MMERGE12';ftypes[12]='text';}(jQuery));var $mcj = jQuery.noConflict(true);</script> | ||
<!--End mc_embed_signup--> | ||
`, | ||
}; | ||
|
||
const VolunteerSignupForm = () => ( | ||
<div> | ||
<h1 className={s.title}>Work With Us</h1> | ||
<p className={s.description}> | ||
Thank you for your interest in partnering with ShelterTech! Enter your | ||
contact information below and we'll get back to you shortly. | ||
</p> | ||
<div dangerouslySetInnerHTML={rawInnerHtml} /> | ||
</div> | ||
); | ||
export default VolunteerSignupForm; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
.title { | ||
font: var(--font-headline); | ||
margin-bottom: 20px; | ||
margin-top: 0; | ||
} | ||
|
||
.description { | ||
font: var(--font-body-medium); | ||
margin-bottom: 40px; | ||
margin-top: 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import React from "react"; | ||
|
||
import VolunteerSignupForm from "./VolunteerSignupForm"; | ||
|
||
export default { | ||
title: "Third Party/Mailchimp/VolunteerSignupForm", | ||
component: VolunteerSignupForm, | ||
}; | ||
|
||
const Template = () => ( | ||
<div style={{ maxWidth: "850px", padding: "50px" }}> | ||
<p | ||
style={{ | ||
fontStyle: "italic", | ||
backgroundColor: "var(--color-gray-300)", | ||
padding: "15px", | ||
}} | ||
> | ||
Note: This is a real form, and submitting it will really subscribe you to | ||
a Mailchimp list. | ||
</p> | ||
<VolunteerSignupForm /> | ||
</div> | ||
); | ||
|
||
export const Default = Template.bind({}); | ||
Default.args = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume you tried other methods in completely covering the whole view of the browser with the darkened hue of the modal but is there a shorter way to cover the whole screen than putting all bottom, top, left and right positions to 0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually didn't try anything else because I had copied these styles over from the default ones that the library comes with. I'm not sure if there's a shorter way to cover it, since it's
position: fixed
. You still need thetop: 0
since the element itself is placed based on where its parent is, not based on the page. Theright
and thebottom
could be replaced withwidth: 100vw
andheight: 100vh
, which doesn't save us much because it's a one-for-one tradeoff.You could possibly leave out
left:
, but it will only work if you don't have anything that pushes the modal's parent's position away from the left edge, which makes it a little bit riskier to do.Overall, I think setting the position across all four dimensions is pretty much as compact and reliable as we're going to get.