1 | # Rheostat
|
2 |
|
3 | > A mobile, tablet, desktop, and accessible slider for the web.
|
4 |
|
5 | ![Rheostat demo](sample.gif)
|
6 |
|
7 | ## Install
|
8 |
|
9 | `npm install rheostat`
|
10 |
|
11 | ## Initialize
|
12 |
|
13 | As of v3.0.0, the `rheostat` project relies on `react-with-styles`. If you want to continue using CSS stylesheets and classes, there is a little bit of extra set-up required to get things going. As such, you need to use to use `rheostat/initialize` to set up class names on your components.
|
14 |
|
15 | import 'rheostat/initialize';
|
16 |
|
17 | For example, the above import should go at the top of your application as you won't be able to import `rheostat` with it.
|
18 |
|
19 | ## Props
|
20 |
|
21 | The algorithm, by default [`linear`](src/algorithms/linear.js), the slider will use. Feel free to write
|
22 | your own as long as it conforms to the shape.
|
23 |
|
24 | ```js
|
25 | algorithm: PropTypes.shape({
|
26 | getValue: PropTypes.func,
|
27 | getPosition: PropTypes.func,
|
28 | })
|
29 | ```
|
30 |
|
31 | Custom class name that will be applied to the root of Rheostat.
|
32 |
|
33 | ```js
|
34 | className: PropTypes.string
|
35 | ```
|
36 |
|
37 | Custom React component overrides for the handles, background, and the "progress" bar.
|
38 |
|
39 | ```js
|
40 | background: PropTypes.oneOfType([PropTypes.func, PropTypes.string])
|
41 | handle: PropTypes.oneOfType([PropTypes.func, PropTypes.string])
|
42 | progressBar: PropTypes.oneOfType([PropTypes.func, PropTypes.string])
|
43 | ```
|
44 |
|
45 | The maximum and minimum possible values, by default 0 - 100.
|
46 |
|
47 | ```js
|
48 | max: PropTypes.number
|
49 | min: PropTypes.number
|
50 | ```
|
51 |
|
52 | `pitComponent` is a custom React component for rendering "pits" across the bar.
|
53 | `pitPoints` is the set of points at which it will render a pit. Points are an array
|
54 | of `values` on the slider.
|
55 |
|
56 | ```js
|
57 | pitComponent: PropTypes.oneOfType([PropTypes.func, PropTypes.string])
|
58 | pitPoints: PropTypes.arrayOf(PropTypes.number)
|
59 | ```
|
60 |
|
61 | NOTE: `onChange` is called whenever the value is changed and committed. This happens at the end of
|
62 | a drag, keypress, or click event. `onChange` is recommended when you wish to persist the values.
|
63 |
|
64 | `onValuesUpdated` is a convenience event that is triggered while the value is being actively
|
65 | changed. This includes dragging, click, or keypress. `onValuesUpdated` is recommended if you need
|
66 | to work with the values before they're committed.
|
67 |
|
68 | If you need to perform custom logic to postprocess the handle position, `getNextHandlePosition` accepts
|
69 | a callback of the form `(handleIdx: int, percentPosition: float) => float`. Return the updated
|
70 | handle position. This is useful if you need to customize ranges within a single slider.
|
71 |
|
72 | ```js
|
73 | onChange: PropTypes.func
|
74 | onClick: PropTypes.func
|
75 | onKeyPress: PropTypes.func
|
76 | onSliderDragEnd: PropTypes.func
|
77 | onSliderDragMove: PropTypes.func
|
78 | onSliderDragStart: PropTypes.func
|
79 | onValuesUpdated: PropTypes.func
|
80 | getNextHandlePosition: PropTypes.func
|
81 | ```
|
82 |
|
83 | `snap` is a boolean which controls the slider's snapping behavior.
|
84 | `snapPoints` is an array of `values` on the slider where the slider should snap to.
|
85 |
|
86 | If `snap` is set to true and no `snapPoints` are set then the slider is snapped into an absolute
|
87 | position. For example, on a scale of 1-10 if the slider is let go at the 54% mark it'll pick the
|
88 | value 5 and snap to 50%.
|
89 |
|
90 | ```js
|
91 | snap: PropTypes.bool
|
92 | snapPoints: PropTypes.arrayOf(PropTypes.number)
|
93 | ```
|
94 |
|
95 | The values, by default 0 and 100.
|
96 |
|
97 | ```js
|
98 | values: PropTypes.arrayOf(PropTypes.number)
|
99 | ```
|
100 |
|
101 | You can disable the slider to prevent the user from moving it.
|
102 |
|
103 | ```js
|
104 | disabled: PropTypes.bool
|
105 | ```
|
106 |
|
107 | ## Usage
|
108 |
|
109 | > Important: Make sure to include the [css file](https://unpkg.com/rheostat@3/css/rheostat.css) or feel free to create your own.
|
110 |
|
111 | * Simple.
|
112 |
|
113 | ```js
|
114 | import Rheostat from 'rheostat';
|
115 |
|
116 | ReactDOM.render(<Rheostat />, document.getElementById('slider-root'));
|
117 | ```
|
118 |
|
119 | * A slider with a multiple handles.
|
120 |
|
121 | ```js
|
122 | import Rheostat from 'rheostat';
|
123 |
|
124 | ReactDOM.render((
|
125 | <Rheostat
|
126 | min={1}
|
127 | max={100}
|
128 | values={[1, 100]}
|
129 | />
|
130 | ), document.getElementById('slider-root'));
|
131 | ```
|
132 |
|
133 | ### Advanced Styling
|
134 |
|
135 | The `rheostat/initialize` script actually relies on [react-with-styles-interface-css](https://github.com/airbnb/react-with-styles-interface-css) under the hood. If you are interested in a different solution for styling in your project, you can do your own initialization of a another [interface](https://github.com/airbnb/react-with-styles/blob/master/README.md#interfaces). At Airbnb, for instance, we rely on [Aphrodite](https://github.com/Khan/aphrodite) under the hood and therefore use the Aphrodite interface for `react-with-styles`. If you want to do the same, you would use the following pattern:
|
136 | ```js
|
137 | import ThemedStyleSheet from 'react-with-styles/lib/ThemedStyleSheet';
|
138 | import aphroditeInterface from 'react-with-styles-interface-aphrodite';
|
139 | import DefaultTheme from 'rheostat/lib/themes/DefaultTheme';
|
140 |
|
141 | ThemedStyleSheet.registerInterface(aphroditeInterface);
|
142 | ThemedStyleSheet.registerTheme(DefaultTheme);
|
143 | ```
|
144 |
|
145 | The above code has to be run before any `rheostat` component is imported. Otherwise, you will get an error. Also note that if you register any custom interface manually, you *must* also manually register a theme.
|
146 |
|
147 | ### Theming
|
148 | `rheostat` also now supports a different way to theme. You can see the default theme values in [this file](https://github.com/airbnb/rheostat/blob/master/src/themes/DefaultTheme.js) and you would override them in the following manner:
|
149 | ```js
|
150 | import ThemedStyleSheet from 'react-with-styles/lib/ThemedStyleSheet';
|
151 | import aphroditeInterface from 'react-with-styles-interface-aphrodite';
|
152 | import DefaultTheme from 'rheostat/lib/themes/DefaultTheme';
|
153 |
|
154 | ThemedStyleSheet.registerInterface(aphroditeInterface);
|
155 | ThemedStyleSheet.registerTheme({
|
156 | rheostat: {
|
157 | ...DefaultTheme.rheostat,
|
158 | color: {
|
159 | ...DefaultTheme.rheostat.color,
|
160 | progressBar: 'red',
|
161 | },
|
162 | },
|
163 | });
|
164 | ```
|
165 |
|
166 | The above code would make the default progress bar red, instead of light blue. Note that you *must* register an interface if you manually register a theme. One will not work without the other.
|
167 |
|
168 | #### A note on using `react-with-styles-interface-css`
|
169 | The default interface that `rheostat` ships with is the [CSS interface](https://github.com/airbnb/react-with-styles-interface-css). If you want to use this interface along with the theme registration method, you will need to rebuild the core `rheostat.css` file. We do not currently expose a utility method to build this file, but you can follow along with the code in https://github.com/airbnb/rheostat/blob/master/scripts/buildCSS.js to build your own custom themed CSS file.
|
170 |
|
171 | ### RTL Support
|
172 |
|
173 | `rheostat` now supports automatic RTL rendering through [`react-with-direction`](https://github.com/airbnb/react-with-direction).
|
174 |
|
175 | ## Live Playground
|
176 |
|
177 | For more examples you can check out the storybook.
|
178 |
|
179 | * Clone this repo on your machine.
|
180 | * `npm install`
|
181 | * `npm run storybook`
|
182 | * Visit `http://localhost:9001/`.
|