From 4c483e9f041168c8b200cb03a8815537c27ca75a Mon Sep 17 00:00:00 2001 From: drolsen Date: Thu, 26 Apr 2018 00:32:58 -0700 Subject: [PATCH] Moves SgColorSwatches to be built after page load with fetch --- build/webpack/lib/colors-export.js | 7 - build/webpack/lib/postcss-plugins.js | 4 +- build/webpack/workflow/browser.js | 5 + package-lock.json | 22 +- package.json | 7 +- .../SgColorSwatch/SgColorSwatch.Container.js | 288 ++++++++++++------ .../molecules/SgColorSwatch/SgColorSwatch.jsx | 118 +------ .../SgColorSwatch/SgColorSwatch__Colors.json | 1 - .../template/ColorSwatches.colors | 34 +++ 9 files changed, 257 insertions(+), 229 deletions(-) delete mode 100644 source/styleguide/molecules/SgColorSwatch/SgColorSwatch__Colors.json create mode 100644 source/styleguide/molecules/SgColorSwatch/template/ColorSwatches.colors diff --git a/build/webpack/lib/colors-export.js b/build/webpack/lib/colors-export.js index dec1b13..11251b7 100644 --- a/build/webpack/lib/colors-export.js +++ b/build/webpack/lib/colors-export.js @@ -64,12 +64,5 @@ module.exports = postcss.plugin('colors-export', (files, filters, options) => /* Save JSON collection */ fs.writeFileSync(options.dest, JSON.stringify(jsonObject), 'utf8'); - - /* Set saved file's timestamp back 60 second to combat webpack-dev-server build loops */ - const now = Date.now() / 1000; - const then = now - 60; - fs.utimesSync(options.dest, then, then, (err) => { - if (err) throw err; - }); } ); \ No newline at end of file diff --git a/build/webpack/lib/postcss-plugins.js b/build/webpack/lib/postcss-plugins.js index b6ecb5c..732a84a 100644 --- a/build/webpack/lib/postcss-plugins.js +++ b/build/webpack/lib/postcss-plugins.js @@ -32,7 +32,7 @@ const ResolverFactory = require('enhanced-resolve/lib/ResolverFactory'); const NodeJsInputFileSystem = require('enhanced-resolve/lib/NodeJsInputFileSystem'); const CachedInputFileSystem = require('enhanced-resolve/lib/CachedInputFileSystem'); -const { source, styleguide } = require('../../lib/path-helpers'); +const { source, dest, styleguide } = require('../../lib/path-helpers'); const { resolve } = require('../workflow/shared'); @@ -56,7 +56,7 @@ const standard = [ mixins(), nested(), colorsExport(['colors.css'], ['--color-'], { - dest: styleguide('molecules/SgColorSwatch/SgColorSwatch__Colors.json') + dest: dest('assets/dlls/styleguide-colors.json') }), cssnext({ features: { diff --git a/build/webpack/workflow/browser.js b/build/webpack/workflow/browser.js index 30d0758..522b36a 100644 --- a/build/webpack/workflow/browser.js +++ b/build/webpack/workflow/browser.js @@ -34,6 +34,11 @@ module.exports = ( exclude: /static/, use: 'json-loader' }, + { + test: /\.colors$/, + exclude: /static/, + use: 'raw-loader' + }, { test: /\.md$/, exclude: /static/, diff --git a/package-lock.json b/package-lock.json index e0cdc74..54ed1c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8468,7 +8468,7 @@ "gulp-merge": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/gulp-merge/-/gulp-merge-0.1.0.tgz", - "integrity": "sha1-pGLuARd6jqfEYPDqia1ULsdSujc=", + "integrity": "sha1-5/q3Bhhh0DyJq4QWzeES+ofjTS0=", "dev": true, "requires": { "through2": "1.1.1" @@ -10096,7 +10096,7 @@ "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", "requires": { "node-fetch": "1.7.3", - "whatwg-fetch": "2.0.3" + "whatwg-fetch": "2.0.4" } }, "isstream": { @@ -11136,6 +11136,12 @@ "integrity": "sha512-k4NaW+vS7ytQn6MgJn3fYpQt20/mOgYM5Ft9BYMfQJDz2QT6yEeS9XJ8k2Nw8JTeWK/znPPW2n3UJGzyYEiMoA==", "dev": true }, + "markup-js": { + "version": "1.5.21", + "resolved": "https://registry.npmjs.org/markup-js/-/markup-js-1.5.21.tgz", + "integrity": "sha1-OJEocDpWWWRXTQ41fhQq3TvkbXk=", + "dev": true + }, "math-expression-evaluator": { "version": "1.2.17", "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", @@ -17280,6 +17286,12 @@ "unpipe": "1.0.0" } }, + "raw-loader": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", + "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", + "dev": true + }, "rc": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.5.tgz", @@ -21921,9 +21933,9 @@ } }, "whatwg-fetch": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", - "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" }, "whatwg-url": { "version": "6.4.0", diff --git a/package.json b/package.json index 72ec173..ce534c2 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "loader-utils": "^1.1.0", "lodash.startcase": "^4.4.0", "markdown-loader": "^2.0.2", + "markup-js": "^1.5.21", "npm-run-all": "^4.1.2", "null-loader": "^0.1.1", "offline-plugin": "^4.9.0", @@ -106,6 +107,7 @@ "prismjs": "^1.10.0", "progress-bar-webpack-plugin": "^1.9.3", "querystring": "^0.2.0", + "raw-loader": "^0.5.1", "reset-css": "^2.2.1", "run-sequence": "^2.2.1", "stats-webpack-plugin": "^0.6.2", @@ -128,14 +130,15 @@ "gulp-watch": "^5.0.0", "html-loader": "^0.5.5", "http-server": "^0.11.1", + "isomorphic-fetch": "^2.2.1", "minimatch": "^3.0.4", "object.assign": "^4.1.0", "pretty": "^2.0.0", "prop-types": "^15.6.0", "rand-token": "^0.4.0", "react": "^16.2.0", + "react-custom-scrollbars": "^4.2.1", "react-dom": "^16.2.0", - "react-element-to-string": "1.0.2", - "react-custom-scrollbars": "^4.2.1" + "react-element-to-string": "1.0.2" } } diff --git a/source/styleguide/molecules/SgColorSwatch/SgColorSwatch.Container.js b/source/styleguide/molecules/SgColorSwatch/SgColorSwatch.Container.js index 61e4af0..3c34e8c 100644 --- a/source/styleguide/molecules/SgColorSwatch/SgColorSwatch.Container.js +++ b/source/styleguide/molecules/SgColorSwatch/SgColorSwatch.Container.js @@ -1,6 +1,55 @@ import chroma from 'chroma-js'; +import Mark from 'markup-js'; +import fetch from 'isomorphic-fetch'; +import ColorSwatches from './template/ColorSwatches.colors'; -const createObject = (value) => { +require('es6-promise').polyfill(); + +/* Gets the contrast ratio between two colors */ +const getContrast = (color1, color2) => chroma.contrast(color1, color2); + +/* + ratio: contrast ratio returned by 'getContrast' above + size: text size for the test. WCAG traditionally tests 14pt and 18pt font for 'normal' and 'large' respectively + level: the level of the test (e.g 'A', 'AA', or 'AAA') +*/ +const runWCAGTest = (ratio, size, level) => { + switch (level) { + /* fun fact, 'A' WCAG standard does not have a contrast ratio criteria. */ + case 'A': + return 'PASS'; + + case 'AA': + if (size === 'large' && ratio > 3) { + return 'PASS'; + } else if (size === 'large--bold' && ratio > 3) { + return 'PASS'; + } else if (size === 'normal' && ratio > 4.5) { + return 'PASS'; + } + return 'FAIL'; + + case 'AAA': + if (size === 'large' && ratio > 4.5) { + return 'PASS'; + } else if (size === 'large--bold' && ratio > 4.5) { + return 'PASS'; + } else if (size === 'normal' && ratio > 7) { + return 'PASS'; + } + return 'FAIL'; + + default: + if (size === 'large' && ratio > 3) { + return 'PASS'; + } else if (size === 'normal' && ratio > 4.5) { + return 'PASS'; + } + return 'FAIL'; + } +}; + +const createObject = (value, contrastOne, contrastTwo, title) => { /* NOTE that HSL support scaffolding is exists in this function. However this component does not yet support recieving an HSL format. @@ -49,125 +98,172 @@ const createObject = (value) => { /* todo hsl */ } - return colorObject; -}; + if (title) { + colorObject.title = title; + } -/* Gets the contrast ratio between two colors */ -const getContrast = (color1, color2) => chroma.contrast(color1, color2); + if (contrastOne && contrastTwo) { + colorObject.contrastPrimary = getContrast(colorObject.hex, contrastOne); + colorObject.contrastSecondary = getContrast(colorObject.hex, contrastTwo); -/* - ratio: contrast ratio returned by 'getContrast' above - size: text size for the test. WCAG traditionally tests 14pt and 18pt font for 'normal' and 'large' respectively - level: the level of the test (e.g 'A', 'AA', or 'AAA') -*/ -const runWCAGTest = (ratio, size, level) => { - switch (level) { - /* fun fact, 'A' WCAG standard does not have a contrast ratio criteria. */ - case 'A': - return 'PASS'; + colorObject.double = []; + colorObject.tripple = []; - case 'AA': - if (size === 'large' && ratio > 3) { - return 'PASS'; - } else if (size === 'large--bold' && ratio > 3) { - return 'PASS'; - } else if (size === 'normal' && ratio > 4.5) { - return 'PASS'; + colorObject.double.primary = [ + { + name: 'normal', + value: runWCAGTest(colorObject.contrastPrimary, 'normal', 'AA') + }, + { + name: 'large--bold', + value: runWCAGTest(colorObject.contrastPrimary, 'large--bold', 'AA') + }, + { + name: 'large', + value: runWCAGTest(colorObject.contrastPrimary, 'large', 'AA') } - return 'FAIL'; + ]; - case 'AAA': - if (size === 'large' && ratio > 4.5) { - return 'PASS'; - } else if (size === 'large--bold' && ratio > 4.5) { - return 'PASS'; - } else if (size === 'normal' && ratio > 7) { - return 'PASS'; + colorObject.double.secondary = [ + { + name: 'normal', + value: runWCAGTest(colorObject.contrastSecondary, 'normal', 'AA') + }, + { + name: 'large--bold', + value: runWCAGTest(colorObject.contrastSecondary, 'large--bold', 'AA') + }, + { + name: 'large', + value: runWCAGTest(colorObject.contrastSecondary, 'large', 'AA') } - return 'FAIL'; + ]; - default: - if (size === 'large' && ratio > 3) { - return 'PASS'; - } else if (size === 'normal' && ratio > 4.5) { - return 'PASS'; + + colorObject.tripple.primary = [ + { + name: 'normal', + value: runWCAGTest(colorObject.contrastPrimary, 'normal', 'AAA') + }, + { + name: 'large--bold', + value: runWCAGTest(colorObject.contrastPrimary, 'large--bold', 'AAA') + }, + { + name: 'large', + value: runWCAGTest(colorObject.contrastPrimary, 'large', 'AAA') } - return 'FAIL'; + ]; + + colorObject.tripple.secondary = [ + { + name: 'normal', + value: runWCAGTest(colorObject.contrastSecondary, 'normal', 'AAA') + }, + { + name: 'large--bold', + value: runWCAGTest(colorObject.contrastSecondary, 'large--bold', 'AAA') + }, + { + name: 'large', + value: runWCAGTest(colorObject.contrastSecondary, 'large', 'AAA') + } + ]; } + + return colorObject; }; /* Binds the events to UI controls for color accessibility testing. */ const SgColorInit = (el) => { - const level = el.querySelector('.SgColorSwatch__controls--level'); - const weight = el.querySelector('.SgColorSwatch__controls--weight'); + fetch('assets/dlls/styleguide-colors.json', { method: 'GET' }) + .then((response) => response.json()) + .then((response) => { + const data = []; + data.colors = []; - const double = el.querySelectorAll('.SgColorSwatch__accessibility--double'); - const triple = el.querySelectorAll('.SgColorSwatch__accessibility--triple'); - const normal = el.querySelectorAll('.SgColorSwatch__accessibility__badge--normal'); - const largeBold = el.querySelectorAll('.SgColorSwatch__accessibility__badge--large--bold'); - const large = el.querySelectorAll('.SgColorSwatch__accessibility__badge--large'); + Object.keys(response).forEach((i) => { + data.colors.push(createObject( + response[i], + response.colorTextPrimary, + response.colorTextSecondary, + i + )); + }); - const search = el.querySelector('.SgColorSwatch__search'); + el.querySelector('.SgColorSwatch__wrapper').innerHTML = Mark.up(ColorSwatches, data); - let i = double.length; - let j = largeBold.length; + const level = el.querySelector('.SgColorSwatch__controls--level'); + const weight = el.querySelector('.SgColorSwatch__controls--weight'); - while (i--) { - triple[i].style.display = 'none'; - } + const double = el.querySelectorAll('.SgColorSwatch__accessibility--double'); + const triple = el.querySelectorAll('.SgColorSwatch__accessibility--triple'); + const normal = el.querySelectorAll('.SgColorSwatch__accessibility__badge--normal'); + const largeBold = el.querySelectorAll('.SgColorSwatch__accessibility__badge--large--bold'); + const large = el.querySelectorAll('.SgColorSwatch__accessibility__badge--large'); - while (j--) { - largeBold[j].style.display = 'none'; - large[j].style.display = 'none'; - } + const search = el.querySelector('.SgColorSwatch__search'); - const churn = () => { - const weightSelector = el.querySelectorAll(weight.options[weight.options.selectedIndex].value); - const levelSelector = el.querySelectorAll(level.options[level.options.selectedIndex].value); + let i = double.length; + let j = largeBold.length; - let m = weightSelector.length; - while (m--) { - normal[m].style.display = 'none'; - largeBold[m].style.display = 'none'; - large[m].style.display = 'none'; - weightSelector[m].removeAttribute('style'); - } + while (i--) { + triple[i].style.display = 'none'; + } - let l = levelSelector.length; - while (l--) { - double[l].style.display = 'none'; - triple[l].style.display = 'none'; - levelSelector[l].removeAttribute('style'); - } - }; - - level.addEventListener('change', () => { - churn(); - }); - - weight.addEventListener('change', () => { - churn(); - }); - - search.addEventListener('keyup', (e) => { - const query = e.target.value; - const colors = document.querySelectorAll('.SgColorSwatch'); - let o = colors.length; - // unable to consolidate to single loop - if (query.length === 0) { - while (o--) { - colors[o].style.display = ''; + while (j--) { + largeBold[j].style.display = 'none'; + large[j].style.display = 'none'; } - } else { - while (o--) { - if (!colors[o].dataset.colorName.toLowerCase().match(query.toLowerCase())) { - colors[o].style.display = 'none'; + + const churn = () => { + const weightSelector = el.querySelectorAll(weight.options[weight.options.selectedIndex].value); + const levelSelector = el.querySelectorAll(level.options[level.options.selectedIndex].value); + + let m = weightSelector.length; + while (m--) { + normal[m].style.display = 'none'; + largeBold[m].style.display = 'none'; + large[m].style.display = 'none'; + weightSelector[m].removeAttribute('style'); + } + + let l = levelSelector.length; + while (l--) { + double[l].style.display = 'none'; + triple[l].style.display = 'none'; + levelSelector[l].removeAttribute('style'); + } + }; + + level.addEventListener('change', () => { + churn(); + }); + + weight.addEventListener('change', () => { + churn(); + }); + + search.addEventListener('keyup', (e) => { + const query = e.target.value; + const colors = document.querySelectorAll('.SgColorSwatch'); + let o = colors.length; + // unable to consolidate to single loop + if (query.length === 0) { + while (o--) { + colors[o].style.display = ''; + } } else { - colors[o].style.display = ''; + while (o--) { + if (!colors[o].dataset.colorName.toLowerCase().match(query.toLowerCase())) { + colors[o].style.display = 'none'; + } else { + colors[o].style.display = ''; + } + } } - } - } - }); + }); + }); }; module.exports = { diff --git a/source/styleguide/molecules/SgColorSwatch/SgColorSwatch.jsx b/source/styleguide/molecules/SgColorSwatch/SgColorSwatch.jsx index aefa472..24931d0 100644 --- a/source/styleguide/molecules/SgColorSwatch/SgColorSwatch.jsx +++ b/source/styleguide/molecules/SgColorSwatch/SgColorSwatch.jsx @@ -1,6 +1,4 @@ -import SgHeading from '@sg-atoms/SgHeading/SgHeading'; -import { createObject, getContrast, runWCAGTest } from './SgColorSwatch.Container'; -import colorVars from './SgColorSwatch__Colors.json'; +import './SgColorSwatch.Container'; export const SgColorSwatch = (props) => { const { @@ -17,48 +15,7 @@ export const SgColorSwatch = (props) => { return ( - { - colorVars ? - Object.keys(colorVars).map((color, i) => { - const title = color; - const obj = createObject(colorVars[color]); - - /* contrast tests */ - const contrastPrimary = getContrast(obj.hex, colorVars.colorTextPrimary); - const contrastSecondary = getContrast(obj.hex, colorVars.colorTextSecondary); - - return ( - - - - - -
- Name -

{title}

-
-
- Hex -

{obj.hex}

-
-
- RGB - {obj.rgb.a ? -

{obj.rgb.r}, {obj.rgb.g}, {obj.rgb.b}, {obj.rgb.a}

:

{obj.rgb.r}, {obj.rgb.g}, {obj.rgb.b}

- } -
-
-
- ); - }) - : No colors passed to SgColorWatch - } + No colors passed to SgColorWatch
); }; @@ -78,70 +35,6 @@ SgColorSwatch.propTypes = { colors: PropTypes.object }; -const SgColorSwatch__accessibility = (props) => { - const { - tagName: Tag, - className, - variant, - children, - contrastPrimary, - contrastSecondary, - level, - ...attrs - } = props; - - const classStack = FcUtils.createClassStack([ - 'SgColorSwatch__accessibility', - `SgColorSwatch__accessibility--${variant}`, - level === 'A' && 'SgColorSwatch__accessibility--single', - level === 'AA' && 'SgColorSwatch__accessibility--double', - level === 'AAA' && 'SgColorSwatch__accessibility--triple', - className - ]); - - return ( - -
- {runWCAGTest(contrastPrimary, 'normal', level)} -
-
- {runWCAGTest(contrastPrimary, 'large--bold', level)} -
-
- {runWCAGTest(contrastPrimary, 'large', level)} -
-
- {runWCAGTest(contrastSecondary, 'normal', level)} -
-
- {runWCAGTest(contrastSecondary, 'large--bold', level)} -
-
- {runWCAGTest(contrastSecondary, 'large', level)} -
-
- ); -}; - -SgColorSwatch__accessibility.defaultProps = { - tagName: 'div', - level: 'AA' -}; - -SgColorSwatch__accessibility.propTypes = { - tagName: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.element, - PropTypes.func - ]), - className: PropTypes.string, - variant: PropTypes.string, - children: PropTypes.node, - contrastPrimary: PropTypes.number.isRequired, - contrastSecondary: PropTypes.number.isRequired, - level: PropTypes.string -}; - const SgColorSwatch__wrapper = FcUtils.createBasicComponent({ name: 'SgColorSwatch__wrapper', defaultProps: { @@ -149,13 +42,6 @@ const SgColorSwatch__wrapper = FcUtils.createBasicComponent({ } }); -const SgColorSwatch__panel = FcUtils.createBasicComponent({ - name: 'SgColorSwatch__panel', - defaultProps: { - tagName: 'div' - } -}); - export const SgColorSwatch__search = FcUtils.createBasicComponent({ name: 'SgColorSwatch__controls SgColorSwatch__search', defaultProps: { diff --git a/source/styleguide/molecules/SgColorSwatch/SgColorSwatch__Colors.json b/source/styleguide/molecules/SgColorSwatch/SgColorSwatch__Colors.json deleted file mode 100644 index b0a673a..0000000 --- a/source/styleguide/molecules/SgColorSwatch/SgColorSwatch__Colors.json +++ /dev/null @@ -1 +0,0 @@ -{"colorGenericBlue":"#003346","colorGenericGreen":"#358450","colorGenericRed":"#a40000","colorRed":"#fa0000","colorBlue":"#0000fa","colorTextPrimary":"#000","colorTextSecondary":"#fff","colorWhite":"#fff","colorGray":"#8c8c8c","colorBlack":"#000","colorAlpha 100":"rgb(0, 0, 0, 1)","colorAlpha 80":"rgb(0, 0, 0, 0.8)","colorAlpha 50":"rgb(0, 0, 0, 0.5)","colorAlpha 25":"rgb(0, 0, 0, 0.25)","colorAlpha 0":"rgb(0, 0, 0, 0)"} \ No newline at end of file diff --git a/source/styleguide/molecules/SgColorSwatch/template/ColorSwatches.colors b/source/styleguide/molecules/SgColorSwatch/template/ColorSwatches.colors new file mode 100644 index 0000000..f378801 --- /dev/null +++ b/source/styleguide/molecules/SgColorSwatch/template/ColorSwatches.colors @@ -0,0 +1,34 @@ +{{colors}} +
+
+ {{double.primary}} +
1}}style="display: none;"{{/if}}>{{value}}
+ {{/double.primary}} + {{double.secondary}} +
1}}style="display: none;"{{/if}}>{{value}}
+ {{/double.secondary}} +
+ +
+
+
Name
+

{{title}}

+
+
+
Hex
+

{{hex}}

+
+
+
RGB
+

{{rgb.r}}, {{rgb.g}}, {{rgb.b}}

+
+
+
+{{/colors}} \ No newline at end of file