flex-item
v4.0.2
Published
React components for styling grids with css flexboxes. Uses emotion under the hood.
Downloads
16
Readme
FlexItem
Responsive grid components for react and emotion.
FlexItem is 3 seperate tools in 1.
- It is a responsive grid.
- It also works well for displaying rows of objects.
- Centering Container.
Installing
npm install flex-item
Note: flex-item
requires React >= v17 and Emotion >= v11 be installed in your project.
npm install react @emotion/react
ThemeProvider Requirements
This component requires a theme provider from the emotion library. Specifically looks for a dimensions and an aspect variable. dimensions is an object that should have a columnSpacing, containerWidth, desktopBreakpoint, rowSpacing, or tabletBreakpoint attribute. aspect is a string with options "desktop", "tablet", or "mobile". This should represent the current aspect ratio the user is on.
The columnSpacing attribute provides a Flex Grid with spacing between the first tier children (columns). This defaults to 6px if nothing is set. This is only used with container prop attribute.
The containerWidth attribute provides a container or max with for the Flex Grid. If you set a containerWidth of 1200 for example, that would limit the FlexGrid to 1200px wide. This defaults to 1200px.
The desktopBreakpoint is first pixel in which the browser size is considered a desktop browser. If you set a desktopBreakpoint of 992 for example, that would start using the tablet media queries at 991px.
The rowSpacing attribute provides a Flex Grid with spacing between each row of first tier children. This defaults to 6px if nothing is set. This is only used with verticalContainer prop attribute.
The tabletBreakpoint is first pixel in which the browser size is considered a tablet browser. If you set a tabletBreakpoint of 768 for example, that would start using the mobile media queries at 767px.
Responsive Grid
FlexItem has 2 main components (FlexGrid and FlexItem).
FlexGrid starts a responsive row. FlexItem represents a column in the row.
FlexGrid has 5 props available.
- className - Allows custom class names on component. FlexGrid always has a flex-grid class for convenience.
- container - Adds padding around each first tier children elements.
- maxMobileRow - Define maximum columns in a row before wrapping for mobile aspect ratio. Defaults to 1. This gives a vertical effect.
- maxPerRow - Define maximum columns in a row before wrapping.
- maxTabletRow - Define maximum columns in a row before wrapping for tablet aspect ratio. Defaults to 1. This gives a vertical effect.
- style - Allows custom inline style.
- verticalContainer - Adds padding around each first tier children elements.
FlexItem has 6 props available.
- className - Allows custom class names on component. FlexItem always has a flex-item class for convenience.
- mobileSize - Amount of columns used for mobile aspect ratio.
- size - Amount of columns used.
- style - Allows custom inline style.
- tabletSize - Amount of columns used for tablet aspect ratio.
Responsive Grid
<FlexGrid container verticalContainer>
<FlexItem>
<div>Thing1</div>
</FlexItem>
<FlexItem>
<div>Thing2</div>
</FlexItem>
<FlexItem>
<div>Thing3</div>
</FlexItem>
</FlexGrid>
Mobile:
Let's adjust this for mobile responsiveness.
<FlexGrid maxMobileRow={2}>
<FlexItem size={2}>
<div>Thing1</div>
</FlexItem>
<FlexItem>
<div>Thing2</div>
</FlexItem>
<FlexItem>
<div>Thing3</div>
</FlexItem>
</FlexGrid>
Rows
<FlexGrid maxPerRow={7} maxTabletRow={4}>
<FlexItem tabletSize={4}>
<div>Thing1</div>
</FlexItem>
<FlexItem size={2} tabletSize={3}>
<div>Thing2</div>
</FlexItem>
<FlexItem tabletSize={1}>
<div>Thing3</div>
</FlexItem>
<FlexItem size={3} tabletSize={4}>
<div>Thing4</div>
</FlexItem>
<FlexItem>
<div>Thing5</div>
</FlexItem>
<FlexItem>
<div>Thing6</div>
</FlexItem>
<FlexItem>
<div>Thing7</div>
</FlexItem>
<FlexItem>
<div>Thing8</div>
</FlexItem>
<FlexItem>
<div>Thing9</div>
</FlexItem>
<FlexItem>
<div>Thing10</div>
</FlexItem>
</FlexGrid>
But on tablet the column ratios are all different.
Setting aspect ratio on ThemeProvider
import React from "react";
import { render } from "react-dom";
import { ThemeProvider } from "emotion-theming";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
aspect: this.fetchAspect()
};
}
componentDidMount() {
window.addEventListener("resize", () => this.updateAspect());
}
componentWillUnmount() {
window.removeEventListener("resize", () => this.updateAspect());
}
fetchAspect() {
const width = Math.max(
document.body.scrollWidth,
document.documentElement.scrollWidth,
document.body.offsetWidth,
document.documentElement.offsetWidth,
document.documentElement.clientWidth
);
let aspect = "desktop";
if(width < Dimensions.tabletBreakpoint) {
aspect = "mobile";
} else if(width < Dimensions.desktopBreakpoint) {
aspect = "tablet";
}
return(aspect);
}
updateAspect() {
const aspect = this.fetchAspect();
if(aspect !== this.state.aspect) {
this.setState({aspect: aspect});
}
}
render() {
const dimensions = {
containerWidth: 1200,
desktopBreakpoint: 992,
tabletBreakpoint: 768
};
return(
<ThemeProvider theme={{aspect: this.state.aspect, dimensions: dimensions}}>
</ThemeProvider>
);
}
}
Demo
The demo app runs Webpack.
Simply run the folling to start the app at localhost:3322
npm install
npm start
Contributing
Contributors to this project should:
- Fork the repository.
- Commit changes to a branch within the fork.
- Start a pull request in GitHub with a description of the fix.
Example
import React from "react";
import { ThemeProvider } from "emotion-theming";
class Example extends React.Component {
render() {
return(
<ThemeProvider theme={{dimensions: {containerWidth: "1200"}}}>
<FlexGrid>
<FlexItem>
<div>Thing1</div>
</FlexItem>
<FlexItem>
<div>Thing2</div>
</FlexItem>
<FlexItem>
<div>Thing3</div>
</FlexItem>
</FlexGrid>
</ThemeProvider>
);
}
}
module.exports = Example;