├── .all-contributorsrc ├── .editorconfig ├── .eslintrc ├── .github └── workflows │ └── publish.yml ├── .gitignore ├── .prettierrc ├── .vscode └── settings.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── babel.config.cjs ├── blog ├── 2021-08-26-welcome │ ├── docusaurus-plushie-banner.jpeg │ └── index.md └── authors.yml ├── docs ├── custom.mdx ├── index.mdx ├── playground.mdx ├── props.mdx ├── usage.mdx └── util.mdx ├── docusaurus.config.ts ├── jest.config.ts ├── jestSetup.ts ├── jsconfig.json ├── lib ├── components │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ ├── col.test.tsx.snap │ │ │ ├── container.test.tsx.snap │ │ │ ├── hidden.test.tsx.snap │ │ │ ├── row.test.tsx.snap │ │ │ └── visible.test.tsx.snap │ │ ├── col.test.tsx │ │ ├── container.test.tsx │ │ ├── hidden.test.tsx │ │ ├── row.test.tsx │ │ ├── screens.test.tsx │ │ └── visible.test.tsx │ ├── grid │ │ ├── col.tsx │ │ ├── container.tsx │ │ └── row.tsx │ ├── helper.ts │ └── util │ │ ├── hidden.tsx │ │ ├── screenBadge.tsx │ │ ├── screenClass.tsx │ │ ├── screens.ts │ │ └── visible.tsx ├── config.ts ├── index.ts ├── styled.d.ts └── types.ts ├── package.json ├── public └── favicon.ico ├── renovate.json ├── rollup.config.mjs ├── sidebars.ts ├── src ├── components │ └── HomepageFeatures │ │ └── index.tsx ├── css │ └── custom.css ├── pages │ ├── demo.tsx │ ├── index.tsx │ └── markdown-page.md └── theme │ └── ReactLiveScope │ └── index.tsx ├── static ├── .nojekyll └── img │ ├── favicon.ico │ ├── icon.svg │ ├── pluto-consistency-and-reliability.png │ ├── pluto-easy-to-use.png │ ├── pluto-focus-on-what-matters.png │ ├── pluto-time-efficiency.png │ └── social-card.png ├── tsconfig.build.json ├── tsconfig.json └── yarn.lock /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "react-awesome-styled-grid", 3 | "projectOwner": "santosfrancisco", 4 | "repoType": "github", 5 | "repoHost": "https://github.com", 6 | "files": [ 7 | "README.md" 8 | ], 9 | "imageSize": 100, 10 | "commit": true, 11 | "contributors": [ 12 | { 13 | "login": "santosfrancisco", 14 | "name": "Francisco Santos", 15 | "avatar_url": "https://avatars3.githubusercontent.com/u/15852005?v=4", 16 | "profile": "http://devchico.com", 17 | "contributions": [ 18 | "code", 19 | "doc", 20 | "review" 21 | ] 22 | }, 23 | { 24 | "login": "camilaibs", 25 | "name": "Camila Belo", 26 | "avatar_url": "https://avatars3.githubusercontent.com/u/6290749?v=4", 27 | "profile": "http://camilaibs.wix.com/blog", 28 | "contributions": [ 29 | "test" 30 | ] 31 | }, 32 | { 33 | "login": "Fabioh", 34 | "name": "Fábio Henrique Gabriele", 35 | "avatar_url": "https://avatars0.githubusercontent.com/u/10605659?v=4", 36 | "profile": "https://github.com/Fabioh", 37 | "contributions": [ 38 | "test" 39 | ] 40 | }, 41 | { 42 | "login": "BernardoMariano", 43 | "name": "Bernardo Mariano", 44 | "avatar_url": "https://avatars2.githubusercontent.com/u/3067157?v=4", 45 | "profile": "https://github.com/BernardoMariano", 46 | "contributions": [ 47 | "code" 48 | ] 49 | }, 50 | { 51 | "login": "ixahmedxi", 52 | "name": "Ahmed Tarek", 53 | "avatar_url": "https://avatars2.githubusercontent.com/u/20271968?v=4", 54 | "profile": "https://github.com/ixahmedxi", 55 | "contributions": [ 56 | "code" 57 | ] 58 | }, 59 | { 60 | "login": "zero0Halo", 61 | "name": "Steve Swanson", 62 | "avatar_url": "https://avatars0.githubusercontent.com/u/2113956?v=4", 63 | "profile": "https://github.com/zero0Halo", 64 | "contributions": [ 65 | "maintenance" 66 | ] 67 | } 68 | ], 69 | "commitConvention": "none" 70 | } 71 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain 2 | # consistent coding styles between different editors and IDEs. 3 | 4 | root = true 5 | 6 | [*] 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | indent_style = space 12 | indent_size = 2 13 | quote_type = single 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "parserOptions": { 4 | "ecmaVersion": 12, 5 | "sourceType": "module" 6 | }, 7 | "plugins": ["@typescript-eslint"], 8 | // HERE 9 | "extends": [ 10 | "eslint:recommended", 11 | "plugin:react/recommended", 12 | "plugin:@typescript-eslint/recommended", 13 | "plugin:react/jsx-runtime", 14 | "prettier" 15 | ], 16 | 17 | "rules": { 18 | "@typescript-eslint/no-unused-vars": "error", 19 | "@typescript-eslint/consistent-type-definitions": ["error", "type"] 20 | }, 21 | "settings": { 22 | "react": { 23 | "version": "detect" 24 | } 25 | }, 26 | "env": { 27 | "browser": true, 28 | "jest": true 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to NPM 2 | on: 3 | release: 4 | types: [created] 5 | 6 | jobs: 7 | publish: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | - uses: actions/setup-node@v3 12 | with: 13 | node-version: "18" 14 | - name: Setup and install dependencies 15 | run: | 16 | npm i -g corepack 17 | yarn install 18 | - name: Build library 🔧 19 | run: yarn build 20 | - uses: JS-DevTools/npm-publish@v3 21 | with: 22 | token: ${{ secrets.NPM_TOKEN }} 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .docz 2 | # lib 3 | dist 4 | /types 5 | .DS_Store 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # Optional npm cache directory 48 | .npm 49 | 50 | # Optional eslint cache 51 | .eslintcache 52 | 53 | # Optional REPL history 54 | .node_repl_history 55 | 56 | # Output of 'npm pack' 57 | *.tgz 58 | 59 | # Yarn Integrity file 60 | .yarn-integrity 61 | 62 | # dotenv environment variables file 63 | .env 64 | 65 | # next.js build output 66 | .next 67 | 68 | # Dependencies 69 | /node_modules 70 | 71 | # Production 72 | /build 73 | 74 | # Generated files 75 | .docusaurus 76 | .cache-loader 77 | 78 | # Misc 79 | .DS_Store 80 | .env.local 81 | .env.development.local 82 | .env.test.local 83 | .env.production.local 84 | 85 | npm-debug.log* 86 | yarn-debug.log* 87 | yarn-error.log* 88 | 89 | #rollup 90 | .rollup.cache 91 | 92 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "none", 4 | "singleQuote": false 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | } 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | 1. Fork it! 4 | 2. Create your feature branch: `git checkout -b my-new-feature` 5 | 3. Commit your changes: `git commit -m 'Add some feature'` 6 | 4. Push to the branch: `git push origin my-new-feature` 7 | 8 | *Remember that we have a pre-push hook with steps that analyzes and prevents mistakes.* 9 | 10 | **After your pull request is merged**, you can safely delete your branch. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Francisco Santos 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![npm version](https://badge.fury.io/js/react-awesome-styled-grid.svg)](https://www.npmjs.com/package/react-awesome-styled-grid) 2 | [![All Contributors](https://img.shields.io/badge/all_contributors-6-orange.svg?style=flat-square)](#contributors) 3 | [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) 4 | [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com) 5 | [![codecov](https://codecov.io/gh/santosfrancisco/react-awesome-styled-grid/branch/master/graph/badge.svg)](https://codecov.io/gh/santosfrancisco/react-awesome-styled-grid) 6 | [![Publish to NPM](https://github.com/santosfrancisco/react-awesome-styled-grid/actions/workflows/publish.yml/badge.svg)](https://github.com/santosfrancisco/react-awesome-styled-grid/actions/workflows/publish.yml) 7 | [![Netlify Status](https://api.netlify.com/api/v1/badges/47a9c7f7-444d-4df9-bc7b-10cb06265ed7/deploy-status)](https://app.netlify.com/sites/awesome-styled-grid/deploys) 8 | 9 | # React Awesome Styled Grid 😎 10 | 11 | A responsive grid system for React using styled-components 12 | 13 | ## Installation 14 | 15 | ```bash 16 | npm i --save react-awesome-styled-grid 17 | ``` 18 | 19 | ## Dependencies 20 | 21 | **styled-components** is a peerDependency and must be installed separately. 22 | 23 | ```bash 24 | npm i --save styled-components 25 | ``` 26 | 27 | ## Documentation 28 | 29 | Click [here](https://awesome-styled-grid.netlify.app/) for documentation 30 | 31 | ## Basic usage 32 | 33 | This grid system is mobile-first based on [Google Material Design](https://material.io/design/layout/responsive-layout-grid.html). 34 | 35 | Number of columns: **xs**: 4, **sm**: 8, **md**: 8, **lg**: 12, **xl**: 12 36 | 37 | Breakpoints size: **xs**: > 1rem, **sm**: > 48rem, **md**: > 64rem, **lg**: > 90rem, **xl**: > 120rem 38 | 39 | > for a custom configuration, [see this section](https://awesome-styled-grid.netlify.app/custom) of documentation 40 | 41 | ```js 42 | import { Container, Row, Col } from "react-awesome-styled-grid"; 43 | 44 | const MyCoolComponent = () => ( 45 | 46 | 47 | 48 | Col A 49 | 50 | 51 | Col B 52 | 53 | 54 | 55 | ); 56 | ``` 57 | 58 | ## Development 59 | 60 | run `yarn install` or `npm install` to install all dependencies 61 | 62 | run `yarn start` or `npm run start` to run Docusaurus on port 3000 63 | 64 | Go to [http://localhost:3000/demo](http://localhost:3000/demo) to see live demo and edit [Demo.tsx](src/pages/demo.tsx) file 65 | 66 | ## Built With 67 | 68 | - [Styled-components](https://github.com/styled-components) - Visual primitives for the component age. 69 | - [Docusaurus](https:://docusaurus.io) - Build optimized websites quickly, focus on your content 70 | - [Rollup](https://rollupjs.org/guide/en) - Rollup is a module bundler for JavaScript 71 | 72 | ## Contributing 73 | 74 | Please read [CONTRIBUTING.md](https://github.com/santosfrancisco/react-awesome-styled-grid/blob/master/CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us. 75 | 76 | See also the list of [contributors](https://github.com/santosfrancisco/react-awesome-styled-grid/contributors) who participated in this project. 77 | 78 | ## License 79 | 80 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details 81 | 82 | ## Contributors 83 | 84 | Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)): 85 | 86 | 87 | 88 |
Francisco Santos
Francisco Santos

💻 📖 👀
Camila Belo
Camila Belo

⚠️
Fábio Henrique Gabriele
Fábio Henrique Gabriele

⚠️
Bernardo Mariano
Bernardo Mariano

💻
Ahmed Tarek
Ahmed Tarek

💻
Steve Swanson
Steve Swanson

🚧
89 | 90 | 91 | 92 | This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome! 93 | -------------------------------------------------------------------------------- /babel.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | ["@babel/preset-env", { targets: { node: "current" } }], 4 | ["@babel/preset-react"], 5 | "@babel/preset-typescript", 6 | "@docusaurus/core/lib/babel/preset" 7 | ], 8 | plugins: [ 9 | "@babel/plugin-proposal-object-rest-spread", 10 | "transform-class-properties", 11 | "babel-plugin-styled-components" 12 | ] 13 | }; 14 | -------------------------------------------------------------------------------- /blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santosfrancisco/react-awesome-styled-grid/f37f04fbcabec505dc2502be47044061f107060e/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg -------------------------------------------------------------------------------- /blog/2021-08-26-welcome/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: welcome 3 | title: Welcome 4 | authors: [santosfrancisco] 5 | tags: [react, styled-components] 6 | --- 7 | 8 | [Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog). 9 | 10 | Simply add Markdown files (or folders) to the `blog` directory. 11 | 12 | Regular blog authors can be added to `authors.yml`. 13 | 14 | The blog post date can be extracted from filenames, such as: 15 | 16 | - `2019-05-30-welcome.md` 17 | - `2019-05-30-welcome/index.md` 18 | 19 | A blog post folder can be convenient to co-locate blog post images: 20 | 21 | ![Docusaurus Plushie](./docusaurus-plushie-banner.jpeg) 22 | 23 | The blog supports tags as well! 24 | 25 | **And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config. 26 | -------------------------------------------------------------------------------- /blog/authors.yml: -------------------------------------------------------------------------------- 1 | santosfrancisco: 2 | name: Francisco Santos 3 | title: Maintainer of RASG 4 | url: https://github.com/santosfrancisco 5 | image_url: https://github.com/santosfrancisco.png 6 | -------------------------------------------------------------------------------- /docs/custom.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | name: Custom configuration 4 | --- 5 | 6 | # Custom configuration 7 | 8 | ## Using a custom configuration 9 | 10 | To use a custom config, import the **ThemeProvider** 11 | from Styled-components `import { ThemeProvider } from 'styled-components'`, 12 | and pass a named object `awesomegrid` to the theme prop, as the example below. 13 | The properties of your custom configuration will overwrite the default settings. Just set properties that are different from the default. 14 | 15 | Try changing any property in `customConf` below and see what happens. 16 | 17 | ```jsx live 18 | function Custom(props) { 19 | const customConf = { 20 | mediaQuery: "only screen", 21 | columns: { 22 | xs: 4, 23 | sm: 8, 24 | md: 8, 25 | lg: 12, 26 | xl: 12 27 | }, 28 | gutterWidth: { 29 | xs: 1, 30 | sm: 1, 31 | md: 1.5, 32 | lg: 1.5, 33 | xl: 1.5 34 | }, 35 | paddingWidth: { 36 | xs: 1, 37 | sm: 1, 38 | md: 1.5, 39 | lg: 1.5, 40 | xl: 1.5 41 | }, 42 | container: { 43 | xs: "full", // 'full' = max-width: 100% 44 | sm: "full", // 'full' = max-width: 100% 45 | md: "full", // 'full' = max-width: 100% 46 | lg: 90, // max-width: 1440px 47 | xl: 90 // max-width: 1440px 48 | }, 49 | breakpoints: { 50 | xs: 1, 51 | sm: 48, // 768px 52 | md: 64, // 1024px 53 | lg: 90, // 1440px 54 | xl: 120 // 1920px 55 | } 56 | }; 57 | 58 | return ( 59 | 60 | 61 | 62 | 63 | 64 | xs={4} sm={5} md={3} 65 | 66 | 67 | xs={4} sm={3} md={9} 68 | 69 | 70 | 71 | 72 | xs={2} sm={6} md={5} lg={6} 73 | 74 | 75 | xs={2} sm={2} md={7} lg={6} 76 | 77 | 78 | 79 | 80 | ( 82 |

87 | Hello! Actual screen is {screen} 88 |

89 | )} 90 | /> 91 | 92 |
93 | 94 |
This text is hidden only on: XS
95 |
96 |
97 |
98 | ); 99 | } 100 | ``` 101 | -------------------------------------------------------------------------------- /docs/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | name: Getting Started 4 | --- 5 | 6 | # Getting Started 7 | 8 | [![npm version](https://badge.fury.io/js/react-awesome-styled-grid.svg)](https://www.npmjs.com/package/react-awesome-styled-grid) 9 | 10 | > A responsive (mobile-first) grid system for React using styled-components 11 | 12 | ## Installation 13 | 14 | ```bash npm2yarn 15 | npm i react-awesome-styled-grid 16 | ``` 17 | 18 | ## Basic usage 19 | 20 | This grid system is based on [Google Material Design](https://material.io/design/layout/responsive-layout-grid.html). 21 | 22 | Number of columns: **xs**: 4, **sm**: 8, **md**: 8, **lg**: 12, **xl**: 12 23 | 24 | Breakpoints size: **xs**: 1rem, **sm**: 48rem, **md**: 64rem, **lg**: 90rem, **xl**: 120rem 25 | 26 | > for a custom configuration, [see this section](/docs/custom) 27 | 28 | ```jsx 29 | import { Container, Row, Col } from "react-awesome-styled-grid"; 30 | 31 | const MyCoolComponent = () => ( 32 | 33 | 34 | 35 | Col A 36 | 37 | 38 | Col B 39 | 40 | 41 | 42 | ); 43 | ``` 44 | -------------------------------------------------------------------------------- /docs/playground.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | name: Playground 4 | --- 5 | 6 | import { 7 | Container, 8 | Row, 9 | Col, 10 | Visible, 11 | Hidden, 12 | ScreenClass, 13 | ScreenBadge, 14 | config, 15 | util 16 | } from "../lib"; 17 | 18 | # Playground 19 | 20 | 😎 Have fun! 21 | 22 | ```jsx live 23 | function Playground() { 24 | return ( 25 | 26 | 27 | 28 | 29 | Column 1 30 | 31 | 32 | Column 2 33 | 34 | 35 | Column 3 36 | 37 | 38 | Column 4 39 | 40 | 41 | 42 | 43 | 44 | Visible XS 45 | 46 | 47 | 48 | 49 | Visible MD 50 | 51 | 52 | 53 | 54 | Hidden XS 55 | 56 | 57 | 58 | 59 | Hidden MD 60 | 61 | 62 | 63 | 64 | ); 65 | } 66 | ``` 67 | -------------------------------------------------------------------------------- /docs/props.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | name: Table of props 4 | --- 5 | 6 | # Table of Props 7 | 8 | ## Container 9 | 10 | | prop | type | description | 11 | | -------- | ------- | -------------------------- | 12 | | fluid | boolean | makes container full-width | 13 | | debug | boolean | enables debug | 14 | | children | node | content | 15 | 16 | ## Row 17 | 18 | | prop | type | description | 19 | | -------- | ---------------- | --------------------------------- | 20 | | justify | string or object | align the content horizontally | 21 | | align | string or object | align the content vertically | 22 | | reverse | number or array | reverses the direction of the row | 23 | | debug | boolean | enables debug | 24 | | children | node | content | 25 | 26 | ## Col 27 | 28 | | prop | type | description | 29 | | -------- | ---------------- | ------------------------------------------ | 30 | | xs | number or string | sets the number of columns on screens _xs_ | 31 | | sm | number or string | sets the number of columns on screens _sm_ | 32 | | md | number or string | sets the number of columns on screens _md_ | 33 | | lg | number or string | sets the number of columns on screens _lg_ | 34 | | xl | number or string | sets the number of columns on screens _xl_ | 35 | | justify | string or object | align the content vertically | 36 | | align | string or object | align the content horizontally | 37 | | offset | number or object | sets the number of the offset columns | 38 | | order | number or object | sets the order of the columns | 39 | | reverse | number or array | reverses the direction of the column | 40 | | noGutter | boolean | removes the gutter | 41 | | debug | boolean | enables debug | 42 | | children | node | content | 43 | 44 | ## Visible 45 | 46 | | prop | type | description | 47 | | -------- | ------- | --------------------------------------------------------------------- | 48 | | xs | boolean | indicates that past content will only be displayed on the screen _xs_ | 49 | | sm | boolean | indicates that past content will only be displayed on the screen _sm_ | 50 | | md | boolean | indicates that past content will only be displayed on the screen _md_ | 51 | | lg | boolean | indicates that past content will only be displayed on the screen _lg_ | 52 | | xl | boolean | indicates that past content will only be displayed on the screen _xl_ | 53 | | children | node | content | 54 | 55 | ## Hidden 56 | 57 | | prop | type | description | 58 | | -------- | ------- | ------------------------------------------------------------------ | 59 | | xs | boolean | indicates that past content will only be hidden on the screen _xs_ | 60 | | sm | boolean | indicates that past content will only be hidden on the screen _sm_ | 61 | | md | boolean | indicates that past content will only be hidden on the screen _md_ | 62 | | lg | boolean | indicates that past content will only be hidden on the screen _lg_ | 63 | | xl | boolean | indicates that past content will only be hidden on the screen _xl_ | 64 | | children | node | content | 65 | 66 | ## ScreenClass 67 | 68 | | prop | type | description | 69 | | ------ | ---- | ------------------------------------------------------------------------------ | 70 | | render | func | the function that will be rendered receiving the current screen as a parameter | 71 | -------------------------------------------------------------------------------- /docs/usage.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | name: Usage 4 | --- 5 | 6 | import { 7 | Container, 8 | Row, 9 | Col, 10 | Visible, 11 | Hidden, 12 | ScreenClass, 13 | ScreenBadge 14 | } from "../lib"; 15 | 16 | # Usage 17 | 18 | ##### Code example 19 | 20 | ```jsx 21 | import { 22 | Container, 23 | Row, 24 | Col, 25 | Visible, 26 | Hidden, 27 | ScreenClass, 28 | ScreenBadge 29 | } from "react-awesome-styled-grid"; 30 | ``` 31 | 32 | Resizes your window to see the responsive magic happening 😎 33 | 34 | ## Responsive 35 | 36 | 37 | 38 | 39 | xs={2} sm={6} md={2} lg={6} 40 | 41 | 42 | xs={2} sm={2} md={6} lg={6} 43 | 44 | 45 | 46 | 47 | xs={2} sm={2} md={6} lg={6} 48 | 49 | 50 | xs={2} sm={6} md={2} lg={6} 51 | 52 | 53 | 54 | 55 | xs={2} sm={6} md={2} lg={6} 56 | 57 | 58 | xs={2} sm={2} md={6} lg={6} 59 | 60 | 61 | 62 | 63 | > 💡**Tip!** if no dimension is defined, the column size will be **auto**. 64 | > (i.e. md={6}. This means that `xs` and `sm` is auto, 65 | > and from `md`, the size will be 6 columns) 66 | 67 | ##### Code example 68 | 69 | ```jsx 70 | 71 | 72 | 73 | xs={2} sm={6} md={2} lg={6} 74 | 75 | 76 | xs={2} sm={2} md={6} lg={6} 77 | 78 | 79 | 80 | 81 | xs={1} sm={4} md={3} lg={4} 82 | 83 | 84 | xs={3} sm={4} md={5} lg={8} 85 | 86 | 87 | 88 | ``` 89 | 90 | ## Offset 91 | 92 | ### Using number 93 | 94 | if you enter a number, the number of columns of the screen xs will be used as base. in this example, 2 columns of 4 will be used for both offset and column size, ie 50%. 95 | 96 | 97 | 98 | 99 | 50% offset 100 | 101 | 102 | 103 | 104 | ### Using object 105 | 106 | in this case, the `offset` prop must receive an object with the screens and their respective values. 107 | 108 | 109 | 110 | 111 |   112 | 113 | 114 | 115 | 116 |   117 | 118 | 119 | 120 | 121 |   122 | 123 | 124 | 125 | 126 |   127 | 128 | 129 | 130 | 131 |   132 | 133 | 134 | 135 | 136 |   137 | 138 | 139 | 140 | 141 |   142 | 143 | 144 | 145 | 146 |   147 | 148 | 149 | 150 | 151 |   152 | 153 | 154 | 155 | 156 |   157 | 158 | 159 | 160 | 161 |   162 | 163 | 164 | 165 | 166 | ##### Code example 167 | 168 | ```jsx 169 | 170 | 171 | 172 |   173 | 174 | 175 | 176 | 177 |   178 | 179 | 180 | 181 | 182 |   183 | 184 | 185 | 186 | 187 |   188 | 189 | 190 | 191 | 192 |   193 | 194 | 195 | 196 | 197 |   198 | 199 | 200 | 201 | 202 |   203 | 204 | 205 | 206 | 207 |   208 | 209 | 210 | 211 | 212 |   213 | 214 | 215 | 216 | 217 |   218 | 219 | 220 | 221 | 222 |   223 | 224 | 225 | 226 | ``` 227 | 228 | ## Order 229 | 230 | ### Using number 231 | 232 | You can order the columns by occlunes using the order property. This is mainly useful when it is necessary for the columns to have a different order for one dimension or another. 233 | 234 | If you enter a number, that number will apply to all screens. 235 | 236 | 237 | 238 | 239 | order 3 240 | 241 | 242 | order 1 243 | 244 | 245 | 246 | 247 | ##### Code example 248 | 249 | ```jsx 250 | 251 | 252 | 253 | order 3 254 | 255 | 256 | order 1 257 | 258 | 259 | 260 | ``` 261 | 262 | ### Using object 263 | 264 | in this case, the `order` prop must receive an object with the screens and their respective values. 265 | 266 | 267 | 268 | 269 | Column A 270 | 271 | 272 | Column B 273 | 274 | 275 | Column C 276 | 277 | 278 | Column D 279 | 280 | 281 | 282 | 283 | ##### Code example 284 | 285 | ```jsx 286 | 287 | 288 | 289 | Column A 290 | 291 | 292 | Column B 293 | 294 | 295 | Column C 296 | 297 | 298 | Column D 299 | 300 | 301 | 302 | ``` 303 | 304 | ## Alignment 305 | 306 | The props `align` and `justify` allow you to centralize `Row` or `Col` content using the [align-items](https://developer.mozilla.org/en-US/docs/Web/CSS/align-items) 307 | and [justify-content](https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content) values from flexbox api 308 | 309 | > The `align` and `justify` props work according to the axis and direction of `flex-items`. 310 | > This means that in the `Col`, the horizontal alignment is changed by prop `align` and the vertical alignment is changed by prop `justify`. 311 | 312 | ### Align 313 | 314 | The prop `align` receives a string or a object with the screens and their respective values and will align the content **_vertically_** in the `Row` and will align **_horizontally_** in the `Col`. 315 | 316 | Accepted values: 317 | 318 | **_align_**: `stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe;` 319 | 320 | #### Using string 321 | 322 | Just pass a valid value from flexbox api to `align` prop 323 | 324 | 325 | 326 | 327 | 😎 328 | 329 | 330 | 🤩 331 | 332 | 333 | 😱 334 | 335 | 336 | 😍 337 | 338 | 339 | 340 | 341 | Aligned at end of row 342 | 343 | 344 | 345 | 346 | ##### Code example 347 | 348 | ```jsx 349 | 350 | 351 | 352 | 😎 353 | 354 | 355 | 🤩 356 | 357 | 358 | 😱 359 | 360 | 361 | 😍 362 | 363 | 364 | 365 | 366 | Aligned at end of row 367 | 368 | 369 | 370 | ``` 371 | 372 | ### Using object 373 | 374 | in this case, the `align` prop must receive an object with the screens and their respective values. 375 | 376 | > 💡**Tip!** When passed an object, since this grid is mobile-first, if a value is entered for a screen (i.e XS), 377 | > the other screens (SM, MD, LG and XL) will inherit these values ​​if not set. 378 | > With that in mind, if you enter `align={{xs: 'center', lg: 'flex-end'}}`, we'll have **_XS_** 379 | > to **_MD_** with align set to center and **_LG_** to **_XL_** set to flex-end. 380 | 381 | 382 | 383 | 384 | 😎 385 | 386 | 387 | 🤩 388 | 389 | 390 | 😱 391 | 392 | 393 | 😍 394 | 395 | 396 | 397 | 403 | XS to MD alignd at end of row, LG to XL is centered 404 | 405 | 406 | 407 | 408 | ##### Code example 409 | 410 | ```jsx 411 | 412 | 413 | 414 | 😎 415 | 416 | 417 | 🤩 418 | 419 | 420 | 😱 421 | 422 | 423 | 😍 424 | 425 | 426 | 427 | 433 | XS to MD alignd at end of row, LG to XL is centered 434 | 435 | 436 | 437 | ``` 438 | 439 | ### Justify 440 | 441 | The prop `justify` receives a string or a object with the screens and their respective values and will align the content **_horizontally_** in the `Row` and will align **_vertically_** in the `Col`. 442 | 443 | Accepted values: 444 | 445 | **_justify_**: `flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;` 446 | 447 | #### Using string 448 | 449 | Just pass a valid value from flexbox api to `justify` prop 450 | 451 | 452 | 453 | 454 | 😎 455 | 456 | 457 | 🤩 458 | 459 | 460 | 461 | 462 | 😱 463 | 464 | 465 | 😍 466 | 467 | 468 | 469 | 470 | Vertically centered 471 | 472 | 473 | 474 | 475 | ##### Code example 476 | 477 | ```jsx 478 | 479 | 480 | 481 | 😎 482 | 483 | 484 | 🤩 485 | 486 | 487 | 488 | 489 | 😱 490 | 491 | 492 | 😍 493 | 494 | 495 | 496 | 497 | Vertically centered 498 | 499 | 500 | 501 | ``` 502 | 503 | ### Using object 504 | 505 | in this case, the `justify` prop must receive an object with the screens and their respective values. 506 | 507 | > 💡**Tip!** When passed an object, since this grid is mobile-first, if a value is entered for a screen (i.e XS), 508 | > the other screens (SM, MD, LG and XL) will inherit these values ​​if not set. 509 | > With that in mind, if you enter `justify={{xs: 'center', lg: 'space-between'}}`, we'll have **_XS_** 510 | > to **_MD_** with justify set to center and **_LG_** to **_XL_** set to space-between. 511 | 512 | 513 | 514 | 515 | 😎 516 | 517 | 518 | 🤩 519 | 520 | 521 | 522 | 523 | 😱 524 | 525 | 526 | 😍 527 | 528 | 529 | 530 | 536 | XS to MD is centered and LG to XL at bottom{" "} 537 | 538 | 539 | 540 | 541 | ##### Code example 542 | 543 | ```jsx 544 | 545 | 546 | 547 | 😎 548 | 549 | 550 | 🤩 551 | 552 | 553 | 554 | 555 | 😱 556 | 557 | 558 | 😍 559 | 560 | 561 | 562 | 568 | XS to MD is centered and LG to XL at bottom{" "} 569 | 570 | 571 | 572 | ``` 573 | 574 | ## Row reverse 575 | 576 | `reverse` receives an array with the screens that will have the flow reversed. if it is passed as boolean, the stream will be inverted at all breakpoints 577 | 578 | 579 | 580 | 581 | Column A 582 | 583 | 584 | Column B 585 | 586 | 587 | 588 | 589 | Column A 590 | 591 | 592 | Column B 593 | 594 | 595 | 596 | 597 | ##### Code example 598 | 599 | ```jsx 600 | 601 | 602 | 603 | Column A 604 | 605 | 606 | Column B 607 | 608 | 609 | 610 | 611 | Column A 612 | 613 | 614 | Column B 615 | 616 | 617 | 618 | ``` 619 | 620 | ## Column reverse 621 | 622 | `reverse` receives an array with the screens that will have the flow reversed. if it is passed as boolean, the stream will be inverted at all breakpoints 623 | 624 | 625 | 626 | 627 |
628 | Column A 629 |
630 |
631 | Column B 632 |
633 |
634 | Column C 635 |
636 | 637 | 638 |
639 | Column A 640 |
641 |
642 | Column B 643 |
644 |
645 | Column C 646 |
647 | 648 |
649 |
650 | 651 | ##### Code example 652 | 653 | ```jsx 654 | 655 | 656 | 657 |
658 | Column A 659 |
660 |
661 | Column B 662 |
663 |
664 | Column C 665 |
666 | 667 | 668 |
669 | Column A 670 |
671 |
672 | Column B 673 |
674 |
675 | Column C 676 |
677 | 678 |
679 |
680 | ``` 681 | 682 | ## Visible 683 | 684 | Show a element only in a specific screen size 685 | 686 | ### Example using only text 687 | 688 |
689 | This text is visible only on: XS 690 | This text is visible only on: SM 691 | This text is visible only on: MD 692 | This text is visible only on: LG 693 | This text is visible only on: XL 694 |
695 | 696 | ##### Code example 697 | 698 | ```jsx
699 | This text is visible only on: XS 700 | This text is visible only on: SM 701 | This text is visible only on: MD 702 | This text is visible only on: LG 703 | This text is visible only on: XL 704 |
705 | ``` 706 | 707 | ### Example using an Row with Col 708 | 709 | 710 | 711 | 712 | Visible only on XS and SM screens 713 | 714 | 715 | Visible only on MD, LG and XL screens 716 | 717 | 718 | 719 | 720 | ##### Code example 721 | 722 | ```jsx 723 | 724 | 725 | 726 | Visible only on XS and SM screens 727 | 728 | 729 | Visible only on MD, LG and XL screens 730 | 731 | 732 | 733 | ``` 734 | 735 | ## Hidden 736 | 737 | Hides a element only in a specific screen size 738 | 739 | ### Example using only text 740 | 741 |
742 | 743 |
This text is hidden only on: XS
744 |
745 | 746 |
This text is hidden only on: SM
747 |
748 | 749 |
This text is hidden only on: MD
750 |
751 | 752 |
This text is hidden only on: LG
753 |
754 | 755 |
This text is hidden only on: XL
756 |
757 |
758 | 759 | ##### Code example 760 | 761 | ```jsx
762 | 763 |
This text is hidden only on: XS
764 |
765 | 766 |
This text is hidden only on: SM
767 |
768 | 769 |
This text is hidden only on: MD
770 |
771 | 772 |
This text is hidden only on: LG
773 |
774 | 775 |
This text is hidden only on: XL
776 |
777 |
778 | ``` 779 | 780 | ### Example using an Row with Col 781 | 782 | 783 | 784 | 785 | Hidden only on XS and SM screens 786 | 787 | 788 | Hidden only on MD, LG and XL screens 789 | 790 | 791 | 792 | 793 | ##### Code example 794 | 795 | ```jsx 796 | 797 | 798 | 799 | Hidden only on XS and SM screens 800 | 801 | 802 | Hidden only on MD, LG and XL screens 803 | 804 | 805 | 806 | ``` 807 | 808 | ## ScreenClass 809 | 810 | ScreenClass receive a prop named `render` and renders this by passing the current screen as parameter 811 | 812 | 813 | 814 | 815 | ( 817 |

820 | Hello! Actual screen is {screen} 821 |

822 | )} 823 | /> 824 | 825 |
826 |
827 | 828 | ##### Code example 829 | 830 | ```jsx 831 | 832 | 833 | 834 | ( 836 |

839 | Hello! Actual screen is {screen} 840 |

841 | )} 842 | /> 843 | 844 |
845 |
846 | ``` 847 | 848 | ## ScreenBadge 849 | 850 | Displays a badge in the lower right corner with the current screen for debug 851 | 852 | 853 | 854 | ##### Code example 855 | 856 | ```jsx 857 | 858 | ``` 859 | -------------------------------------------------------------------------------- /docs/util.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | name: Utilities 4 | --- 5 | 6 | # Utilities 7 | 8 | ## Media Queries 9 | 10 | To use in your css the media queries with the same breakpoints of the grid, 11 | just import the config as in the example below. If you are not using a 12 | custom config, it is not mandatory to pass _props_ to config 13 | 14 | > **Tip:** since react-awesome-styled-grid is mobile-first grid, 15 | > the css inserted without media querie is applied in mobile resolution. 16 | > The next media querie (e.g. SM `config().media['sm']`), will apply css on the 17 | > devices with resolutions above of 48 rem (768px), and so on... 18 | 19 | ```jsx 20 | import React from "react"; 21 | import styled from "styled-components"; 22 | import { Container, Row, Col, config } from "react-awesome-styled-grid"; 23 | 24 | export default styled(({ className, children }) => { 25 | return ( 26 | 27 | 28 | {children} 29 | 30 | 31 | ); 32 | })` 33 | // css here... 34 | 35 | ${(props) => config(props).media["sm"]` 36 | color: red; 37 | // ...more css here 38 | `} 39 | 40 | ${(props) => config(props).media["md"]` 41 | color: purple; 42 | font-size: 1.5rem; 43 | // ...more css here 44 | `} 45 | `; 46 | ``` 47 | 48 | > **Your code** 49 | > 50 | > ```jsx 51 | > ${props => config(props).media['sm']` 52 | > color: red; 53 | > // ...more css here 54 | > `} 55 | > ``` 56 | > 57 | > **Your output** 58 | > 59 | > ```css 60 | > @media only screen and (min-width: 48rem) { 61 | > color: red; 62 | > // ...more css here 63 | > } 64 | > ``` 65 | -------------------------------------------------------------------------------- /docusaurus.config.ts: -------------------------------------------------------------------------------- 1 | import { themes as prismThemes } from "prism-react-renderer"; 2 | import type { Config } from "@docusaurus/types"; 3 | import type * as Preset from "@docusaurus/preset-classic"; 4 | 5 | const config: Config = { 6 | title: "React awesome styled grid", 7 | tagline: 8 | "A responsive 8-point grid system layout for React using styled-components", 9 | favicon: "img/favicon.ico", 10 | 11 | // Set the production url of your site here 12 | url: "https://awesome-styled-grid.netlify.app/", 13 | // Set the // pathname under which your site is served 14 | // For GitHub pages deployment, it is often '//' 15 | baseUrl: "/", 16 | 17 | // GitHub pages deployment config. 18 | // If you aren't using GitHub pages, you don't need these. 19 | organizationName: "santosfrancisco", // Usually your GitHub org/user name. 20 | projectName: "react-awesome-styled-grid", // Usually your repo name. 21 | 22 | onBrokenLinks: "throw", 23 | onBrokenMarkdownLinks: "warn", 24 | 25 | // Even if you don't use internationalization, you can use this field to set 26 | // useful metadata like html lang. For example, if your site is Chinese, you 27 | // may want to replace "en" with "zh-Hans". 28 | i18n: { 29 | defaultLocale: "en", 30 | locales: ["en"] 31 | }, 32 | 33 | presets: [ 34 | [ 35 | "classic", 36 | { 37 | docs: { 38 | remarkPlugins: [ 39 | [require("@docusaurus/remark-plugin-npm2yarn"), { sync: true }] 40 | ], 41 | sidebarPath: "./sidebars.ts", 42 | // Please change this to your repo. 43 | // Remove this to remove the "edit this page" links. 44 | editUrl: 45 | "https://github.com/santosfrancisco/react-awesome-styled-grid" 46 | }, 47 | pages: { 48 | remarkPlugins: [require("@docusaurus/remark-plugin-npm2yarn")] 49 | }, 50 | blog: { 51 | remarkPlugins: [ 52 | [ 53 | require("@docusaurus/remark-plugin-npm2yarn"), 54 | { converters: ["pnpm"] } 55 | ] 56 | ], 57 | showReadingTime: true, 58 | // Please change this to your repo. 59 | // Remove this to remove the "edit this page" links. 60 | editUrl: 61 | "https://github.com/santosfrancisco/react-awesome-styled-grid" 62 | }, 63 | theme: { 64 | customCss: "./src/css/custom.css" 65 | } 66 | } satisfies Preset.Options 67 | ] 68 | ], 69 | themes: ["@docusaurus/theme-live-codeblock"], 70 | themeConfig: { 71 | liveCodeBlock: { 72 | /** 73 | * The position of the live playground, above or under the editor 74 | * Possible values: "top" | "bottom" 75 | */ 76 | playgroundPosition: "top" 77 | }, 78 | // Replace with your project's social card 79 | image: "img/social-card.jpg", 80 | navbar: { 81 | title: "React Awesome Styled Grid", 82 | logo: { 83 | alt: "react awesome styled grid logo", 84 | src: "img/icon.svg" 85 | }, 86 | items: [ 87 | { 88 | type: "docSidebar", 89 | sidebarId: "tutorialSidebar", 90 | position: "left", 91 | label: "Docs" 92 | }, 93 | { to: "/demo", label: "Demo", position: "left" }, 94 | // { to: "/blog", label: "Blog", position: "left" }, 95 | { 96 | href: "https://github.com/santosfrancisco/react-awesome-styled-grid", 97 | label: "GitHub", 98 | position: "right" 99 | } 100 | ] 101 | }, 102 | footer: { 103 | style: "dark", 104 | links: [ 105 | { 106 | title: "Docs", 107 | items: [ 108 | { 109 | label: "Tutorial", 110 | to: "/docs" 111 | }, 112 | { 113 | label: "Demo", 114 | to: "/demo" 115 | } 116 | ] 117 | }, 118 | { 119 | title: "Community", 120 | items: [ 121 | { 122 | label: "Issues", 123 | href: "https://github.com/santosfrancisco/react-awesome-styled-grid/issues" 124 | }, 125 | { 126 | label: "Contributing", 127 | href: "https://github.com/santosfrancisco/react-awesome-styled-grid/blob/master/CONTRIBUTING.md" 128 | } 129 | ] 130 | }, 131 | { 132 | title: "More", 133 | items: [ 134 | { 135 | label: "Blog", 136 | to: "/blog" 137 | }, 138 | { 139 | label: "GitHub", 140 | href: "https://github.com/santosfrancisco/react-awesome-styled-grid" 141 | } 142 | ] 143 | } 144 | ], 145 | copyright: `Copyright © ${new Date().getFullYear()} React Awesome Styled Grid, Inc. Built with Docusaurus.` 146 | }, 147 | prism: { 148 | theme: prismThemes.github, 149 | darkTheme: prismThemes.dracula 150 | } 151 | } satisfies Preset.ThemeConfig 152 | }; 153 | 154 | export default config; 155 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import { defaults as tsjPreset } from "ts-jest/presets"; 2 | 3 | module.exports = { 4 | preset: "ts-jest", 5 | testMatch: ["**/__tests__/**/*.test.tsx"], 6 | testEnvironment: "jsdom", 7 | setupFilesAfterEnv: ["/jestSetup.ts"], 8 | transform: { 9 | ...tsjPreset.transform 10 | // [...] 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /jestSetup.ts: -------------------------------------------------------------------------------- 1 | import "jest-styled-components"; 2 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017" 4 | }, 5 | "allowSyntheticDefaultImports": false, 6 | "baseUrl": ".", 7 | "exclude": ["node_modules", "dist"] 8 | } 9 | -------------------------------------------------------------------------------- /lib/components/__tests__/__snapshots__/col.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should have a offset space for all media 1`] = ` 4 | 5 | .c0 { 6 | box-sizing: border-box; 7 | flex: 1 0 auto; 8 | max-width: 100%; 9 | display: flex; 10 | flex-direction: column; 11 | } 12 | 13 | @media only screen and (min-width: 1rem) { 14 | .c0 { 15 | padding-right: 0.5rem; 16 | padding-left: 0.5rem; 17 | } 18 | } 19 | 20 | @media only screen and (min-width: 48rem) { 21 | .c0 { 22 | padding-right: 0.5rem; 23 | padding-left: 0.5rem; 24 | } 25 | } 26 | 27 | @media only screen and (min-width: 64rem) { 28 | .c0 { 29 | padding-right: 0.75rem; 30 | padding-left: 0.75rem; 31 | } 32 | } 33 | 34 | @media only screen and (min-width: 90rem) { 35 | .c0 { 36 | padding-right: 0.75rem; 37 | padding-left: 0.75rem; 38 | } 39 | } 40 | 41 | @media only screen and (min-width: 120rem) { 42 | .c0 { 43 | padding-right: 0.75rem; 44 | padding-left: 0.75rem; 45 | } 46 | } 47 | 48 | @media only screen and (min-width: 1rem) { 49 | .c0 { 50 | margin-left: 50%; 51 | } 52 | } 53 | 54 | @media only screen and (min-width: 48rem) { 55 | .c0 { 56 | margin-left: 50%; 57 | } 58 | } 59 | 60 | @media only screen and (min-width: 64rem) { 61 | .c0 { 62 | margin-left: 50%; 63 | } 64 | } 65 | 66 | @media only screen and (min-width: 90rem) { 67 | .c0 { 68 | margin-left: 50%; 69 | } 70 | } 71 | 72 | @media only screen and (min-width: 120rem) { 73 | .c0 { 74 | margin-left: 50%; 75 | } 76 | } 77 | 78 |
82 | children 83 |
84 |
85 | `; 86 | 87 | exports[` should have a offset space for each media 1`] = ` 88 | 89 | .c0 { 90 | box-sizing: border-box; 91 | flex: 1 0 auto; 92 | max-width: 100%; 93 | display: flex; 94 | flex-direction: column; 95 | } 96 | 97 | @media only screen and (min-width: 1rem) { 98 | .c0 { 99 | padding-right: 0.5rem; 100 | padding-left: 0.5rem; 101 | } 102 | } 103 | 104 | @media only screen and (min-width: 48rem) { 105 | .c0 { 106 | padding-right: 0.5rem; 107 | padding-left: 0.5rem; 108 | } 109 | } 110 | 111 | @media only screen and (min-width: 64rem) { 112 | .c0 { 113 | padding-right: 0.75rem; 114 | padding-left: 0.75rem; 115 | } 116 | } 117 | 118 | @media only screen and (min-width: 90rem) { 119 | .c0 { 120 | padding-right: 0.75rem; 121 | padding-left: 0.75rem; 122 | } 123 | } 124 | 125 | @media only screen and (min-width: 120rem) { 126 | .c0 { 127 | padding-right: 0.75rem; 128 | padding-left: 0.75rem; 129 | } 130 | } 131 | 132 | @media only screen and (min-width: 1rem) { 133 | .c0 { 134 | margin-left: 25%; 135 | } 136 | } 137 | 138 | @media only screen and (min-width: 48rem) { 139 | .c0 { 140 | margin-left: 25%; 141 | } 142 | } 143 | 144 | @media only screen and (min-width: 64rem) { 145 | .c0 { 146 | margin-left: 0%; 147 | } 148 | } 149 | 150 | @media only screen and (min-width: 90rem) { 151 | .c0 { 152 | margin-left: 33.33333333333333%; 153 | } 154 | } 155 | 156 | @media only screen and (min-width: 120rem) { 157 | .c0 { 158 | margin-left: 41.66666666666667%; 159 | } 160 | } 161 | 162 |
166 | children 167 |
168 |
169 | `; 170 | 171 | exports[` should have a order space for all media 1`] = ` 172 | 173 | .c0 { 174 | box-sizing: border-box; 175 | flex: 1 0 auto; 176 | max-width: 100%; 177 | display: flex; 178 | flex-direction: column; 179 | } 180 | 181 | @media only screen and (min-width: 1rem) { 182 | .c0 { 183 | padding-right: 0.5rem; 184 | padding-left: 0.5rem; 185 | } 186 | } 187 | 188 | @media only screen and (min-width: 48rem) { 189 | .c0 { 190 | padding-right: 0.5rem; 191 | padding-left: 0.5rem; 192 | } 193 | } 194 | 195 | @media only screen and (min-width: 64rem) { 196 | .c0 { 197 | padding-right: 0.75rem; 198 | padding-left: 0.75rem; 199 | } 200 | } 201 | 202 | @media only screen and (min-width: 90rem) { 203 | .c0 { 204 | padding-right: 0.75rem; 205 | padding-left: 0.75rem; 206 | } 207 | } 208 | 209 | @media only screen and (min-width: 120rem) { 210 | .c0 { 211 | padding-right: 0.75rem; 212 | padding-left: 0.75rem; 213 | } 214 | } 215 | 216 | @media only screen and (min-width: 1rem) { 217 | .c0 { 218 | order: 3; 219 | } 220 | } 221 | 222 | @media only screen and (min-width: 48rem) { 223 | .c0 { 224 | order: 3; 225 | } 226 | } 227 | 228 | @media only screen and (min-width: 64rem) { 229 | .c0 { 230 | order: 3; 231 | } 232 | } 233 | 234 | @media only screen and (min-width: 90rem) { 235 | .c0 { 236 | order: 3; 237 | } 238 | } 239 | 240 | @media only screen and (min-width: 120rem) { 241 | .c0 { 242 | order: 3; 243 | } 244 | } 245 | 246 |
250 | children 251 |
252 |
253 | `; 254 | 255 | exports[` should have a order space for each media 1`] = ` 256 | 257 | .c0 { 258 | box-sizing: border-box; 259 | flex: 1 0 auto; 260 | max-width: 100%; 261 | display: flex; 262 | flex-direction: column; 263 | } 264 | 265 | @media only screen and (min-width: 1rem) { 266 | .c0 { 267 | padding-right: 0.5rem; 268 | padding-left: 0.5rem; 269 | } 270 | } 271 | 272 | @media only screen and (min-width: 48rem) { 273 | .c0 { 274 | padding-right: 0.5rem; 275 | padding-left: 0.5rem; 276 | } 277 | } 278 | 279 | @media only screen and (min-width: 64rem) { 280 | .c0 { 281 | padding-right: 0.75rem; 282 | padding-left: 0.75rem; 283 | } 284 | } 285 | 286 | @media only screen and (min-width: 90rem) { 287 | .c0 { 288 | padding-right: 0.75rem; 289 | padding-left: 0.75rem; 290 | } 291 | } 292 | 293 | @media only screen and (min-width: 120rem) { 294 | .c0 { 295 | padding-right: 0.75rem; 296 | padding-left: 0.75rem; 297 | } 298 | } 299 | 300 | @media only screen and (min-width: 1rem) { 301 | .c0 { 302 | order: 5; 303 | } 304 | } 305 | 306 | @media only screen and (min-width: 48rem) { 307 | .c0 { 308 | order: 3; 309 | } 310 | } 311 | 312 | @media only screen and (min-width: 64rem) { 313 | .c0 { 314 | order: 2; 315 | } 316 | } 317 | 318 | @media only screen and (min-width: 90rem) { 319 | .c0 { 320 | order: 6; 321 | } 322 | } 323 | 324 | @media only screen and (min-width: 120rem) { 325 | .c0 { 326 | order: 8; 327 | } 328 | } 329 | 330 |
334 | children 335 |
336 |
337 | `; 338 | 339 | exports[` should have a reverse direction for all medias 1`] = ` 340 | 341 | .c0 { 342 | box-sizing: border-box; 343 | flex: 1 0 auto; 344 | max-width: 100%; 345 | display: flex; 346 | flex-direction: column; 347 | flex-direction: column-reverse; 348 | } 349 | 350 | @media only screen and (min-width: 1rem) { 351 | .c0 { 352 | padding-right: 0.5rem; 353 | padding-left: 0.5rem; 354 | } 355 | } 356 | 357 | @media only screen and (min-width: 48rem) { 358 | .c0 { 359 | padding-right: 0.5rem; 360 | padding-left: 0.5rem; 361 | } 362 | } 363 | 364 | @media only screen and (min-width: 64rem) { 365 | .c0 { 366 | padding-right: 0.75rem; 367 | padding-left: 0.75rem; 368 | } 369 | } 370 | 371 | @media only screen and (min-width: 90rem) { 372 | .c0 { 373 | padding-right: 0.75rem; 374 | padding-left: 0.75rem; 375 | } 376 | } 377 | 378 | @media only screen and (min-width: 120rem) { 379 | .c0 { 380 | padding-right: 0.75rem; 381 | padding-left: 0.75rem; 382 | } 383 | } 384 | 385 |
388 | children 389 |
390 |
391 | `; 392 | 393 | exports[` should have a reverse direction only for MD media 1`] = ` 394 | 395 | .c0 { 396 | box-sizing: border-box; 397 | flex: 1 0 auto; 398 | max-width: 100%; 399 | display: flex; 400 | flex-direction: column; 401 | } 402 | 403 | @media only screen and (min-width: 1rem) { 404 | .c0 { 405 | padding-right: 0.5rem; 406 | padding-left: 0.5rem; 407 | } 408 | } 409 | 410 | @media only screen and (min-width: 48rem) { 411 | .c0 { 412 | padding-right: 0.5rem; 413 | padding-left: 0.5rem; 414 | } 415 | } 416 | 417 | @media only screen and (min-width: 64rem) { 418 | .c0 { 419 | padding-right: 0.75rem; 420 | padding-left: 0.75rem; 421 | } 422 | } 423 | 424 | @media only screen and (min-width: 90rem) { 425 | .c0 { 426 | padding-right: 0.75rem; 427 | padding-left: 0.75rem; 428 | } 429 | } 430 | 431 | @media only screen and (min-width: 120rem) { 432 | .c0 { 433 | padding-right: 0.75rem; 434 | padding-left: 0.75rem; 435 | } 436 | } 437 | 438 | @media only screen and (min-width: 1rem) { 439 | .c0 { 440 | flex-direction: column; 441 | } 442 | } 443 | 444 | @media only screen and (min-width: 48rem) { 445 | .c0 { 446 | flex-direction: column; 447 | } 448 | } 449 | 450 | @media only screen and (min-width: 64rem) { 451 | .c0 { 452 | flex-direction: column-reverse; 453 | } 454 | } 455 | 456 | @media only screen and (min-width: 90rem) { 457 | .c0 { 458 | flex-direction: column; 459 | } 460 | } 461 | 462 | @media only screen and (min-width: 120rem) { 463 | .c0 { 464 | flex-direction: column; 465 | } 466 | } 467 | 468 |
471 | children 472 |
473 |
474 | `; 475 | 476 | exports[` should have a reverse direction only for all media 1`] = ` 477 | 478 | .c0 { 479 | box-sizing: border-box; 480 | flex: 1 0 auto; 481 | max-width: 100%; 482 | display: flex; 483 | flex-direction: column; 484 | flex-direction: column-reverse; 485 | } 486 | 487 | @media only screen and (min-width: 1rem) { 488 | .c0 { 489 | padding-right: 0.5rem; 490 | padding-left: 0.5rem; 491 | } 492 | } 493 | 494 | @media only screen and (min-width: 48rem) { 495 | .c0 { 496 | padding-right: 0.5rem; 497 | padding-left: 0.5rem; 498 | } 499 | } 500 | 501 | @media only screen and (min-width: 64rem) { 502 | .c0 { 503 | padding-right: 0.75rem; 504 | padding-left: 0.75rem; 505 | } 506 | } 507 | 508 | @media only screen and (min-width: 90rem) { 509 | .c0 { 510 | padding-right: 0.75rem; 511 | padding-left: 0.75rem; 512 | } 513 | } 514 | 515 | @media only screen and (min-width: 120rem) { 516 | .c0 { 517 | padding-right: 0.75rem; 518 | padding-left: 0.75rem; 519 | } 520 | } 521 | 522 |
525 | children 526 |
527 |
528 | `; 529 | 530 | exports[` should have different style when it\`s debug props is true 1`] = ` 531 | 532 | .c0 { 533 | box-sizing: border-box; 534 | flex: 1 0 auto; 535 | max-width: 100%; 536 | display: flex; 537 | flex-direction: column; 538 | background-color: #5901ad40; 539 | outline: #fff solid 1px; 540 | } 541 | 542 | @media only screen and (min-width: 1rem) { 543 | .c0 { 544 | padding-right: 0.5rem; 545 | padding-left: 0.5rem; 546 | } 547 | } 548 | 549 | @media only screen and (min-width: 48rem) { 550 | .c0 { 551 | padding-right: 0.5rem; 552 | padding-left: 0.5rem; 553 | } 554 | } 555 | 556 | @media only screen and (min-width: 64rem) { 557 | .c0 { 558 | padding-right: 0.75rem; 559 | padding-left: 0.75rem; 560 | } 561 | } 562 | 563 | @media only screen and (min-width: 90rem) { 564 | .c0 { 565 | padding-right: 0.75rem; 566 | padding-left: 0.75rem; 567 | } 568 | } 569 | 570 | @media only screen and (min-width: 120rem) { 571 | .c0 { 572 | padding-right: 0.75rem; 573 | padding-left: 0.75rem; 574 | } 575 | } 576 | 577 |
580 | children 581 |
582 |
583 | `; 584 | 585 | exports[` should have no gutter 1`] = ` 586 | 587 | .c0 { 588 | box-sizing: border-box; 589 | flex: 1 0 auto; 590 | max-width: 100%; 591 | display: flex; 592 | flex-direction: column; 593 | } 594 | 595 |
598 | children 599 |
600 |
601 | `; 602 | 603 | exports[` should have the css rule align-items center 1`] = ` 604 | 605 | .c0 { 606 | box-sizing: border-box; 607 | flex: 1 0 auto; 608 | max-width: 100%; 609 | display: flex; 610 | flex-direction: column; 611 | align-items: center; 612 | } 613 | 614 | @media only screen and (min-width: 1rem) { 615 | .c0 { 616 | padding-right: 0.5rem; 617 | padding-left: 0.5rem; 618 | } 619 | } 620 | 621 | @media only screen and (min-width: 48rem) { 622 | .c0 { 623 | padding-right: 0.5rem; 624 | padding-left: 0.5rem; 625 | } 626 | } 627 | 628 | @media only screen and (min-width: 64rem) { 629 | .c0 { 630 | padding-right: 0.75rem; 631 | padding-left: 0.75rem; 632 | } 633 | } 634 | 635 | @media only screen and (min-width: 90rem) { 636 | .c0 { 637 | padding-right: 0.75rem; 638 | padding-left: 0.75rem; 639 | } 640 | } 641 | 642 | @media only screen and (min-width: 120rem) { 643 | .c0 { 644 | padding-right: 0.75rem; 645 | padding-left: 0.75rem; 646 | } 647 | } 648 | 649 |
652 | children 653 |
654 |
655 | `; 656 | 657 | exports[` should have the css rule align-items center only in MD screen 1`] = ` 658 | 659 | .c0 { 660 | box-sizing: border-box; 661 | flex: 1 0 auto; 662 | max-width: 100%; 663 | display: flex; 664 | flex-direction: column; 665 | } 666 | 667 | @media only screen and (min-width: 1rem) { 668 | .c0 { 669 | padding-right: 0.5rem; 670 | padding-left: 0.5rem; 671 | } 672 | } 673 | 674 | @media only screen and (min-width: 48rem) { 675 | .c0 { 676 | padding-right: 0.5rem; 677 | padding-left: 0.5rem; 678 | } 679 | } 680 | 681 | @media only screen and (min-width: 64rem) { 682 | .c0 { 683 | padding-right: 0.75rem; 684 | padding-left: 0.75rem; 685 | } 686 | } 687 | 688 | @media only screen and (min-width: 90rem) { 689 | .c0 { 690 | padding-right: 0.75rem; 691 | padding-left: 0.75rem; 692 | } 693 | } 694 | 695 | @media only screen and (min-width: 120rem) { 696 | .c0 { 697 | padding-right: 0.75rem; 698 | padding-left: 0.75rem; 699 | } 700 | } 701 | 702 | @media only screen and (min-width: 64rem) { 703 | .c0 { 704 | align-items: center; 705 | } 706 | } 707 | 708 |
711 | children 712 |
713 |
714 | `; 715 | 716 | exports[` should have the css rule justify-content center 1`] = ` 717 | 718 | .c0 { 719 | box-sizing: border-box; 720 | flex: 1 0 auto; 721 | max-width: 100%; 722 | display: flex; 723 | flex-direction: column; 724 | justify-content: center; 725 | } 726 | 727 | @media only screen and (min-width: 1rem) { 728 | .c0 { 729 | padding-right: 0.5rem; 730 | padding-left: 0.5rem; 731 | } 732 | } 733 | 734 | @media only screen and (min-width: 48rem) { 735 | .c0 { 736 | padding-right: 0.5rem; 737 | padding-left: 0.5rem; 738 | } 739 | } 740 | 741 | @media only screen and (min-width: 64rem) { 742 | .c0 { 743 | padding-right: 0.75rem; 744 | padding-left: 0.75rem; 745 | } 746 | } 747 | 748 | @media only screen and (min-width: 90rem) { 749 | .c0 { 750 | padding-right: 0.75rem; 751 | padding-left: 0.75rem; 752 | } 753 | } 754 | 755 | @media only screen and (min-width: 120rem) { 756 | .c0 { 757 | padding-right: 0.75rem; 758 | padding-left: 0.75rem; 759 | } 760 | } 761 | 762 |
765 | children 766 |
767 |
768 | `; 769 | 770 | exports[` should have the css rule justify-content center only in MD screen 1`] = ` 771 | 772 | .c0 { 773 | box-sizing: border-box; 774 | flex: 1 0 auto; 775 | max-width: 100%; 776 | display: flex; 777 | flex-direction: column; 778 | } 779 | 780 | @media only screen and (min-width: 1rem) { 781 | .c0 { 782 | padding-right: 0.5rem; 783 | padding-left: 0.5rem; 784 | } 785 | } 786 | 787 | @media only screen and (min-width: 48rem) { 788 | .c0 { 789 | padding-right: 0.5rem; 790 | padding-left: 0.5rem; 791 | } 792 | } 793 | 794 | @media only screen and (min-width: 64rem) { 795 | .c0 { 796 | padding-right: 0.75rem; 797 | padding-left: 0.75rem; 798 | } 799 | } 800 | 801 | @media only screen and (min-width: 90rem) { 802 | .c0 { 803 | padding-right: 0.75rem; 804 | padding-left: 0.75rem; 805 | } 806 | } 807 | 808 | @media only screen and (min-width: 120rem) { 809 | .c0 { 810 | padding-right: 0.75rem; 811 | padding-left: 0.75rem; 812 | } 813 | } 814 | 815 | @media only screen and (min-width: 64rem) { 816 | .c0 { 817 | justify-content: center; 818 | } 819 | } 820 | 821 |
824 | children 825 |
826 |
827 | `; 828 | 829 | exports[` should have the specified size 1`] = ` 830 | 831 | .c0 { 832 | box-sizing: border-box; 833 | flex: 1 0 auto; 834 | max-width: 100%; 835 | display: flex; 836 | flex-direction: column; 837 | } 838 | 839 | @media only screen and (min-width: 1rem) { 840 | .c0 { 841 | padding-right: 0.5rem; 842 | padding-left: 0.5rem; 843 | } 844 | } 845 | 846 | @media only screen and (min-width: 48rem) { 847 | .c0 { 848 | padding-right: 0.5rem; 849 | padding-left: 0.5rem; 850 | } 851 | } 852 | 853 | @media only screen and (min-width: 64rem) { 854 | .c0 { 855 | padding-right: 0.75rem; 856 | padding-left: 0.75rem; 857 | } 858 | } 859 | 860 | @media only screen and (min-width: 90rem) { 861 | .c0 { 862 | padding-right: 0.75rem; 863 | padding-left: 0.75rem; 864 | } 865 | } 866 | 867 | @media only screen and (min-width: 120rem) { 868 | .c0 { 869 | padding-right: 0.75rem; 870 | padding-left: 0.75rem; 871 | } 872 | } 873 | 874 | @media only screen and (min-width: 1rem) { 875 | .c0 { 876 | flex: 1 1 25%; 877 | max-width: 25%; 878 | } 879 | } 880 | 881 | @media only screen and (min-width: 48rem) { 882 | .c0 { 883 | flex: 1 1 25%; 884 | max-width: 25%; 885 | } 886 | } 887 | 888 | @media only screen and (min-width: 64rem) { 889 | .c0 { 890 | flex: 1 1 37.5%; 891 | max-width: 37.5%; 892 | } 893 | } 894 | 895 | @media only screen and (min-width: 90rem) { 896 | .c0 { 897 | flex: 1 1 33.33333333333333%; 898 | max-width: 33.33333333333333%; 899 | } 900 | } 901 | 902 | @media only screen and (min-width: 120rem) { 903 | .c0 { 904 | flex: 1 1 41.66666666666667%; 905 | max-width: 41.66666666666667%; 906 | } 907 | } 908 | 909 |
912 | children 913 |
914 |
915 | `; 916 | 917 | exports[` should render default style correctly 1`] = ` 918 | 919 | .c0 { 920 | box-sizing: border-box; 921 | flex: 1 0 auto; 922 | max-width: 100%; 923 | display: flex; 924 | flex-direction: column; 925 | } 926 | 927 | @media only screen and (min-width: 1rem) { 928 | .c0 { 929 | padding-right: 0.5rem; 930 | padding-left: 0.5rem; 931 | } 932 | } 933 | 934 | @media only screen and (min-width: 48rem) { 935 | .c0 { 936 | padding-right: 0.5rem; 937 | padding-left: 0.5rem; 938 | } 939 | } 940 | 941 | @media only screen and (min-width: 64rem) { 942 | .c0 { 943 | padding-right: 0.75rem; 944 | padding-left: 0.75rem; 945 | } 946 | } 947 | 948 | @media only screen and (min-width: 90rem) { 949 | .c0 { 950 | padding-right: 0.75rem; 951 | padding-left: 0.75rem; 952 | } 953 | } 954 | 955 | @media only screen and (min-width: 120rem) { 956 | .c0 { 957 | padding-right: 0.75rem; 958 | padding-left: 0.75rem; 959 | } 960 | } 961 | 962 |
965 | children 966 |
967 |
968 | `; 969 | -------------------------------------------------------------------------------- /lib/components/__tests__/__snapshots__/container.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should have a max-width 100% when it is a fluid container 1`] = ` 4 | 5 | .c0 { 6 | margin-right: auto; 7 | margin-left: auto; 8 | max-width: 100%; 9 | width: 100%; 10 | box-sizing: border-box; 11 | } 12 | 13 | @media only screen and (min-width: 1rem) { 14 | .c0 { 15 | padding-left: 1rem; 16 | padding-right: 1rem; 17 | } 18 | } 19 | 20 | @media only screen and (min-width: 48rem) { 21 | .c0 { 22 | padding-left: 1rem; 23 | padding-right: 1rem; 24 | } 25 | } 26 | 27 | @media only screen and (min-width: 64rem) { 28 | .c0 { 29 | padding-left: 1.5rem; 30 | padding-right: 1.5rem; 31 | } 32 | } 33 | 34 | @media only screen and (min-width: 90rem) { 35 | .c0 { 36 | padding-left: 1.5rem; 37 | padding-right: 1.5rem; 38 | } 39 | } 40 | 41 | @media only screen and (min-width: 120rem) { 42 | .c0 { 43 | padding-left: 1.5rem; 44 | padding-right: 1.5rem; 45 | } 46 | } 47 | 48 |
51 | children 52 |
53 |
54 | `; 55 | 56 | exports[` should have different style when it\`s debug props is true 1`] = ` 57 | 58 | .c0 { 59 | margin-right: auto; 60 | margin-left: auto; 61 | max-width: 100%; 62 | width: 100%; 63 | box-sizing: border-box; 64 | background-color: #5901ad40; 65 | outline: #fff solid 1px; 66 | } 67 | 68 | @media only screen and (min-width: 1rem) { 69 | .c0 { 70 | padding-left: 1rem; 71 | padding-right: 1rem; 72 | } 73 | } 74 | 75 | @media only screen and (min-width: 48rem) { 76 | .c0 { 77 | padding-left: 1rem; 78 | padding-right: 1rem; 79 | } 80 | } 81 | 82 | @media only screen and (min-width: 64rem) { 83 | .c0 { 84 | padding-left: 1.5rem; 85 | padding-right: 1.5rem; 86 | } 87 | } 88 | 89 | @media only screen and (min-width: 90rem) { 90 | .c0 { 91 | padding-left: 1.5rem; 92 | padding-right: 1.5rem; 93 | } 94 | } 95 | 96 | @media only screen and (min-width: 120rem) { 97 | .c0 { 98 | padding-left: 1.5rem; 99 | padding-right: 1.5rem; 100 | } 101 | } 102 | 103 | @media only screen and (min-width: 1rem) { 104 | .c0 { 105 | width: 100%; 106 | } 107 | } 108 | 109 | @media only screen and (min-width: 48rem) { 110 | .c0 { 111 | width: 100%; 112 | } 113 | } 114 | 115 | @media only screen and (min-width: 64rem) { 116 | .c0 { 117 | width: 100%; 118 | } 119 | } 120 | 121 | @media only screen and (min-width: 90rem) { 122 | .c0 { 123 | max-width: 90rem; 124 | } 125 | } 126 | 127 | @media only screen and (min-width: 120rem) { 128 | .c0 { 129 | max-width: 90rem; 130 | } 131 | } 132 | 133 |
136 | children 137 |
138 |
139 | `; 140 | 141 | exports[` should render default style correctly 1`] = ` 142 | 143 | .c0 { 144 | margin-right: auto; 145 | margin-left: auto; 146 | max-width: 100%; 147 | width: 100%; 148 | box-sizing: border-box; 149 | } 150 | 151 | @media only screen and (min-width: 1rem) { 152 | .c0 { 153 | padding-left: 1rem; 154 | padding-right: 1rem; 155 | } 156 | } 157 | 158 | @media only screen and (min-width: 48rem) { 159 | .c0 { 160 | padding-left: 1rem; 161 | padding-right: 1rem; 162 | } 163 | } 164 | 165 | @media only screen and (min-width: 64rem) { 166 | .c0 { 167 | padding-left: 1.5rem; 168 | padding-right: 1.5rem; 169 | } 170 | } 171 | 172 | @media only screen and (min-width: 90rem) { 173 | .c0 { 174 | padding-left: 1.5rem; 175 | padding-right: 1.5rem; 176 | } 177 | } 178 | 179 | @media only screen and (min-width: 120rem) { 180 | .c0 { 181 | padding-left: 1.5rem; 182 | padding-right: 1.5rem; 183 | } 184 | } 185 | 186 | @media only screen and (min-width: 1rem) { 187 | .c0 { 188 | width: 100%; 189 | } 190 | } 191 | 192 | @media only screen and (min-width: 48rem) { 193 | .c0 { 194 | width: 100%; 195 | } 196 | } 197 | 198 | @media only screen and (min-width: 64rem) { 199 | .c0 { 200 | width: 100%; 201 | } 202 | } 203 | 204 | @media only screen and (min-width: 90rem) { 205 | .c0 { 206 | max-width: 90rem; 207 | } 208 | } 209 | 210 | @media only screen and (min-width: 120rem) { 211 | .c0 { 212 | max-width: 90rem; 213 | } 214 | } 215 | 216 |
219 | children 220 |
221 |
222 | `; 223 | -------------------------------------------------------------------------------- /lib/components/__tests__/__snapshots__/hidden.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should render default style correctly 1`] = ` 4 |

5 | children 6 |

7 | `; 8 | -------------------------------------------------------------------------------- /lib/components/__tests__/__snapshots__/row.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`children should have a reverse direction for each media 1`] = ` 4 | 5 | .c0 { 6 | box-sizing: border-box; 7 | display: flex; 8 | flex: 1 1 auto; 9 | flex-wrap: wrap; 10 | flex-direction: row-reverse; 11 | flex-wrap: wrap-reverse; 12 | } 13 | 14 | @media only screen and (min-width: 1rem) { 15 | .c0 { 16 | margin-left: -0.5rem; 17 | margin-right: -0.5rem; 18 | } 19 | } 20 | 21 | @media only screen and (min-width: 48rem) { 22 | .c0 { 23 | margin-left: -0.5rem; 24 | margin-right: -0.5rem; 25 | } 26 | } 27 | 28 | @media only screen and (min-width: 64rem) { 29 | .c0 { 30 | margin-left: -0.75rem; 31 | margin-right: -0.75rem; 32 | } 33 | } 34 | 35 | @media only screen and (min-width: 90rem) { 36 | .c0 { 37 | margin-left: -0.75rem; 38 | margin-right: -0.75rem; 39 | } 40 | } 41 | 42 | @media only screen and (min-width: 120rem) { 43 | .c0 { 44 | margin-left: -0.75rem; 45 | margin-right: -0.75rem; 46 | } 47 | } 48 | 49 |
52 | children 53 |
54 |
55 | `; 56 | 57 | exports[`children should have a reverse direction for specific screen 1`] = ` 58 | 59 | .c0 { 60 | box-sizing: border-box; 61 | display: flex; 62 | flex: 1 1 auto; 63 | flex-wrap: wrap; 64 | } 65 | 66 | @media only screen and (min-width: 1rem) { 67 | .c0 { 68 | margin-left: -0.5rem; 69 | margin-right: -0.5rem; 70 | } 71 | } 72 | 73 | @media only screen and (min-width: 48rem) { 74 | .c0 { 75 | margin-left: -0.5rem; 76 | margin-right: -0.5rem; 77 | } 78 | } 79 | 80 | @media only screen and (min-width: 64rem) { 81 | .c0 { 82 | margin-left: -0.75rem; 83 | margin-right: -0.75rem; 84 | } 85 | } 86 | 87 | @media only screen and (min-width: 90rem) { 88 | .c0 { 89 | margin-left: -0.75rem; 90 | margin-right: -0.75rem; 91 | } 92 | } 93 | 94 | @media only screen and (min-width: 120rem) { 95 | .c0 { 96 | margin-left: -0.75rem; 97 | margin-right: -0.75rem; 98 | } 99 | } 100 | 101 | @media only screen and (min-width: 1rem) { 102 | .c0 { 103 | flex-direction: row; 104 | flex-wrap: wrap; 105 | } 106 | } 107 | 108 | @media only screen and (min-width: 48rem) { 109 | .c0 { 110 | flex-direction: row; 111 | flex-wrap: wrap; 112 | } 113 | } 114 | 115 | @media only screen and (min-width: 64rem) { 116 | .c0 { 117 | flex-direction: row-reverse; 118 | flex-wrap: wrap-reverse; 119 | } 120 | } 121 | 122 | @media only screen and (min-width: 90rem) { 123 | .c0 { 124 | flex-direction: row-reverse; 125 | flex-wrap: wrap-reverse; 126 | } 127 | } 128 | 129 | @media only screen and (min-width: 120rem) { 130 | .c0 { 131 | flex-direction: row; 132 | flex-wrap: wrap; 133 | } 134 | } 135 | 136 |
139 | children 140 |
141 |
142 | `; 143 | 144 | exports[`children should have different style when it\`s debug props is true 1`] = ` 145 | 146 | .c0 { 147 | box-sizing: border-box; 148 | display: flex; 149 | flex: 1 1 auto; 150 | flex-wrap: wrap; 151 | background-color: #5901ad40; 152 | outline: #fff solid 1px; 153 | } 154 | 155 | @media only screen and (min-width: 1rem) { 156 | .c0 { 157 | margin-left: -0.5rem; 158 | margin-right: -0.5rem; 159 | } 160 | } 161 | 162 | @media only screen and (min-width: 48rem) { 163 | .c0 { 164 | margin-left: -0.5rem; 165 | margin-right: -0.5rem; 166 | } 167 | } 168 | 169 | @media only screen and (min-width: 64rem) { 170 | .c0 { 171 | margin-left: -0.75rem; 172 | margin-right: -0.75rem; 173 | } 174 | } 175 | 176 | @media only screen and (min-width: 90rem) { 177 | .c0 { 178 | margin-left: -0.75rem; 179 | margin-right: -0.75rem; 180 | } 181 | } 182 | 183 | @media only screen and (min-width: 120rem) { 184 | .c0 { 185 | margin-left: -0.75rem; 186 | margin-right: -0.75rem; 187 | } 188 | } 189 | 190 |
193 | children 194 |
195 |
196 | `; 197 | 198 | exports[`children should have the css rule align-items center 1`] = ` 199 | 200 | .c0 { 201 | box-sizing: border-box; 202 | display: flex; 203 | flex: 1 1 auto; 204 | flex-wrap: wrap; 205 | align-items: center; 206 | } 207 | 208 | @media only screen and (min-width: 1rem) { 209 | .c0 { 210 | margin-left: -0.5rem; 211 | margin-right: -0.5rem; 212 | } 213 | } 214 | 215 | @media only screen and (min-width: 48rem) { 216 | .c0 { 217 | margin-left: -0.5rem; 218 | margin-right: -0.5rem; 219 | } 220 | } 221 | 222 | @media only screen and (min-width: 64rem) { 223 | .c0 { 224 | margin-left: -0.75rem; 225 | margin-right: -0.75rem; 226 | } 227 | } 228 | 229 | @media only screen and (min-width: 90rem) { 230 | .c0 { 231 | margin-left: -0.75rem; 232 | margin-right: -0.75rem; 233 | } 234 | } 235 | 236 | @media only screen and (min-width: 120rem) { 237 | .c0 { 238 | margin-left: -0.75rem; 239 | margin-right: -0.75rem; 240 | } 241 | } 242 | 243 |
246 | children 247 |
248 |
249 | `; 250 | 251 | exports[`children should have the css rule align-items center only in MD screen 1`] = ` 252 | 253 | .c0 { 254 | box-sizing: border-box; 255 | display: flex; 256 | flex: 1 1 auto; 257 | flex-wrap: wrap; 258 | } 259 | 260 | @media only screen and (min-width: 1rem) { 261 | .c0 { 262 | margin-left: -0.5rem; 263 | margin-right: -0.5rem; 264 | } 265 | } 266 | 267 | @media only screen and (min-width: 48rem) { 268 | .c0 { 269 | margin-left: -0.5rem; 270 | margin-right: -0.5rem; 271 | } 272 | } 273 | 274 | @media only screen and (min-width: 64rem) { 275 | .c0 { 276 | margin-left: -0.75rem; 277 | margin-right: -0.75rem; 278 | } 279 | } 280 | 281 | @media only screen and (min-width: 90rem) { 282 | .c0 { 283 | margin-left: -0.75rem; 284 | margin-right: -0.75rem; 285 | } 286 | } 287 | 288 | @media only screen and (min-width: 120rem) { 289 | .c0 { 290 | margin-left: -0.75rem; 291 | margin-right: -0.75rem; 292 | } 293 | } 294 | 295 | @media only screen and (min-width: 64rem) { 296 | .c0 { 297 | align-items: center; 298 | } 299 | } 300 | 301 |
304 | children 305 |
306 |
307 | `; 308 | 309 | exports[`children should have the css rule justify-content center 1`] = ` 310 | 311 | .c0 { 312 | box-sizing: border-box; 313 | display: flex; 314 | flex: 1 1 auto; 315 | flex-wrap: wrap; 316 | justify-content: center; 317 | } 318 | 319 | @media only screen and (min-width: 1rem) { 320 | .c0 { 321 | margin-left: -0.5rem; 322 | margin-right: -0.5rem; 323 | } 324 | } 325 | 326 | @media only screen and (min-width: 48rem) { 327 | .c0 { 328 | margin-left: -0.5rem; 329 | margin-right: -0.5rem; 330 | } 331 | } 332 | 333 | @media only screen and (min-width: 64rem) { 334 | .c0 { 335 | margin-left: -0.75rem; 336 | margin-right: -0.75rem; 337 | } 338 | } 339 | 340 | @media only screen and (min-width: 90rem) { 341 | .c0 { 342 | margin-left: -0.75rem; 343 | margin-right: -0.75rem; 344 | } 345 | } 346 | 347 | @media only screen and (min-width: 120rem) { 348 | .c0 { 349 | margin-left: -0.75rem; 350 | margin-right: -0.75rem; 351 | } 352 | } 353 | 354 |
357 | children 358 |
359 |
360 | `; 361 | 362 | exports[`children should have the css rule justify-content center only in MD screen 1`] = ` 363 | 364 | .c0 { 365 | box-sizing: border-box; 366 | display: flex; 367 | flex: 1 1 auto; 368 | flex-wrap: wrap; 369 | } 370 | 371 | @media only screen and (min-width: 1rem) { 372 | .c0 { 373 | margin-left: -0.5rem; 374 | margin-right: -0.5rem; 375 | } 376 | } 377 | 378 | @media only screen and (min-width: 48rem) { 379 | .c0 { 380 | margin-left: -0.5rem; 381 | margin-right: -0.5rem; 382 | } 383 | } 384 | 385 | @media only screen and (min-width: 64rem) { 386 | .c0 { 387 | margin-left: -0.75rem; 388 | margin-right: -0.75rem; 389 | } 390 | } 391 | 392 | @media only screen and (min-width: 90rem) { 393 | .c0 { 394 | margin-left: -0.75rem; 395 | margin-right: -0.75rem; 396 | } 397 | } 398 | 399 | @media only screen and (min-width: 120rem) { 400 | .c0 { 401 | margin-left: -0.75rem; 402 | margin-right: -0.75rem; 403 | } 404 | } 405 | 406 | @media only screen and (min-width: 64rem) { 407 | .c0 { 408 | justify-content: center; 409 | } 410 | } 411 | 412 |
415 | children 416 |
417 |
418 | `; 419 | 420 | exports[`children should render default style correctly 1`] = ` 421 | 422 | .c0 { 423 | box-sizing: border-box; 424 | display: flex; 425 | flex: 1 1 auto; 426 | flex-wrap: wrap; 427 | } 428 | 429 | @media only screen and (min-width: 1rem) { 430 | .c0 { 431 | margin-left: -0.5rem; 432 | margin-right: -0.5rem; 433 | } 434 | } 435 | 436 | @media only screen and (min-width: 48rem) { 437 | .c0 { 438 | margin-left: -0.5rem; 439 | margin-right: -0.5rem; 440 | } 441 | } 442 | 443 | @media only screen and (min-width: 64rem) { 444 | .c0 { 445 | margin-left: -0.75rem; 446 | margin-right: -0.75rem; 447 | } 448 | } 449 | 450 | @media only screen and (min-width: 90rem) { 451 | .c0 { 452 | margin-left: -0.75rem; 453 | margin-right: -0.75rem; 454 | } 455 | } 456 | 457 | @media only screen and (min-width: 120rem) { 458 | .c0 { 459 | margin-left: -0.75rem; 460 | margin-right: -0.75rem; 461 | } 462 | } 463 | 464 |
467 | children 468 |
469 |
470 | `; 471 | -------------------------------------------------------------------------------- /lib/components/__tests__/__snapshots__/visible.test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[` should render default style correctly 1`] = `null`; 4 | -------------------------------------------------------------------------------- /lib/components/__tests__/col.test.tsx: -------------------------------------------------------------------------------- 1 | import { render } from "@testing-library/react"; 2 | import { Col } from "../grid/col"; 3 | import { GridBreakpoints } from "@site/lib/types"; 4 | 5 | describe("", () => { 6 | it("should render default style correctly", () => { 7 | const { asFragment } = render(children); 8 | expect(asFragment()).toMatchSnapshot(); 9 | }); 10 | 11 | it("should have no gutter", () => { 12 | const { asFragment } = render(children); 13 | expect(asFragment()).toMatchSnapshot(); 14 | }); 15 | 16 | it("should have the specified size", () => { 17 | const props = { 18 | xs: 1, 19 | sm: 2, 20 | md: 3, 21 | lg: 4, 22 | xl: 5 23 | }; 24 | 25 | const { asFragment } = render(children); 26 | 27 | expect(asFragment()).toMatchSnapshot(); 28 | }); 29 | 30 | it("should have a offset space for each media", () => { 31 | const props = { 32 | offset: { 33 | xs: 1, 34 | sm: 2, 35 | md: 0, 36 | lg: 4, 37 | xl: 5 38 | } 39 | }; 40 | 41 | const { asFragment } = render(children); 42 | 43 | expect(asFragment()).toMatchSnapshot(); 44 | }); 45 | 46 | it("should have a offset space for all media", () => { 47 | const props = { 48 | offset: 2 49 | }; 50 | 51 | const { asFragment } = render(children); 52 | 53 | expect(asFragment()).toMatchSnapshot(); 54 | }); 55 | 56 | it("should have a order space for each media", () => { 57 | const props = { 58 | order: { 59 | xs: 5, 60 | sm: 3, 61 | md: 2, 62 | lg: 6, 63 | xl: 8 64 | } 65 | }; 66 | 67 | const { asFragment } = render(children); 68 | 69 | expect(asFragment()).toMatchSnapshot(); 70 | }); 71 | 72 | it("should have a order space for all media", () => { 73 | const props = { 74 | order: 3 75 | }; 76 | 77 | const { asFragment } = render(children); 78 | 79 | expect(asFragment()).toMatchSnapshot(); 80 | }); 81 | 82 | it("should have a reverse direction for all medias", () => { 83 | const { asFragment } = render(children); 84 | expect(asFragment()).toMatchSnapshot(); 85 | }); 86 | 87 | it("should have the css rule justify-content center", () => { 88 | const props = { 89 | justify: "center" 90 | }; 91 | const { asFragment } = render(children); 92 | 93 | expect(asFragment()).toMatchSnapshot(); 94 | }); 95 | 96 | it("should have the css rule justify-content center only in MD screen", () => { 97 | const props = { 98 | justify: { 99 | md: "center" 100 | } 101 | }; 102 | 103 | const { asFragment } = render(children); 104 | 105 | expect(asFragment()).toMatchSnapshot(); 106 | }); 107 | 108 | it("should have the css rule align-items center", () => { 109 | const props = { 110 | align: "center" 111 | }; 112 | const { asFragment } = render(children); 113 | 114 | expect(asFragment()).toMatchSnapshot(); 115 | }); 116 | 117 | it("should have the css rule align-items center only in MD screen", () => { 118 | const props = { 119 | align: { 120 | md: "center" 121 | } 122 | }; 123 | 124 | const { asFragment } = render(children); 125 | 126 | expect(asFragment()).toMatchSnapshot(); 127 | }); 128 | 129 | it("should have a reverse direction only for all media", () => { 130 | const props = { 131 | reverse: true 132 | }; 133 | const { asFragment } = render(children); 134 | 135 | expect(asFragment()).toMatchSnapshot(); 136 | }); 137 | 138 | it("should have a reverse direction only for MD media", () => { 139 | const props = { 140 | reverse: ["md"] as GridBreakpoints[] 141 | }; 142 | const { asFragment } = render(children); 143 | 144 | expect(asFragment()).toMatchSnapshot(); 145 | }); 146 | 147 | it("should have different style when it`s debug props is true", () => { 148 | const { asFragment } = render(children); 149 | 150 | expect(asFragment()).toMatchSnapshot(); 151 | }); 152 | }); 153 | -------------------------------------------------------------------------------- /lib/components/__tests__/container.test.tsx: -------------------------------------------------------------------------------- 1 | import { render } from "@testing-library/react"; 2 | import { Container } from "../grid/container"; 3 | 4 | describe("", () => { 5 | it("should render default style correctly", () => { 6 | const { asFragment } = render(children); 7 | expect(asFragment()).toMatchSnapshot(); 8 | }); 9 | 10 | it("should have a max-width 100% when it is a fluid container", () => { 11 | const { asFragment } = render(children); 12 | expect(asFragment()).toMatchSnapshot(); 13 | }); 14 | 15 | it("should have different style when it`s debug props is true", () => { 16 | const { asFragment } = render(children); 17 | expect(asFragment()).toMatchSnapshot(); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /lib/components/__tests__/hidden.test.tsx: -------------------------------------------------------------------------------- 1 | import { act, render, screen } from "@testing-library/react"; 2 | import config from "../../config"; 3 | import { Hidden } from "../util/hidden"; 4 | 5 | describe("", () => { 6 | const resize = (width) => { 7 | global.window.innerWidth = width; 8 | global.window.dispatchEvent(new Event("resize")); 9 | }; 10 | 11 | it("should render default style correctly", () => { 12 | const { container } = render( 13 | 14 |

children

15 |
16 | ); 17 | expect(container.firstChild).toMatchSnapshot(); 18 | }); 19 | 20 | it("should initialize state", () => { 21 | act(() => { 22 | resize(1); 23 | }); 24 | render(hidden); 25 | expect(screen.queryAllByText("hidden")).toHaveLength(0); 26 | act(() => { 27 | resize(768); 28 | }); 29 | expect(screen.queryAllByText("hidden")).toHaveLength(1); 30 | }); 31 | 32 | it("should control screen state", () => { 33 | act(() => { 34 | resize(1); 35 | }); 36 | render(hidden); 37 | expect(screen.queryAllByText("hidden")).toHaveLength(1); 38 | act(() => { 39 | resize(768); 40 | }); 41 | expect(screen.queryAllByText("hidden")).toHaveLength(0); 42 | }); 43 | 44 | it("should always be hidden", () => { 45 | render( 46 | 47 | hidden 48 | 49 | ); 50 | Object.values(config().breakpoints).forEach((b) => { 51 | act(() => { 52 | resize(b * 16); 53 | }); 54 | expect(screen.queryAllByText("hidden")).toHaveLength(0); 55 | }); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /lib/components/__tests__/row.test.tsx: -------------------------------------------------------------------------------- 1 | import { render } from "@testing-library/react"; 2 | import { Row } from "../grid/row"; 3 | import { GridBreakpoints } from "@site/lib/types"; 4 | 5 | describe("children", () => { 6 | it("should render default style correctly", () => { 7 | const { asFragment } = render(children); 8 | expect(asFragment()).toMatchSnapshot(); 9 | }); 10 | 11 | it("should have a reverse direction for each media", () => { 12 | const { asFragment } = render(children); 13 | expect(asFragment()).toMatchSnapshot(); 14 | }); 15 | 16 | it("should have a reverse direction for specific screen", () => { 17 | const props = { 18 | reverse: ["md", "lg"] as GridBreakpoints[] 19 | }; 20 | const { asFragment } = render(children); 21 | expect(asFragment()).toMatchSnapshot(); 22 | }); 23 | 24 | it("should have the css rule justify-content center", () => { 25 | const props = { 26 | justify: "center" 27 | }; 28 | const { asFragment } = render(children); 29 | expect(asFragment()).toMatchSnapshot(); 30 | }); 31 | 32 | it("should have the css rule justify-content center only in MD screen", () => { 33 | const props = { 34 | justify: { 35 | md: "center" 36 | } 37 | }; 38 | const { asFragment } = render(children); 39 | expect(asFragment()).toMatchSnapshot(); 40 | }); 41 | 42 | it("should have the css rule align-items center", () => { 43 | const props = { 44 | align: "center" 45 | }; 46 | const { asFragment } = render(children); 47 | expect(asFragment()).toMatchSnapshot(); 48 | }); 49 | 50 | it("should have the css rule align-items center only in MD screen", () => { 51 | const props = { 52 | align: { 53 | md: "center" 54 | } 55 | }; 56 | 57 | const { asFragment } = render(children); 58 | expect(asFragment()).toMatchSnapshot(); 59 | }); 60 | 61 | it("should have different style when it`s debug props is true", () => { 62 | const { asFragment } = render(children); 63 | expect(asFragment()).toMatchSnapshot(); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /lib/components/__tests__/screens.test.tsx: -------------------------------------------------------------------------------- 1 | import config, { DIMENSIONS } from '../../config' 2 | import { getViewPort, getScreenClass } from '../util/screens' 3 | 4 | describe('screens', () => { 5 | it('should return null', () => { 6 | global.window.innerWidth = null 7 | expect(getViewPort()).toBeNull() 8 | }) 9 | 10 | it('should return window inner width', () => { 11 | global.window.innerWidth = 768 12 | expect(getViewPort()).toBe(768) 13 | }) 14 | 15 | it('should return undefined screen class', () => { 16 | global.window.innerWidth = null 17 | expect(getScreenClass()).toBeUndefined() 18 | }) 19 | 20 | it('should return the correct screen class', () => { 21 | Object.values(config().breakpoints).forEach((b, i) => { 22 | global.window.innerWidth = b * 16 23 | expect(getScreenClass()).toBe(DIMENSIONS[i]) 24 | }) 25 | }) 26 | }) -------------------------------------------------------------------------------- /lib/components/__tests__/visible.test.tsx: -------------------------------------------------------------------------------- 1 | import { act, render, screen } from "@testing-library/react"; 2 | import config from "../../config"; 3 | import { Visible } from "../util/visible"; 4 | 5 | describe("", () => { 6 | const resize = (width) => { 7 | global.window.innerWidth = width; 8 | global.window.dispatchEvent(new Event("resize")); 9 | }; 10 | 11 | it("should render default style correctly", () => { 12 | const { container } = render( 13 | 14 |

children

15 |
16 | ); 17 | expect(container.firstChild).toMatchSnapshot(); 18 | }); 19 | 20 | it("should initialize state", () => { 21 | act(() => { 22 | resize(1); 23 | }); 24 | render(visible); 25 | expect(screen.queryAllByText("visible")).toHaveLength(1); 26 | act(() => { 27 | resize(768); 28 | }); 29 | expect(screen.queryAllByText("visible")).toHaveLength(0); 30 | }); 31 | 32 | it("should control screen state", () => { 33 | act(() => { 34 | resize(1); 35 | }); 36 | render(visible); 37 | expect(screen.queryAllByText("visible")).toHaveLength(0); 38 | act(() => { 39 | resize(768); 40 | }); 41 | expect(screen.queryAllByText("visible")).toHaveLength(1); 42 | }); 43 | 44 | it("should always be visible", () => { 45 | render( 46 | 47 | visible 48 | 49 | ); 50 | Object.values(config().breakpoints).forEach((b) => { 51 | act(() => { 52 | resize(b * 16); 53 | }); 54 | expect(screen.queryAllByText("visible")).toHaveLength(1); 55 | }); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /lib/components/grid/col.tsx: -------------------------------------------------------------------------------- 1 | import styled, { css } from "styled-components"; 2 | import isPropValid from "@emotion/is-prop-valid"; 3 | import config, { DIMENSIONS } from "../../config"; 4 | import { GridColProps } from "../../types"; 5 | 6 | export const Col = styled.div.withConfig({ 7 | shouldForwardProp: (prop) => isPropValid(prop) 8 | })` 9 | box-sizing: border-box; 10 | flex: 1 0 auto; 11 | max-width: 100%; 12 | display: flex; 13 | flex-direction: column; 14 | 15 | ${(props) => 16 | !props.noGutter && 17 | css` 18 | ${DIMENSIONS.map( 19 | (dimension) => 20 | config(props).breakpoints[dimension] && 21 | config(props).media[dimension]` 22 | padding-right: ${config(props).gutterWidth[dimension] / 2}rem; 23 | padding-left: ${config(props).gutterWidth[dimension] / 2}rem; 24 | ` 25 | )} 26 | `} 27 | 28 | ${(props) => css` 29 | ${DIMENSIONS.map( 30 | (dimension) => 31 | props[dimension] && 32 | config(props).breakpoints[dimension] && 33 | config(props).media[dimension]` 34 | flex: 1 1 ${(+props[dimension] / config(props).columns[dimension]) * 100}%; 35 | max-width: ${(+props[dimension] / config(props).columns[dimension]) * 100}%; 36 | ` 37 | )} 38 | `} 39 | 40 | ${(props) => 41 | props.offset && 42 | css` 43 | ${DIMENSIONS.map( 44 | (dimension) => 45 | config(props).breakpoints[dimension] && 46 | config(props).media[dimension]` 47 | ${ 48 | typeof props.offset === "object" 49 | ? props.offset[dimension] !== undefined && 50 | `margin-left: ${props.offset[dimension] > 0 ? (props.offset[dimension] / config(props).columns[dimension]) * 100 : 0}%` 51 | : `margin-left: ${(props.offset / config(props).columns["xs"]) * 100}%` 52 | }; 53 | ` 54 | )} 55 | `} 56 | 57 | ${(props) => 58 | props.order !== undefined && 59 | css` 60 | ${DIMENSIONS.map( 61 | (dimension) => 62 | config(props).breakpoints[dimension] && 63 | config(props).media[dimension]` 64 | ${ 65 | typeof props.order === "object" 66 | ? props.order[dimension] !== undefined && 67 | `order: ${props.order[dimension]}` 68 | : `order: ${props.order}` 69 | }; 70 | ` 71 | )} 72 | `} 73 | 74 | ${(props) => 75 | props.reverse && 76 | css` 77 | ${Array.isArray(props.reverse) 78 | ? DIMENSIONS.map( 79 | (dimension) => 80 | config(props).breakpoints[dimension] && 81 | config(props).media[dimension]` 82 | flex-direction: ${Array.isArray(props.reverse) && props.reverse.indexOf(dimension) !== -1 ? "column-reverse" : "column"}; 83 | ` 84 | ) 85 | : "flex-direction: column-reverse;"} 86 | `} 87 | 88 | ${(props) => 89 | props.align && 90 | css` 91 | ${typeof props.align === "object" 92 | ? DIMENSIONS.map( 93 | (dimensions) => 94 | config(props).breakpoints[dimensions] && 95 | config(props).media[ 96 | dimensions 97 | ]`${props.align[dimensions] && `align-items: ${props.align[dimensions]}`}` 98 | ) 99 | : `align-items: ${props.align};`} 100 | `} 101 | 102 | ${(props) => 103 | props.justify && 104 | css` 105 | ${typeof props.justify === "object" 106 | ? DIMENSIONS.map( 107 | (dimensions) => 108 | config(props).breakpoints[dimensions] && 109 | config(props).media[ 110 | dimensions 111 | ]`${props.justify[dimensions] && `justify-content: ${props.justify[dimensions]}`}` 112 | ) 113 | : `justify-content: ${props.justify};`} 114 | `} 115 | 116 | ${({ debug }) => 117 | debug && 118 | css` 119 | background-color: #5901ad40; 120 | outline: #fff solid 1px; 121 | `} 122 | `; 123 | -------------------------------------------------------------------------------- /lib/components/grid/container.tsx: -------------------------------------------------------------------------------- 1 | import styled, { css } from "styled-components"; 2 | import isPropValid from "@emotion/is-prop-valid"; 3 | import config, { DIMENSIONS } from "../../config"; 4 | import { GridContainerProps } from "../../types"; 5 | 6 | export const Container = styled("div").withConfig({ 7 | shouldForwardProp: (prop) => isPropValid(prop) 8 | })` 9 | margin-right: auto; 10 | margin-left: auto; 11 | max-width: 100%; 12 | width: 100%; 13 | box-sizing: border-box; 14 | 15 | ${(props) => css` 16 | ${DIMENSIONS.map( 17 | (d) => 18 | config(props).container[d] && 19 | config(props).media[d]` 20 | padding-left: ${config(props).paddingWidth[d]}rem; 21 | padding-right: ${config(props).paddingWidth[d]}rem; 22 | ` 23 | )} 24 | `} 25 | 26 | ${(props) => 27 | !props.fluid && 28 | css` 29 | ${DIMENSIONS.map( 30 | (d) => 31 | config(props).container[d] && 32 | config(props).media[d]` 33 | ${ 34 | typeof config(props).container[d] === "number" 35 | ? `max-width: ${config(props).container[d]}rem;` 36 | : `width: 100%;` 37 | } 38 | ` 39 | )} 40 | `} 41 | 42 | ${({ debug }) => 43 | debug && 44 | css` 45 | background-color: #5901ad40; 46 | outline: #fff solid 1px; 47 | `} 48 | `; 49 | -------------------------------------------------------------------------------- /lib/components/grid/row.tsx: -------------------------------------------------------------------------------- 1 | import styled, { css } from "styled-components"; 2 | import isPropValid from "@emotion/is-prop-valid"; 3 | import config, { DIMENSIONS } from "../../config"; 4 | import { GridRowProps } from "../../types"; 5 | 6 | export const Row = styled.div.withConfig({ 7 | shouldForwardProp: (prop) => isPropValid(prop) 8 | })` 9 | box-sizing: border-box; 10 | display: flex; 11 | flex: 1 1 auto; 12 | flex-wrap: wrap; 13 | 14 | ${(props) => css` 15 | ${DIMENSIONS.map( 16 | (dimension) => 17 | config(props).container[dimension] && 18 | config(props).media[dimension]` 19 | margin-left: -${config(props).gutterWidth[dimension] / 2}rem; 20 | margin-right: -${config(props).gutterWidth[dimension] / 2}rem; 21 | ` 22 | )} 23 | `} 24 | 25 | ${(props) => 26 | props.reverse && 27 | css` 28 | ${Array.isArray(props.reverse) 29 | ? DIMENSIONS.map( 30 | (dimension) => 31 | config(props).breakpoints[dimension] && 32 | config(props).media[dimension]` 33 | ${ 34 | Array.isArray(props.reverse) && 35 | props.reverse.indexOf(dimension) !== -1 36 | ? ` 37 | flex-direction: row-reverse; 38 | flex-wrap: wrap-reverse; 39 | ` 40 | : ` 41 | flex-direction: row; 42 | flex-wrap: wrap; 43 | ` 44 | }; 45 | 46 | ` 47 | ) 48 | : ` 49 | flex-direction: row-reverse; 50 | flex-wrap: wrap-reverse; 51 | `} 52 | `} 53 | 54 | ${(props) => 55 | props.align && 56 | css` 57 | ${typeof props.align === "object" 58 | ? DIMENSIONS.map( 59 | (dimension) => 60 | config(props).breakpoints[dimension] && 61 | config(props).media[ 62 | dimension 63 | ]`${props.align[dimension] && `align-items: ${props.align[dimension]}`}` 64 | ) 65 | : `align-items: ${props.align};`} 66 | `} 67 | 68 | ${(props) => 69 | props.justify && 70 | css` 71 | ${typeof props.justify === "object" 72 | ? DIMENSIONS.map( 73 | (dimension) => 74 | config(props).breakpoints[dimension] && 75 | config(props).media[dimension]`${ 76 | props.justify[dimension] && 77 | `justify-content: ${props.justify[dimension]}` 78 | }` 79 | ) 80 | : `justify-content: ${props.justify};`} 81 | `} 82 | 83 | ${({ debug }) => 84 | debug && 85 | css` 86 | background-color: #5901ad40; 87 | outline: #fff solid 1px; 88 | `} 89 | `; 90 | -------------------------------------------------------------------------------- /lib/components/helper.ts: -------------------------------------------------------------------------------- 1 | import isPropValid from "@emotion/is-prop-valid"; 2 | 3 | export const isValidProp = (prop: string) => isPropValid(prop); 4 | -------------------------------------------------------------------------------- /lib/components/util/hidden.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useEffect, Fragment } from "react"; 2 | import useEventListener from "@use-it/event-listener"; 3 | import { getScreenClass } from "./screens"; 4 | import { ConfigProps, HiddenProps } from "../../types"; 5 | 6 | export const Hidden = ({ 7 | xs, 8 | sm, 9 | md, 10 | lg, 11 | xl, 12 | children, 13 | theme 14 | }: HiddenProps & ConfigProps) => { 15 | const [currentScreen, setCurrentScreen] = useState("xs"); 16 | 17 | const setScreen = () => { 18 | const newScreen = getScreenClass({ theme }); 19 | if (currentScreen !== newScreen) { 20 | setCurrentScreen(newScreen); 21 | } 22 | }; 23 | useEffect(() => { 24 | setScreen(); 25 | }, []); 26 | 27 | useEventListener("orientationchange", setScreen); 28 | useEventListener("resize", setScreen); 29 | 30 | const isHidden = () => { 31 | switch (currentScreen) { 32 | case "xs": 33 | return xs; 34 | case "sm": 35 | return sm; 36 | case "md": 37 | return md; 38 | case "lg": 39 | return lg; 40 | case "xl": 41 | return xl; 42 | } 43 | }; 44 | if (isHidden()) return false; 45 | return {children}; 46 | }; 47 | -------------------------------------------------------------------------------- /lib/components/util/screenBadge.tsx: -------------------------------------------------------------------------------- 1 | import styled, { css } from "styled-components"; 2 | import isPropValid from "@emotion/is-prop-valid"; 3 | import config, { DIMENSIONS } from "../../config"; 4 | 5 | export const ScreenBadge = styled.div.withConfig({ 6 | shouldForwardProp: (prop) => isPropValid(prop) 7 | })` 8 | z-index: 10; 9 | position: fixed; 10 | font-size: 1.5rem; 11 | font-weight: bold; 12 | right: 10px; 13 | bottom: 10px; 14 | width: 50px; 15 | height: 30px; 16 | background-color: #5901ad40; 17 | display: flex; 18 | border-radius: 5px; 19 | justify-content: center; 20 | align-items: center; 21 | ${(props) => css` 22 | ${DIMENSIONS.map( 23 | (dimension) => 24 | config(props).breakpoints[dimension] && 25 | config(props).media[dimension]` 26 | &::before { 27 | content: '${dimension}' 28 | } 29 | ` 30 | )} 31 | `} 32 | `; 33 | -------------------------------------------------------------------------------- /lib/components/util/screenClass.tsx: -------------------------------------------------------------------------------- 1 | import { useCallback, useEffect, useState, ReactNode, Fragment } from "react"; 2 | import { getScreenClass } from "./screens"; 3 | import { ConfigProps } from "../../types"; 4 | import { DIMENSIONS } from "../../config"; 5 | 6 | type ScreenClassProps = { 7 | render: (screen: string) => ReactNode; 8 | }; 9 | 10 | export const ScreenClass = (props: ScreenClassProps & ConfigProps) => { 11 | const [currentScreen, setCurrentScreen] = useState(DIMENSIONS[0]); 12 | 13 | const setScreen = useCallback(() => { 14 | const lastScreenClass = currentScreen; 15 | const newScreenClass = getScreenClass(props); 16 | if (lastScreenClass !== newScreenClass) { 17 | setCurrentScreen(newScreenClass); 18 | } 19 | }, [currentScreen]); 20 | 21 | useEffect(() => { 22 | setScreen(); 23 | }, []); 24 | 25 | useEffect(() => { 26 | if (typeof window !== "undefined") { 27 | window.addEventListener("orientationchange", setScreen, false); 28 | window.addEventListener("resize", setScreen, false); 29 | } 30 | return () => { 31 | if (typeof window !== "undefined") { 32 | window.removeEventListener("orientationchange", setScreen); 33 | window.removeEventListener("resize", setScreen); 34 | } 35 | }; 36 | }, [currentScreen]); 37 | 38 | return {props?.render(currentScreen)}; 39 | }; 40 | -------------------------------------------------------------------------------- /lib/components/util/screens.ts: -------------------------------------------------------------------------------- 1 | import { ConfigProps, GridBreakpoints } from "../../types"; 2 | import config, { DIMENSIONS } from "../../config"; 3 | 4 | export function getViewPort() { 5 | if (typeof window !== "undefined" && window.innerWidth) { 6 | return window.innerWidth; 7 | } 8 | return null; 9 | } 10 | 11 | export function getScreenClass(props?: ConfigProps) { 12 | const screenClasses = DIMENSIONS; 13 | const breakpoints = config(props).breakpoints; 14 | 15 | const rootFont = 16 | typeof window !== "undefined" 17 | ? +window 18 | .getComputedStyle(document.querySelector("html")) 19 | .getPropertyValue("font-size") 20 | .replace("px", "") || 16 21 | : 16; 22 | 23 | const pxBreakpoints = Object.values(breakpoints).map((bp) => bp * rootFont); 24 | 25 | let screenClass: GridBreakpoints; 26 | const viewport = getViewPort(); 27 | if (viewport) { 28 | screenClass = screenClasses[0]; 29 | if (pxBreakpoints[1] && viewport >= pxBreakpoints[1]) 30 | screenClass = screenClasses[1]; 31 | if (pxBreakpoints[2] && viewport >= pxBreakpoints[2]) 32 | screenClass = screenClasses[2]; 33 | if (pxBreakpoints[3] && viewport >= pxBreakpoints[3]) 34 | screenClass = screenClasses[3]; 35 | if (pxBreakpoints[4] && viewport >= pxBreakpoints[4]) 36 | screenClass = screenClasses[4]; 37 | } 38 | return screenClass; 39 | } 40 | -------------------------------------------------------------------------------- /lib/components/util/visible.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useEffect, Fragment } from "react"; 2 | import useEventListener from "@use-it/event-listener"; 3 | import { ConfigProps, VisibleProps } from "../../types"; 4 | import { getScreenClass } from "./screens"; 5 | 6 | export const Visible = ({ 7 | xs, 8 | sm, 9 | md, 10 | lg, 11 | xl, 12 | children, 13 | theme 14 | }: VisibleProps & ConfigProps) => { 15 | const [currentScreen, setCurrentScreen] = useState("xs"); 16 | 17 | const setScreen = () => { 18 | const newScreen = getScreenClass({ theme }); 19 | if (currentScreen !== newScreen) { 20 | setCurrentScreen(newScreen); 21 | } 22 | }; 23 | useEffect(() => { 24 | setScreen(); 25 | }, []); 26 | 27 | useEventListener("orientationchange", setScreen); 28 | useEventListener("resize", setScreen); 29 | 30 | const isVisible = () => { 31 | switch (currentScreen) { 32 | case "xs": 33 | return xs; 34 | case "sm": 35 | return sm; 36 | case "md": 37 | return md; 38 | case "lg": 39 | return lg; 40 | case "xl": 41 | return xl; 42 | } 43 | }; 44 | if (!isVisible()) return false; 45 | return {children}; 46 | }; 47 | -------------------------------------------------------------------------------- /lib/config.ts: -------------------------------------------------------------------------------- 1 | import { Config, ConfigProps, GridBreakpoints, Media } from "./types"; 2 | import { css, CSSObject } from "styled-components"; 3 | 4 | export const CUSTOM_CONF = "awesomegrid"; 5 | export const DIMENSIONS: GridBreakpoints[] = ["xs", "sm", "md", "lg", "xl"]; 6 | export const BASE_CONF: Config = { 7 | media: null, 8 | mediaQuery: "only screen", 9 | columns: { 10 | xs: 4, 11 | sm: 8, 12 | md: 8, 13 | lg: 12, 14 | xl: 12 15 | }, 16 | gutterWidth: { 17 | xs: 1, 18 | sm: 1, 19 | md: 1.5, 20 | lg: 1.5, 21 | xl: 1.5 22 | }, 23 | paddingWidth: { 24 | xs: 1, 25 | sm: 1, 26 | md: 1.5, 27 | lg: 1.5, 28 | xl: 1.5 29 | }, 30 | container: { 31 | xs: "full", // 'full' = max-width: 100% 32 | sm: "full", // 'full' = max-width: 100% 33 | md: "full", // 'full' = max-width: 100% 34 | lg: 90, // max-width: 1440px 35 | xl: 90 // max-width: 1440px 36 | }, 37 | breakpoints: { 38 | xs: 1, 39 | sm: 48, // 768px 40 | md: 64, // 1024px 41 | lg: 90, // 1440px 42 | xl: 120 // 1920px 43 | } 44 | }; 45 | 46 | const configs = []; 47 | const hasCustomConf = (props: ConfigProps) => { 48 | if (!props?.theme) return {}; 49 | return JSON.stringify(props.theme[CUSTOM_CONF] || {}); 50 | }; 51 | const resolveConfig = (props: ConfigProps) => { 52 | let themeConf = {}; 53 | if (props?.theme) { 54 | themeConf = props.theme[CUSTOM_CONF] || {}; 55 | } 56 | 57 | const conf: Config = { 58 | ...BASE_CONF, 59 | ...themeConf 60 | }; 61 | 62 | conf.media = Object.keys(conf.breakpoints).reduce((media, breakpoint) => { 63 | const breakpointWidth = conf.breakpoints[breakpoint]; 64 | media[breakpoint] = makeMedia( 65 | [ 66 | conf.mediaQuery, 67 | breakpointWidth >= 0 && `(min-width: ${breakpointWidth}rem)` 68 | ] 69 | .filter(Boolean) 70 | .join(" and ") 71 | ); 72 | return media; 73 | }, {} as Media); 74 | 75 | return conf; 76 | }; 77 | 78 | export default function config(props?: ConfigProps): Config { 79 | const customConf = hasCustomConf(props); 80 | if (configs[0] === customConf) { 81 | return configs[1]; 82 | } 83 | 84 | const conf = resolveConfig(props); 85 | 86 | configs[0] = customConf; 87 | configs[1] = conf; 88 | 89 | return conf; 90 | } 91 | 92 | function makeMedia(media: string) { 93 | return (...args: CSSObject[] | TemplateStringsArray) => css` 94 | @media ${media} { 95 | ${css.apply(null, [...args])} 96 | } 97 | `; 98 | } 99 | -------------------------------------------------------------------------------- /lib/index.ts: -------------------------------------------------------------------------------- 1 | import { Container } from "./components/grid/container"; 2 | import { Row } from "./components/grid/row"; 3 | import { Col } from "./components/grid/col"; 4 | import { Visible } from "./components/util/visible"; 5 | import { Hidden } from "./components/util/hidden"; 6 | import { ScreenClass } from "./components/util/screenClass"; 7 | import { ScreenBadge } from "./components/util/screenBadge"; 8 | import config from "./config"; 9 | 10 | import { getScreenClass, getViewPort } from "./components/util/screens"; 11 | 12 | const util = { 13 | getScreenClass, 14 | getViewPort 15 | }; 16 | 17 | export { 18 | Container, 19 | Row, 20 | Col, 21 | Visible, 22 | Hidden, 23 | ScreenClass, 24 | ScreenBadge, 25 | config, 26 | util 27 | }; 28 | -------------------------------------------------------------------------------- /lib/styled.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/consistent-type-definitions */ 2 | // import original module declarations 3 | import "styled-components"; 4 | import { Config } from "./types"; 5 | import { CUSTOM_CONF } from "../lib/config"; 6 | 7 | // and extend them! 8 | declare module "styled-components" { 9 | export interface DefaultTheme { 10 | [CUSTOM_CONF]: Partial; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/types.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_CONF } from "./config"; 2 | import * as React from "react"; 3 | import { DefaultTheme, css } from "styled-components"; 4 | export type GridBreakpoints = "xs" | "sm" | "md" | "lg" | "xl"; 5 | 6 | export type AlignOrJustifyOptions = { 7 | xs?: string; 8 | sm?: string; 9 | md?: string; 10 | lg?: string; 11 | xl?: string; 12 | }; 13 | 14 | export type OffsetOptions = { 15 | xs?: number; 16 | sm?: number; 17 | md?: number; 18 | lg?: number; 19 | xl?: number; 20 | }; 21 | 22 | export type OrderOptions = { 23 | xs?: number; 24 | sm?: number; 25 | md?: number; 26 | lg?: number; 27 | xl?: number; 28 | }; 29 | 30 | export type Grid = { 31 | children: React.ReactNode; 32 | style?: React.CSSProperties; 33 | debug?: boolean; 34 | }; 35 | 36 | export type GridContainerProps = Grid & { 37 | fluid?: boolean; 38 | }; 39 | 40 | export type GridRowProps = Grid & { 41 | reverse?: boolean | GridBreakpoints[]; 42 | align?: string | object; 43 | justify?: string | object; 44 | }; 45 | 46 | export type GridColProps = Grid & { 47 | xs?: number | string; 48 | sm?: number | string; 49 | md?: number | string; 50 | lg?: number | string; 51 | xl?: number | string; 52 | offset?: number | OffsetOptions; 53 | order?: number | OrderOptions; 54 | reverse?: boolean | GridBreakpoints[]; 55 | align?: string | AlignOrJustifyOptions; 56 | justify?: string | AlignOrJustifyOptions; 57 | noGutter?: boolean; 58 | }; 59 | 60 | export type VisibleProps = { 61 | xs?: boolean; 62 | sm?: boolean; 63 | md?: boolean; 64 | lg?: boolean; 65 | xl?: boolean; 66 | children: React.ReactNode; 67 | }; 68 | 69 | export type HiddenProps = { 70 | xs?: boolean; 71 | sm?: boolean; 72 | md?: boolean; 73 | lg?: boolean; 74 | xl?: boolean; 75 | children: React.ReactNode; 76 | }; 77 | 78 | export type ScreenClassProps = { 79 | render: (screen: GridBreakpoints) => React.ReactNode; 80 | }; 81 | 82 | export type Media = Record; 83 | 84 | export type Config = { 85 | media: Media; 86 | mediaQuery: string; 87 | columns: Record; 88 | gutterWidth: Record; 89 | paddingWidth: Record; 90 | container: Record; 91 | breakpoints: Record; 92 | }; 93 | 94 | export type AwesomeTheme = { [CUSTOM_CONF]: Partial }; 95 | 96 | export type ConfigProps = { theme?: DefaultTheme }; 97 | 98 | export type Util = { 99 | getScreenClass: (props?: ConfigProps) => GridBreakpoints; 100 | getViewPort: () => number | null; 101 | }; 102 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-awesome-styled-grid", 3 | "version": "4.0.1", 4 | "description": "A responsive grid system layout for React using styled-components", 5 | "main": "dist/react-awesome-styled-grid.cjs.js", 6 | "module": "dist/react-awesome-styled-grid.es.js", 7 | "browser": "dist/react-awesome-styled-grid.js", 8 | "types": "dist/types/index.d.ts", 9 | "files": [ 10 | "dist" 11 | ], 12 | "scripts": { 13 | "build": "yarn tsc && rollup -c", 14 | "clean": "rm -rf ./dist && rm -rf types", 15 | "docusaurus": "docusaurus", 16 | "start": "docusaurus start", 17 | "build-doc": "docusaurus build", 18 | "swizzle": "docusaurus swizzle", 19 | "deploy": "docusaurus deploy", 20 | "clear": "docusaurus clear", 21 | "serve": "docusaurus serve", 22 | "write-translations": "docusaurus write-translations", 23 | "write-heading-ids": "docusaurus write-heading-ids", 24 | "tsc": "tsc --project tsconfig.build.json ", 25 | "lint": "eslint \"**/*.{js,ts,tsx}\"", 26 | "format": "prettier --ignore-path .gitignore --write \"**/*.+(js|ts|tsx|json)\"", 27 | "test": "jest --runInBand", 28 | "test:watch": "jest --watch", 29 | "test:coverage": "jest --coverage", 30 | "contributors:add": "all-contributors add", 31 | "contributors:generate": "all-contributors generate" 32 | }, 33 | "repository": { 34 | "type": "git", 35 | "url": "git+https://github.com/santosfrancisco/react-awesome-styled-grid.git" 36 | }, 37 | "keywords": [ 38 | "react", 39 | "grid", 40 | "styled-components", 41 | "javascript" 42 | ], 43 | "author": "Francisco Santos", 44 | "license": "MIT", 45 | "bugs": { 46 | "url": "https://github.com/santosfrancisco/react-awesome-styled-grid/issues" 47 | }, 48 | "homepage": "https://awesome-styled-grid.netlify.app/", 49 | "peerDependencies": { 50 | "react": ">=18", 51 | "styled-components": ">=6" 52 | }, 53 | "devDependencies": { 54 | "@babel/cli": "7.24.6", 55 | "@babel/core": "7.24.6", 56 | "@babel/plugin-external-helpers": "7.24.6", 57 | "@babel/plugin-proposal-object-rest-spread": "7.20.7", 58 | "@babel/plugin-transform-runtime": "7.24.6", 59 | "@babel/preset-env": "7.24.6", 60 | "@babel/preset-react": "7.24.6", 61 | "@babel/preset-typescript": "7.24.6", 62 | "@docusaurus/core": "3.2.1", 63 | "@docusaurus/module-type-aliases": "3.2.1", 64 | "@docusaurus/preset-classic": "3.2.1", 65 | "@docusaurus/remark-plugin-npm2yarn": "3.2.1", 66 | "@docusaurus/theme-live-codeblock": "3.2.1", 67 | "@docusaurus/tsconfig": "3.2.1", 68 | "@docusaurus/types": "3.2.1", 69 | "@emotion/is-prop-valid": "1.2.2", 70 | "@jest/globals": "29.7.0", 71 | "@mdx-js/react": "3.0.1", 72 | "@rollup/plugin-node-resolve": "15.2.3", 73 | "@rollup/plugin-terser": "0.4.4", 74 | "@rollup/plugin-typescript": "11.1.6", 75 | "@testing-library/react": "15.0.2", 76 | "@types/jest": "27", 77 | "@types/react": "18.2.74", 78 | "@types/styled-components": "5.1.34", 79 | "@typescript-eslint/eslint-plugin": "6.7.3", 80 | "@typescript-eslint/parser": "6.7.3", 81 | "@use-it/event-listener": "0.1.7", 82 | "all-contributors-cli": "6.16.0", 83 | "babel-eslint": "10.1.0", 84 | "babel-jest": "27", 85 | "babel-loader": "8.1.0", 86 | "babel-plugin-styled-components": "2.1.4", 87 | "babel-plugin-transform-class-properties": "6.24.1", 88 | "clsx": "2.0.0", 89 | "eslint": "7.2.0", 90 | "eslint-config-prettier": "9.1.0", 91 | "eslint-config-standard": "14.1.1", 92 | "eslint-config-standard-react": "9.2.0", 93 | "eslint-plugin-import": "2.25.2", 94 | "eslint-plugin-node": "11.1.0", 95 | "eslint-plugin-promise": "6.1.1", 96 | "eslint-plugin-react": "7.34.1", 97 | "eslint-plugin-standard": "4.0.1", 98 | "globals": "15.0.0", 99 | "jest": "27", 100 | "jest-cli": "27", 101 | "jest-styled-components": "7.2.0", 102 | "prettier": "3.2.5", 103 | "prism-react-renderer": "2.3.1", 104 | "react": "18.2.0", 105 | "react-dom": "18.2.0", 106 | "regenerator-runtime": "0.13.5", 107 | "rollup": "4.14.1", 108 | "rollup-plugin-peer-deps-external": "2.2.4", 109 | "styled-components": "6.1.8", 110 | "ts-jest": "29.1.2", 111 | "ts-node": "10.9.2", 112 | "typescript": "5.2.2" 113 | }, 114 | "resolutions": { 115 | "tough-cookie": "^4.1.3" 116 | }, 117 | "browserslist": { 118 | "production": [ 119 | ">0.5%", 120 | "not dead", 121 | "not op_mini all" 122 | ], 123 | "development": [ 124 | "last 3 chrome version", 125 | "last 3 firefox version", 126 | "last 5 safari version" 127 | ] 128 | }, 129 | "engines": { 130 | "node": ">=18.0" 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santosfrancisco/react-awesome-styled-grid/f37f04fbcabec505dc2502be47044061f107060e/public/favicon.ico -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /rollup.config.mjs: -------------------------------------------------------------------------------- 1 | import resolve from "@rollup/plugin-node-resolve"; 2 | import typescript from "@rollup/plugin-typescript"; 3 | import terser from "@rollup/plugin-terser"; 4 | import peerDepsExternal from "rollup-plugin-peer-deps-external"; 5 | import pkg from "./package.json" assert { type: "json" }; 6 | 7 | const globals = { 8 | react: "React", 9 | "styled-components": "styled", 10 | "react/jsx-runtime": "jsxRuntime" 11 | }; 12 | 13 | export default [ 14 | { 15 | input: "lib/index.ts", 16 | output: { 17 | file: pkg.main, 18 | format: "cjs", 19 | sourcemap: true, 20 | name: pkg.name, 21 | interop: "compat", 22 | globals 23 | }, 24 | plugins: [ 25 | peerDepsExternal(), 26 | typescript({ 27 | tsconfig: "tsconfig.build.json" 28 | }), 29 | resolve() 30 | ], 31 | external: [...Object.keys(pkg.peerDependencies || {})] 32 | }, 33 | { 34 | input: "lib/index.ts", 35 | output: { 36 | file: pkg.module, 37 | format: "es", 38 | sourcemap: true, 39 | name: pkg.name, 40 | interop: "compat", 41 | globals 42 | }, 43 | plugins: [ 44 | peerDepsExternal(), 45 | typescript({ 46 | tsconfig: "tsconfig.build.json" 47 | }), 48 | resolve() 49 | ], 50 | external: [...Object.keys(pkg.peerDependencies || {})] 51 | }, 52 | { 53 | input: "lib/index.ts", 54 | output: { 55 | file: pkg.browser, 56 | format: "umd", 57 | sourcemap: true, 58 | name: pkg.name, 59 | interop: "compat", 60 | globals 61 | }, 62 | plugins: [ 63 | peerDepsExternal(), 64 | typescript({ 65 | tsconfig: "tsconfig.build.json" 66 | }), 67 | resolve({ browser: true }), 68 | terser() 69 | ], 70 | external: [...Object.keys(pkg.peerDependencies || {})] 71 | } 72 | ]; 73 | -------------------------------------------------------------------------------- /sidebars.ts: -------------------------------------------------------------------------------- 1 | import type { SidebarsConfig } from "@docusaurus/plugin-content-docs"; 2 | 3 | /** 4 | * Creating a sidebar enables you to: 5 | - create an ordered group of docs 6 | - render a sidebar for each doc of that group 7 | - provide next/previous navigation 8 | 9 | The sidebars can be generated from the filesystem, or explicitly defined here. 10 | 11 | Create as many sidebars as you want. 12 | */ 13 | const sidebars: SidebarsConfig = { 14 | // By default, Docusaurus generates a sidebar from the docs folder structure 15 | tutorialSidebar: [{ type: "autogenerated", dirName: "." }], 16 | 17 | // But you can create a sidebar manually 18 | /* 19 | tutorialSidebar: [ 20 | 'intro', 21 | 'hello', 22 | { 23 | type: 'category', 24 | label: 'Tutorial', 25 | items: ['tutorial-basics/create-a-document'], 26 | }, 27 | ], 28 | */ 29 | }; 30 | 31 | export default sidebars; 32 | -------------------------------------------------------------------------------- /src/components/HomepageFeatures/index.tsx: -------------------------------------------------------------------------------- 1 | import Heading from "@theme/Heading"; 2 | import { Col, Row } from "@site/lib"; 3 | 4 | type FeatureItem = { 5 | title: string; 6 | imgSrc: string; 7 | description: JSX.Element; 8 | }; 9 | 10 | const FeatureList: FeatureItem[] = [ 11 | { 12 | title: "Easy to Use", 13 | imgSrc: "img/pluto-easy-to-use.png", 14 | description: ( 15 | <> 16 | React-awesome-styled-grid was designed from the ground up to be easily 17 | installed and used to make responsive web applications in minutes with 18 | zero configuration. 19 | 20 | ) 21 | }, 22 | { 23 | title: "Focus on What Matters", 24 | imgSrc: "img/pluto-focus-on-what-matters.png", 25 | description: ( 26 | <> 27 | You can redirect your focus towards developing the core functionalities 28 | of your React application. This allows for more efficient allocation of 29 | time and resources, accelerating the overall development process while 30 | ensuring that your application remains responsive and user-friendly 31 | 32 | ) 33 | }, 34 | { 35 | title: "Consistency and Reliability", 36 | imgSrc: "img/pluto-consistency-and-reliability.png", 37 | description: ( 38 | <> 39 | Responsive design involves ensuring that your application looks and 40 | functions well across various devices and screen sizes. By adopting 41 | react-awesome-styled-grid, you ensure consistency in design and behavior 42 | across various devices and screen sizes. This library has been 43 | thoroughly tested and is regularly updated, guaranteeing reliability and 44 | compatibility with the latest devices and browsers. Your application 45 | will maintain a polished and professional appearance regardless of the 46 | platform it's accessed from. 47 | 48 | ) 49 | }, 50 | { 51 | title: "Time Efficiency", 52 | imgSrc: "img/pluto-time-efficiency.png", 53 | description: ( 54 | <> 55 | Leveraging react-awesome-styled-grid streamlines the implementation of 56 | responsive design features, saving considerable time and effort. Instead 57 | of manually crafting complex CSS media queries, you can utilize the 58 | pre-built components and utilities provided by the library to quickly 59 | achieve responsiveness in your React application. 60 | 61 | ) 62 | } 63 | ]; 64 | 65 | function Feature({ title, imgSrc, description }: FeatureItem) { 66 | return ( 67 | 68 |
69 | 74 |
75 |
76 | {title} 77 |

{description}

78 |
79 | 80 | ); 81 | } 82 | 83 | export default function HomepageFeatures(): JSX.Element { 84 | return ( 85 |
93 |
94 | 95 | {FeatureList.map((props, idx) => ( 96 | 97 | ))} 98 | 99 |
100 |
101 | ); 102 | } 103 | -------------------------------------------------------------------------------- /src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | /* You can override the default Infima variables here. */ 8 | :root { 9 | --ifm-color-primary: #2e8555; 10 | --ifm-color-primary-dark: #29784c; 11 | --ifm-color-primary-darker: #277148; 12 | --ifm-color-primary-darkest: #205d3b; 13 | --ifm-color-primary-light: #33925d; 14 | --ifm-color-primary-lighter: #359962; 15 | --ifm-color-primary-lightest: #3cad6e; 16 | --ifm-code-font-size: 95%; 17 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); 18 | } 19 | 20 | /* For readability concerns, you should choose a lighter palette in dark mode. */ 21 | [data-theme='dark'] { 22 | --ifm-color-primary: #25c2a0; 23 | --ifm-color-primary-dark: #21af90; 24 | --ifm-color-primary-darker: #1fa588; 25 | --ifm-color-primary-darkest: #1a8870; 26 | --ifm-color-primary-light: #29d5b0; 27 | --ifm-color-primary-lighter: #32d8b4; 28 | --ifm-color-primary-lightest: #4fddbf; 29 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); 30 | } 31 | 32 | 33 | /* index page start */ 34 | 35 | .heroBanner { 36 | padding: 2rem 0; 37 | text-align: center; 38 | position: relative; 39 | overflow: hidden; 40 | } 41 | 42 | .buttons { 43 | display: flex; 44 | align-items: center; 45 | justify-content: center; 46 | } 47 | 48 | .button + .button { 49 | margin-left: 16px; 50 | } 51 | 52 | @media only screen and (min-width: 48rem) { 53 | .heroBanner { 54 | padding: 4rem 0; 55 | text-align: left; 56 | } 57 | 58 | .buttons { 59 | -webkit-box-pack: start; 60 | justify-content: start; 61 | } 62 | } 63 | 64 | /* index page end */ 65 | -------------------------------------------------------------------------------- /src/pages/demo.tsx: -------------------------------------------------------------------------------- 1 | import styled, { ThemeProvider } from "styled-components"; 2 | import { Container, Row, Col, ScreenClass, ScreenBadge } from "@site/lib"; 3 | import Layout from "@theme/Layout"; 4 | import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; 5 | 6 | const customConf = { 7 | mediaQuery: "only screen", 8 | columns: { 9 | xs: 4, 10 | sm: 8, 11 | md: 8, 12 | lg: 12, 13 | xl: 12 14 | }, 15 | gutterWidth: { 16 | xs: 1, 17 | sm: 1, 18 | md: 1.5, 19 | lg: 1.5, 20 | xl: 1.5 21 | }, 22 | paddingWidth: { 23 | xs: 1, 24 | sm: 1, 25 | md: 1.5, 26 | lg: 1.5, 27 | xl: 1.5 28 | }, 29 | container: { 30 | xs: "full", // 'full' = max-width: 100% 31 | sm: "full", // 'full' = max-width: 100% 32 | md: "full", // 'full' = max-width: 100% 33 | lg: 90, // max-width: 1440px 34 | xl: 90 // max-width: 1440px 35 | }, 36 | breakpoints: { 37 | xs: 1, 38 | sm: 48, // 768px 39 | md: 64, // 1024px 40 | lg: 90, // 1440px 41 | xl: 120 // 1920px 42 | } 43 | }; 44 | 45 | type DemoProps = { 46 | className: string; 47 | }; 48 | 49 | const Demo = ({ className }: DemoProps) => { 50 | return ( 51 | 52 |
53 | 54 |
55 |

Resize your browser window and see what happens!

56 |
57 | 58 | 59 | 60 | ( 62 |

67 | Current screen is {screen.toUpperCase()} 68 |

69 | )} 70 | /> 71 | 72 |
73 | 74 | 75 |
76 | xs={2} sm={3} md={4} lg={3} xl={6} 77 |
78 | 79 | 80 |
81 | xs={2} sm={5} md={4} lg={3} xl={6} 82 |
83 | 84 | 85 |
86 | xs={4} sm={5} md={4} lg={6} xl={6} 87 |
88 | 89 | 90 |
91 | xs={4} sm={3} md={4} lg={12} xl={6} 92 |
93 | 94 |
95 |
96 |
97 |
98 | ); 99 | }; 100 | 101 | export default styled(({ className }) => { 102 | const { siteConfig } = useDocusaurusContext(); 103 | 104 | return ( 105 | 109 |
110 | 111 |
112 |
113 | ); 114 | })` 115 | display: flex; 116 | padding-top: 48px; 117 | 118 | .grid-container { 119 | padding-top: 20px; 120 | position: relative; 121 | background-color: rgb(243, 100, 2, 0.3); 122 | border-radius: 2px; 123 | } 124 | 125 | .grid-col { 126 | width: 100%; 127 | background-color: rgb(243, 4, 242, 0.3); 128 | min-height: 100px; 129 | margin-bottom: 20px; 130 | border-radius: 2px; 131 | } 132 | `; 133 | -------------------------------------------------------------------------------- /src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import clsx from "clsx"; 2 | import Link from "@docusaurus/Link"; 3 | import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; 4 | import Layout from "@theme/Layout"; 5 | import HomepageFeatures from "@site/src/components/HomepageFeatures"; 6 | import Heading from "@theme/Heading"; 7 | import { Container } from "@site/lib"; 8 | 9 | function HomepageHeader() { 10 | const { siteConfig } = useDocusaurusContext(); 11 | return ( 12 |
13 |
14 | 15 | {siteConfig.title} 16 | 17 |

{siteConfig.tagline}

18 |
19 | 20 | Get started 21 | 22 | 26 | Try a demo 27 | 28 |
29 |
30 |
31 | ); 32 | } 33 | 34 | export default function IndexPage() { 35 | const { siteConfig } = useDocusaurusContext(); 36 | return ( 37 | 38 | 39 | 40 | 41 | 42 | 43 | ); 44 | } 45 | -------------------------------------------------------------------------------- /src/pages/markdown-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Markdown page example 3 | --- 4 | 5 | # Markdown page example 6 | 7 | You don't need React to write simple standalone pages. 8 | -------------------------------------------------------------------------------- /src/theme/ReactLiveScope/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { ThemeProvider } from "styled-components"; 3 | import { 4 | Container, 5 | Row, 6 | Col, 7 | Visible, 8 | Hidden, 9 | ScreenClass, 10 | ScreenBadge, 11 | config, 12 | util 13 | } from "../../../lib"; 14 | 15 | // Add react-live imports you need here 16 | const ReactLiveScope = { 17 | React, 18 | ...React, 19 | ThemeProvider, 20 | Container, 21 | Row, 22 | Col, 23 | Visible, 24 | Hidden, 25 | ScreenClass, 26 | ScreenBadge, 27 | config, 28 | util 29 | }; 30 | 31 | export default ReactLiveScope; 32 | -------------------------------------------------------------------------------- /static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santosfrancisco/react-awesome-styled-grid/f37f04fbcabec505dc2502be47044061f107060e/static/.nojekyll -------------------------------------------------------------------------------- /static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santosfrancisco/react-awesome-styled-grid/f37f04fbcabec505dc2502be47044061f107060e/static/img/favicon.ico -------------------------------------------------------------------------------- /static/img/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /static/img/pluto-consistency-and-reliability.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santosfrancisco/react-awesome-styled-grid/f37f04fbcabec505dc2502be47044061f107060e/static/img/pluto-consistency-and-reliability.png -------------------------------------------------------------------------------- /static/img/pluto-easy-to-use.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santosfrancisco/react-awesome-styled-grid/f37f04fbcabec505dc2502be47044061f107060e/static/img/pluto-easy-to-use.png -------------------------------------------------------------------------------- /static/img/pluto-focus-on-what-matters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santosfrancisco/react-awesome-styled-grid/f37f04fbcabec505dc2502be47044061f107060e/static/img/pluto-focus-on-what-matters.png -------------------------------------------------------------------------------- /static/img/pluto-time-efficiency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santosfrancisco/react-awesome-styled-grid/f37f04fbcabec505dc2502be47044061f107060e/static/img/pluto-time-efficiency.png -------------------------------------------------------------------------------- /static/img/social-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/santosfrancisco/react-awesome-styled-grid/f37f04fbcabec505dc2502be47044061f107060e/static/img/social-card.png -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | // This file is not used in compilation. It is here just for a nice editor experience. 3 | "compilerOptions": { 4 | "skipLibCheck": true, 5 | "jsx": "react-jsx", 6 | "declaration": true, 7 | "emitDeclarationOnly": true, 8 | "noEmit": false, 9 | "baseUrl": ".", 10 | "rootDir": "./lib", 11 | "outDir": "./types", 12 | "allowSyntheticDefaultImports": true 13 | }, 14 | 15 | "include": ["lib"], 16 | "exclude": [ 17 | "node_modules", 18 | "sidebars.ts", 19 | "docusaurus.config.ts", 20 | "src", 21 | "dist", 22 | "build", 23 | "lib/components/__tests__/**" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // This file is not used in compilation. It is here just for a nice editor experience. 3 | "extends": "@docusaurus/tsconfig", 4 | "compilerOptions": { 5 | "types": ["node", "jest"], 6 | "jsx": "react-jsx", 7 | "baseUrl": ".", 8 | "paths": { 9 | "@site/*": ["./*"] 10 | } 11 | } 12 | } 13 | --------------------------------------------------------------------------------