├── .babelrc ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .importjs.js ├── .travis.yml ├── CONTRIBUTING.md ├── README.md ├── package.json ├── src ├── __tests__ │ └── withAvailableWidth-test.jsx ├── test.css ├── test.html ├── test.jsx └── withAvailableWidth.jsx ├── webpack.config.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "transform-react-jsx", 4 | "add-module-exports" 5 | ], 6 | "presets": ["es2015"] 7 | } 8 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'airbnb', 3 | parserOptions: { 4 | ecmaVersion: 6, 5 | sourceType: 'module', 6 | }, 7 | env: { 8 | jasmine: true, 9 | jest: true, 10 | browser: true, 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /.importjs.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | importDevDependencies: true, 3 | excludes: [ 4 | './dist/**', 5 | ], 6 | }; 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: false 3 | node_js: 4 | - '6' 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | 1. Install dependencies by running `yarn install` 4 | 2. Start watching for changes: `yarn run build-test -- --watch` 5 | 3. Make changes 6 | 4. View effect of changes by opening `src/test.html` in one or more browsers 7 | 8 | # Building the distributed package 9 | 10 | Run `yarn run build`. This will automatically happen during publishing. 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Truly responsive React components 2 | 3 | Using media queries to style components differently depending on the screen 4 | width is great if you're only working in a single column. But let's say you 5 | have a multi-column layout where you want responsive components based on the 6 | available width in the current container? Or you want a component to be able to 7 | render in a lot of different contexts, with unknown widths? With regular 8 | media-queries, you can't do that. 9 | 10 | `withAvailableWidth` is a 11 | [HOC](https://facebook.github.io/react/docs/higher-order-components.html) that 12 | will inject a `availableWidth` prop to the wrapped component. It will allow you 13 | to write components that render differently based on the currently available 14 | width. Here's an example -- a `ToggleButton` that collapses to a checkbox in 15 | narrow contexts. 16 | 17 | ```jsx 18 | function ToggleButton({ 19 | downLabel, 20 | upLabel, 21 | isDown, 22 | availableWidth, 23 | }) { 24 | if (availableWidth < 50) { 25 | return ; 26 | } 27 | return ( 28 |
90 | This page lists components wrapped in
91 | {' '}
92 | withAvailableWidth
93 | {' '}
94 | in a number of contexts. Each example is rendered twice. First, with a
95 | default resize observer (listening to resize
events on
96 | the window
object). Then with a
97 | {' '}
98 |
99 | ResizeObserver
polyfill
100 | . After the examples, a comparison is rendered in light blue.
101 | The blue element is not using the HOC.
102 |
107 | This element should span the entire width of the document. 108 | Try resizing the window to make sure it updates. 109 |
110 |117 | The element is absolutely positioned at the bottom right edge. 118 | Try resizing to see how max-width comes into play. 119 |
120 |148 | This element should take up as much space as its siblings. 149 |
150 |164 | This element should take up as much space as possible. 165 |
166 |188 | Browsers ignore the width of elements, and use content to size 189 | the different columns. The available width here is what an empty 190 | div would be assigned in the same context. 191 |
192 |One | 199 |Two | 200 |Three | 201 |
---|---|---|
220 | All columns should have the same width. 221 |
222 |One | 229 |Two | 230 |Three | 231 |
---|---|---|
250 | Some setups will render the DOM once without any css, then apply
251 | styling. Only the ResizeObserver
powered element will
252 | work here.
253 |
266 | Only the ResizeObserver
powered element will adjust its
267 | width here.
268 |
281 | The scroll position should be maintained when resizing the window. 282 |
283 |293 | Sometimes it is useful to have a child that does not render anything. 294 | It is important that these components don't throw errors. 295 |
296 |