├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | yarn.lock 3 | package-lock.json 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [Unreleased] 9 | 10 | ## [0.2.0] - 2022-07-28 11 | 12 | ### Added 13 | 14 | - Depend on `tailwindcss@^3.0.0` to use the newly String-based `addVariant` 15 | function 16 | 17 | ## [0.1.0] - 2022-07-27 18 | 19 | - Initial release 20 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of conduct 2 | 3 | By participating in this project, you agree to abide by the 4 | [thoughtbot code of conduct][1]. 5 | 6 | [1]: https://thoughtbot.com/open-source-code-of-conduct 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Sean Doyle and thoughtbot, inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @thoughtbot/tailwindcss-aria-attributes 2 | 3 | A plugin that provides variants for various [`aria-*` 4 | attributes](https://www.w3.org/TR/wai-aria/#state_prop_def) and their supported 5 | values. 6 | 7 | ## Installation 8 | 9 | Install the plugin from npm: 10 | 11 | ```sh 12 | # Using npm 13 | npm install @thoughtbot/tailwindcss-aria-attributes 14 | 15 | # Using Yarn 16 | yarn add @thoughtbot/tailwindcss-aria-attributes 17 | ``` 18 | 19 | Then add the plugin to your `tailwind.config.js` file: 20 | 21 | ```js 22 | // tailwind.config.js 23 | module.exports = { 24 | theme: { 25 | // ... 26 | }, 27 | plugins: [ 28 | require("@thoughtbot/tailwindcss-aria-attributes"), 29 | // ... 30 | ], 31 | } 32 | ``` 33 | 34 | ## Usage 35 | 36 | There are two styles of attributes supported by the variants: boolean 37 | attributes, and enumerated values. 38 | 39 | In some cases, attributes belong to both groups. 40 | 41 | ### Boolean attributes 42 | 43 | Variants for boolean attributes are active when the value is `"true"` and _only_ 44 | `"true"`. When the attribute is missing or the value is `"false"`, its other 45 | applicable utility classes are applied. 46 | 47 | Currently, the collection of variants includes support for the following boolean 48 | attributes: 49 | 50 | | Attribute | Variant 51 | |-------------------------------------------------------------------------------------|------------------------ 52 | | [aria-atomic="true"](https://www.w3.org/TR/wai-aria/#aria-atomic) | `aria-atomic:` 53 | | [aria-busy="true"](https://www.w3.org/TR/wai-aria/#aria-busy) | `aria-busy:` 54 | | [aria-checked="true"](https://www.w3.org/TR/wai-aria/#aria-checked) | `aria-checked:` 55 | | [aria-current="true"](https://www.w3.org/TR/wai-aria/#aria-current) | `aria-current:` 56 | | [aria-disabled="true"](https://www.w3.org/TR/wai-aria/#aria-disabled) | `aria-disabled:` 57 | | [aria-expanded="true"](https://www.w3.org/TR/wai-aria/#aria-expanded) | `aria-expanded:` 58 | | [aria-grabbed="true"](https://www.w3.org/TR/wai-aria/#aria-grabbed) | `aria-grabbed:` 59 | | [aria-haspopup="true"](https://www.w3.org/TR/wai-aria/#aria-haspopup) | `aria-haspopup:` 60 | | [aria-hidden="true"](https://www.w3.org/TR/wai-aria/#aria-hidden) | `aria-hidden:` 61 | | [aria-invalid="true"](https://www.w3.org/TR/wai-aria/#aria-invalid) | `aria-invalid:` 62 | | [aria-live="true"](https://www.w3.org/TR/wai-aria/#aria-live) | `aria-live:` 63 | | [aria-modal="true"](https://www.w3.org/TR/wai-aria/#aria-modal) | `aria-modal:` 64 | | [aria-multiline="true"](https://www.w3.org/TR/wai-aria/#aria-multiline) | `aria-multiline:` 65 | | [aria-multiselectable="true"](https://www.w3.org/TR/wai-aria/#aria-multiselectable) | `aria-multiselectable:` 66 | | [aria-pressed="true"](https://www.w3.org/TR/wai-aria/#aria-pressed) | `aria-pressed:` 67 | | [aria-readonly="true"](https://www.w3.org/TR/wai-aria/#aria-readonly) | `aria-readonly:` 68 | | [aria-required="true"](https://www.w3.org/TR/wai-aria/#aria-required) | `aria-required:` 69 | | [aria-selected="true"](https://www.w3.org/TR/wai-aria/#aria-selected) | `aria-selected:` 70 | 71 | To utilize a boolean variant, prefix the attribute name with `aria-` and omit 72 | the value: 73 | 74 | ```html 75 | 79 | 80 | 81 | ``` 82 | 83 | ### Enumerated values 84 | 85 | Variants for enumerated values are active when the value is equivalent to the 86 | variant's suffix. 87 | 88 | When the attribute is missing or the value does not match the specified suffix, 89 | its other applicable utility classes are applied. 90 | 91 | Currently, the collection of variants includes support for the following 92 | attributes and value combinations: 93 | 94 | | Attribute | Variants | 95 | |------------------------------------------------------------------------|-------------------------------| 96 | | [aria-autocomplete](https://www.w3.org/TR/wai-aria/#aria-autocomplete) | `aria-autocomplete-both:` 97 | | | `aria-autocomplete-inline:` 98 | | | `aria-autocomplete-list:` 99 | | | `aria-autocomplete-none:` 100 | | [aria-current](https://www.w3.org/TR/wai-aria/#aria-current) | `aria-current-date:` 101 | | | `aria-current-location:` 102 | | | `aria-current-page:` 103 | | | `aria-current-step:` 104 | | | `aria-current-time:` 105 | | [aria-dropeffect](https://www.w3.org/TR/wai-aria/#aria-dropeffect) | `aria-dropeffect-copy:` 106 | | | `aria-dropeffect-execute:` 107 | | | `aria-dropeffect-link:` 108 | | | `aria-dropeffect-move:` 109 | | | `aria-dropeffect-none:` 110 | | | `aria-dropeffect-popup:` 111 | | [aria-haspopup](https://www.w3.org/TR/wai-aria/#aria-dropeffect) | `aria-haspopup-dialog:` 112 | | | `aria-haspopup-grid:` 113 | | | `aria-haspopup-listbox:` 114 | | | `aria-haspopup-menu:` 115 | | | `aria-haspopup-tree:` 116 | | [aria-orientation](https://www.w3.org/TR/wai-aria/#aria-dropeffect) | `aria-orientation-horizontal:` 117 | | | `aria-orientation-undefined:` 118 | | | `aria-orientation-vertical:` 119 | | [aria-sort](https://www.w3.org/TR/wai-aria/#aria-dropeffect) | `aria-sort-ascending:` 120 | | | `aria-sort-descending:` 121 | | | `aria-sort-none:` 122 | | | `aria-sort-other:` 123 | | [aria-relevant](https://www.w3.org/TR/wai-aria/#aria-dropeffect) | `aria-relevant-additions:` 124 | | | `aria-relevant-all:` 125 | | | `aria-relevant-removals:` 126 | | | `aria-relevant-text:` 127 | 128 | To utilize an enumerated value variant, prefix the attribute name with `aria-` 129 | and include the value: 130 | 131 | ```html 132 | 136 | ``` 137 | 138 | ## License 139 | 140 | tailwindcss-aria-attributes is Copyright (c) 2021 thoughtbot, inc. 141 | It contains free software that may be redistributed 142 | under the terms specified in the [LICENSE] file. 143 | 144 | [LICENSE]: /LICENSE 145 | 146 | ## About 147 | 148 | ![thoughtbot](http://presskit.thoughtbot.com/images/thoughtbot-logo-for-readmes.svg) 149 | 150 | This project is maintained and funded by thoughtbot, inc. 151 | The names and logos for thoughtbot are trademarks of thoughtbot, inc. 152 | 153 | We love open source software! 154 | See [our other projects][community] 155 | or [hire us][hire] to help build your product. 156 | 157 | [community]: https://thoughtbot.com/community?utm_source=github 158 | [hire]: https://thoughtbot.com/hire-us?utm_source=github 159 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const plugin = require("tailwindcss/plugin") 2 | 3 | module.exports = plugin(({ addVariant }) => { 4 | const addAriaVariant = (name, value) => { 5 | addVariant(name, `[${name}="${value}"]&`) 6 | addVariant(`peer-${name}`, `:merge(.peer)[${name}="${value}"] ~ &`) 7 | addVariant(`group-${name}`, `:merge(.group)[${name}="${value}"] &`) 8 | } 9 | const addAriaEnumVariant = (name, value) => { 10 | addVariant(`${name}-${value}`, `[${name}="${value}"]&`) 11 | addVariant(`peer-${name}-${value}`, `:merge(.peer)[${name}="${value}"] ~ &`) 12 | addVariant(`group-${name}-${value}`, `:merge(.group)[${name}="${value}"] &`) 13 | } 14 | 15 | const booleans = [ 16 | "atomic", 17 | "busy", 18 | "checked", 19 | "current", 20 | "disabled", 21 | "expanded", 22 | "grabbed", 23 | "haspopup", 24 | "hidden", 25 | "invalid", 26 | "live", 27 | "modal", 28 | "multiline", 29 | "multiselectable", 30 | "pressed", 31 | "readonly", 32 | "required", 33 | "selected", 34 | ] 35 | 36 | for (const attribute of booleans) { 37 | addAriaVariant(`aria-${attribute}`, "true") 38 | } 39 | 40 | const enumerables = { 41 | autocomplete: [ "both", "inline", "list", "none" ], 42 | current: [ "date", "location", "page", "step", "time" ], 43 | dropeffect: [ "copy", "execute", "link", "move", "none", "popup" ], 44 | haspopup: [ "dialog", "grid", "listbox", "menu", "tree" ], 45 | orientation: [ "horizontal", "undefined", "vertial" ], 46 | relevant: [ "additions", "all", "removals", "text" ], 47 | sort: [ "ascending", "descending", "none", "other" ], 48 | } 49 | 50 | for (const [ attribute, values ] of Object.entries(enumerables)) { 51 | for (const value of values) { 52 | addAriaEnumVariant(`aria-${attribute}`, value) 53 | } 54 | } 55 | }) 56 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@thoughtbot/tailwindcss-aria-attributes", 3 | "version": "0.2.0", 4 | "description": "TailwindCSS aria- attribute utilities plugin", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/thoughtbot/tailwindcss-aria-attributes.git" 9 | }, 10 | "keywords": [ 11 | "tailwindcss" 12 | ], 13 | "author": "Sean Doyle ", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/thoughtbot/tailwindcss-aria-attributes/issues" 17 | }, 18 | "homepage": "https://github.com/thoughtbot/tailwindcss-aria-attributes#readme", 19 | "devDependencies": { 20 | "tailwindcss": "^3.0.0" 21 | } 22 | } 23 | --------------------------------------------------------------------------------