1 | <h1 align="center">
|
2 | react-toggled โ๏ธ
|
3 | <br>
|
4 | <img src="https://cdn.rawgit.com/kentcdodds/react-toggled/master/other/logo/react-toggled.png" alt="react-toggled logo" title="react-toggled logo" width="300">
|
5 | <br>
|
6 | </h1>
|
7 | <p align="center" style="font-size: 1.2rem;">Component to build simple, flexible, and accessible toggle components</p>
|
8 |
|
9 | <hr />
|
10 |
|
11 | [![Build Status][build-badge]][build]
|
12 | [![Code Coverage][coverage-badge]][coverage]
|
13 | [![downloads][downloads-badge]][npmcharts]
|
14 | [![version][version-badge]][package]
|
15 | [![MIT License][license-badge]][license]
|
16 |
|
17 | [![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors)
|
18 | [![PRs Welcome][prs-badge]][prs]
|
19 | [![Chat][chat-badge]][chat]
|
20 | [![Code of Conduct][coc-badge]][coc]
|
21 |
|
22 | [![Supports React and Preact][react-badge]][react]
|
23 | [![size][size-badge]][unpkg-dist]
|
24 | [![gzip size][gzip-badge]][unpkg-dist]
|
25 | [![module formats: umd, cjs, and es][module-formats-badge]][unpkg-dist]
|
26 |
|
27 | [![Watch on GitHub][github-watch-badge]][github-watch]
|
28 | [![Star on GitHub][github-star-badge]][github-star]
|
29 | [![Tweet][twitter-badge]][twitter]
|
30 |
|
31 | ## The problem
|
32 |
|
33 | You want a toggle component that's simple and gives you complete control over
|
34 | rendering and state.
|
35 |
|
36 | ## This solution
|
37 |
|
38 | This follows the patterns in [`downshift`][downshift] to expose an API that
|
39 | renders nothing and simply encapsulates the logic of a toggle component.
|
40 |
|
41 | ## Table of Contents
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 | * [Installation](#installation)
|
48 | * [Usage](#usage)
|
49 | * [Props:](#props)
|
50 | * [defaultOn](#defaulton)
|
51 | * [onToggle](#ontoggle)
|
52 | * [on](#on)
|
53 | * [children](#children)
|
54 | * [Examples](#examples)
|
55 | * [Inspiration](#inspiration)
|
56 | * [Other Solutions](#other-solutions)
|
57 | * [Contributors](#contributors)
|
58 | * [LICENSE](#license)
|
59 |
|
60 |
|
61 |
|
62 | ## Installation
|
63 |
|
64 | This module is distributed via [npm][npm] which is bundled with [node][node] and
|
65 | should be installed as one of your project's `dependencies`:
|
66 |
|
67 | ```
|
68 | npm install --save react-toggled
|
69 | ```
|
70 |
|
71 | > This package also depends on `react` and `prop-types`. Please make sure you
|
72 | > have those installed as well.
|
73 |
|
74 | > Note also this library supports `preact` out of the box. If you are using
|
75 | > `preact` then look in the `preact/` folder and use the module you want.
|
76 | > You should be able to simply do: `import Toggle from 'react-toggled/preact'`
|
77 |
|
78 | ## Usage
|
79 |
|
80 | ```jsx
|
81 | import React from 'react'
|
82 | import {render} from 'react-dom'
|
83 | import Toggle from 'react-toggled'
|
84 |
|
85 | render(
|
86 | <Toggle>
|
87 | {({on, getTogglerProps}) => (
|
88 | <div>
|
89 | <button {...getTogglerProps()}>Toggle me</button>
|
90 | <div>{on ? 'Toggled On' : 'Toggled Off'}</div>
|
91 | </div>
|
92 | )}
|
93 | </Toggle>,
|
94 | document.getElementById('root'),
|
95 | )
|
96 | ```
|
97 |
|
98 | `react-toggled` is the only component. It doesn't render anything itself, it just
|
99 | calls the child function and renders that. Wrap everything in
|
100 | `<Toggle>{/* your function here! */}</Toggle>`.
|
101 |
|
102 | ## Props:
|
103 |
|
104 | ### defaultOn
|
105 |
|
106 | > `boolean` | defaults to `false`
|
107 |
|
108 | The initial `on` state.
|
109 |
|
110 | ### onToggle
|
111 |
|
112 | > `function(on: boolean, object: TogglerStateAndHelpers)` | optional, no useful default
|
113 |
|
114 | Called when the toggler is clicked.
|
115 |
|
116 | * `on`: The new on state
|
117 | * `TogglerStateAndHelpers`: the exact same thing you get in your child render
|
118 | prop function.
|
119 |
|
120 | ### on
|
121 |
|
122 | > `boolean` | **control prop**
|
123 |
|
124 | react-toggled manages its own state internally and calls your `onToggle`
|
125 | handler whenever the `on` state changes. Your child render prop function
|
126 | (read more below) can be used to manipulate this state from within the render
|
127 | function and can likely support many of your use cases.
|
128 |
|
129 | However, if more control is needed, you can pass the `on` state as a prop
|
130 | and that state becomes controlled. As soon as
|
131 | `this.props.on !== undefined`, internally, `react-toggled` will determine
|
132 | its state based on your prop's value rather than its own internal state. You
|
133 | will be required to keep the state up to date (this is where `onToggle` comes in
|
134 | really handy), but you can also control the state from anywhere, be
|
135 | that state from other components, `redux`, `react-router`, or anywhere else.
|
136 |
|
137 | > Note: This is very similar to how normal controlled components work elsewhere
|
138 | > in react (like `<input />`). If you want to learn more about this concept, you
|
139 | > can learn about that from this the
|
140 | > ["Controlled Components" lecture][controlled-components-lecture] and
|
141 | > exercises from [React Training's][react-training] > [Advanced React][advanced-react] course.
|
142 |
|
143 | ### children
|
144 |
|
145 | > `function({})` | _required_
|
146 |
|
147 | This is called with an object.
|
148 |
|
149 | This is where you render whatever you want to based on the state of `react-toggled`.
|
150 | The function is passed as the child prop:
|
151 | `<Toggle>{/* right here*/}</Toggle>`
|
152 |
|
153 |
|
154 |
|
155 | | property | category | type | description |
|
156 | | ------------------------ | ----------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
157 | | `on` | state | `boolean` | The current `on` state of toggle |
|
158 | | `getTogglerProps` | prop getter | `function(props: object)` | returns the props you should apply to the button element you render. Includes `aria-` attributes |
|
159 | | `getInputTogglerProps` | prop getter | `function(props: object)` | returns the props you should apply to the input (checkbox) element you render. Includes `aria-` attributes |
|
160 | | `getElementTogglerProps` | prop getter | `function(props: object)` | returns the props you should apply to the element you render. Use this if you are not using a button or inputโfor example, a span. Includes `aria-` attributes |
|
161 | | `setOn` | action | `function()` | Sets the `on` state to `true` |
|
162 | | `setOff` | action | `function()` | Sets the `on` state to `false` |
|
163 | | `toggle` | action | `function()` | Toggles the `on` state (i.e. if it's currently `true`, will set to `false`) |
|
164 |
|
165 | ## Examples
|
166 |
|
167 | Examples exist on [codesandbox.io][examples]:
|
168 |
|
169 | * [Bare bones toggle](https://codesandbox.io/s/m38674w9vy)
|
170 |
|
171 | If you would like to add an example, follow these steps:
|
172 |
|
173 | 1. Fork [this codesandbox](https://codesandbox.io/s/m38674w9vy)
|
174 | 2. Make sure your version (under dependencies) is the latest available version.
|
175 | 3. Update the title and description
|
176 | 4. Update the code for your example (add some form of documentation to explain what it is)
|
177 | 5. Add the tag: `react-toggled:example`
|
178 |
|
179 | You'll find other examples in the `stories/examples` folder of the repo.
|
180 | And you'll find
|
181 | [a live version of those examples here](https://react-toggled.netlify.com)
|
182 |
|
183 | ## Inspiration
|
184 |
|
185 | I built this while building [an example of using `glamorous` with `next.js`][glamorous-with-next]
|
186 |
|
187 | ## Other Solutions
|
188 |
|
189 | You can implement any of the other solutions using `react-toggled`, but if
|
190 | you'd prefer to use these out of the box solutions, then that's fine too. There
|
191 | are tons of them, so just
|
192 | [checkout npm](https://www.npmjs.com/search?q=react%20toggle).
|
193 |
|
194 | ## Contributors
|
195 |
|
196 | Thanks goes to these people ([emoji key][emojis]):
|
197 |
|
198 |
|
199 |
|
200 | | [<img src="https://avatars.githubusercontent.com/u/1500684?v=3" width="100px;"/><br /><sub><b>Kent C. Dodds</b></sub>](https://kentcdodds.com)<br />[๐ป](https://github.com/kentcdodds/react-toggled/commits?author=kentcdodds "Code") [๐](https://github.com/kentcdodds/react-toggled/commits?author=kentcdodds "Documentation") [๐](#infra-kentcdodds "Infrastructure (Hosting, Build-Tools, etc)") [โ ๏ธ](https://github.com/kentcdodds/react-toggled/commits?author=kentcdodds "Tests") | [<img src="https://avatars3.githubusercontent.com/u/9488719?v=4" width="100px;"/><br /><sub><b>Frank Tan</b></sub>](https://github.com/tansongyang)<br />[๐ป](https://github.com/kentcdodds/react-toggled/commits?author=tansongyang "Code") [๐](https://github.com/kentcdodds/react-toggled/commits?author=tansongyang "Documentation") [โ ๏ธ](https://github.com/kentcdodds/react-toggled/commits?author=tansongyang "Tests") | [<img src="https://avatars1.githubusercontent.com/u/9408641?v=4" width="100px;"/><br /><sub><b>Oliver</b></sub>](http://www.oliverjam.es)<br />[๐ป](https://github.com/kentcdodds/react-toggled/commits?author=oliverjam "Code") | [<img src="https://avatars2.githubusercontent.com/u/11708648?v=4" width="100px;"/><br /><sub><b>Jedrzej Lewandowski</b></sub>](http://www.thefullresolution.com/)<br />[๐ป](https://github.com/kentcdodds/react-toggled/commits?author=TheFullResolution "Code") | [<img src="https://avatars1.githubusercontent.com/u/603386?v=4" width="100px;"/><br /><sub><b>Ben Slinger</b></sub>](https://github.com/bslinger)<br />[๐ป](https://github.com/kentcdodds/react-toggled/commits?author=bslinger "Code") [โ ๏ธ](https://github.com/kentcdodds/react-toggled/commits?author=bslinger "Tests") |
|
201 | | :---: | :---: | :---: | :---: | :---: |
|
202 |
|
203 |
|
204 | This project follows the [all-contributors][all-contributors] specification.
|
205 | Contributions of any kind welcome!
|
206 |
|
207 | ## LICENSE
|
208 |
|
209 | MIT
|
210 |
|
211 | [npm]: https://www.npmjs.com/
|
212 | [node]: https://nodejs.org
|
213 | [build-badge]: https://img.shields.io/travis/kentcdodds/react-toggled.svg?style=flat-square
|
214 | [build]: https://travis-ci.org/kentcdodds/react-toggled
|
215 | [coverage-badge]: https://img.shields.io/codecov/c/github/kentcdodds/react-toggled.svg?style=flat-square
|
216 | [coverage]: https://codecov.io/github/kentcdodds/react-toggled
|
217 | [version-badge]: https://img.shields.io/npm/v/react-toggled.svg?style=flat-square
|
218 | [package]: https://www.npmjs.com/package/react-toggled
|
219 | [downloads-badge]: https://img.shields.io/npm/dm/react-toggled.svg?style=flat-square
|
220 | [npmcharts]: http://npmcharts.com/compare/react-toggled
|
221 | [license-badge]: https://img.shields.io/npm/l/react-toggled.svg?style=flat-square
|
222 | [license]: https://github.com/kentcdodds/react-toggled/blob/master/LICENSE
|
223 | [prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
|
224 | [prs]: http://makeapullrequest.com
|
225 | [chat]: https://gitter.im/kentcdodds/react-toggled
|
226 | [chat-badge]: https://img.shields.io/gitter/room/kentcdodds/react-toggled.svg?style=flat-square
|
227 | [coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square
|
228 | [coc]: https://github.com/kentcdodds/react-toggled/blob/master/other/CODE_OF_CONDUCT.md
|
229 | [react-badge]: https://img.shields.io/badge/%E2%9A%9B%EF%B8%8F-(p)react-00d8ff.svg?style=flat-square
|
230 | [react]: https://facebook.github.io/react/
|
231 | [gzip-badge]: http://img.badgesize.io/https://unpkg.com/react-toggled/dist/react-toggled.umd.min.js?compression=gzip&label=gzip%20size&style=flat-square
|
232 | [size-badge]: http://img.badgesize.io/https://unpkg.com/react-toggled/dist/react-toggled.umd.min.js?label=size&style=flat-square
|
233 | [unpkg-dist]: https://unpkg.com/react-toggled/dist/
|
234 | [module-formats-badge]: https://img.shields.io/badge/module%20formats-umd%2C%20cjs%2C%20es-green.svg?style=flat-square
|
235 | [github-watch-badge]: https://img.shields.io/github/watchers/kentcdodds/react-toggled.svg?style=social
|
236 | [github-watch]: https://github.com/kentcdodds/react-toggled/watchers
|
237 | [github-star-badge]: https://img.shields.io/github/stars/kentcdodds/react-toggled.svg?style=social
|
238 | [github-star]: https://github.com/kentcdodds/react-toggled/stargazers
|
239 | [twitter]: https://twitter.com/intent/tweet?text=Check%20out%20react-toggled%20by%20%40kentcdodds%20https%3A%2F%2Fgithub.com%2Fkentcdodds%2Freact-toggled%20%F0%9F%91%8D
|
240 | [twitter-badge]: https://img.shields.io/twitter/url/https/github.com/kentcdodds/react-toggled.svg?style=social
|
241 | [emojis]: https://github.com/kentcdodds/all-contributors#emoji-key
|
242 | [all-contributors]: https://github.com/kentcdodds/all-contributors
|
243 | [ryan]: https://github.com/ryanflorence
|
244 | [compound-components-lecture]: https://courses.reacttraining.com/courses/advanced-react/lectures/3060560
|
245 | [examples]: https://codesandbox.io/search?refinementList%5Btags%5D%5B0%5D=react-toggled%3Aexample&page=1
|
246 | [controlled-components-lecture]: https://courses.reacttraining.com/courses/advanced-react/lectures/3172720
|
247 | [react-training]: https://reacttraining.com/
|
248 | [advanced-react]: https://courses.reacttraining.com/courses/enrolled/200086
|
249 | [fac]: https://medium.com/merrickchristensen/function-as-child-components-5f3920a9ace9
|
250 | [glamorous-with-next]: https://github.com/kentcdodds/glamorous-with-next
|
251 | [downshift]: https://github.com/paypal/downshift
|