├── src ├── images │ ├── a11yfav.png │ └── demoapp.png ├── fonts │ ├── Inter-Black.woff │ ├── Inter-Black.woff2 │ ├── work-sans-v4-latin-600.woff │ ├── work-sans-v4-latin-800.woff │ ├── work-sans-v4-latin-600.woff2 │ ├── work-sans-v4-latin-800.woff2 │ ├── merriweather-v19-latin-300.woff │ ├── merriweather-v19-latin-300.woff2 │ ├── merriweather-v19-latin-300italic.woff │ └── merriweather-v19-latin-300italic.woff2 ├── components │ ├── stage.js │ ├── editText.js │ ├── pattern-details.js │ ├── image.js │ ├── about.js │ ├── arrow.js │ ├── demoApp.js │ ├── challenges.js │ ├── Intro.js │ ├── newsletterSignup.js │ ├── header.js │ ├── patterns-all.js │ ├── patterns.js │ ├── layout.js │ ├── seo.js │ └── layout.css ├── pages │ ├── 404.js │ ├── patterns.js │ └── index.js ├── html.js └── templates │ ├── longread.js │ └── pattern.js ├── gatsby-browser.js ├── static └── images │ ├── a11yappscreenshot.png │ └── a11yappscreenshot_larger.png ├── content ├── demo-app.md ├── intro.md ├── patterns │ ├── teaser-progress.md │ ├── teaser-routing.md │ ├── teaser-animation.md │ ├── teaser-menu.md │ ├── teaser-notifications.md │ ├── teaser-modals.md │ └── vue │ │ ├── animation.md │ │ ├── notifications.md │ │ ├── menu.md │ │ ├── progress.md │ │ ├── modals.md │ │ └── routing.md ├── about.md └── longreads │ ├── contribute.md │ ├── people.md │ └── a11y-challenges.md ├── README.md ├── gatsby-ssr.js ├── .gitignore ├── package.json ├── gatsby-config.js ├── gatsby-node.js └── .eslintrc /src/images/a11yfav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/src/images/a11yfav.png -------------------------------------------------------------------------------- /src/images/demoapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/src/images/demoapp.png -------------------------------------------------------------------------------- /src/fonts/Inter-Black.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/src/fonts/Inter-Black.woff -------------------------------------------------------------------------------- /src/fonts/Inter-Black.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/src/fonts/Inter-Black.woff2 -------------------------------------------------------------------------------- /gatsby-browser.js: -------------------------------------------------------------------------------- 1 | // gatsby-browser.js 2 | 3 | export const onClientEntry = async () => { 4 | await import(`focus-visible`); 5 | }; 6 | -------------------------------------------------------------------------------- /src/fonts/work-sans-v4-latin-600.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/src/fonts/work-sans-v4-latin-600.woff -------------------------------------------------------------------------------- /src/fonts/work-sans-v4-latin-800.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/src/fonts/work-sans-v4-latin-800.woff -------------------------------------------------------------------------------- /static/images/a11yappscreenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/static/images/a11yappscreenshot.png -------------------------------------------------------------------------------- /src/fonts/work-sans-v4-latin-600.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/src/fonts/work-sans-v4-latin-600.woff2 -------------------------------------------------------------------------------- /src/fonts/work-sans-v4-latin-800.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/src/fonts/work-sans-v4-latin-800.woff2 -------------------------------------------------------------------------------- /src/fonts/merriweather-v19-latin-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/src/fonts/merriweather-v19-latin-300.woff -------------------------------------------------------------------------------- /src/fonts/merriweather-v19-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/src/fonts/merriweather-v19-latin-300.woff2 -------------------------------------------------------------------------------- /static/images/a11yappscreenshot_larger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/static/images/a11yappscreenshot_larger.png -------------------------------------------------------------------------------- /src/fonts/merriweather-v19-latin-300italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/src/fonts/merriweather-v19-latin-300italic.woff -------------------------------------------------------------------------------- /src/fonts/merriweather-v19-latin-300italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessible-app/accessible-app_com/HEAD/src/fonts/merriweather-v19-latin-300italic.woff2 -------------------------------------------------------------------------------- /src/components/stage.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Stage = props => ( 4 |
5 |
{props.children}
6 |
7 | ); 8 | 9 | export default Stage; 10 | -------------------------------------------------------------------------------- /content/demo-app.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: The Demo App "Accessibooks" 3 | type: demoapp 4 | --- 5 | 6 | Reading about patterns in theory only gets you so far – often times you need a concrete example to learn. This is why *Accessibooks* SPA exists. 7 | 8 | [Go to the version built in Vue](https://vuejs.accessible-app.com/)

9 | -------------------------------------------------------------------------------- /content/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Patterns & Strategies for accessible web-apps 3 | intro: Learn how to build inclusive web applications and Single Page Apps in modern JavaScript frameworks. This project collects strategies, links, patterns and plugins for React, Vue and Angular. 4 | type: intro 5 | --- 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # accessible-app.com 2 | 3 | This is the repository for accessible-app.com. The page is built with Gatsby ([please check out its documentation if you want to make changes to the site that are not content-related](https://www.gatsbyjs.org/docs/)). You can find all relevant content in the `/content` directory in Markdown format. 4 | -------------------------------------------------------------------------------- /content/patterns/teaser-progress.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Showing Progress 3 | type: pattern_teaser 4 | vue: /pattern/vue/progress 5 | react: false 6 | angular: false 7 | order: 7 8 | --- 9 | 10 | Using animated progressbars is fine for visual users, but more often than not, screen readers remain silent when your app is in an interstitial (e.g. loading) state. Here is a strategy to prevent that. -------------------------------------------------------------------------------- /content/patterns/teaser-routing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Accessible routing 3 | type: pattern_teaser 4 | vue: /pattern/vue/routing 5 | react: false 6 | angular: false 7 | order: 4 8 | --- 9 | 10 | A Single Page Application consists of one single HTML document - anything else is being loaded without ever really navigating off of or reloading the page. This leads to accessibility challenges 11 | -------------------------------------------------------------------------------- /src/components/editText.js: -------------------------------------------------------------------------------- 1 | import PropTypes from "prop-types"; 2 | import React from "react"; 3 | 4 | const EditText = ({ link }) => ( 5 | <> 6 | 7 | Edit this content 8 | 9 | 10 | ); 11 | 12 | EditText.propTypes = { 13 | link: PropTypes.string 14 | }; 15 | 16 | export default EditText; 17 | -------------------------------------------------------------------------------- /src/pages/404.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import Layout from "../components/layout"; 4 | import SEO from "../components/seo"; 5 | 6 | const NotFoundPage = () => ( 7 | 8 | 9 |

NOT FOUND

10 |

You just hit a route that doesn't exist... the sadness.

11 |
12 | ); 13 | 14 | export default NotFoundPage; 15 | -------------------------------------------------------------------------------- /content/patterns/teaser-animation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Responsible animation 3 | type: pattern_teaser 4 | vue: /pattern/vue/responsible-animation 5 | react: false 6 | angular: false 7 | order: 1 8 | --- 9 | 10 | While the experience of your app could benefit from animations, sudden movements could cause, for example, dizziness, vertigo or nausea for some of your users. Here's a strategy to deal with this. 11 | -------------------------------------------------------------------------------- /content/patterns/teaser-menu.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Menus & Dropdowns 3 | type: pattern_teaser 4 | vue: /pattern/vue/menu 5 | react: false 6 | angular: false 7 | order: 5 8 | 9 | --- 10 | 11 | Web-apps are full of interactive items that show a new container with links and options once you interact with them. A simple user experience pattern, but hard to get right if you want to build it with accessibility in mind 12 | -------------------------------------------------------------------------------- /content/patterns/teaser-notifications.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Notifications for all users 3 | type: pattern_teaser 4 | vue: /pattern/vue/notifications 5 | react: false 6 | angular: false 7 | order: 2 8 | --- 9 | 10 | You have to inform every user about dynamic changes in your web app - not just the ones using a visual browser. Learn more about programmatically exposing asynchronous content changes to screen readers 11 | -------------------------------------------------------------------------------- /content/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: About accessible-app.com 3 | type: about 4 | --- 5 | 6 | This project aims to be a resource for inclusive modern JavaScript framework usage - so it needs contribution from people who specialize in accessibility regarding React, Angular and Vue. Got ideas, framework knowledge, feedback or want to contribute? 7 | 8 | [Find and contribute to this project on GitHub](http://github.com/accessible-app/) 9 | -------------------------------------------------------------------------------- /content/patterns/teaser-modals.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: (Modal) dialog windows 3 | type: pattern_teaser 4 | vue: /pattern/vue/modal-dialogs 5 | react: false 6 | angular: false 7 | order: 3 8 | --- 9 | 10 | A modal dialog requires a user's response and makes it mandatory to interact with it. Focus, both literally and proverbially, can't be moved away from the modal. Learn more about what to look out for when using dialog windows 11 | -------------------------------------------------------------------------------- /src/components/pattern-details.js: -------------------------------------------------------------------------------- 1 | import PropTypes from "prop-types"; 2 | import React from "react"; 3 | 4 | const PatternDetails = ({ label, link }) => ( 5 | <> 6 | {(() => { 7 | if (link) { 8 | return ( 9 | 10 | {label} 11 | 12 | ); 13 | } else { 14 | return {label}; 15 | } 16 | })()} 17 | 18 | ); 19 | 20 | export default PatternDetails; 21 | -------------------------------------------------------------------------------- /src/pages/patterns.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Layout from "../components/layout"; 3 | import Patterns from "../components/patterns-all"; 4 | import SEO from "../components/seo"; 5 | 6 | const PatternsPage = () => ( 7 | 8 | 9 |
10 |
11 |

Different types of patterns

12 | 13 |
14 |
15 |
16 | ); 17 | 18 | export default PatternsPage; 19 | -------------------------------------------------------------------------------- /src/components/image.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StaticQuery, graphql } from "gatsby"; 3 | import Img from "gatsby-image"; 4 | 5 | const Image = () => ( 6 | } 19 | /> 20 | ); 21 | export default Image; 22 | -------------------------------------------------------------------------------- /src/components/about.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StaticQuery, graphql } from "gatsby"; 3 | 4 | export default () => ( 5 | ( 17 |
18 |

{data.markdownRemark.frontmatter.title}

19 |
24 |
25 | )} 26 | /> 27 | ); 28 | -------------------------------------------------------------------------------- /gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/no-danger */ 2 | import React from 'react' 3 | import { extractStyles } from 'evergreen-ui' 4 | 5 | export const onRenderBody = ({ setHeadComponents }) => { 6 | // Get the css and hydration script from Evergreen. 7 | const { css, hydrationScript } = extractStyles(); 8 | 9 | // Takes an array of components as its first argument which are added to 10 | // the headComponents array which is passed to the html.js component. 11 | setHeadComponents([ 12 | // We need a key here for Gatsby to stop complaining. 13 | 14 |