|
| 1 | +<div align="center"> |
| 2 | + <h1>✨react-incrementor🎄</h1> |
| 3 | +</div> |
| 4 | + |
| 5 | +<p align="center" style="font-size: 1.2rem;">Component to build simple, flexible, and accessible incrementor components</p> |
| 6 | + |
| 7 | +[![Build Status][build-badge]][build] |
| 8 | +[![Code Coverage][coverage-badge]][coverage] |
| 9 | +[![downloads][downloads-badge]][npmcharts] |
| 10 | +[![version][version-badge]][package] |
| 11 | +[![MIT License][license-badge]][license] |
| 12 | + |
| 13 | +[![PRs Welcome][prs-badge]][prs] |
| 14 | + |
| 15 | +[![size][size-badge]][unpkg-dist] |
| 16 | +[![gzip size][gzip-badge]][unpkg-dist] |
| 17 | + |
| 18 | +## The problem |
| 19 | + |
| 20 | +You want an incrementor component that's simple and gives you complete control over |
| 21 | +rendering and state. |
| 22 | + |
| 23 | +## This solution |
| 24 | + |
| 25 | +This follows the `controlled prop pattern` and `render prop pattern` to expose an API that |
| 26 | +renders nothing and simply encapsulates the logic of a incrementor component. |
| 27 | + |
| 28 | +## Table of Contents |
| 29 | + |
| 30 | +* [Installation](#installation) |
| 31 | +* [Usage](#usage) |
| 32 | +* [Props:](#props) |
| 33 | + * [defaultValue](#defaultvalue) |
| 34 | + * [value](#value) |
| 35 | + * [onChange](#onchange) |
| 36 | + * [render](#render) |
| 37 | +* [Examples](#examples) |
| 38 | +* [Inspiration](#inspiration) |
| 39 | +* [LICENSE](#license) |
| 40 | + |
| 41 | +## Installation |
| 42 | + |
| 43 | +This module is distributed via [npm][npm] which is bundled with [node][node] and |
| 44 | +should be installed as one of your project's `dependencies`: |
| 45 | + |
| 46 | +``` |
| 47 | +npm install --save react-incrementor |
| 48 | +``` |
| 49 | + |
| 50 | +> This package also depends on `react` and `prop-types`. Please make sure you |
| 51 | +> have those installed as well. |
| 52 | +
|
| 53 | +## Usage |
| 54 | + |
| 55 | +```jsx |
| 56 | +import React from 'react'; |
| 57 | +import { render } from 'react-dom'; |
| 58 | + |
| 59 | +import Incrementor from 'react-incrementor'; |
| 60 | + |
| 61 | +function BasicIncrementor() { |
| 62 | + return ( |
| 63 | + <Incrementor |
| 64 | + render={({ value, getDecrementerProps, getIncrementerProps }) => { |
| 65 | + return ( |
| 66 | + <div> |
| 67 | + <div> |
| 68 | + <span>{value}</span> |
| 69 | + </div> |
| 70 | + |
| 71 | + <div> |
| 72 | + <button {...getDecrementerProps()}>Minus 1</button> |
| 73 | + <button {...getIncrementerProps()}>Plus 1</button> |
| 74 | + </div> |
| 75 | + </div> |
| 76 | + ); |
| 77 | + }} |
| 78 | + /> |
| 79 | + ); |
| 80 | +} |
| 81 | + |
| 82 | +render(<BasicIncrementor />, document.getElementById('root')); |
| 83 | +``` |
| 84 | + |
| 85 | +`react-incrementor` is the only component. It doesn't render anything itself, it just |
| 86 | +calls the `render` function and renders that. |
| 87 | + |
| 88 | +## Props: |
| 89 | + |
| 90 | +### defaultValue |
| 91 | + |
| 92 | +> `number` | defaults to `0` |
| 93 | +
|
| 94 | +The default `value` state. |
| 95 | + |
| 96 | +### onChange |
| 97 | + |
| 98 | +> `function(value: number)` | optional |
| 99 | +
|
| 100 | +Called at interaction with the incrementor |
| 101 | + |
| 102 | +* `value`: The new value after increment / decrement |
| 103 | + |
| 104 | +### value |
| 105 | + |
| 106 | +> `number` | **control prop** |
| 107 | +
|
| 108 | +react-incrementor manages its own state internally and calls your `onChange` |
| 109 | +handler whenever the `value` state changes. Pass the `value` state as a prop |
| 110 | +and that state becomes controlled. It is your responsibility to keep the `value` updated by re-rendering the component. |
| 111 | + |
| 112 | +### render |
| 113 | + |
| 114 | +> `function({})` | _required_ |
| 115 | +
|
| 116 | +This is called with an object that exposes the public API of this component. |
| 117 | + |
| 118 | +The function is passed as the render prop: |
| 119 | +`<Incrementor render={(value) => {/* awesome code */}} />` |
| 120 | + |
| 121 | +<!-- This table was generated via http://www.tablesgenerator.com/markdown_tables --> |
| 122 | + |
| 123 | +| property | category | type | description | |
| 124 | +| --------------------- | ----------- | ------------------------- | ------------------------------------------------------------------------------------------------------------ | |
| 125 | +| `value` | state | `boolean` | The current `value` state of the incrementor | |
| 126 | +| `getIncrementerProps` | prop getter | `function(props: object)` | returns the props you should apply to the incrementer button element you render. Includes `aria-` attributes | |
| 127 | +| `getDecrementerProps` | prop getter | `function(props: object)` | returns the props you should apply to the decrementer button element you render. Includes `aria-` attributes | |
| 128 | + |
| 129 | +## Inspiration |
| 130 | + |
| 131 | +This was build as a learning exercise for the `controlled prop pattern` and `render prop pattern`. It is heavily influenced by [Kent C. Dodds](https://github.com/kentcdodds)'s [react-toggled](https://github.com/kentcdodds/react-toggled) component |
| 132 | + |
| 133 | +## LICENSE |
| 134 | + |
| 135 | +MIT |
0 commit comments