diff --git a/index.js b/index.js
deleted file mode 100644
index 4d75547..0000000
--- a/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// eslint-disable-next-line import/no-unresolved
-const bare = require('./dist/bare');
-
-// Only export the bare version, anything else should be imported from dist
-module.exports = bare;
diff --git a/package.json b/package.json
index 097056e..e66e11c 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "@takingitglobal/a11ize",
"repository": "https://github.com/takingitglobal/a11ize.git",
- "main": "index.js",
+ "main": "src/index.js",
"jsdelivr": "dist/with-react-cjs/index.js",
"version": "0.0.0-development",
"description": "A React and JS Accessibility Toolkit",
diff --git a/src/components/A11yWrapper.js b/src/components/A11yWrapper.js
deleted file mode 100644
index cb79f8b..0000000
--- a/src/components/A11yWrapper.js
+++ /dev/null
@@ -1,589 +0,0 @@
-// react button goes here
-import React, { useState, useEffect, useRef } from 'react';
-import PropTypes from 'prop-types';
-import cx from 'classnames';
-import {
- FaTextHeight,
- FaTextWidth,
- FaUniversalAccess,
- FaBan,
-} from 'react-icons/fa';
-
-import { MdFormatLineSpacing } from 'react-icons/md';
-import styles from './A11yWrapper.module.scss';
-import ColorizeFilter from '../ColorizeFilter';
-
-const i18n = {
- // eslint-disable-next-line global-require
- en: require('../i18n/en.yml'),
- // eslint-disable-next-line global-require
- fr: require('../i18n/fr.yml'),
-};
-
-const AccessibilityPanel = ({
- id,
- activePanels,
- heading,
- label,
- children: panelChildren,
-}) => {
- const panelId = id.split('-')[id.split('-').length - 1];
- return (
- activePanels.includes(panelId) && (
-
-
{heading}
-
-
{panelChildren}
-
- )
- );
-};
-
-AccessibilityPanel.propTypes = {
- id: PropTypes.string.isRequired,
- heading: PropTypes.string.isRequired,
- label: PropTypes.string.isRequired,
- children: PropTypes.element.isRequired,
- activePanels: PropTypes.arrayOf(PropTypes.string).isRequired,
-};
-
-const AccessibilityButton = ({
- id,
- children,
- dangerouslySet,
- lang = 'en',
- primaryColor = '#921d5b',
- secondaryColor = '#01364c',
- buttonColor = '#fff',
- activePanels,
-}) => {
- const [active, setActive] = useState(false);
- const contentRef = useRef();
- // font size
- const [fontScale, setFontScaleRaw] = useState(1);
- const setFontScale = (value) => {
- if (value >= 0.5 && value <= 2.0) {
- setFontScaleRaw(value);
- }
- };
- // font family
- const [fontFamily, setFontFamily] = useState('Default');
- // line height
- const [lineSpacing, setLineSpacingRaw] = useState(1);
- const setLineSpacing = (value) => {
- if (value >= 1 && value <= 2.0) {
- setLineSpacingRaw(value);
- }
- };
- // letter spacing
- const [letterSpacing, setLetterSpacingRaw] = useState(0);
- const setLetterSpacing = (value) => {
- if (value >= 0 && value <= 5) {
- setLetterSpacingRaw(value);
- }
- };
- // word spacing
- const [wordSpacing, setWordSpacingRaw] = useState(0);
- const setWordSpacing = (value) => {
- if (value >= 0 && value <= 10) {
- setWordSpacingRaw(value);
- }
- };
- // theme
- const [theme, setTheme] = useState('Default');
- // switches
- const [clickableHighlight, setClickableHighlight] = useState(false);
- const [tableOfContents, setTableOfContents] = useState(false);
-
- useEffect(() => {
- if (typeof document === 'object') {
- // modify definition of 1 rem
- document.documentElement.style.fontSize = `${fontScale}rem`;
- // push window resize event for polyfills
- if (typeof window === 'object') {
- const evt = document.createEvent('Event');
- evt.initEvent('resize', true, false);
- window.dispatchEvent(evt);
- }
- }
- }, [fontScale, fontFamily, lineSpacing, letterSpacing, wordSpacing]);
-
- // persist on page changes
- const restoreState = () => {
- if (typeof window === 'object') {
- const stateString = window.localStorage.getItem('a11y-state');
- const state = stateString ? JSON.parse(stateString) : {};
- // console.log(state);
- setActive(false);
- setFontScaleRaw(state.fontScale || 1);
- setFontFamily(state.fontFamily || 'Default');
- setLineSpacingRaw(state.lineSpacing || 1);
- setLetterSpacingRaw(state.letterSpacing || 0);
- setWordSpacingRaw(state.wordSpacing || 0);
- setTheme(state.theme || 'Default');
- setClickableHighlight(state.clickableHighlight || false);
- setTableOfContents(state.tableOfContents || false);
- }
- };
-
- // initial load
- const text = i18n[lang] ? i18n[lang] : i18n.en;
- useEffect(async () => {
- restoreState();
- // lazily load font
- await import('../opendyslexic.scss');
- }, []);
-
- useEffect(() => {
- if (typeof window === 'object') {
- const state = {
- fontScale,
- fontFamily,
- lineSpacing,
- letterSpacing,
- wordSpacing,
- theme,
- clickableHighlight,
- tableOfContents,
- };
- window.localStorage.setItem('a11y-state', JSON.stringify(state));
- }
- }, [
- fontScale,
- fontFamily,
- lineSpacing,
- letterSpacing,
- wordSpacing,
- theme,
- clickableHighlight,
- tableOfContents,
- ]);
-
- // i18n helpers
- const toggleText = (what, on) =>
- `${text.toggle} ${what.toLowerCase()} (${text.currently} ${
- on ? text.toggleOn : text.toggleOff
- })`;
- const increase = (what) => `${text.up} ${what.toLowerCase()}`;
- const decrease = (what) => `${text.down} ${what.toLowerCase()}`;
-
- const themes = ['Default', 'Bw', 'Wb', 'By', 'Yb', 'Brown'];
-
- const headers = contentRef.current
- ? Array.from(contentRef.current.querySelectorAll('h1, h2, h3, h4, h5, h6'))
- : [];
- let toc = '';
- let currentHeader = 0;
- headers.forEach((header) => {
- const level = Number.parseInt(header.tagName.substring(1), 10);
- if (level > currentHeader) {
- toc += new Array(level - currentHeader + 1).join('');
- } else if (level < currentHeader) {
- toc += new Array(currentHeader - level + 1).join('
');
- }
-
- let href = header.getAttribute('id');
- if (!href) {
- const slug = header.innerHTML.toLowerCase().replace(/[^0-9a-z]+/g, '-');
- header.setAttribute('id', slug);
- href = slug;
- }
- toc += `
-
- ${header.innerHTML}
-
- `;
- currentHeader = level;
- });
- if (currentHeader) toc += new Array(currentHeader + 1).join('');
-
- return (
- // menu
-
-
-
-
-
-
-
-
1 ? `${lineSpacing * 1.6}` : 'normal',
- }}
- ref={contentRef}
- >
- {tableOfContents && (
-
- )}
- {children}
- {dangerouslySet && (
-
- )}
-
-
- );
-};
-
-AccessibilityButton.propTypes = {
- id: PropTypes.string,
- children: PropTypes.element,
- dangerouslySet: PropTypes.string,
- lang: PropTypes.string,
- primaryColor: PropTypes.string,
- secondaryColor: PropTypes.string,
- buttonColor: PropTypes.string,
- activePanels: PropTypes.arrayOf(PropTypes.string),
-};
-
-AccessibilityButton.defaultProps = {
- id: 'a11ize',
- children: undefined,
- dangerouslySet: undefined,
- lang: 'en',
- primaryColor: '#921d5b',
- secondaryColor: '#01364c',
- buttonColor: '#fff',
- activePanels: [
- 'textsize',
- 'fontfamily',
- 'linespacing',
- 'letterspacing',
- 'wordspacing',
- 'contrast',
- 'clickables',
- 'toc',
- ],
-};
-
-export default AccessibilityButton;
diff --git a/src/components/A11yWrapper.stories.js b/src/components/A11yWrapper.stories.js
index c60d670..56688b3 100644
--- a/src/components/A11yWrapper.stories.js
+++ b/src/components/A11yWrapper.stories.js
@@ -1,7 +1,7 @@
import React from 'react';
// eslint-disable-next-line import/no-extraneous-dependencies
import { withKnobs, text } from '@storybook/addon-knobs';
-import A11yWrapper from './A11yWrapper';
+import A11yWrapper from '../index';
export default {
title: 'a11ize',
diff --git a/src/ColorizeFilter/index.js b/src/components/ColorizeFilter.js
similarity index 100%
rename from src/ColorizeFilter/index.js
rename to src/components/ColorizeFilter.js
diff --git a/src/components/Panel.js b/src/components/Panel.js
new file mode 100644
index 0000000..c6ea5ae
--- /dev/null
+++ b/src/components/Panel.js
@@ -0,0 +1,35 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import styles from './A11yWrapper.module.scss';
+
+const Panel = ({
+ id,
+ activePanels,
+ heading,
+ label,
+ children: panelChildren,
+}) => {
+ const panelId = id.split('-')[id.split('-').length - 1];
+ return (
+ activePanels.includes(panelId) && (
+
+
{heading}
+
+
{panelChildren}
+
+ )
+ );
+};
+
+Panel.propTypes = {
+ id: PropTypes.string.isRequired,
+ heading: PropTypes.string.isRequired,
+ label: PropTypes.string.isRequired,
+ children: PropTypes.element.isRequired,
+ activePanels: PropTypes.arrayOf(PropTypes.string).isRequired,
+};
+
+export default Panel;
diff --git a/src/index.js b/src/index.js
index 3bc656c..34ddd96 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,3 +1,562 @@
-const { A11yWrapper } = import('./components/A11yWrapper');
-// eslint-disable-next-line import/prefer-default-export
-export { A11yWrapper };
+// react button goes here
+import React, { useState, useEffect, useRef } from 'react';
+import PropTypes from 'prop-types';
+import cx from 'classnames';
+import {
+ FaTextHeight,
+ FaTextWidth,
+ FaUniversalAccess,
+ FaBan,
+} from 'react-icons/fa';
+import { MdFormatLineSpacing } from 'react-icons/md';
+
+import styles from './components/A11yWrapper.module.scss';
+import ColorizeFilter from './components/ColorizeFilter';
+import Panel from './components/Panel';
+
+// TODO: dynamic require to minimize bundle size
+const i18n = {
+ // eslint-disable-next-line global-require
+ en: require('./i18n/en.yml'),
+ // eslint-disable-next-line global-require
+ fr: require('./i18n/fr.yml'),
+};
+
+const A11yWrapper = ({
+ id,
+ children,
+ dangerouslySet,
+ lang = 'en',
+ primaryColor = '#921d5b',
+ secondaryColor = '#01364c',
+ buttonColor = '#fff',
+ activePanels,
+}) => {
+ const [active, setActive] = useState(false);
+ const contentRef = useRef();
+ // font size
+ const [fontScale, setFontScaleRaw] = useState(1);
+ const setFontScale = (value) => {
+ if (value >= 0.5 && value <= 2.0) {
+ setFontScaleRaw(value);
+ }
+ };
+ // font family
+ const [fontFamily, setFontFamily] = useState('Default');
+ // line height
+ const [lineSpacing, setLineSpacingRaw] = useState(1);
+ const setLineSpacing = (value) => {
+ if (value >= 1 && value <= 2.0) {
+ setLineSpacingRaw(value);
+ }
+ };
+ // letter spacing
+ const [letterSpacing, setLetterSpacingRaw] = useState(0);
+ const setLetterSpacing = (value) => {
+ if (value >= 0 && value <= 5) {
+ setLetterSpacingRaw(value);
+ }
+ };
+ // word spacing
+ const [wordSpacing, setWordSpacingRaw] = useState(0);
+ const setWordSpacing = (value) => {
+ if (value >= 0 && value <= 10) {
+ setWordSpacingRaw(value);
+ }
+ };
+ // theme
+ const [theme, setTheme] = useState('Default');
+ // switches
+ const [clickableHighlight, setClickableHighlight] = useState(false);
+ const [tableOfContents, setTableOfContents] = useState(false);
+
+ useEffect(() => {
+ if (typeof document === 'object') {
+ // modify definition of 1 rem
+ document.documentElement.style.fontSize = `${fontScale}rem`;
+ // push window resize event for polyfills
+ if (typeof window === 'object') {
+ const evt = document.createEvent('Event');
+ evt.initEvent('resize', true, false);
+ window.dispatchEvent(evt);
+ }
+ }
+ }, [fontScale, fontFamily, lineSpacing, letterSpacing, wordSpacing]);
+
+ // persist on page changes
+ const restoreState = () => {
+ if (typeof window === 'object') {
+ const stateString = window.localStorage.getItem('a11y-state');
+ const state = stateString ? JSON.parse(stateString) : {};
+ // console.log(state);
+ setActive(false);
+ setFontScaleRaw(state.fontScale || 1);
+ setFontFamily(state.fontFamily || 'Default');
+ setLineSpacingRaw(state.lineSpacing || 1);
+ setLetterSpacingRaw(state.letterSpacing || 0);
+ setWordSpacingRaw(state.wordSpacing || 0);
+ setTheme(state.theme || 'Default');
+ setClickableHighlight(state.clickableHighlight || false);
+ setTableOfContents(state.tableOfContents || false);
+ }
+ };
+
+ // initial load
+ const text = i18n[lang] ? i18n[lang] : i18n.en;
+ useEffect(async () => {
+ restoreState();
+ // lazily load font
+ await import('./opendyslexic.css');
+ }, []);
+
+ useEffect(() => {
+ if (typeof window === 'object') {
+ const state = {
+ fontScale,
+ fontFamily,
+ lineSpacing,
+ letterSpacing,
+ wordSpacing,
+ theme,
+ clickableHighlight,
+ tableOfContents,
+ };
+ window.localStorage.setItem('a11y-state', JSON.stringify(state));
+ }
+ }, [
+ fontScale,
+ fontFamily,
+ lineSpacing,
+ letterSpacing,
+ wordSpacing,
+ theme,
+ clickableHighlight,
+ tableOfContents,
+ ]);
+
+ // i18n helpers
+ const toggleText = (what, on) =>
+ `${text.toggle} ${what.toLowerCase()} (${text.currently} ${
+ on ? text.toggleOn : text.toggleOff
+ })`;
+ const increase = (what) => `${text.up} ${what.toLowerCase()}`;
+ const decrease = (what) => `${text.down} ${what.toLowerCase()}`;
+
+ const themes = ['Default', 'Bw', 'Wb', 'By', 'Yb', 'Brown'];
+
+ const headers = contentRef.current
+ ? Array.from(contentRef.current.querySelectorAll('h1, h2, h3, h4, h5, h6'))
+ : [];
+ let toc = '';
+ let currentHeader = 0;
+ headers.forEach((header) => {
+ const level = Number.parseInt(header.tagName.substring(1), 10);
+ if (level > currentHeader) {
+ toc += new Array(level - currentHeader + 1).join('');
+ } else if (level < currentHeader) {
+ toc += new Array(currentHeader - level + 1).join('
');
+ }
+
+ let href = header.getAttribute('id');
+ if (!href) {
+ const slug = header.innerHTML.toLowerCase().replace(/[^0-9a-z]+/g, '-');
+ header.setAttribute('id', slug);
+ href = slug;
+ }
+ toc += `
+
+ ${header.innerHTML}
+
+ `;
+ currentHeader = level;
+ });
+ if (currentHeader) toc += new Array(currentHeader + 1).join('');
+
+ return (
+ // menu
+
+
+
+
+
+
+
+
1 ? `${lineSpacing * 1.6}` : 'normal',
+ }}
+ ref={contentRef}
+ >
+ {tableOfContents && (
+
+ )}
+ {children}
+ {dangerouslySet && (
+
+ )}
+
+
+ );
+};
+
+A11yWrapper.propTypes = {
+ id: PropTypes.string,
+ children: PropTypes.element,
+ dangerouslySet: PropTypes.string,
+ lang: PropTypes.string,
+ primaryColor: PropTypes.string,
+ secondaryColor: PropTypes.string,
+ buttonColor: PropTypes.string,
+ activePanels: PropTypes.arrayOf(PropTypes.string),
+};
+
+A11yWrapper.defaultProps = {
+ id: 'a11ize',
+ children: undefined,
+ dangerouslySet: undefined,
+ lang: 'en',
+ primaryColor: '#921d5b',
+ secondaryColor: '#01364c',
+ buttonColor: '#fff',
+ activePanels: [
+ 'textsize',
+ 'fontfamily',
+ 'linespacing',
+ 'letterspacing',
+ 'wordspacing',
+ 'contrast',
+ 'clickables',
+ 'toc',
+ ],
+};
+
+export default A11yWrapper;
diff --git a/src/opendyslexic.scss b/src/opendyslexic.css
similarity index 100%
rename from src/opendyslexic.scss
rename to src/opendyslexic.css
diff --git a/src/with-react.js b/src/with-react.js
index 07ff5be..ac78b00 100644
--- a/src/with-react.js
+++ b/src/with-react.js
@@ -1,7 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import getBundleURL from './getBundleUrl';
-import A11yWrapper from './components/A11yWrapper';
+import A11yWrapper from './index';
// eslint-disable-next-line import/no-extraneous-dependencies
import 'regenerator-runtime/runtime';
diff --git a/webpack.config.js b/webpack.config.js
index 895b880..0008650 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -58,6 +58,10 @@ module.exports = [
},
],
},
+ {
+ test: /\.css$/,
+ loader: ['style-loader', 'css-loader'],
+ },
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
@@ -157,6 +161,10 @@ module.exports = [
},
],
},
+ {
+ test: /\.css$/,
+ loader: ['style-loader', 'css-loader'],
+ },
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
@@ -246,6 +254,10 @@ module.exports = [
},
],
},
+ {
+ test: /\.css$/,
+ loader: ['style-loader', 'css-loader'],
+ },
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,