Breaking up main stylesheet into per-component styles

This commit is contained in:
Jeff Avallone 2018-02-13 17:12:02 -05:00
parent 7238643740
commit 20adf55c11
17 changed files with 182 additions and 158 deletions

View File

@ -75,6 +75,7 @@
"json-loader": "^0.5.7",
"npm-run-all": "^4.1.2",
"postcss-cssnext": "^3.1.0",
"postcss-import": "^11.1.0",
"postcss-loader": "^2.1.0",
"raven-js": "^3.22.2",
"react": "^16.2.0",

View File

@ -1,5 +1,6 @@
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-cssnext')
]
};

View File

@ -1,6 +1,8 @@
import React from 'react';
import { translate, Trans } from 'react-i18next';
import './style.css';
const Footer = () => (
<footer>
<ul className="inline with-separator">

View File

@ -0,0 +1,11 @@
@import url('../../globals.css');
footer {
margin: var(--spacing-margin) 0;
& img {
vertical-align: text-top;
width: 80px;
height: 15px;
}
}

View File

@ -3,7 +3,6 @@
exports[`Header rendering 1`] = `
<header
data-banner="testing"
id="main"
>
<h1>
<a

View File

@ -1,10 +1,11 @@
import React from 'react';
import { translate, Trans } from 'react-i18next';
import style from './style.css';
import GithubIcon from 'feather-icons/dist/icons/github.svg';
const Header = () => (
<header id="main" data-banner={ process.env.BANNER }>
<header className={ style.header } data-banner={ process.env.BANNER }>
<h1>
<a href="/">Regexper</a>
</h1>

View File

@ -0,0 +1,63 @@
@import url('../../globals.css');
.header {
background: var(--color-green) linear-gradient(to bottom,
var(--color-green) 0%,
color(var(--color-green) shade(40%)) 100%);
box-shadow: 0 0 1rem var(--color-black);
padding: 0 var(--content-margin);
margin: 0 calc(-1 * var(--content-margin)) var(--spacing-margin) calc(-1 * var(--content-margin));
position: relative;
&:after {
content: attr(data-banner);
pointer-events: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: var(--header-height);
line-height: var(--header-height);
text-transform: uppercase;
text-align: center;
font-size: calc(var(--header-height) * 0.7);
font-weight: bold;
opacity: 0.2;
}
& h1 {
font-family: 'Bangers', 'cursive';
font-size: 4rem;
font-weight: normal;
display: inline-block;
margin: 0;
line-height: var(--header-height);
}
& a {
text-decoration: none;
display: inline-block;
}
& ul {
line-height: var(--header-height);
position: absolute;
top: 0;
right: var(--content-margin);
}
& li {
& a:hover,
& a:active {
text-decoration: underline;
}
& svg {
display: inline-block;
width: 1em;
height: 1em;
margin-right: 0.5rem;
vertical-align: text-top;
}
}
}

View File

@ -2,18 +2,14 @@
exports[`Message rendering 1`] = `
<div
className="message testing"
className=""
>
<div
className="header"
>
<div>
<h2>
Testing
</h2>
</div>
<div
className="content"
>
<div>
<p>
Message content
</p>
@ -23,18 +19,14 @@ exports[`Message rendering 1`] = `
exports[`Message rendering with icon 1`] = `
<div
class="message"
class=""
>
<div
class="header"
>
<div>
<h2>
Sample icon SVGTesting
</h2>
</div>
<div
class="content"
>
<div>
<p>
Message content
</p>

View File

@ -1,6 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import style from './style.css';
const renderIcon = icon => {
if (!icon) {
return;
@ -10,19 +12,21 @@ const renderIcon = icon => {
return <Icon/>;
};
const Message = ({ className, icon, heading, children }) => (
<div className={ ['message', className].filter(Boolean).join(' ') }>
<div className="header">
const Message = ({ type, icon, heading, children }) => (
<div className={ [ style.message, type && style[type] ].filter(Boolean).join(' ') }>
<div className={ style.header }>
<h2>{ renderIcon(icon) }{ heading }</h2>
</div>
<div className="content">
<div className={ style.content }>
{ children }
</div>
</div>
);
Message.propTypes = {
className: PropTypes.string,
type: PropTypes.oneOf([
'error'
]),
icon: PropTypes.oneOfType([
PropTypes.element,
PropTypes.func

View File

@ -0,0 +1,41 @@
@import url('../../globals.css');
.message {
background: var(--color-tan);
margin: var(--spacing-margin) 0;
& .header {
padding: var(--spacing-margin);
& h2 {
margin: 0;
}
& h2 svg {
margin-right: 0.5rem;
height: 3rem;
width: 3rem;
vertical-align: bottom;
}
}
& .content {
padding: var(--spacing-margin);
}
& p {
margin-top: 0;
margin-bottom: var(--spacing-margin) 0;
}
& p:last-child {
margin-bottom: 0;
}
&.error {
& .header {
background: var(--color-red);
color: var(--color-white);
}
}
}

View File

@ -2,9 +2,9 @@
exports[`RavenError rendering 1`] = `
<Message
className="error"
heading="translate(An error has occurred)"
icon={[Function]}
type="error"
>
<p>
<Trans

View File

@ -23,7 +23,7 @@ class RavenError extends React.Component {
render() {
const { t } = this.props;
return <Message className="error" icon={ AlertIcon } heading={ t('An error has occurred') }>
return <Message type="error" icon={ AlertIcon } heading={ t('An error has occurred') }>
<p><Trans i18nKey="This error has been logged">
This error has been logged. You may also <a href="#error-report" onClick={ this.reportError }>fill out a report</a>.
</Trans></p>

12
src/globals.css Normal file
View File

@ -0,0 +1,12 @@
:root {
--color-green: #bada55;
--color-brown: #6b6659;
--color-tan: #cbcbba;
--color-black: #000;
--color-white: #fff;
--color-red: #b3151a;
--header-height: 6rem;
--content-margin: 2rem;
--spacing-margin: 1rem;
}

View File

@ -9,7 +9,7 @@ import Footer from '../../components/Footer';
const Component = ({ t }) => ( // eslint-disable-line react/prop-types
<React.Fragment>
<Header/>
<Message className="error" icon={ AlertIcon } heading={ t('404 Page Not Found') }>
<Message type="error" icon={ AlertIcon } heading={ t('404 Page Not Found') }>
<p><Trans>The page you have requested could not be found</Trans></p>
</Message>
<Footer/>

View File

@ -10,7 +10,7 @@ const Component = () => (
<React.Fragment>
<Header/>
<noscript>
<Message className="error" icon={ AlertIcon } heading="JavaScript Required">
<Message type="error" icon={ AlertIcon } heading="JavaScript Required">
<p>You need to enable JavaScript to use Regexper.</p>
<p>Regexper and the tools used to create it are all open source. If you are concerned that the JavaScript being delivered is in any way malicious, please inspect the source by following the GitHub link in the header. There are two data collection tools integrated in the app:</p>
<ul>

View File

@ -1,17 +1,5 @@
@import url('//fonts.googleapis.com/css?family=Bangers&text=Regxpr');
:root {
--color-green: #bada55;
--color-brown: #6b6659;
--color-tan: #cbcbba;
--color-black: #000;
--color-white: #fff;
--color-red: #b3151a;
--header-height: 6rem;
--content-margin: 2rem;
--spacing-margin: 1rem;
}
@import url('./globals.css');
html {
font-size: 62.5%;
@ -25,83 +13,11 @@ body {
font-size: 1.6rem;
}
#main {
background: var(--color-green) linear-gradient(to bottom,
var(--color-green) 0%,
color(var(--color-green) shade(40%)) 100%);
box-shadow: 0 0 1rem var(--color-black);
padding: 0 var(--content-margin);
margin: 0 calc(-1 * var(--content-margin)) var(--spacing-margin) calc(-1 * var(--content-margin));
position: relative;
&:after {
content: attr(data-banner);
pointer-events: none;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: var(--header-height);
line-height: var(--header-height);
text-transform: uppercase;
text-align: center;
font-size: calc(var(--header-height) * 0.7);
font-weight: bold;
opacity: 0.2;
}
& h1 {
font-family: 'Bangers', 'cursive';
font-size: 4rem;
font-weight: normal;
display: inline-block;
margin: 0;
line-height: var(--header-height);
}
& a {
text-decoration: none;
display: inline-block;
}
& ul {
line-height: var(--header-height);
position: absolute;
top: 0;
right: var(--content-margin);
}
& li {
& a:hover,
& a:active {
text-decoration: underline;
}
& svg {
display: inline-block;
width: 1em;
height: 1em;
margin-right: 0.5rem;
vertical-align: text-top;
}
}
}
footer {
margin: var(--spacing-margin) 0;
& img {
vertical-align: text-top;
width: 80px;
height: 15px;
}
}
a {
color: inherit;
}
.inline {
ul.inline {
list-style: none;
margin: 0;
padding: 0;
@ -111,55 +27,15 @@ a {
display: inline-block;
white-space: nowrap;
}
}
.with-separator {
& li:after {
content: '//';
padding: 0 0.5rem;
}
& li:last-child:after {
content: '';
}
}
.message {
background: var(--color-tan);
margin: var(--spacing-margin) 0;
& .header {
padding: var(--spacing-margin);
& h2 {
margin: 0;
&.with-separator {
& li:after {
content: '//';
padding: 0 0.5rem;
}
& h2 svg {
margin-right: 0.5rem;
height: 3rem;
width: 3rem;
vertical-align: bottom;
}
}
& .content {
padding: var(--spacing-margin);
}
& p {
margin-top: 0;
margin-bottom: var(--spacing-margin) 0;
}
& p:last-child {
margin-bottom: 0;
}
&.error {
& .header {
background: var(--color-red);
color: var(--color-white);
& li:last-child:after {
content: '';
}
}
}

View File

@ -5743,7 +5743,7 @@ phantomjs-prebuilt@^2.1.10:
request-progress "^2.0.1"
which "^1.2.10"
pify@^2.0.0:
pify@^2.0.0, pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@ -6037,6 +6037,15 @@ postcss-image-set-polyfill@^0.3.5:
postcss "^6.0.1"
postcss-media-query-parser "^0.2.3"
postcss-import@^11.1.0:
version "11.1.0"
resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-11.1.0.tgz#55c9362c9192994ec68865d224419df1db2981f0"
dependencies:
postcss "^6.0.1"
postcss-value-parser "^3.2.3"
read-cache "^1.0.0"
resolve "^1.1.7"
postcss-initial@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-2.0.0.tgz#72715f7336e0bb79351d99ee65c4a253a8441ba4"
@ -6599,6 +6608,12 @@ react-test-renderer@^16.0.0-0:
object-assign "^4.1.1"
prop-types "^15.6.0"
read-cache@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774"
dependencies:
pify "^2.3.0"
read-chunk@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-1.0.1.tgz#5f68cab307e663f19993527d9b589cace4661194"
@ -6934,6 +6949,12 @@ resolve@1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
resolve@^1.1.7:
version "1.5.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
dependencies:
path-parse "^1.0.5"
restore-cursor@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"