Skip to content

Commit 27e03ec

Browse files
committed
Initial commit
0 parents  commit 27e03ec

5 files changed

Lines changed: 150 additions & 0 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
dist

.npmignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
src
3+
.rush

README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# React Responsive Div
2+
3+
Responsive React container using breakpoints based on container (not viewport) width.
4+
5+
The core of https://github.com/philipwalton/responsive-components ported to React
6+
using hooks to manage creation/cleanup of observers for each container instead of using a global observer.
7+
8+
### Default breakpoints:
9+
10+
{
11+
SM: 384,
12+
MD: 576,
13+
LG: 768,
14+
XL: 960,
15+
}
16+
17+
## Usage:
18+
19+
```sh
20+
npm install --save @walrusk/react-responsive-div
21+
```
22+
23+
```javascript
24+
import Div from '@walrusk/react-responsive-div';
25+
```
26+
27+
```javascript
28+
<Div>
29+
...
30+
responsive content
31+
...
32+
</Div>
33+
```
34+
35+
```javascript
36+
const customBreakpoints = {
37+
SM: 384,
38+
MD: 576,
39+
LG: 768,
40+
XL: 960,
41+
};
42+
<Div breakpoints={customBreakpoints}>
43+
...
44+
content
45+
...
46+
</Div>
47+
```
48+
49+
## Output based on container size:
50+
```html
51+
<div class="SM">... content ...</div>
52+
or
53+
<div class="SM MD">... content ...</div>
54+
or
55+
<div class="SM MD LG">... content ...</div>
56+
or
57+
<div class="SM MD LG XL">... content ...</div>
58+
```
59+
60+
## Notes:
61+
62+
Considered adjusting behaviour to only set class of current breakpoint e.g. medium being `MD` instead of `SM MD`. May add a prop for this in future but not sure yet if this is actually needed. In most cases in CSS you want to target both and you can target small only with this pattern using `.SM:not(.MD)`.

package.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"name": "@walrusk/react-responsive-div",
3+
"version": "0.1.0",
4+
"description": "Responsive React container using breakpoints based on container (not viewport) width.",
5+
"homepage": "https://github.com/walrusk/react-responsive-div#readme",
6+
"author": "Rob Norman <walrusk@gmail.com> (https://magnetnet.net)",
7+
"main": "dist/Div.js",
8+
"module": "dist/Div.js",
9+
"license": "MIT",
10+
"scripts": {
11+
"build": "NODE_ENV=production && rm -rf dist && mkdir dist && babel src --out-dir dist --copy-files"
12+
},
13+
"peerDependencies": {
14+
"react": "^16.13.1",
15+
"react-dom": "^16.13.1"
16+
},
17+
"devDependencies": {
18+
"babel-cli": "^6.26.0",
19+
"babel-preset-env": "^1.7.0",
20+
"babel-preset-react": "^6.24.1",
21+
"babel-preset-stage-2": "^6.24.1"
22+
},
23+
"repository": {
24+
"type" : "git",
25+
"url" : "https://github.com/walrusk/react-responsive-div.git"
26+
},
27+
"browserslist": [
28+
">0.2%",
29+
"not dead",
30+
"not ie <= 11",
31+
"not op_mini all"
32+
],
33+
"babel": {
34+
"presets": [
35+
"react",
36+
"env",
37+
"stage-2"
38+
]
39+
}
40+
}

src/Div.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React, {useRef, useEffect} from 'react';
2+
3+
// Default breakpoints that should apply to all observed
4+
// elements that don't define their own custom breakpoints.
5+
const defaultBreakpoints = {
6+
SM: 384,
7+
MD: 576,
8+
LG: 768,
9+
XL: 960,
10+
};
11+
12+
export default function Div({ breakpoints: customBreakpoints, ...props }) {
13+
const breakpoints = customBreakpoints || defaultBreakpoints;
14+
const containerRef = useRef(null);
15+
useResizeObserver(breakpoints, containerRef);
16+
return (
17+
<div ref={containerRef} {...props} />
18+
);
19+
}
20+
21+
export function useResizeObserver(breakpoints, containerRef) {
22+
useEffect(() => {
23+
if (window.ResizeObserver) {
24+
const ro = new window.ResizeObserver((entries) => {
25+
entries.forEach((entry) => {
26+
// Update the matching breakpoints on the observed element.
27+
Object.keys(breakpoints).forEach(breakpoint => {
28+
const minWidth = breakpoints[breakpoint];
29+
if (entry.contentRect.width >= minWidth) {
30+
entry.target.classList.add(breakpoint);
31+
} else {
32+
entry.target.classList.remove(breakpoint);
33+
}
34+
});
35+
});
36+
});
37+
ro.observe(containerRef.current);
38+
return () => ro.disconnect();
39+
} else if (process && process.env.NODE_ENV === 'development') {
40+
console.warn('Resize observer not supported');
41+
}
42+
}, []);
43+
}

0 commit comments

Comments
 (0)