├── .eslintrc.js ├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── assets └── react-raster-logo.png ├── babel.config.json ├── components └── SpecialBox.tsx ├── dist ├── index.es.js ├── index.es.js.map ├── index.js └── index.js.map ├── next-env.d.ts ├── next.config.js ├── package.json ├── pages ├── _app.tsx ├── _document.tsx ├── css │ ├── index.css │ └── reset.css ├── framer.tsx ├── getting-started.tsx ├── index.tsx ├── intersection.tsx └── test.tsx ├── react-raster.code-workspace ├── rollup.config.js ├── src ├── Box │ ├── Container.tsx │ ├── StyledBox.tsx │ ├── hooks │ │ ├── useBreakpoint.ts │ │ ├── useBreakpoints.ts │ │ ├── useClassName.ts │ │ ├── useColsEffective.ts │ │ ├── useColsTotal.ts │ │ ├── useCombinedRefs.ts │ │ ├── useControl.ts │ │ ├── useDisplay.ts │ │ ├── useGap │ │ │ ├── getGap.ts │ │ │ ├── index.ts │ │ │ └── useGapShort.ts │ │ ├── useIntersect.ts │ │ ├── useNormalize.ts │ │ ├── useProp.ts │ │ ├── useResizeObserver.ts │ │ ├── useSpacing │ │ │ ├── convertIfNumber.ts │ │ │ ├── index.ts │ │ │ ├── spacingObject.ts │ │ │ └── useSpacingShort.ts │ │ ├── useSpacingCSS.ts │ │ └── useUndefinedProps.ts │ ├── index.tsx │ ├── props.ts │ └── utils │ │ ├── debounce.ts │ │ └── useIsomorphicLayoutEffect.ts ├── Control │ └── index.tsx ├── context.ts └── index.ts ├── tsconfig.json ├── tsconfig.rollup.json └── yarn.lock /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: "next", 3 | rules: { 4 | quotes: ["error", "double"], 5 | semi: ["error", "always"], 6 | indent: ["error", 2], 7 | "no-multiple-empty-lines": ["error"], 8 | "jsx-a11y/anchor-is-valid": 0, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __assets 2 | /dist 3 | 4 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 5 | 6 | # dependencies 7 | /node_modules 8 | /.pnp 9 | .pnp.js 10 | 11 | # testing 12 | /coverage 13 | 14 | # next.js 15 | /.next/ 16 | /out/ 17 | 18 | # production 19 | /build 20 | 21 | # misc 22 | .DS_Store 23 | .env* 24 | 25 | # debug 26 | npm-debug.log* 27 | yarn-debug.log* 28 | yarn-error.log* 29 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | #### 8.2.1 (2021-07-27) 2 | 3 | ### 8.2.0 (2021-07-25) 4 | 5 | ##### New Features 6 | 7 | * add bar-notation (9771677c) 8 | 9 | #### 8.1.4 (2021-07-25) 10 | 11 | ##### Bug Fixes 12 | 13 | * fix colsTotal (fe2853a3) 14 | 15 | #### 8.1.3 (2021-07-25) 16 | 17 | ##### Bug Fixes 18 | 19 | * remove console-statements (3365b6b2) 20 | 21 | #### 8.1.2 (2021-07-25) 22 | 23 | ##### Documentation Changes 24 | 25 | * add test-pages (cc34d2ec) 26 | 27 | ##### New Features 28 | 29 | * add will-change (a7b6be2d) 30 | 31 | ##### Bug Fixes 32 | 33 | * fix willChange (9c3ab52a) 34 | * fix useProp array-handling (51d7007c) 35 | 36 | #### 8.1.1 (2021-07-23) 37 | 38 | ##### Bug Fixes 39 | 40 | * fix gap and column-inheritance (567d46f5) 41 | 42 | ##### Other Changes 43 | 44 | * fix prop tag (1e3a0adf) 45 | 46 | ### 8.1.0 (2021-07-23) 47 | 48 | ##### New Features 49 | 50 | * add gap (e32f08db) 51 | 52 | ##### Bug Fixes 53 | 54 | * change description (cab83f84) 55 | 56 | #### 8.0.5 (2021-07-21) 57 | 58 | ##### Bug Fixes 59 | 60 | * remove unnecessary moduls (9adcb911) 61 | 62 | #### 8.0.4 (2021-07-20) 63 | 64 | ##### New Features 65 | 66 | * add font-weight, font-style, text-align (96fd604f) 67 | 68 | #### 8.0.3 (2021-07-06) 69 | 70 | ##### Build System / Dependencies 71 | 72 | * **deps:** 73 | * bump hosted-git-info from 2.8.8 to 2.8.9 (40352d24) 74 | * bump elliptic from 6.5.3 to 6.5.4 (69bbfa9f) 75 | 76 | ##### Bug Fixes 77 | 78 | * fix control (e62f1b38) 79 | * add isomorphicLayoutEffect (a48c35c8) 80 | 81 | #### 8.0.2 (2021-07-06) 82 | 83 | ##### Other Changes 84 | 85 | * correct readme. (63e72a3c) 86 | 87 | #### 8.0.1 (2021-07-03) 88 | 89 | ##### Other Changes 90 | 91 | * performance optimization (3295e80c) 92 | 93 | #### 7.0.7 (2021-03-13) 94 | 95 | ##### Documentation Changes 96 | 97 | * fix typo (5a99e5e1) 98 | * add known issues (5bd12173) 99 | 100 | #### 7.0.6 (2021-01-29) 101 | 102 | ##### Bug Fixes 103 | 104 | * fix types again (bd1d2ec2) 105 | 106 | #### 7.0.5 (2021-01-29) 107 | 108 | ##### Bug Fixes 109 | 110 | * fix typescript types of Grid and Box (a3ffe4d6) 111 | 112 | #### 7.0.4 (2021-01-29) 113 | 114 | ##### Bug Fixes 115 | 116 | * fix grid control-props (6850f23f) 117 | 118 | #### 7.0.3 (2021-01-29) 119 | 120 | ##### Bug Fixes 121 | 122 | * fix control-grid (1fe305b0) 123 | 124 | #### 7.0.2 (2021-01-29) 125 | 126 | ##### Bug Fixes 127 | 128 | * fix colspan adaptation (7f97ed70) 129 | 130 | #### 7.0.1 (2021-01-29) 131 | 132 | ##### Documentation Changes 133 | 134 | * fix props-table (c2437585) 135 | * some typo-fixes (c9eeee1a) 136 | 137 | ##### Bug Fixes 138 | 139 | * prevent and warn, if Box needs more cols than parent (2d7ed8a8) 140 | 141 | ## 7.0.0 (2021-01-24) 142 | 143 | ##### Breaking Changes 144 | 145 | * pass generic props automatically (7d53ee95) 146 | 147 | ### 6.7.0 (2021-01-23) 148 | 149 | ##### Documentation Changes 150 | 151 | * add colspan-array (b764339b) 152 | 153 | ##### New Features 154 | 155 | * add height (f53fd315) 156 | 157 | ### 6.6.0 (2021-01-22) 158 | 159 | ##### New Features 160 | 161 | * make colspan variable (26094ed6) 162 | 163 | #### 6.5.1 (2021-01-22) 164 | 165 | ##### Bug Fixes 166 | 167 | * execute onResize only if argument is not null (c415befa) 168 | 169 | ### 6.5.0 (2021-01-22) 170 | 171 | ##### New Features 172 | 173 | * add onResize-callback (70a4810a) 174 | 175 | #### 6.4.6 (2021-01-17) 176 | 177 | ##### Bug Fixes 178 | 179 | * fix context-check and error-handling in Box (4fac82a9) 180 | 181 | #### 6.4.5 (2021-01-17) 182 | 183 | ##### Other Changes 184 | 185 | * fix parentcols-behaviour (434252d2) 186 | 187 | #### 6.4.4 (2021-01-17) 188 | 189 | ##### Bug Fixes 190 | 191 | * fix context-props. fix flex-bug in grid-component. (a88e95b0) 192 | 193 | #### 6.4.3 (2021-01-17) 194 | 195 | ##### Bug Fixes 196 | 197 | * fix normalizeProps (0bddcb72) 198 | 199 | #### 6.4.2 (2021-01-17) 200 | 201 | ##### Bug Fixes 202 | 203 | * fix className (33e86bb4) 204 | 205 | #### 6.4.1 (2021-01-17) 206 | 207 | ##### Bug Fixes 208 | 209 | * remove classnames package (9933179a) 210 | 211 | ### 6.4.0 (2021-01-16) 212 | 213 | ##### New Features 214 | 215 | * export types (c30e39c1) 216 | 217 | ### 6.3.0 (2021-01-15) 218 | 219 | ##### New Features 220 | 221 | * add innerHTML (e5d51db7) 222 | 223 | ### 6.2.0 (2021-01-14) 224 | 225 | ##### New Features 226 | 227 | * add order-prop (81e7c23d) 228 | 229 | #### 6.1.2 (2021-01-08) 230 | 231 | ##### Bug Fixes 232 | 233 | * fix breakpoint-type (7f5bc182) 234 | 235 | #### 6.1.1 (2021-01-08) 236 | 237 | ##### Documentation Changes 238 | 239 | * fix useRaster-example (49e8a2c1) 240 | 241 | ##### Bug Fixes 242 | 243 | * change context (98251ec5) 244 | 245 | ### 6.1.0 (2021-01-08) 246 | 247 | ##### Documentation Changes 248 | 249 | * add useRaster (c23819fb) 250 | 251 | ##### New Features 252 | 253 | * add useRaster (5461b185) 254 | 255 | ##### Bug Fixes 256 | 257 | * fix breakpoint-type (d2a370c2) 258 | * fix breakpoint-type (ac3de8f2) 259 | * change raster to src (6de8b070) 260 | 261 | #### 6.0.12 (2020-12-29) 262 | 263 | ##### Bug Fixes 264 | 265 | * add license (4aa22d1d) 266 | 267 | #### 6.0.11 (2020-12-29) 268 | 269 | ##### Documentation Changes 270 | 271 | * add exmaples to example-page (22bd6471) 272 | 273 | ##### Bug Fixes 274 | 275 | * fix peerDependencies (4182cf12) 276 | 277 | #### 6.0.10 (2020-12-12) 278 | 279 | ##### Bug Fixes 280 | 281 | * update dependencies (35f7d336) 282 | 283 | #### 6.0.9 (2020-12-12) 284 | 285 | ##### Bug Fixes 286 | 287 | * make component-prop optional everywhere (38050fb5) 288 | 289 | ##### Other Changes 290 | 291 | * add component-prop (7e68dbf9) 292 | 293 | #### 6.0.8 (2020-12-10) 294 | 295 | ##### Bug Fixes 296 | 297 | * show error-message, if Box is not child of a Grid (f9fea99e) 298 | 299 | #### 6.0.7 (2020-12-10) 300 | 301 | ##### Bug Fixes 302 | 303 | * nanoId threw error so switched to nanoid/non-secure (67da56c1) 304 | 305 | #### 6.0.6 (2020-12-10) 306 | 307 | ##### Documentation Changes 308 | 309 | * improve highlighting (5e4525b2) 310 | * add line (78a9786c) 311 | 312 | ##### Bug Fixes 313 | 314 | * make cssMode-detection actually work (7bb721c3) 315 | 316 | #### 6.0.5 (2020-12-05) 317 | 318 | ##### Documentation Changes 319 | 320 | * fix props-table (95d2e6a0) 321 | * add concept (a98b636c) 322 | 323 | ##### Bug Fixes 324 | 325 | * fix align-types (83b89d29) 326 | * make centering possible again when multiple rows (ee297927) 327 | 328 | #### 6.0.4 (2020-12-05) 329 | 330 | ##### Documentation Changes 331 | 332 | * add lines to readme for better legibility (70dc04ec) 333 | * fix example for gh-pages (379cc221) 334 | * fix badge (4297a4ab) 335 | 336 | ##### Bug Fixes 337 | 338 | * add custom-style to flexbox again (db842db1) 339 | 340 | ##### Other Changes 341 | 342 | * check next-link-functionality (e8bb0d52) 343 | 344 | ##### Refactors 345 | 346 | * outsource hooks from box to make it stronger typed and better readable (ce044125) 347 | 348 | #### 6.0.3 (2020-11-28) 349 | 350 | ##### Other Changes 351 | 352 | * add tags (07c2fe9e) 353 | 354 | #### 6.0.2 (2020-11-28) 355 | 356 | ##### Documentation Changes 357 | 358 | * fix gutter-default-value (233bb380) 359 | 360 | #### 6.0.1 (2020-11-28) 361 | 362 | ##### Bug Fixes 363 | 364 | * Fix centering and type specific functions (7054fb56) 365 | 366 | ## 6.0.0 (2020-11-28) 367 | 368 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019-present Andreas Faust 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![react-raster Logo](https://raw.github.com/andreasfaust/react-raster/master/assets/react-raster-logo.png?sanitize=true) 2 | 3 | **react-raster** is an advanced grid- and layout-system based on **styled-components**. It is highly customizable while being easy to use. Regardless, if your grid is simple or complex: react-raster simplifies layouting. 😽 4 | 5 | [![NPM](https://img.shields.io/npm/v/react-raster.svg)](https://www.npmjs.com/package/react-raster) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) 6 | 7 | - Custom Breakpoints and Colspan 8 | - Free nesting of Boxes while preserving the grid 9 | - Custom styles for every element at every breakpoint 10 | - Extending functionality of CSS-Grid-Layout 11 | - Lightweight and performant architecture 12 | - Visual control via ESC-key 13 | - Written in TypeScript 14 | - Ready for server-side-rendering 15 | 16 | ## ✍️ [See the Documentation!](https://andreasfaust.github.io/react-raster-docs) 17 | 18 | **⭐ Try it out and _star it_ if you like it!** 19 | 20 | --- 21 | 22 | ## PeerDependencies 23 | 24 | - react: >= 16.8.0, 25 | - react-dom: >= 16.8.0, 26 | - styled-components: >= 5.2.0 27 | 28 | --- 29 | 30 | ## Install 31 | 32 | Install all dependencies via `yarn` or `npm`. 33 | 34 | ```bash 35 | yarn add react-raster styled-components react react-dom 36 | ``` 37 | 38 | --- 39 | 40 | ## Basic Usage 41 | 42 | - `react-raster` has only one component called **Box**. 43 | - Define `brekpoints` and a `colspan` to start a new Grid and nest `Box`-Elements inside each other — they will preserve the Grid automatically. 44 | - Further style your `Box`-Elements directly via `props`. The API is close to CSS, only CamelCase. 45 | 46 | ```jsx 47 | 58 | 59 | Hello World! 60 | 61 | 62 | 70 | Stop 71 | 72 | 79 | Wars! 80 | 81 | 82 | 83 | ``` 84 | 85 | --- 86 | 87 | ## Contributing 88 | 89 | Every contribution is very much appreciated. 90 | 91 | **If you like `react-raster`, don't hesitate to star it on [GitHub](https://github.com/AndreasFaust/react-raster).** 92 | 93 | --- 94 | 95 | ## License 96 | 97 | Licensed under the MIT License, Copyright © 2019-present Andreas Faust. 98 | 99 | See [LICENSE](LICENSE.md) for more information. 100 | -------------------------------------------------------------------------------- /assets/react-raster-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AndreasFaust/react-raster/7321a3210c0c0b416c20c2a3c4421d43140b2edd/assets/react-raster-logo.png -------------------------------------------------------------------------------- /babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["next/babel"], 3 | "plugins": [["styled-components", { "ssr": true }]] 4 | } 5 | -------------------------------------------------------------------------------- /components/SpecialBox.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Link from "next/link"; 3 | import Box, { Props } from "../src"; 4 | 5 | const SpecialBox: React.FC = (props) => ( 6 | 7 | 8 | {props.children} 9 | 10 | 11 | ); 12 | 13 | SpecialBox.defaultProps = { 14 | cols: [6, 6, 3], 15 | styles: "background: green;", 16 | }; 17 | 18 | export default SpecialBox; 19 | -------------------------------------------------------------------------------- /dist/index.es.js: -------------------------------------------------------------------------------- 1 | import React, { useRef, useEffect, useContext } from 'react'; 2 | import styled, { css } from 'styled-components'; 3 | 4 | var Context = React.createContext({}); 5 | function useRaster() { 6 | return React.useContext(Context); 7 | } 8 | 9 | /*! ***************************************************************************** 10 | Copyright (c) Microsoft Corporation. 11 | 12 | Permission to use, copy, modify, and/or distribute this software for any 13 | purpose with or without fee is hereby granted. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 16 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 17 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 18 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 19 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 | PERFORMANCE OF THIS SOFTWARE. 22 | ***************************************************************************** */ 23 | 24 | var __assign = function() { 25 | __assign = Object.assign || function __assign(t) { 26 | for (var s, i = 1, n = arguments.length; i < n; i++) { 27 | s = arguments[i]; 28 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 29 | } 30 | return t; 31 | }; 32 | return __assign.apply(this, arguments); 33 | }; 34 | 35 | function __rest(s, e) { 36 | var t = {}; 37 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 38 | t[p] = s[p]; 39 | if (s != null && typeof Object.getOwnPropertySymbols === "function") 40 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 41 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 42 | t[p[i]] = s[p[i]]; 43 | } 44 | return t; 45 | } 46 | 47 | function __spreadArray(to, from, pack) { 48 | if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { 49 | if (ar || !(i in from)) { 50 | if (!ar) ar = Array.prototype.slice.call(from, 0, i); 51 | ar[i] = from[i]; 52 | } 53 | } 54 | return to.concat(ar || from); 55 | } 56 | 57 | function __makeTemplateObject(cooked, raw) { 58 | if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } 59 | return cooked; 60 | } 61 | 62 | function useCombinedRefs(ref) { 63 | var targetRef = React.useRef(); 64 | React.useEffect(function () { 65 | if (!ref) 66 | return; 67 | if (typeof ref === "function") { 68 | ref(targetRef.current); 69 | } 70 | else { 71 | ref.current = targetRef.current; 72 | } 73 | }, [ref]); 74 | return targetRef; 75 | } 76 | 77 | function debounce(func, delay) { 78 | var _this = this; 79 | if (delay === void 0) { delay = 300; } 80 | var timer; 81 | return function () { 82 | var args = []; 83 | for (var _i = 0; _i < arguments.length; _i++) { 84 | args[_i] = arguments[_i]; 85 | } 86 | clearTimeout(timer); 87 | timer = setTimeout(function () { 88 | func.apply(_this, args); 89 | }, delay); 90 | }; 91 | } 92 | 93 | function useResizeObserver(ref, onResize) { 94 | React.useEffect(function () { 95 | if (!ref.current || !onResize) 96 | return; 97 | var dOnResize = debounce(function () { 98 | if (onResize && ref.current) 99 | onResize(ref.current); 100 | }, 150); 101 | var observer = new ResizeObserver(dOnResize); 102 | observer.observe(ref.current); 103 | return function () { 104 | if (ref.current) 105 | observer.unobserve(ref.current); 106 | }; 107 | }, [ref.current]); 108 | } 109 | 110 | function useColsTotal(colspanTotal, margin, cols) { 111 | return React.useMemo(function () { 112 | var left = typeof margin.left === "number" ? margin.left : 0; 113 | var right = typeof margin.right === "number" ? margin.right : 0; 114 | if (typeof cols === "number") { 115 | return cols + left + right; 116 | } 117 | return colspanTotal; 118 | }, [cols, colspanTotal, margin.left, margin.right]); 119 | } 120 | 121 | function useColsEffective(colspan, margin, padding, cols) { 122 | return React.useMemo(function () { 123 | var paddingLeft = typeof padding.left === "number" ? padding.left : 0; 124 | var paddingRight = typeof padding.right === "number" ? padding.right : 0; 125 | var marginLeft = typeof margin.left === "number" ? margin.left : 0; 126 | var marginRight = typeof margin.right === "number" ? margin.right : 0; 127 | if (typeof cols === "number") 128 | return cols - paddingLeft - paddingRight; 129 | return colspan - paddingLeft - paddingRight - marginLeft - marginRight; 130 | }, [cols, colspan, padding.left, padding.right, margin.left, margin.right]); 131 | } 132 | 133 | function convertStringToNumber(prop) { 134 | if (typeof prop !== "string") 135 | return prop; 136 | var parsed = +prop; 137 | if (Object.is(NaN, parsed)) 138 | return prop; 139 | return parsed; 140 | } 141 | function checkForStringNotation(prop, breakpoint) { 142 | if (typeof prop !== "string") 143 | return prop; 144 | if (prop.includes(" | ")) { 145 | var propArray = prop.split(" | "); 146 | return normalizePropArray(propArray, breakpoint); 147 | } 148 | return prop; 149 | } 150 | function normalizePropArray(prop, breakpoint) { 151 | if (breakpoint < prop.length) 152 | return prop[breakpoint]; 153 | return prop[prop.length - 1]; 154 | } 155 | function getProp(prop, breakpoint) { 156 | if (!Array.isArray(prop)) { 157 | return checkForStringNotation(prop, breakpoint); 158 | } 159 | return normalizePropArray(prop, breakpoint); 160 | } 161 | function normalizeProp(breakpoint, prop, defaultValue) { 162 | if (typeof prop === "undefined" || prop === null) { 163 | return defaultValue; 164 | } 165 | return convertStringToNumber(getProp(prop, breakpoint)); 166 | } 167 | function useProp(breakpoint, prop, defaultValue) { 168 | return React.useMemo(function () { return normalizeProp(breakpoint, prop, defaultValue); }, [breakpoint, prop, defaultValue]); 169 | } 170 | 171 | function convertIfNumber(string) { 172 | var parsed = +string; 173 | if (Object.is(NaN, parsed)) 174 | return string; 175 | return parsed; 176 | } 177 | 178 | function getShortArray(spacing) { 179 | if (typeof spacing === "number") { 180 | return [spacing]; 181 | } 182 | return spacing.split(" ").map(function (string) { return convertIfNumber(string); }); 183 | } 184 | function getShortObject(spacing) { 185 | if (typeof spacing === "undefined" || spacing === "null" || spacing === "") { 186 | return { top: null, bottom: null, left: null, right: null }; 187 | } 188 | var shortArray = getShortArray(spacing); 189 | switch (shortArray.length) { 190 | case 1: 191 | return { 192 | top: shortArray[0], 193 | right: shortArray[0], 194 | bottom: shortArray[0], 195 | left: shortArray[0], 196 | }; 197 | case 2: 198 | return { 199 | top: shortArray[0], 200 | right: shortArray[1], 201 | bottom: shortArray[0], 202 | left: shortArray[1], 203 | }; 204 | case 3: 205 | return { 206 | top: shortArray[0], 207 | right: shortArray[1], 208 | bottom: shortArray[2], 209 | left: shortArray[1], 210 | }; 211 | default: 212 | return { 213 | top: shortArray[0], 214 | right: shortArray[1], 215 | bottom: shortArray[2], 216 | left: shortArray[3], 217 | }; 218 | } 219 | } 220 | function useSpacingShort(breakpoint, spacing) { 221 | var spacingNormalized = useProp(breakpoint, spacing); 222 | var spacingObject = React.useMemo(function () { return getShortObject(spacingNormalized); }, [breakpoint, spacing]); 223 | return spacingObject; 224 | } 225 | 226 | function useSpacing(breakpoint, short, left, right, top, bottom) { 227 | var shortNormalized = useSpacingShort(breakpoint, short); 228 | var leftNormalized = useProp(breakpoint, left); 229 | var rightNormalized = useProp(breakpoint, right); 230 | var topNormalized = useProp(breakpoint, top); 231 | var bottomNormalized = useProp(breakpoint, bottom); 232 | return React.useMemo(function () { return ({ 233 | left: (leftNormalized || shortNormalized.left), 234 | right: (rightNormalized || shortNormalized.right), 235 | top: (topNormalized || shortNormalized.top), 236 | bottom: (bottomNormalized || shortNormalized.bottom), 237 | }); }, [ 238 | shortNormalized, 239 | leftNormalized, 240 | rightNormalized, 241 | topNormalized, 242 | bottomNormalized, 243 | ]); 244 | } 245 | 246 | var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect; 247 | 248 | function useBreakpoint(breakpoints, contextBreakpoint, propsBreakpoints, propsColspan) { 249 | var _a = React.useState(contextBreakpoint), currentBp = _a[0], setCurrentBp = _a[1]; 250 | useIsomorphicLayoutEffect(function () { 251 | function onResize() { 252 | var w = window.innerWidth; 253 | var bp = breakpoints.findIndex(function (breakpoint) { return breakpoint > w; }) - 1; 254 | setCurrentBp(bp === -2 ? breakpoints.length - 1 : bp); 255 | } 256 | if (propsBreakpoints || propsColspan) { 257 | onResize(); 258 | var dOnResize_1 = debounce(onResize, 100); 259 | window.addEventListener("resize", dOnResize_1); 260 | return function () { return window.removeEventListener("resize", dOnResize_1); }; 261 | } 262 | }, []); 263 | React.useEffect(function () { 264 | if (propsBreakpoints || propsColspan) 265 | return; 266 | setCurrentBp(contextBreakpoint); 267 | }, [contextBreakpoint, propsBreakpoints, propsColspan]); 268 | return currentBp; 269 | } 270 | 271 | function useDisplay(breakpoint, display, hasChildBoxes) { 272 | var displayNormalized = useProp(breakpoint, display); 273 | return displayNormalized || (hasChildBoxes ? "grid" : "block"); 274 | } 275 | 276 | function getGapObject(gap) { 277 | if (!gap) 278 | return { row: null, column: null }; 279 | var _a = gap.split(" "), row = _a[0], column = _a[1]; 280 | return { row: row, column: column }; 281 | } 282 | function useGapShort(breakpoint, gap) { 283 | var gapNormalized = useProp(breakpoint, gap); 284 | var _a = React.useState(getGapObject(gapNormalized)), gapObject = _a[0], setGapObject = _a[1]; 285 | React.useEffect(function () { 286 | setGapObject(getGapObject(gapNormalized)); 287 | }, [gapNormalized]); 288 | return gapObject; 289 | } 290 | 291 | function getGap(_a) { 292 | var contextGap = _a.contextGap, gap = _a.gap, gridGap = _a.gridGap, rowGap = _a.rowGap, columnGap = _a.columnGap, gridColumnGap = _a.gridColumnGap, gridRowGap = _a.gridRowGap; 293 | if (!gap.row && 294 | !gap.column && 295 | !gridGap.row && 296 | !gridGap.column && 297 | !rowGap && 298 | !columnGap && 299 | !gridColumnGap && 300 | !gridRowGap) { 301 | return contextGap || { row: "0px", column: "0px" }; 302 | } 303 | return { 304 | row: gridRowGap || rowGap || gap.row || gridGap.row || "0px", 305 | column: columnGap || gridColumnGap || gap.column || gridGap.column || "0px", 306 | }; 307 | } 308 | 309 | var useGap = function (props) { 310 | var gap = useGapShort(props.breakpoint, props.propsGap); 311 | var gridGap = useGapShort(props.breakpoint, props.gridGap); 312 | var rowGap = useProp(props.breakpoint, props.rowGap); 313 | var columnGap = useProp(props.breakpoint, props.columnGap); 314 | var gridColumnGap = useProp(props.breakpoint, props.gridColumnGap); 315 | var gridRowGap = useProp(props.breakpoint, props.gridRowGap); 316 | return React.useMemo(function () { 317 | return getGap({ 318 | contextGap: props.contextGap, 319 | gap: gap, 320 | gridGap: gridGap, 321 | rowGap: rowGap, 322 | columnGap: columnGap, 323 | gridColumnGap: gridColumnGap, 324 | gridRowGap: gridRowGap, 325 | }); 326 | }, [ 327 | props.contextGap, 328 | gap, 329 | gridGap, 330 | rowGap, 331 | columnGap, 332 | gridColumnGap, 333 | gridRowGap, 334 | ]); 335 | }; 336 | 337 | function useBreakpoints(propsBreakpoints, contextBreakpoints) { 338 | var breakpoints = React.useState(propsBreakpoints || contextBreakpoints || [0, 432, 768, 1024, 1200, 1400])[0]; 339 | return breakpoints; 340 | } 341 | 342 | function useSpacingValue(gap, colspan, prop, counterProp) { 343 | return React.useMemo(function () { 344 | switch (typeof prop) { 345 | case "number": 346 | var counter = counterProp === "string" ? counterProp : "0px"; 347 | return "calc(((100% + " + gap + " - " + counter + ") / " + colspan + ") * " + prop + ")"; 348 | default: 349 | return prop; 350 | } 351 | }, [gap, colspan, prop, counterProp]); 352 | } 353 | function useSpacingCSS(gap, colspan, spacing) { 354 | var left = useSpacingValue(gap.column, colspan, spacing.left, spacing.right); 355 | var right = useSpacingValue(gap.column, colspan, spacing.right, spacing.left); 356 | var top = useSpacingValue(gap.row, colspan, spacing.top, spacing.bottom); 357 | var bottom = useSpacingValue(gap.row, colspan, spacing.bottom, spacing.top); 358 | return { left: left, right: right, top: top, bottom: bottom }; 359 | } 360 | 361 | function useNormalize(props, context, hasChildBoxes) { 362 | var breakpoints = useBreakpoints(props.breakpoints, context.breakpoints); 363 | var breakpoint = useBreakpoint(breakpoints, context.breakpoint, props.breakpoints, props.colspan); 364 | var display = useDisplay(breakpoint, props.display, hasChildBoxes); 365 | var gap = useGap({ 366 | contextGap: context.gap, 367 | propsGap: props.gap, 368 | gridGap: props.gridGap, 369 | rowGap: props.rowGap, 370 | columnGap: props.columnGap, 371 | gridColumnGap: props.gridColumnGap, 372 | gridRowGap: props.gridRowGap, 373 | breakpoint: breakpoint, 374 | }); 375 | var marginRaw = useSpacing(breakpoint, props.margin, props.marginLeft, props.marginRight, props.marginTop, props.marginBottom); 376 | var paddingRaw = useSpacing(breakpoint, props.padding, props.paddingLeft, props.paddingRight, props.paddingTop, props.paddingBottom); 377 | var colspanTotal = useProp(breakpoint, props.colspan || context.colspan || 1); 378 | var cols = useProp(breakpoint, props.cols); 379 | // gets applied to StyledBox 380 | var colsEffective = useColsEffective(colspanTotal, marginRaw, paddingRaw, cols); 381 | var colsTotal = useColsTotal(colspanTotal, marginRaw, cols); 382 | var margin = useSpacingCSS(gap, colsTotal, marginRaw); 383 | var padding = useSpacingCSS(gap, colsTotal, paddingRaw); 384 | var styles = useProp(breakpoint, props.styles); 385 | var width = useProp(breakpoint, props.width); 386 | var minWidth = useProp(breakpoint, props.minWidth); 387 | var maxWidth = useProp(breakpoint, props.maxWidth); 388 | var height = useProp(breakpoint, props.height); 389 | var minHeight = useProp(breakpoint, props.minHeight); 390 | var maxHeight = useProp(breakpoint, props.maxHeight); 391 | var position = useProp(breakpoint, props.position, "relative"); 392 | var zIndex = useProp(breakpoint, props.zIndex); 393 | var left = useProp(breakpoint, props.left); 394 | var right = useProp(breakpoint, props.right); 395 | var top = useProp(breakpoint, props.top); 396 | var bottom = useProp(breakpoint, props.bottom); 397 | var pointerEvents = useProp(breakpoint, props.pointerEvents); 398 | var cursor = useProp(breakpoint, props.cursor); 399 | var gridTemplateRows = useProp(breakpoint, props.gridTemplateRows); 400 | var gridColumn = useProp(breakpoint, props.gridColumn); 401 | var gridRow = useProp(breakpoint, props.gridRow); 402 | var gridAutoRows = useProp(breakpoint, props.gridAutoRows); 403 | var gridTemplateColumns = useProp(breakpoint, props.gridTemplateColumns); 404 | var autoFlow = useProp(breakpoint, props.autoFlow); 405 | var order = useProp(breakpoint, props.order); 406 | var alignItems = useProp(breakpoint, props.alignItems); 407 | var alignContent = useProp(breakpoint, props.alignContent); 408 | var alignSelf = useProp(breakpoint, props.alignSelf); 409 | var justifyContent = useProp(breakpoint, props.justifyContent); 410 | var justifyItems = useProp(breakpoint, props.justifyItems); 411 | var justifySelf = useProp(breakpoint, props.justifySelf); 412 | var flexDirection = useProp(breakpoint, props.flexDirection); 413 | var flexWrap = useProp(breakpoint, props.flexWrap); 414 | var flexShrink = useProp(breakpoint, props.flexShrink); 415 | var flexGrow = useProp(breakpoint, props.flexGrow); 416 | var border = useProp(breakpoint, props.border); 417 | var borderLeft = useProp(breakpoint, props.borderLeft); 418 | var borderRight = useProp(breakpoint, props.borderRight); 419 | var borderTop = useProp(breakpoint, props.borderTop); 420 | var borderBottom = useProp(breakpoint, props.borderBottom); 421 | var background = useProp(breakpoint, props.background); 422 | var backgroundColor = useProp(breakpoint, props.backgroundColor); 423 | var backgroundImage = useProp(breakpoint, props.backgroundImage); 424 | var backgroundPosition = useProp(breakpoint, props.backgroundPosition); 425 | var backgroundAttachment = useProp(breakpoint, props.backgroundAttachment); 426 | var backgroundSize = useProp(breakpoint, props.backgroundSize); 427 | var filter = useProp(breakpoint, props.filter); 428 | var backdropFilter = useProp(breakpoint, props.backdropFilter); 429 | var mixBlendMode = useProp(breakpoint, props.mixBlendMode); 430 | var backgroundBlendMode = useProp(breakpoint, props.backgroundBlendMode); 431 | var textShadow = useProp(breakpoint, props.textShadow); 432 | var boxShadow = useProp(breakpoint, props.boxShadow); 433 | var textStroke = useProp(breakpoint, props.textStroke); 434 | var fontFamily = useProp(breakpoint, props.fontFamily); 435 | var fontSize = useProp(breakpoint, props.fontSize); 436 | var fontWeight = useProp(breakpoint, props.fontWeight); 437 | var fontStyle = useProp(breakpoint, props.fontStyle); 438 | var textAlign = useProp(breakpoint, props.textAlign); 439 | var color = useProp(breakpoint, props.color); 440 | var lineHeight = useProp(breakpoint, props.lineHeight); 441 | var letterSpacing = useProp(breakpoint, props.letterSpacing); 442 | var textDecoration = useProp(breakpoint, props.textDecoration); 443 | var hyphens = useProp(breakpoint, props.hyphens); 444 | var transform = useProp(breakpoint, props.transform); 445 | var transition = useProp(breakpoint, props.transition); 446 | var animation = useProp(breakpoint, props.animation); 447 | var opacity = useProp(breakpoint, props.opacity); 448 | var willChange = useProp(breakpoint, props.willChange); 449 | var overflow = useProp(breakpoint, props.overflow); 450 | var overflowX = useProp(breakpoint, props.overflowX); 451 | var overflowY = useProp(breakpoint, props.overflowY); 452 | var rootMargin = useProp(breakpoint, props.rootMargin); 453 | return { 454 | breakpoints: breakpoints, 455 | breakpoint: breakpoint, 456 | colsTotal: colsTotal, 457 | colspanTotal: colspanTotal, 458 | colsEffective: colsEffective, 459 | margin: margin, 460 | padding: padding, 461 | marginRaw: marginRaw, 462 | paddingRaw: paddingRaw, 463 | display: display, 464 | gap: gap, 465 | controlColor: props.controlColor || context.controlColor, 466 | styles: styles, 467 | width: width, 468 | minWidth: minWidth, 469 | maxWidth: maxWidth, 470 | height: height, 471 | minHeight: minHeight, 472 | maxHeight: maxHeight, 473 | position: position, 474 | zIndex: zIndex, 475 | left: left, 476 | right: right, 477 | top: top, 478 | bottom: bottom, 479 | pointerEvents: pointerEvents, 480 | cursor: cursor, 481 | gridTemplateRows: gridTemplateRows, 482 | gridColumn: gridColumn, 483 | gridRow: gridRow, 484 | gridAutoRows: gridAutoRows, 485 | gridTemplateColumns: gridTemplateColumns, 486 | autoFlow: autoFlow, 487 | order: order, 488 | alignItems: alignItems, 489 | alignContent: alignContent, 490 | alignSelf: alignSelf, 491 | justifyContent: justifyContent, 492 | justifyItems: justifyItems, 493 | justifySelf: justifySelf, 494 | flexDirection: flexDirection, 495 | flexWrap: flexWrap, 496 | flexShrink: flexShrink, 497 | flexGrow: flexGrow, 498 | border: border, 499 | borderLeft: borderLeft, 500 | borderRight: borderRight, 501 | borderTop: borderTop, 502 | borderBottom: borderBottom, 503 | background: background, 504 | backgroundColor: backgroundColor, 505 | backgroundImage: backgroundImage, 506 | backgroundPosition: backgroundPosition, 507 | backgroundAttachment: backgroundAttachment, 508 | backgroundSize: backgroundSize, 509 | filter: filter, 510 | backdropFilter: backdropFilter, 511 | mixBlendMode: mixBlendMode, 512 | backgroundBlendMode: backgroundBlendMode, 513 | textShadow: textShadow, 514 | boxShadow: boxShadow, 515 | textStroke: textStroke, 516 | fontFamily: fontFamily, 517 | fontSize: fontSize, 518 | fontWeight: fontWeight, 519 | fontStyle: fontStyle, 520 | textAlign: textAlign, 521 | color: color, 522 | lineHeight: lineHeight, 523 | letterSpacing: letterSpacing, 524 | textDecoration: textDecoration, 525 | hyphens: hyphens, 526 | transform: transform, 527 | transition: transition, 528 | animation: animation, 529 | opacity: opacity, 530 | willChange: willChange, 531 | overflow: overflow, 532 | overflowX: overflowX, 533 | overflowY: overflowY, 534 | rootMargin: rootMargin, 535 | }; 536 | } 537 | 538 | var useControl = function (control, controlIsVisible) { 539 | var _a = React.useState(false), isVisible = _a[0], setIsVisible = _a[1]; 540 | React.useEffect(function () { 541 | setIsVisible(!!controlIsVisible); 542 | }, [controlIsVisible]); 543 | React.useEffect(function () { 544 | function onKeyup(event) { 545 | if (event.keyCode !== 27) 546 | return; 547 | setIsVisible(function (prevState) { return !prevState; }); 548 | } 549 | if (control) { 550 | document.addEventListener("keyup", onKeyup); 551 | return function () { return document.removeEventListener("keyup", onKeyup); }; 552 | } 553 | }, []); 554 | return isVisible; 555 | }; 556 | 557 | function useUndefinedProps(props) { 558 | props.display; props.breakpoints; props.width; props.minWidth; props.maxWidth; props.height; props.minHeight; props.maxHeight; props.colspan; props.cols; props.margin; props.marginLeft; props.marginRight; props.marginTop; props.marginBottom; props.padding; props.paddingLeft; props.paddingRight; props.paddingTop; props.paddingBottom; props.gap; props.gridRowGap; props.rowGap; props.gridColumnGap; props.columnGap; props.gridTemplateRows; props.gridAutoRows; props.gridTemplateColumns; props.gridRow; props.gridColumn; props.autoFlow; props.component; props.innerHTML; props.cursor; props.pointerEvents; props.onResize; props.onIntersect; props.root; props.rootMargin; props.threshold; props.styles; props.as; props.control; props.controlColor; props.order; props.position; props.zIndex; props.top; props.bottom; props.left; props.right; props.alignItems; props.alignContent; props.alignSelf; props.justifyContent; props.justifyItems; props.justifySelf; props.flexDirection; props.flexWrap; props.flexShrink; props.flexGrow; props.background; props.backgroundColor; props.backgroundImage; props.backgroundPosition; props.backgroundSize; props.backgroundAttachment; props.filter; props.backdropFilter; props.mixBlendMode; props.backgroundBlendMode; props.textShadow; props.boxShadow; props.textStroke; props.border; props.borderLeft; props.borderRight; props.borderTop; props.borderBottom; props.fontFamily; props.fontSize; props.fontWeight; props.fontStyle; props.textAlign; props.color; props.lineHeight; props.letterSpacing; props.textDecoration; props.hyphens; props.overflow; props.overflowX; props.overflowY; props.transition; props.animation; props.opacity; props.transform; props.willChange; props.className; props.children; props.isControl; props.ref; var rest = __rest(props, ["display", "breakpoints", "width", "minWidth", "maxWidth", "height", "minHeight", "maxHeight", "colspan", "cols", "margin", "marginLeft", "marginRight", "marginTop", "marginBottom", "padding", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", "gap", "gridRowGap", "rowGap", "gridColumnGap", "columnGap", "gridTemplateRows", "gridAutoRows", "gridTemplateColumns", "gridRow", "gridColumn", "autoFlow", "component", "innerHTML", "cursor", "pointerEvents", "onResize", "onIntersect", "root", "rootMargin", "threshold", "styles", "as", "control", "controlColor", "order", "position", "zIndex", "top", "bottom", "left", "right", "alignItems", "alignContent", "alignSelf", "justifyContent", "justifyItems", "justifySelf", "flexDirection", "flexWrap", "flexShrink", "flexGrow", "background", "backgroundColor", "backgroundImage", "backgroundPosition", "backgroundSize", "backgroundAttachment", "filter", "backdropFilter", "mixBlendMode", "backgroundBlendMode", "textShadow", "boxShadow", "textStroke", "border", "borderLeft", "borderRight", "borderTop", "borderBottom", "fontFamily", "fontSize", "fontWeight", "fontStyle", "textAlign", "color", "lineHeight", "letterSpacing", "textDecoration", "hyphens", "overflow", "overflowX", "overflowY", "transition", "animation", "opacity", "transform", "willChange", "className", "children", "isControl", "ref"]); 559 | return rest; 560 | } 561 | 562 | function onIntersect(_a) { 563 | var ref = _a.ref, _b = _a.root, root = _b === void 0 ? null : _b, rootMargin = _a.rootMargin, _c = _a.threshold, threshold = _c === void 0 ? 0 : _c, onIntersect = _a.onIntersect; 564 | var observer = useRef(null); 565 | useEffect(function () { 566 | if (typeof onIntersect !== "function") 567 | return; 568 | observer.current = new IntersectionObserver(function (_a, observer) { 569 | var entry = _a[0]; 570 | return onIntersect(entry, observer); 571 | }, { 572 | root: root, 573 | rootMargin: rootMargin, 574 | threshold: threshold, 575 | }); 576 | if (ref.current && observer.current) 577 | observer.current.observe(ref.current); 578 | return function () { return observer.current && observer.current.disconnect(); }; 579 | }, []); 580 | } 581 | 582 | var Container = React.forwardRef(function (_a, ref) { 583 | var className = _a.className, children = _a.children, component = _a.component, _b = _a.attrs, attrs = _b === void 0 ? {} : _b, _c = _a.tag, tag = _c === void 0 ? "div" : _c; 584 | if (component) { 585 | return React.cloneElement(component, __assign({ children: children, className: className }, attrs)); 586 | } 587 | return React.createElement(tag, __assign(__assign({}, attrs), { className: className, ref: ref }), tag !== "img" && !attrs.dangerouslySetInnerHTML ? children : null); 588 | }); 589 | Container.displayName = "Container"; 590 | 591 | var StyledBoxStyles = styled(Container)(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n box-sizing: border-box;\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n"], ["\n box-sizing: border-box;\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n"])), function (props) { return css(templateObject_1$1 || (templateObject_1$1 = __makeTemplateObject(["\n position: ", ";\n z-index: ", ";\n display: ", ";\n pointer-events: ", ";\n cursor: ", ";\n\n width: ", ";\n min-width: ", ";\n max-width: ", ";\n height: ", ";\n min-height: ", ";\n max-height: ", ";\n\n padding-left: ", ";\n padding-right: ", ";\n padding-top: ", ";\n padding-bottom: ", ";\n\n margin-left: ", ";\n margin-right: ", ";\n margin-top: ", ";\n margin-bottom: ", ";\n\n order: ", ";\n\n top: ", ";\n bottom: ", ";\n left: ", ";\n right: ", ";\n\n align-items: ", ";\n align-content: ", ";\n align-self: ", ";\n justify-content: ", ";\n justify-items: ", ";\n justify-self: ", ";\n\n flex-direction: ", ";\n flex-wrap: ", ";\n flex-shrink: ", ";\n flex-grow: ", ";\n\n background: ", ";\n background-color: ", ";\n background-image: ", ";\n background-position: ", ";\n background-size: ", ";\n background-attachment: ", ";\n\n filter: ", ";\n backdrop-filter: ", ";\n mix-blend-mode: ", ";\n background-blend-mode: ", ";\n text-shadow: ", ";\n box-shadow: ", ";\n -webkit-text-stroke: ", ";\n text-stroke: ", ";\n\n border: ", ";\n border-left: ", ";\n border-right: ", ";\n border-top: ", ";\n border-bottom: ", ";\n\n font-family: ", ";\n font-size: ", ";\n font-weight: ", ";\n font-style: ", ";\n text-align: ", ";\n color: ", ";\n line-height: ", ";\n letter-spacing: ", ";\n text-decoration: ", ";\n hyphens: ", ";\n\n transition: ", ";\n transform: ", ";\n animation: ", ";\n opacity: ", ";\n will-change: ", ";\n\n overflow: ", ";\n overflow-x: ", ";\n overflow-y: ", ";\n\n ", "\n "], ["\n position: ", ";\n z-index: ", ";\n display: ", ";\n pointer-events: ", ";\n cursor: ", ";\n\n width: ", ";\n min-width: ", ";\n max-width: ", ";\n height: ", ";\n min-height: ", ";\n max-height: ", ";\n\n padding-left: ", ";\n padding-right: ", ";\n padding-top: ", ";\n padding-bottom: ", ";\n\n margin-left: ", ";\n margin-right: ", ";\n margin-top: ", ";\n margin-bottom: ", ";\n\n order: ", ";\n\n top: ", ";\n bottom: ", ";\n left: ", ";\n right: ", ";\n\n align-items: ", ";\n align-content: ", ";\n align-self: ", ";\n justify-content: ", ";\n justify-items: ", ";\n justify-self: ", ";\n\n flex-direction: ", ";\n flex-wrap: ", ";\n flex-shrink: ", ";\n flex-grow: ", ";\n\n background: ", ";\n background-color: ", ";\n background-image: ", ";\n background-position: ", ";\n background-size: ", ";\n background-attachment: ", ";\n\n filter: ", ";\n backdrop-filter: ", ";\n mix-blend-mode: ", ";\n background-blend-mode: ", ";\n text-shadow: ", ";\n box-shadow: ", ";\n -webkit-text-stroke: ", ";\n text-stroke: ", ";\n\n border: ", ";\n border-left: ", ";\n border-right: ", ";\n border-top: ", ";\n border-bottom: ", ";\n\n font-family: ", ";\n font-size: ", ";\n font-weight: ", ";\n font-style: ", ";\n text-align: ", ";\n color: ", ";\n line-height: ", ";\n letter-spacing: ", ";\n text-decoration: ", ";\n hyphens: ", ";\n\n transition: ", ";\n transform: ", ";\n animation: ", ";\n opacity: ", ";\n will-change: ", ";\n\n overflow: ", ";\n overflow-x: ", ";\n overflow-y: ", ";\n\n ", "\n "])), props.position, props.zIndex, props.display, props.pointerEvents, props.cursor, props.width, props.minWidth, props.maxWidth, props.height, props.minHeight, props.maxHeight, props.padding.left, props.padding.right, props.padding.top, props.padding.bottom, props.margin.left, props.margin.right, props.margin.top, props.margin.bottom, props.order, props.top, props.bottom, props.left, props.right, props.alignItems, props.alignContent, props.alignSelf, props.justifyContent, props.justifyItems, props.justifySelf, props.flexDirection, props.flexWrap, props.flexShrink, props.flexGrow, props.background, props.backgroundColor, props.backgroundImage, props.backgroundPosition, props.backgroundSize, props.backgroundAttachment, props.filter, props.backdropFilter, props.mixBlendMode, props.backgroundBlendMode, props.textShadow, props.boxShadow, props.textStroke, props.textStroke, props.border, props.borderLeft, props.borderRight, props.borderTop, props.borderBottom, props.fontFamily, props.fontSize, props.fontWeight, props.fontStyle, props.textAlign, props.color, props.lineHeight, props.letterSpacing, props.textDecoration, props.hyphens, props.transition, props.transform, props.animation, props.opacity, props.willChange, props.overflow, props.overflowX, props.overflowY, props.styles ? props.styles : ""); }, function (props) { 592 | return props.display === "grid" && css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n grid-template-columns: repeat(", ", 1fr);\n\n grid-auto-rows: ", ";\n grid-template-rows: ", ";\n grid-template-columns: ", ";\n grid-auto-flow: ", ";\n\n grid-gap: ", " ", ";\n\n ", "\n "], ["\n grid-template-columns: repeat(", ", 1fr);\n\n grid-auto-rows: ", ";\n grid-template-rows: ", ";\n grid-template-columns: ", ";\n grid-auto-flow: ", ";\n\n grid-gap: ", " ", ";\n\n ", "\n "])), props.colsEffective, props.gridAutoRows, props.gridTemplateRows, props.gridTemplateColumns, props.autoFlow, props.gap.row, props.gap.column, props.isControl && 593 | (props.gap.column === "0px" ? "grid-column-gap: 1px;" : "")); 594 | }, function (props) { 595 | return props.display === "flex" && css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n gap: ", " ", ";\n "], ["\n gap: ", " ", ";\n "])), props.gap.row, props.gap.column); 596 | }, function (props) { return css(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n grid-column: auto / span ", ";\n grid-column: ", ";\n grid-row: ", ";\n "], ["\n grid-column: auto / span ", ";\n grid-column: ", ";\n grid-row: ", ";\n "])), props.colsTotal, props.gridColumn, props.gridRow); }, function (props) { 597 | return props.tag === "img" && 598 | props.controlIsVisible && css(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n box-shadow: 0 0 999em ", " inset;\n "], ["\n box-shadow: 0 0 999em ", " inset;\n "])), props.controlColor); 599 | }); 600 | var StyledBox = React.forwardRef(function (props, ref) { 601 | return React.createElement(StyledBoxStyles, __assign({}, props, { ref: ref })); 602 | }); 603 | StyledBox.displayName = "StyledBox"; 604 | var StyledBox$1 = React.memo(StyledBox); 605 | var templateObject_1$1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6; 606 | 607 | function getSideBearing(padding) { 608 | return typeof padding === "number" ? 0 : padding; 609 | } 610 | var ControlGrid = function (props) { 611 | var colspanTotal = props.colspanTotal; 612 | return (React.createElement(Box$1, { position: "absolute", className: "GridControl", zIndex: 1000, colspan: colspanTotal, gridColumnGap: props.gap.column, gridAutoRows: "100%", top: 0, bottom: 0, left: 0, right: 0, marginLeft: getSideBearing(props.paddingRaw.left), marginRight: getSideBearing(props.paddingRaw.right), marginTop: getSideBearing(props.paddingRaw.top), marginBottom: getSideBearing(props.paddingRaw.bottom), pointerEvents: "none", isControl: true }, __spreadArray([], Array(colspanTotal)).map(function (_, index) { return (React.createElement(Box$1, { key: index, display: "flex", alignSelf: "stretch", cols: 1, backgroundColor: props.controlColor || "rgba(0,0,0,0.12)" })); }))); 613 | }; 614 | var ControlBox = styled("span")(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n position: absolute;\n z-index: 10000;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n background-color: ", ";\n pointer-events: none;\n"], ["\n position: absolute;\n z-index: 10000;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n background-color: ", ";\n pointer-events: none;\n"])), function (props) { return props.controlColor || "rgba(0,0,0,0.12)"; }); 615 | var Control = function (props) { 616 | return props.isNewGrid ? (React.createElement(ControlGrid, __assign({}, props))) : (React.createElement(ControlBox, { controlColor: props.controlColor })); 617 | }; 618 | var templateObject_1; 619 | 620 | var Box = React.forwardRef(function (props, ref) { 621 | var context = useContext(Context); 622 | var _a = React.useState(false), hasChildBoxes = _a[0], registerChildBox = _a[1]; 623 | React.useEffect(function () { 624 | if (typeof context.registerChildBox === "function") { 625 | context.registerChildBox(); 626 | } 627 | }, []); 628 | var propsNormalized = useNormalize(props, context, hasChildBoxes); 629 | var controlIsVisible = useControl(props.control, context.controlIsVisible); 630 | var boxRef = useCombinedRefs(ref); 631 | var undefinedProps = useUndefinedProps(props); 632 | var breakpoint = { 633 | index: propsNormalized.breakpoint + 1, 634 | value: propsNormalized.breakpoints[propsNormalized.breakpoint], 635 | }; 636 | var defaultClass = "Box bp-" + breakpoint.value + " bp-" + breakpoint.index; 637 | useResizeObserver(boxRef, props.onResize); 638 | onIntersect({ 639 | ref: boxRef, 640 | root: props.root, 641 | rootMargin: propsNormalized.rootMargin, 642 | threshold: props.threshold, 643 | onIntersect: props.onIntersect, 644 | }); 645 | return (React.createElement(StyledBox$1, __assign({}, propsNormalized, { tag: props.as, component: props.component, className: props.className 646 | ? [defaultClass, props.className].join(" ") 647 | : defaultClass, controlIsVisible: controlIsVisible, ref: boxRef, styles: propsNormalized.styles, isControl: props.isControl, attrs: __assign(__assign({}, undefinedProps), (props.innerHTML && { 648 | dangerouslySetInnerHTML: { __html: props.innerHTML }, 649 | })) }), 650 | controlIsVisible && (React.createElement(Control, __assign({ isNewGrid: !!props.colspan }, propsNormalized))), 651 | React.createElement(Context.Provider, { value: { 652 | breakpoints: propsNormalized.breakpoints, 653 | breakpoint: propsNormalized.breakpoint, 654 | currentBreakpoint: breakpoint, 655 | gap: propsNormalized.gap, 656 | colspan: propsNormalized.colsEffective, 657 | controlIsVisible: controlIsVisible, 658 | controlColor: propsNormalized.controlColor, 659 | registerChildBox: function () { return registerChildBox(true); }, 660 | } }, props.children))); 661 | }); 662 | Box.displayName = "Box"; 663 | var Box$1 = React.memo(Box); 664 | 665 | export default Box$1; 666 | export { useRaster }; 667 | //# sourceMappingURL=index.es.js.map 668 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { value: true }); 4 | 5 | var React = require('react'); 6 | var styled = require('styled-components'); 7 | 8 | function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } 9 | 10 | var React__default = /*#__PURE__*/_interopDefaultLegacy(React); 11 | var styled__default = /*#__PURE__*/_interopDefaultLegacy(styled); 12 | 13 | var Context = React__default['default'].createContext({}); 14 | function useRaster() { 15 | return React__default['default'].useContext(Context); 16 | } 17 | 18 | /*! ***************************************************************************** 19 | Copyright (c) Microsoft Corporation. 20 | 21 | Permission to use, copy, modify, and/or distribute this software for any 22 | purpose with or without fee is hereby granted. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 25 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 26 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 27 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 28 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 29 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 30 | PERFORMANCE OF THIS SOFTWARE. 31 | ***************************************************************************** */ 32 | 33 | var __assign = function() { 34 | __assign = Object.assign || function __assign(t) { 35 | for (var s, i = 1, n = arguments.length; i < n; i++) { 36 | s = arguments[i]; 37 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 38 | } 39 | return t; 40 | }; 41 | return __assign.apply(this, arguments); 42 | }; 43 | 44 | function __rest(s, e) { 45 | var t = {}; 46 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 47 | t[p] = s[p]; 48 | if (s != null && typeof Object.getOwnPropertySymbols === "function") 49 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 50 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 51 | t[p[i]] = s[p[i]]; 52 | } 53 | return t; 54 | } 55 | 56 | function __spreadArray(to, from, pack) { 57 | if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { 58 | if (ar || !(i in from)) { 59 | if (!ar) ar = Array.prototype.slice.call(from, 0, i); 60 | ar[i] = from[i]; 61 | } 62 | } 63 | return to.concat(ar || from); 64 | } 65 | 66 | function __makeTemplateObject(cooked, raw) { 67 | if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } 68 | return cooked; 69 | } 70 | 71 | function useCombinedRefs(ref) { 72 | var targetRef = React__default['default'].useRef(); 73 | React__default['default'].useEffect(function () { 74 | if (!ref) 75 | return; 76 | if (typeof ref === "function") { 77 | ref(targetRef.current); 78 | } 79 | else { 80 | ref.current = targetRef.current; 81 | } 82 | }, [ref]); 83 | return targetRef; 84 | } 85 | 86 | function debounce(func, delay) { 87 | var _this = this; 88 | if (delay === void 0) { delay = 300; } 89 | var timer; 90 | return function () { 91 | var args = []; 92 | for (var _i = 0; _i < arguments.length; _i++) { 93 | args[_i] = arguments[_i]; 94 | } 95 | clearTimeout(timer); 96 | timer = setTimeout(function () { 97 | func.apply(_this, args); 98 | }, delay); 99 | }; 100 | } 101 | 102 | function useResizeObserver(ref, onResize) { 103 | React__default['default'].useEffect(function () { 104 | if (!ref.current || !onResize) 105 | return; 106 | var dOnResize = debounce(function () { 107 | if (onResize && ref.current) 108 | onResize(ref.current); 109 | }, 150); 110 | var observer = new ResizeObserver(dOnResize); 111 | observer.observe(ref.current); 112 | return function () { 113 | if (ref.current) 114 | observer.unobserve(ref.current); 115 | }; 116 | }, [ref.current]); 117 | } 118 | 119 | function useColsTotal(colspanTotal, margin, cols) { 120 | return React__default['default'].useMemo(function () { 121 | var left = typeof margin.left === "number" ? margin.left : 0; 122 | var right = typeof margin.right === "number" ? margin.right : 0; 123 | if (typeof cols === "number") { 124 | return cols + left + right; 125 | } 126 | return colspanTotal; 127 | }, [cols, colspanTotal, margin.left, margin.right]); 128 | } 129 | 130 | function useColsEffective(colspan, margin, padding, cols) { 131 | return React__default['default'].useMemo(function () { 132 | var paddingLeft = typeof padding.left === "number" ? padding.left : 0; 133 | var paddingRight = typeof padding.right === "number" ? padding.right : 0; 134 | var marginLeft = typeof margin.left === "number" ? margin.left : 0; 135 | var marginRight = typeof margin.right === "number" ? margin.right : 0; 136 | if (typeof cols === "number") 137 | return cols - paddingLeft - paddingRight; 138 | return colspan - paddingLeft - paddingRight - marginLeft - marginRight; 139 | }, [cols, colspan, padding.left, padding.right, margin.left, margin.right]); 140 | } 141 | 142 | function convertStringToNumber(prop) { 143 | if (typeof prop !== "string") 144 | return prop; 145 | var parsed = +prop; 146 | if (Object.is(NaN, parsed)) 147 | return prop; 148 | return parsed; 149 | } 150 | function checkForStringNotation(prop, breakpoint) { 151 | if (typeof prop !== "string") 152 | return prop; 153 | if (prop.includes(" | ")) { 154 | var propArray = prop.split(" | "); 155 | return normalizePropArray(propArray, breakpoint); 156 | } 157 | return prop; 158 | } 159 | function normalizePropArray(prop, breakpoint) { 160 | if (breakpoint < prop.length) 161 | return prop[breakpoint]; 162 | return prop[prop.length - 1]; 163 | } 164 | function getProp(prop, breakpoint) { 165 | if (!Array.isArray(prop)) { 166 | return checkForStringNotation(prop, breakpoint); 167 | } 168 | return normalizePropArray(prop, breakpoint); 169 | } 170 | function normalizeProp(breakpoint, prop, defaultValue) { 171 | if (typeof prop === "undefined" || prop === null) { 172 | return defaultValue; 173 | } 174 | return convertStringToNumber(getProp(prop, breakpoint)); 175 | } 176 | function useProp(breakpoint, prop, defaultValue) { 177 | return React__default['default'].useMemo(function () { return normalizeProp(breakpoint, prop, defaultValue); }, [breakpoint, prop, defaultValue]); 178 | } 179 | 180 | function convertIfNumber(string) { 181 | var parsed = +string; 182 | if (Object.is(NaN, parsed)) 183 | return string; 184 | return parsed; 185 | } 186 | 187 | function getShortArray(spacing) { 188 | if (typeof spacing === "number") { 189 | return [spacing]; 190 | } 191 | return spacing.split(" ").map(function (string) { return convertIfNumber(string); }); 192 | } 193 | function getShortObject(spacing) { 194 | if (typeof spacing === "undefined" || spacing === "null" || spacing === "") { 195 | return { top: null, bottom: null, left: null, right: null }; 196 | } 197 | var shortArray = getShortArray(spacing); 198 | switch (shortArray.length) { 199 | case 1: 200 | return { 201 | top: shortArray[0], 202 | right: shortArray[0], 203 | bottom: shortArray[0], 204 | left: shortArray[0], 205 | }; 206 | case 2: 207 | return { 208 | top: shortArray[0], 209 | right: shortArray[1], 210 | bottom: shortArray[0], 211 | left: shortArray[1], 212 | }; 213 | case 3: 214 | return { 215 | top: shortArray[0], 216 | right: shortArray[1], 217 | bottom: shortArray[2], 218 | left: shortArray[1], 219 | }; 220 | default: 221 | return { 222 | top: shortArray[0], 223 | right: shortArray[1], 224 | bottom: shortArray[2], 225 | left: shortArray[3], 226 | }; 227 | } 228 | } 229 | function useSpacingShort(breakpoint, spacing) { 230 | var spacingNormalized = useProp(breakpoint, spacing); 231 | var spacingObject = React__default['default'].useMemo(function () { return getShortObject(spacingNormalized); }, [breakpoint, spacing]); 232 | return spacingObject; 233 | } 234 | 235 | function useSpacing(breakpoint, short, left, right, top, bottom) { 236 | var shortNormalized = useSpacingShort(breakpoint, short); 237 | var leftNormalized = useProp(breakpoint, left); 238 | var rightNormalized = useProp(breakpoint, right); 239 | var topNormalized = useProp(breakpoint, top); 240 | var bottomNormalized = useProp(breakpoint, bottom); 241 | return React__default['default'].useMemo(function () { return ({ 242 | left: (leftNormalized || shortNormalized.left), 243 | right: (rightNormalized || shortNormalized.right), 244 | top: (topNormalized || shortNormalized.top), 245 | bottom: (bottomNormalized || shortNormalized.bottom), 246 | }); }, [ 247 | shortNormalized, 248 | leftNormalized, 249 | rightNormalized, 250 | topNormalized, 251 | bottomNormalized, 252 | ]); 253 | } 254 | 255 | var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React__default['default'].useLayoutEffect : React__default['default'].useEffect; 256 | 257 | function useBreakpoint(breakpoints, contextBreakpoint, propsBreakpoints, propsColspan) { 258 | var _a = React__default['default'].useState(contextBreakpoint), currentBp = _a[0], setCurrentBp = _a[1]; 259 | useIsomorphicLayoutEffect(function () { 260 | function onResize() { 261 | var w = window.innerWidth; 262 | var bp = breakpoints.findIndex(function (breakpoint) { return breakpoint > w; }) - 1; 263 | setCurrentBp(bp === -2 ? breakpoints.length - 1 : bp); 264 | } 265 | if (propsBreakpoints || propsColspan) { 266 | onResize(); 267 | var dOnResize_1 = debounce(onResize, 100); 268 | window.addEventListener("resize", dOnResize_1); 269 | return function () { return window.removeEventListener("resize", dOnResize_1); }; 270 | } 271 | }, []); 272 | React__default['default'].useEffect(function () { 273 | if (propsBreakpoints || propsColspan) 274 | return; 275 | setCurrentBp(contextBreakpoint); 276 | }, [contextBreakpoint, propsBreakpoints, propsColspan]); 277 | return currentBp; 278 | } 279 | 280 | function useDisplay(breakpoint, display, hasChildBoxes) { 281 | var displayNormalized = useProp(breakpoint, display); 282 | return displayNormalized || (hasChildBoxes ? "grid" : "block"); 283 | } 284 | 285 | function getGapObject(gap) { 286 | if (!gap) 287 | return { row: null, column: null }; 288 | var _a = gap.split(" "), row = _a[0], column = _a[1]; 289 | return { row: row, column: column }; 290 | } 291 | function useGapShort(breakpoint, gap) { 292 | var gapNormalized = useProp(breakpoint, gap); 293 | var _a = React__default['default'].useState(getGapObject(gapNormalized)), gapObject = _a[0], setGapObject = _a[1]; 294 | React__default['default'].useEffect(function () { 295 | setGapObject(getGapObject(gapNormalized)); 296 | }, [gapNormalized]); 297 | return gapObject; 298 | } 299 | 300 | function getGap(_a) { 301 | var contextGap = _a.contextGap, gap = _a.gap, gridGap = _a.gridGap, rowGap = _a.rowGap, columnGap = _a.columnGap, gridColumnGap = _a.gridColumnGap, gridRowGap = _a.gridRowGap; 302 | if (!gap.row && 303 | !gap.column && 304 | !gridGap.row && 305 | !gridGap.column && 306 | !rowGap && 307 | !columnGap && 308 | !gridColumnGap && 309 | !gridRowGap) { 310 | return contextGap || { row: "0px", column: "0px" }; 311 | } 312 | return { 313 | row: gridRowGap || rowGap || gap.row || gridGap.row || "0px", 314 | column: columnGap || gridColumnGap || gap.column || gridGap.column || "0px", 315 | }; 316 | } 317 | 318 | var useGap = function (props) { 319 | var gap = useGapShort(props.breakpoint, props.propsGap); 320 | var gridGap = useGapShort(props.breakpoint, props.gridGap); 321 | var rowGap = useProp(props.breakpoint, props.rowGap); 322 | var columnGap = useProp(props.breakpoint, props.columnGap); 323 | var gridColumnGap = useProp(props.breakpoint, props.gridColumnGap); 324 | var gridRowGap = useProp(props.breakpoint, props.gridRowGap); 325 | return React__default['default'].useMemo(function () { 326 | return getGap({ 327 | contextGap: props.contextGap, 328 | gap: gap, 329 | gridGap: gridGap, 330 | rowGap: rowGap, 331 | columnGap: columnGap, 332 | gridColumnGap: gridColumnGap, 333 | gridRowGap: gridRowGap, 334 | }); 335 | }, [ 336 | props.contextGap, 337 | gap, 338 | gridGap, 339 | rowGap, 340 | columnGap, 341 | gridColumnGap, 342 | gridRowGap, 343 | ]); 344 | }; 345 | 346 | function useBreakpoints(propsBreakpoints, contextBreakpoints) { 347 | var breakpoints = React__default['default'].useState(propsBreakpoints || contextBreakpoints || [0, 432, 768, 1024, 1200, 1400])[0]; 348 | return breakpoints; 349 | } 350 | 351 | function useSpacingValue(gap, colspan, prop, counterProp) { 352 | return React__default['default'].useMemo(function () { 353 | switch (typeof prop) { 354 | case "number": 355 | var counter = counterProp === "string" ? counterProp : "0px"; 356 | return "calc(((100% + " + gap + " - " + counter + ") / " + colspan + ") * " + prop + ")"; 357 | default: 358 | return prop; 359 | } 360 | }, [gap, colspan, prop, counterProp]); 361 | } 362 | function useSpacingCSS(gap, colspan, spacing) { 363 | var left = useSpacingValue(gap.column, colspan, spacing.left, spacing.right); 364 | var right = useSpacingValue(gap.column, colspan, spacing.right, spacing.left); 365 | var top = useSpacingValue(gap.row, colspan, spacing.top, spacing.bottom); 366 | var bottom = useSpacingValue(gap.row, colspan, spacing.bottom, spacing.top); 367 | return { left: left, right: right, top: top, bottom: bottom }; 368 | } 369 | 370 | function useNormalize(props, context, hasChildBoxes) { 371 | var breakpoints = useBreakpoints(props.breakpoints, context.breakpoints); 372 | var breakpoint = useBreakpoint(breakpoints, context.breakpoint, props.breakpoints, props.colspan); 373 | var display = useDisplay(breakpoint, props.display, hasChildBoxes); 374 | var gap = useGap({ 375 | contextGap: context.gap, 376 | propsGap: props.gap, 377 | gridGap: props.gridGap, 378 | rowGap: props.rowGap, 379 | columnGap: props.columnGap, 380 | gridColumnGap: props.gridColumnGap, 381 | gridRowGap: props.gridRowGap, 382 | breakpoint: breakpoint, 383 | }); 384 | var marginRaw = useSpacing(breakpoint, props.margin, props.marginLeft, props.marginRight, props.marginTop, props.marginBottom); 385 | var paddingRaw = useSpacing(breakpoint, props.padding, props.paddingLeft, props.paddingRight, props.paddingTop, props.paddingBottom); 386 | var colspanTotal = useProp(breakpoint, props.colspan || context.colspan || 1); 387 | var cols = useProp(breakpoint, props.cols); 388 | // gets applied to StyledBox 389 | var colsEffective = useColsEffective(colspanTotal, marginRaw, paddingRaw, cols); 390 | var colsTotal = useColsTotal(colspanTotal, marginRaw, cols); 391 | var margin = useSpacingCSS(gap, colsTotal, marginRaw); 392 | var padding = useSpacingCSS(gap, colsTotal, paddingRaw); 393 | var styles = useProp(breakpoint, props.styles); 394 | var width = useProp(breakpoint, props.width); 395 | var minWidth = useProp(breakpoint, props.minWidth); 396 | var maxWidth = useProp(breakpoint, props.maxWidth); 397 | var height = useProp(breakpoint, props.height); 398 | var minHeight = useProp(breakpoint, props.minHeight); 399 | var maxHeight = useProp(breakpoint, props.maxHeight); 400 | var position = useProp(breakpoint, props.position, "relative"); 401 | var zIndex = useProp(breakpoint, props.zIndex); 402 | var left = useProp(breakpoint, props.left); 403 | var right = useProp(breakpoint, props.right); 404 | var top = useProp(breakpoint, props.top); 405 | var bottom = useProp(breakpoint, props.bottom); 406 | var pointerEvents = useProp(breakpoint, props.pointerEvents); 407 | var cursor = useProp(breakpoint, props.cursor); 408 | var gridTemplateRows = useProp(breakpoint, props.gridTemplateRows); 409 | var gridColumn = useProp(breakpoint, props.gridColumn); 410 | var gridRow = useProp(breakpoint, props.gridRow); 411 | var gridAutoRows = useProp(breakpoint, props.gridAutoRows); 412 | var gridTemplateColumns = useProp(breakpoint, props.gridTemplateColumns); 413 | var autoFlow = useProp(breakpoint, props.autoFlow); 414 | var order = useProp(breakpoint, props.order); 415 | var alignItems = useProp(breakpoint, props.alignItems); 416 | var alignContent = useProp(breakpoint, props.alignContent); 417 | var alignSelf = useProp(breakpoint, props.alignSelf); 418 | var justifyContent = useProp(breakpoint, props.justifyContent); 419 | var justifyItems = useProp(breakpoint, props.justifyItems); 420 | var justifySelf = useProp(breakpoint, props.justifySelf); 421 | var flexDirection = useProp(breakpoint, props.flexDirection); 422 | var flexWrap = useProp(breakpoint, props.flexWrap); 423 | var flexShrink = useProp(breakpoint, props.flexShrink); 424 | var flexGrow = useProp(breakpoint, props.flexGrow); 425 | var border = useProp(breakpoint, props.border); 426 | var borderLeft = useProp(breakpoint, props.borderLeft); 427 | var borderRight = useProp(breakpoint, props.borderRight); 428 | var borderTop = useProp(breakpoint, props.borderTop); 429 | var borderBottom = useProp(breakpoint, props.borderBottom); 430 | var background = useProp(breakpoint, props.background); 431 | var backgroundColor = useProp(breakpoint, props.backgroundColor); 432 | var backgroundImage = useProp(breakpoint, props.backgroundImage); 433 | var backgroundPosition = useProp(breakpoint, props.backgroundPosition); 434 | var backgroundAttachment = useProp(breakpoint, props.backgroundAttachment); 435 | var backgroundSize = useProp(breakpoint, props.backgroundSize); 436 | var filter = useProp(breakpoint, props.filter); 437 | var backdropFilter = useProp(breakpoint, props.backdropFilter); 438 | var mixBlendMode = useProp(breakpoint, props.mixBlendMode); 439 | var backgroundBlendMode = useProp(breakpoint, props.backgroundBlendMode); 440 | var textShadow = useProp(breakpoint, props.textShadow); 441 | var boxShadow = useProp(breakpoint, props.boxShadow); 442 | var textStroke = useProp(breakpoint, props.textStroke); 443 | var fontFamily = useProp(breakpoint, props.fontFamily); 444 | var fontSize = useProp(breakpoint, props.fontSize); 445 | var fontWeight = useProp(breakpoint, props.fontWeight); 446 | var fontStyle = useProp(breakpoint, props.fontStyle); 447 | var textAlign = useProp(breakpoint, props.textAlign); 448 | var color = useProp(breakpoint, props.color); 449 | var lineHeight = useProp(breakpoint, props.lineHeight); 450 | var letterSpacing = useProp(breakpoint, props.letterSpacing); 451 | var textDecoration = useProp(breakpoint, props.textDecoration); 452 | var hyphens = useProp(breakpoint, props.hyphens); 453 | var transform = useProp(breakpoint, props.transform); 454 | var transition = useProp(breakpoint, props.transition); 455 | var animation = useProp(breakpoint, props.animation); 456 | var opacity = useProp(breakpoint, props.opacity); 457 | var willChange = useProp(breakpoint, props.willChange); 458 | var overflow = useProp(breakpoint, props.overflow); 459 | var overflowX = useProp(breakpoint, props.overflowX); 460 | var overflowY = useProp(breakpoint, props.overflowY); 461 | var rootMargin = useProp(breakpoint, props.rootMargin); 462 | return { 463 | breakpoints: breakpoints, 464 | breakpoint: breakpoint, 465 | colsTotal: colsTotal, 466 | colspanTotal: colspanTotal, 467 | colsEffective: colsEffective, 468 | margin: margin, 469 | padding: padding, 470 | marginRaw: marginRaw, 471 | paddingRaw: paddingRaw, 472 | display: display, 473 | gap: gap, 474 | controlColor: props.controlColor || context.controlColor, 475 | styles: styles, 476 | width: width, 477 | minWidth: minWidth, 478 | maxWidth: maxWidth, 479 | height: height, 480 | minHeight: minHeight, 481 | maxHeight: maxHeight, 482 | position: position, 483 | zIndex: zIndex, 484 | left: left, 485 | right: right, 486 | top: top, 487 | bottom: bottom, 488 | pointerEvents: pointerEvents, 489 | cursor: cursor, 490 | gridTemplateRows: gridTemplateRows, 491 | gridColumn: gridColumn, 492 | gridRow: gridRow, 493 | gridAutoRows: gridAutoRows, 494 | gridTemplateColumns: gridTemplateColumns, 495 | autoFlow: autoFlow, 496 | order: order, 497 | alignItems: alignItems, 498 | alignContent: alignContent, 499 | alignSelf: alignSelf, 500 | justifyContent: justifyContent, 501 | justifyItems: justifyItems, 502 | justifySelf: justifySelf, 503 | flexDirection: flexDirection, 504 | flexWrap: flexWrap, 505 | flexShrink: flexShrink, 506 | flexGrow: flexGrow, 507 | border: border, 508 | borderLeft: borderLeft, 509 | borderRight: borderRight, 510 | borderTop: borderTop, 511 | borderBottom: borderBottom, 512 | background: background, 513 | backgroundColor: backgroundColor, 514 | backgroundImage: backgroundImage, 515 | backgroundPosition: backgroundPosition, 516 | backgroundAttachment: backgroundAttachment, 517 | backgroundSize: backgroundSize, 518 | filter: filter, 519 | backdropFilter: backdropFilter, 520 | mixBlendMode: mixBlendMode, 521 | backgroundBlendMode: backgroundBlendMode, 522 | textShadow: textShadow, 523 | boxShadow: boxShadow, 524 | textStroke: textStroke, 525 | fontFamily: fontFamily, 526 | fontSize: fontSize, 527 | fontWeight: fontWeight, 528 | fontStyle: fontStyle, 529 | textAlign: textAlign, 530 | color: color, 531 | lineHeight: lineHeight, 532 | letterSpacing: letterSpacing, 533 | textDecoration: textDecoration, 534 | hyphens: hyphens, 535 | transform: transform, 536 | transition: transition, 537 | animation: animation, 538 | opacity: opacity, 539 | willChange: willChange, 540 | overflow: overflow, 541 | overflowX: overflowX, 542 | overflowY: overflowY, 543 | rootMargin: rootMargin, 544 | }; 545 | } 546 | 547 | var useControl = function (control, controlIsVisible) { 548 | var _a = React__default['default'].useState(false), isVisible = _a[0], setIsVisible = _a[1]; 549 | React__default['default'].useEffect(function () { 550 | setIsVisible(!!controlIsVisible); 551 | }, [controlIsVisible]); 552 | React__default['default'].useEffect(function () { 553 | function onKeyup(event) { 554 | if (event.keyCode !== 27) 555 | return; 556 | setIsVisible(function (prevState) { return !prevState; }); 557 | } 558 | if (control) { 559 | document.addEventListener("keyup", onKeyup); 560 | return function () { return document.removeEventListener("keyup", onKeyup); }; 561 | } 562 | }, []); 563 | return isVisible; 564 | }; 565 | 566 | function useUndefinedProps(props) { 567 | props.display; props.breakpoints; props.width; props.minWidth; props.maxWidth; props.height; props.minHeight; props.maxHeight; props.colspan; props.cols; props.margin; props.marginLeft; props.marginRight; props.marginTop; props.marginBottom; props.padding; props.paddingLeft; props.paddingRight; props.paddingTop; props.paddingBottom; props.gap; props.gridRowGap; props.rowGap; props.gridColumnGap; props.columnGap; props.gridTemplateRows; props.gridAutoRows; props.gridTemplateColumns; props.gridRow; props.gridColumn; props.autoFlow; props.component; props.innerHTML; props.cursor; props.pointerEvents; props.onResize; props.onIntersect; props.root; props.rootMargin; props.threshold; props.styles; props.as; props.control; props.controlColor; props.order; props.position; props.zIndex; props.top; props.bottom; props.left; props.right; props.alignItems; props.alignContent; props.alignSelf; props.justifyContent; props.justifyItems; props.justifySelf; props.flexDirection; props.flexWrap; props.flexShrink; props.flexGrow; props.background; props.backgroundColor; props.backgroundImage; props.backgroundPosition; props.backgroundSize; props.backgroundAttachment; props.filter; props.backdropFilter; props.mixBlendMode; props.backgroundBlendMode; props.textShadow; props.boxShadow; props.textStroke; props.border; props.borderLeft; props.borderRight; props.borderTop; props.borderBottom; props.fontFamily; props.fontSize; props.fontWeight; props.fontStyle; props.textAlign; props.color; props.lineHeight; props.letterSpacing; props.textDecoration; props.hyphens; props.overflow; props.overflowX; props.overflowY; props.transition; props.animation; props.opacity; props.transform; props.willChange; props.className; props.children; props.isControl; props.ref; var rest = __rest(props, ["display", "breakpoints", "width", "minWidth", "maxWidth", "height", "minHeight", "maxHeight", "colspan", "cols", "margin", "marginLeft", "marginRight", "marginTop", "marginBottom", "padding", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom", "gap", "gridRowGap", "rowGap", "gridColumnGap", "columnGap", "gridTemplateRows", "gridAutoRows", "gridTemplateColumns", "gridRow", "gridColumn", "autoFlow", "component", "innerHTML", "cursor", "pointerEvents", "onResize", "onIntersect", "root", "rootMargin", "threshold", "styles", "as", "control", "controlColor", "order", "position", "zIndex", "top", "bottom", "left", "right", "alignItems", "alignContent", "alignSelf", "justifyContent", "justifyItems", "justifySelf", "flexDirection", "flexWrap", "flexShrink", "flexGrow", "background", "backgroundColor", "backgroundImage", "backgroundPosition", "backgroundSize", "backgroundAttachment", "filter", "backdropFilter", "mixBlendMode", "backgroundBlendMode", "textShadow", "boxShadow", "textStroke", "border", "borderLeft", "borderRight", "borderTop", "borderBottom", "fontFamily", "fontSize", "fontWeight", "fontStyle", "textAlign", "color", "lineHeight", "letterSpacing", "textDecoration", "hyphens", "overflow", "overflowX", "overflowY", "transition", "animation", "opacity", "transform", "willChange", "className", "children", "isControl", "ref"]); 568 | return rest; 569 | } 570 | 571 | function onIntersect(_a) { 572 | var ref = _a.ref, _b = _a.root, root = _b === void 0 ? null : _b, rootMargin = _a.rootMargin, _c = _a.threshold, threshold = _c === void 0 ? 0 : _c, onIntersect = _a.onIntersect; 573 | var observer = React.useRef(null); 574 | React.useEffect(function () { 575 | if (typeof onIntersect !== "function") 576 | return; 577 | observer.current = new IntersectionObserver(function (_a, observer) { 578 | var entry = _a[0]; 579 | return onIntersect(entry, observer); 580 | }, { 581 | root: root, 582 | rootMargin: rootMargin, 583 | threshold: threshold, 584 | }); 585 | if (ref.current && observer.current) 586 | observer.current.observe(ref.current); 587 | return function () { return observer.current && observer.current.disconnect(); }; 588 | }, []); 589 | } 590 | 591 | var Container = React__default['default'].forwardRef(function (_a, ref) { 592 | var className = _a.className, children = _a.children, component = _a.component, _b = _a.attrs, attrs = _b === void 0 ? {} : _b, _c = _a.tag, tag = _c === void 0 ? "div" : _c; 593 | if (component) { 594 | return React__default['default'].cloneElement(component, __assign({ children: children, className: className }, attrs)); 595 | } 596 | return React__default['default'].createElement(tag, __assign(__assign({}, attrs), { className: className, ref: ref }), tag !== "img" && !attrs.dangerouslySetInnerHTML ? children : null); 597 | }); 598 | Container.displayName = "Container"; 599 | 600 | var StyledBoxStyles = styled__default['default'](Container)(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n box-sizing: border-box;\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n"], ["\n box-sizing: border-box;\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n"])), function (props) { return styled.css(templateObject_1$1 || (templateObject_1$1 = __makeTemplateObject(["\n position: ", ";\n z-index: ", ";\n display: ", ";\n pointer-events: ", ";\n cursor: ", ";\n\n width: ", ";\n min-width: ", ";\n max-width: ", ";\n height: ", ";\n min-height: ", ";\n max-height: ", ";\n\n padding-left: ", ";\n padding-right: ", ";\n padding-top: ", ";\n padding-bottom: ", ";\n\n margin-left: ", ";\n margin-right: ", ";\n margin-top: ", ";\n margin-bottom: ", ";\n\n order: ", ";\n\n top: ", ";\n bottom: ", ";\n left: ", ";\n right: ", ";\n\n align-items: ", ";\n align-content: ", ";\n align-self: ", ";\n justify-content: ", ";\n justify-items: ", ";\n justify-self: ", ";\n\n flex-direction: ", ";\n flex-wrap: ", ";\n flex-shrink: ", ";\n flex-grow: ", ";\n\n background: ", ";\n background-color: ", ";\n background-image: ", ";\n background-position: ", ";\n background-size: ", ";\n background-attachment: ", ";\n\n filter: ", ";\n backdrop-filter: ", ";\n mix-blend-mode: ", ";\n background-blend-mode: ", ";\n text-shadow: ", ";\n box-shadow: ", ";\n -webkit-text-stroke: ", ";\n text-stroke: ", ";\n\n border: ", ";\n border-left: ", ";\n border-right: ", ";\n border-top: ", ";\n border-bottom: ", ";\n\n font-family: ", ";\n font-size: ", ";\n font-weight: ", ";\n font-style: ", ";\n text-align: ", ";\n color: ", ";\n line-height: ", ";\n letter-spacing: ", ";\n text-decoration: ", ";\n hyphens: ", ";\n\n transition: ", ";\n transform: ", ";\n animation: ", ";\n opacity: ", ";\n will-change: ", ";\n\n overflow: ", ";\n overflow-x: ", ";\n overflow-y: ", ";\n\n ", "\n "], ["\n position: ", ";\n z-index: ", ";\n display: ", ";\n pointer-events: ", ";\n cursor: ", ";\n\n width: ", ";\n min-width: ", ";\n max-width: ", ";\n height: ", ";\n min-height: ", ";\n max-height: ", ";\n\n padding-left: ", ";\n padding-right: ", ";\n padding-top: ", ";\n padding-bottom: ", ";\n\n margin-left: ", ";\n margin-right: ", ";\n margin-top: ", ";\n margin-bottom: ", ";\n\n order: ", ";\n\n top: ", ";\n bottom: ", ";\n left: ", ";\n right: ", ";\n\n align-items: ", ";\n align-content: ", ";\n align-self: ", ";\n justify-content: ", ";\n justify-items: ", ";\n justify-self: ", ";\n\n flex-direction: ", ";\n flex-wrap: ", ";\n flex-shrink: ", ";\n flex-grow: ", ";\n\n background: ", ";\n background-color: ", ";\n background-image: ", ";\n background-position: ", ";\n background-size: ", ";\n background-attachment: ", ";\n\n filter: ", ";\n backdrop-filter: ", ";\n mix-blend-mode: ", ";\n background-blend-mode: ", ";\n text-shadow: ", ";\n box-shadow: ", ";\n -webkit-text-stroke: ", ";\n text-stroke: ", ";\n\n border: ", ";\n border-left: ", ";\n border-right: ", ";\n border-top: ", ";\n border-bottom: ", ";\n\n font-family: ", ";\n font-size: ", ";\n font-weight: ", ";\n font-style: ", ";\n text-align: ", ";\n color: ", ";\n line-height: ", ";\n letter-spacing: ", ";\n text-decoration: ", ";\n hyphens: ", ";\n\n transition: ", ";\n transform: ", ";\n animation: ", ";\n opacity: ", ";\n will-change: ", ";\n\n overflow: ", ";\n overflow-x: ", ";\n overflow-y: ", ";\n\n ", "\n "])), props.position, props.zIndex, props.display, props.pointerEvents, props.cursor, props.width, props.minWidth, props.maxWidth, props.height, props.minHeight, props.maxHeight, props.padding.left, props.padding.right, props.padding.top, props.padding.bottom, props.margin.left, props.margin.right, props.margin.top, props.margin.bottom, props.order, props.top, props.bottom, props.left, props.right, props.alignItems, props.alignContent, props.alignSelf, props.justifyContent, props.justifyItems, props.justifySelf, props.flexDirection, props.flexWrap, props.flexShrink, props.flexGrow, props.background, props.backgroundColor, props.backgroundImage, props.backgroundPosition, props.backgroundSize, props.backgroundAttachment, props.filter, props.backdropFilter, props.mixBlendMode, props.backgroundBlendMode, props.textShadow, props.boxShadow, props.textStroke, props.textStroke, props.border, props.borderLeft, props.borderRight, props.borderTop, props.borderBottom, props.fontFamily, props.fontSize, props.fontWeight, props.fontStyle, props.textAlign, props.color, props.lineHeight, props.letterSpacing, props.textDecoration, props.hyphens, props.transition, props.transform, props.animation, props.opacity, props.willChange, props.overflow, props.overflowX, props.overflowY, props.styles ? props.styles : ""); }, function (props) { 601 | return props.display === "grid" && styled.css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n grid-template-columns: repeat(", ", 1fr);\n\n grid-auto-rows: ", ";\n grid-template-rows: ", ";\n grid-template-columns: ", ";\n grid-auto-flow: ", ";\n\n grid-gap: ", " ", ";\n\n ", "\n "], ["\n grid-template-columns: repeat(", ", 1fr);\n\n grid-auto-rows: ", ";\n grid-template-rows: ", ";\n grid-template-columns: ", ";\n grid-auto-flow: ", ";\n\n grid-gap: ", " ", ";\n\n ", "\n "])), props.colsEffective, props.gridAutoRows, props.gridTemplateRows, props.gridTemplateColumns, props.autoFlow, props.gap.row, props.gap.column, props.isControl && 602 | (props.gap.column === "0px" ? "grid-column-gap: 1px;" : "")); 603 | }, function (props) { 604 | return props.display === "flex" && styled.css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n gap: ", " ", ";\n "], ["\n gap: ", " ", ";\n "])), props.gap.row, props.gap.column); 605 | }, function (props) { return styled.css(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n grid-column: auto / span ", ";\n grid-column: ", ";\n grid-row: ", ";\n "], ["\n grid-column: auto / span ", ";\n grid-column: ", ";\n grid-row: ", ";\n "])), props.colsTotal, props.gridColumn, props.gridRow); }, function (props) { 606 | return props.tag === "img" && 607 | props.controlIsVisible && styled.css(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n box-shadow: 0 0 999em ", " inset;\n "], ["\n box-shadow: 0 0 999em ", " inset;\n "])), props.controlColor); 608 | }); 609 | var StyledBox = React__default['default'].forwardRef(function (props, ref) { 610 | return React__default['default'].createElement(StyledBoxStyles, __assign({}, props, { ref: ref })); 611 | }); 612 | StyledBox.displayName = "StyledBox"; 613 | var StyledBox$1 = React__default['default'].memo(StyledBox); 614 | var templateObject_1$1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6; 615 | 616 | function getSideBearing(padding) { 617 | return typeof padding === "number" ? 0 : padding; 618 | } 619 | var ControlGrid = function (props) { 620 | var colspanTotal = props.colspanTotal; 621 | return (React__default['default'].createElement(Box$1, { position: "absolute", className: "GridControl", zIndex: 1000, colspan: colspanTotal, gridColumnGap: props.gap.column, gridAutoRows: "100%", top: 0, bottom: 0, left: 0, right: 0, marginLeft: getSideBearing(props.paddingRaw.left), marginRight: getSideBearing(props.paddingRaw.right), marginTop: getSideBearing(props.paddingRaw.top), marginBottom: getSideBearing(props.paddingRaw.bottom), pointerEvents: "none", isControl: true }, __spreadArray([], Array(colspanTotal)).map(function (_, index) { return (React__default['default'].createElement(Box$1, { key: index, display: "flex", alignSelf: "stretch", cols: 1, backgroundColor: props.controlColor || "rgba(0,0,0,0.12)" })); }))); 622 | }; 623 | var ControlBox = styled__default['default']("span")(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n position: absolute;\n z-index: 10000;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n background-color: ", ";\n pointer-events: none;\n"], ["\n position: absolute;\n z-index: 10000;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n background-color: ", ";\n pointer-events: none;\n"])), function (props) { return props.controlColor || "rgba(0,0,0,0.12)"; }); 624 | var Control = function (props) { 625 | return props.isNewGrid ? (React__default['default'].createElement(ControlGrid, __assign({}, props))) : (React__default['default'].createElement(ControlBox, { controlColor: props.controlColor })); 626 | }; 627 | var templateObject_1; 628 | 629 | var Box = React__default['default'].forwardRef(function (props, ref) { 630 | var context = React.useContext(Context); 631 | var _a = React__default['default'].useState(false), hasChildBoxes = _a[0], registerChildBox = _a[1]; 632 | React__default['default'].useEffect(function () { 633 | if (typeof context.registerChildBox === "function") { 634 | context.registerChildBox(); 635 | } 636 | }, []); 637 | var propsNormalized = useNormalize(props, context, hasChildBoxes); 638 | var controlIsVisible = useControl(props.control, context.controlIsVisible); 639 | var boxRef = useCombinedRefs(ref); 640 | var undefinedProps = useUndefinedProps(props); 641 | var breakpoint = { 642 | index: propsNormalized.breakpoint + 1, 643 | value: propsNormalized.breakpoints[propsNormalized.breakpoint], 644 | }; 645 | var defaultClass = "Box bp-" + breakpoint.value + " bp-" + breakpoint.index; 646 | useResizeObserver(boxRef, props.onResize); 647 | onIntersect({ 648 | ref: boxRef, 649 | root: props.root, 650 | rootMargin: propsNormalized.rootMargin, 651 | threshold: props.threshold, 652 | onIntersect: props.onIntersect, 653 | }); 654 | return (React__default['default'].createElement(StyledBox$1, __assign({}, propsNormalized, { tag: props.as, component: props.component, className: props.className 655 | ? [defaultClass, props.className].join(" ") 656 | : defaultClass, controlIsVisible: controlIsVisible, ref: boxRef, styles: propsNormalized.styles, isControl: props.isControl, attrs: __assign(__assign({}, undefinedProps), (props.innerHTML && { 657 | dangerouslySetInnerHTML: { __html: props.innerHTML }, 658 | })) }), 659 | controlIsVisible && (React__default['default'].createElement(Control, __assign({ isNewGrid: !!props.colspan }, propsNormalized))), 660 | React__default['default'].createElement(Context.Provider, { value: { 661 | breakpoints: propsNormalized.breakpoints, 662 | breakpoint: propsNormalized.breakpoint, 663 | currentBreakpoint: breakpoint, 664 | gap: propsNormalized.gap, 665 | colspan: propsNormalized.colsEffective, 666 | controlIsVisible: controlIsVisible, 667 | controlColor: propsNormalized.controlColor, 668 | registerChildBox: function () { return registerChildBox(true); }, 669 | } }, props.children))); 670 | }); 671 | Box.displayName = "Box"; 672 | var Box$1 = React__default['default'].memo(Box); 673 | 674 | exports.default = Box$1; 675 | exports.useRaster = useRaster; 676 | //# sourceMappingURL=index.js.map 677 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | const isProduction = process.env.NODE_ENV === "production"; 2 | const productionPath = "/react-raster"; 3 | 4 | module.exports = { 5 | basePath: isProduction ? productionPath : "", 6 | env: { 7 | productionPath: isProduction ? productionPath + "/" : "", 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-raster", 3 | "version": "8.2.1", 4 | "description": "Advanced grid- and styling-system which is highly customizable and ready for server-side-rendering.", 5 | "author": "AndreasFaust", 6 | "license": "MIT", 7 | "repository": "AndreasFaust/react-raster", 8 | "homepage": "https://andreasfaust.github.io/react-raster-docs/", 9 | "main": "dist/index.js", 10 | "module": "dist/index.es.js", 11 | "jsnext:main": "dist/index.es.js", 12 | "types": "./dist/index.d.ts", 13 | "files": [ 14 | "/dist" 15 | ], 16 | "engines": { 17 | "node": ">=8", 18 | "npm": ">=5" 19 | }, 20 | "dependencies": {}, 21 | "devDependencies": { 22 | "@rollup/plugin-commonjs": "^19.0.0", 23 | "@rollup/plugin-node-resolve": "^13.0.0", 24 | "@rollup/plugin-url": "^6.0.0", 25 | "@types/node": "^15.12.5", 26 | "@types/react": "^17.0.11", 27 | "@types/resize-observer-browser": "^0.1.5", 28 | "@types/styled-components": "^5.1.10", 29 | "@typescript-eslint/eslint-plugin": "4.28.0", 30 | "@typescript-eslint/parser": "4.28.0", 31 | "babel-eslint": "^10.1.0", 32 | "babel-plugin-styled-components": "^1.12.0", 33 | "eslint": "7.29.0", 34 | "eslint-config-next": "^11.0.1", 35 | "framer-motion": "^4.1.17", 36 | "generate-changelog": "^1.8.0", 37 | "gh-pages": "^3.2.3", 38 | "lodash": "^4.17.21", 39 | "next": "11.0.1", 40 | "react": "17.0.2", 41 | "react-dom": "^17.0.2", 42 | "rollup": "^2.52.3", 43 | "rollup-plugin-css-only": "^3.1.0", 44 | "rollup-plugin-peer-deps-external": "^2.2.4", 45 | "rollup-plugin-typescript2": "^0.30.0", 46 | "styled-components": "^5.3.0", 47 | "typescript": "^4.3.4" 48 | }, 49 | "peerDependencies": { 50 | "react": ">=16.8.0", 51 | "react-dom": ">=16.8.0", 52 | "styled-components": ">=5.2.1" 53 | }, 54 | "keywords": [ 55 | "React", 56 | "Grid", 57 | "Layout", 58 | "Styled Components", 59 | "Server Side Rendering", 60 | "Raster", 61 | "Next JS", 62 | "NextJS" 63 | ], 64 | "scripts": { 65 | "dev": "next dev", 66 | "start": "yarn dev", 67 | "build": "rollup -c", 68 | "lint": "next lint", 69 | "release:major": "yarn build && git add . && changelog -M && git add CHANGELOG.md && git commit -m 'updated CHANGELOG.md' && npm version major && git push origin && git push origin --tags && npm publish", 70 | "release:minor": "yarn build && git add . && changelog -m && git add CHANGELOG.md && git commit -m 'updated CHANGELOG.md' && npm version minor && git push origin && git push origin --tags && npm publish", 71 | "release:patch": "yarn build && git add . && changelog -p && git add CHANGELOG.md && git commit -m 'updated CHANGELOG.md' && npm version patch && git push origin && git push origin --tags && npm publish", 72 | "release:dev": "yarn build && git add . && git commit -m 'Do Beta-Release' && git push origin && git push origin --tags && npm version 8.0.0-next.19 && npm publish --tag next", 73 | "deploy": "yarn next build && yarn next export && touch out/.nojekyll && gh-pages -t -d out" 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { AnimatePresence } from "framer-motion"; 3 | import "./css/reset.css"; 4 | import "./css/index.css"; 5 | 6 | function MyApp({ Component, pageProps, router }) { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | } 13 | 14 | export default MyApp; 15 | -------------------------------------------------------------------------------- /pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import Document, { DocumentContext } from "next/document"; 2 | import { ServerStyleSheet } from "styled-components"; 3 | 4 | export default class MyDocument extends Document { 5 | static async getInitialProps(ctx: DocumentContext) { 6 | const sheet = new ServerStyleSheet(); 7 | const originalRenderPage = ctx.renderPage; 8 | 9 | try { 10 | ctx.renderPage = () => 11 | originalRenderPage({ 12 | enhanceApp: (App) => (props) => 13 | sheet.collectStyles(), 14 | }); 15 | 16 | const initialProps = await Document.getInitialProps(ctx); 17 | return { 18 | ...initialProps, 19 | styles: ( 20 | <> 21 | {initialProps.styles} 22 | {sheet.getStyleElement()} 23 | 24 | ), 25 | }; 26 | } finally { 27 | sheet.seal(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /pages/css/index.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-family: Italic, serif; 3 | -ms-text-size-adjust: 100%; 4 | -webkit-text-size-adjust: 100%; 5 | } 6 | body { 7 | margin: 0; 8 | } 9 | 10 | img { 11 | display: block; 12 | width: 100%; 13 | } 14 | 15 | pre { 16 | display: inline; 17 | font-family: Plex; 18 | font-size: 75%; 19 | padding: 0.1em 0.3em 0.15em; 20 | margin-right: 0.15em; 21 | border-radius: 0.15em; 22 | background: hsla(0, 0%, 0%, 0.1); 23 | } 24 | 25 | h1, 26 | h2 { 27 | text-align: center; 28 | } 29 | .bp-1 h1 { 30 | font-size: 1.5rem; 31 | } 32 | .bp-2 h1 { 33 | font-size: 1.75rem; 34 | } 35 | .bp-3 h1 { 36 | font-size: 2rem; 37 | } 38 | .bp-4 h1 { 39 | font-size: 2.25rem; 40 | } 41 | .bp-5 h1, 42 | .bp-6 h1 { 43 | font-size: 2.5rem; 44 | } 45 | 46 | .topnav { 47 | position: fixed; 48 | top: 0; 49 | left: 0.5rem; 50 | right: 0.5rem; 51 | display: flex; 52 | justify-content: space-between; 53 | align-items: center; 54 | z-index: 1000; 55 | } 56 | 57 | .gitHub { 58 | display: block; 59 | width: 3rem; 60 | height: 3rem; 61 | } 62 | 63 | .gitHub:hover path { 64 | fill: #000; 65 | } 66 | 67 | .modeSelect { 68 | min-width: 10rem; 69 | } 70 | 71 | .hint { 72 | display: flex; 73 | align-items: center; 74 | } 75 | .hintIcon { 76 | padding: 0.25rem; 77 | background: hsla(0, 0%, 0%, 0.1); 78 | border-radius: 0.2rem; 79 | width: 2.5rem; 80 | height: 2.5rem; 81 | margin: 0 0.75rem 0 0; 82 | } 83 | 84 | small { 85 | letter-spacing: 0.025em; 86 | } 87 | .bp-1 small, 88 | .bp-2 small { 89 | font-size: 0.9rem; 90 | } 91 | .bp-3 small, 92 | .bp-4 small, 93 | .bp-5 small, 94 | .bp-6 small { 95 | font-size: 1rem; 96 | } 97 | 98 | .logo { 99 | max-height: 50vh; 100 | } 101 | -------------------------------------------------------------------------------- /pages/css/reset.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-family: sans-serif; 3 | -ms-text-size-adjust: 100%; 4 | -webkit-text-size-adjust: 100%; 5 | } 6 | body { 7 | margin: 0; 8 | } 9 | article, 10 | aside, 11 | details, 12 | figcaption, 13 | figure, 14 | footer, 15 | header, 16 | main, 17 | menu, 18 | nav, 19 | section, 20 | summary { 21 | display: block; 22 | } 23 | audio, 24 | canvas, 25 | progress, 26 | video { 27 | display: inline-block; 28 | } 29 | audio:not([controls]) { 30 | display: none; 31 | height: 0; 32 | } 33 | progress { 34 | vertical-align: baseline; 35 | } 36 | [hidden], 37 | template { 38 | display: none; 39 | } 40 | a { 41 | background-color: transparent; 42 | -webkit-text-decoration-skip: objects; 43 | color: $greyText; 44 | text-decoration: none; 45 | } 46 | a:active, 47 | a:hover { 48 | outline-width: 0; 49 | } 50 | abbr[title] { 51 | border-bottom: none; 52 | text-decoration: underline; 53 | text-decoration: underline dotted; 54 | } 55 | b, 56 | strong { 57 | font-weight: normal; 58 | } 59 | dfn { 60 | font-style: normal; 61 | } 62 | mark { 63 | background-color: #ff0; 64 | color: #000; 65 | } 66 | small { 67 | } 68 | sub, 69 | sup { 70 | font-size: 75%; 71 | line-height: 0; 72 | position: relative; 73 | vertical-align: baseline; 74 | } 75 | sub { 76 | bottom: -0.25em; 77 | } 78 | sup { 79 | top: -0.5em; 80 | } 81 | img { 82 | border-style: none; 83 | } 84 | svg:not(:root) { 85 | overflow: hidden; 86 | } 87 | code, 88 | kbd, 89 | pre, 90 | samp { 91 | font-family: monospace, monospace; 92 | font-size: 1em; 93 | } 94 | figure { 95 | /* // margin: 1em 40px; */ 96 | } 97 | hr { 98 | box-sizing: content-box; 99 | height: 0; 100 | overflow: visible; 101 | } 102 | button, 103 | input, 104 | optgroup, 105 | select, 106 | textarea { 107 | font: inherit; 108 | margin: 0; 109 | } 110 | optgroup { 111 | font-weight: 700; 112 | } 113 | button, 114 | input { 115 | overflow: visible; 116 | } 117 | button, 118 | select { 119 | text-transform: none; 120 | } 121 | [type="reset"], 122 | [type="submit"], 123 | button, 124 | html [type="button"] { 125 | -webkit-appearance: button; 126 | } 127 | [type="button"]::-moz-focus-inner, 128 | [type="reset"]::-moz-focus-inner, 129 | [type="submit"]::-moz-focus-inner, 130 | button::-moz-focus-inner { 131 | border-style: none; 132 | padding: 0; 133 | } 134 | [type="button"]:-moz-focusring, 135 | [type="reset"]:-moz-focusring, 136 | [type="submit"]:-moz-focusring, 137 | button:-moz-focusring { 138 | outline: 1px dotted ButtonText; 139 | } 140 | fieldset { 141 | border: 1px solid silver; 142 | margin: 0 2px; 143 | padding: 0.35em 0.625em 0.75em; 144 | } 145 | legend { 146 | box-sizing: border-box; 147 | color: inherit; 148 | display: table; 149 | max-width: 100%; 150 | padding: 0; 151 | white-space: normal; 152 | } 153 | textarea { 154 | overflow: auto; 155 | } 156 | [type="checkbox"], 157 | [type="radio"] { 158 | box-sizing: border-box; 159 | padding: 0; 160 | } 161 | [type="number"]::-webkit-inner-spin-button, 162 | [type="number"]::-webkit-outer-spin-button { 163 | height: auto; 164 | } 165 | [type="search"] { 166 | -webkit-appearance: textfield; 167 | outline-offset: -2px; 168 | } 169 | [type="search"]::-webkit-search-cancel-button, 170 | [type="search"]::-webkit-search-decoration { 171 | -webkit-appearance: none; 172 | } 173 | ::-webkit-input-placeholder { 174 | color: inherit; 175 | opacity: 0.54; 176 | } 177 | ::-webkit-file-upload-button { 178 | -webkit-appearance: button; 179 | font: inherit; 180 | } 181 | html { 182 | box-sizing: border-box; 183 | } 184 | * { 185 | box-sizing: inherit; 186 | } 187 | *:before { 188 | box-sizing: inherit; 189 | } 190 | *:after { 191 | box-sizing: inherit; 192 | } 193 | body { 194 | color: $greyText; 195 | font-weight: normal; 196 | word-wrap: break-word; 197 | font-kerning: normal; 198 | -moz-font-feature-settings: "kern", "liga", "clig", "calt"; 199 | -ms-font-feature-settings: "kern", "liga", "clig", "calt"; 200 | -webkit-font-feature-settings: "kern", "liga", "clig", "calt"; 201 | font-feature-settings: "kern", "liga", "clig", "calt"; 202 | } 203 | img { 204 | max-width: 100%; 205 | margin-left: 0; 206 | margin-right: 0; 207 | margin-top: 0; 208 | margin-bottom: 0; 209 | padding-bottom: 0; 210 | padding-left: 0; 211 | padding-right: 0; 212 | padding-top: 0; 213 | } 214 | h1 { 215 | margin-left: 0; 216 | margin-right: 0; 217 | margin-top: 0; 218 | margin-bottom: 0; 219 | padding-bottom: 0; 220 | padding-left: 0; 221 | padding-right: 0; 222 | padding-top: 0; 223 | color: inherit; 224 | font-weight: normal; 225 | text-rendering: optimizeLegibility; 226 | } 227 | h2 { 228 | margin-left: 0; 229 | margin-right: 0; 230 | margin-top: 0; 231 | margin-bottom: 0; 232 | padding-bottom: 0; 233 | padding-left: 0; 234 | padding-right: 0; 235 | padding-top: 0; 236 | color: inherit; 237 | font-weight: normal; 238 | text-rendering: optimizeLegibility; 239 | } 240 | h3 { 241 | margin-left: 0; 242 | margin-right: 0; 243 | margin-top: 0; 244 | margin-bottom: 0; 245 | padding-bottom: 0; 246 | padding-left: 0; 247 | padding-right: 0; 248 | padding-top: 0; 249 | color: inherit; 250 | font-weight: normal; 251 | text-rendering: optimizeLegibility; 252 | } 253 | h4 { 254 | margin-left: 0; 255 | margin-right: 0; 256 | margin-top: 0; 257 | margin-bottom: 0; 258 | padding-bottom: 0; 259 | padding-left: 0; 260 | padding-right: 0; 261 | padding-top: 0; 262 | color: inherit; 263 | font-weight: normal; 264 | text-rendering: optimizeLegibility; 265 | } 266 | h5 { 267 | margin-left: 0; 268 | margin-right: 0; 269 | margin-top: 0; 270 | margin-bottom: 0; 271 | padding-bottom: 0; 272 | padding-left: 0; 273 | padding-right: 0; 274 | padding-top: 0; 275 | color: inherit; 276 | font-weight: normal; 277 | text-rendering: optimizeLegibility; 278 | } 279 | h6 { 280 | margin-left: 0; 281 | margin-right: 0; 282 | margin-top: 0; 283 | margin-bottom: 0; 284 | padding-bottom: 0; 285 | padding-left: 0; 286 | padding-right: 0; 287 | padding-top: 0; 288 | color: inherit; 289 | font-weight: normal; 290 | text-rendering: optimizeLegibility; 291 | } 292 | hgroup { 293 | margin-left: 0; 294 | margin-right: 0; 295 | margin-top: 0; 296 | padding-bottom: 0; 297 | padding-left: 0; 298 | padding-right: 0; 299 | padding-top: 0; 300 | margin-bottom: 1.45rem; 301 | } 302 | ul { 303 | margin-left: 0; 304 | margin-right: 0; 305 | margin-top: 0; 306 | margin-bottom: 0; 307 | padding-bottom: 0; 308 | padding-left: 0; 309 | padding-right: 0; 310 | padding-top: 0; 311 | list-style: none; 312 | list-style-image: none; 313 | } 314 | ol { 315 | margin-left: 0; 316 | margin-right: 0; 317 | margin-top: 0; 318 | margin-bottom: 0; 319 | padding-bottom: 0; 320 | padding-left: 0; 321 | padding-right: 0; 322 | padding-top: 0; 323 | list-style-position: outside; 324 | list-style-image: none; 325 | } 326 | dl { 327 | margin-left: 0; 328 | margin-right: 0; 329 | margin-top: 0; 330 | padding-bottom: 0; 331 | padding-left: 0; 332 | padding-right: 0; 333 | padding-top: 0; 334 | margin-bottom: 0; 335 | } 336 | dd { 337 | margin-left: 0; 338 | margin-right: 0; 339 | margin-top: 0; 340 | padding-bottom: 0; 341 | padding-left: 0; 342 | padding-right: 0; 343 | padding-top: 0; 344 | margin-bottom: 0; 345 | } 346 | p { 347 | margin-left: 0; 348 | margin-right: 0; 349 | margin-top: 0; 350 | padding-bottom: 0; 351 | padding-left: 0; 352 | padding-right: 0; 353 | padding-top: 0; 354 | margin-bottom: 0; 355 | } 356 | figure { 357 | margin-left: 0; 358 | margin-right: 0; 359 | margin-top: 0; 360 | padding-bottom: 0; 361 | padding-left: 0; 362 | padding-right: 0; 363 | padding-top: 0; 364 | margin-bottom: 0; 365 | } 366 | pre { 367 | margin-left: 0; 368 | margin-right: 0; 369 | margin-top: 0; 370 | padding-bottom: 0; 371 | padding-left: 0; 372 | padding-right: 0; 373 | padding-top: 0; 374 | margin-bottom: 0; 375 | font-size: 0.85rem; 376 | line-height: 1.42; 377 | background: hsla(0, 0%, 0%, 0.04); 378 | border-radius: 3px; 379 | overflow: auto; 380 | word-wrap: normal; 381 | padding: 0; 382 | } 383 | table { 384 | margin-left: 0; 385 | margin-right: 0; 386 | margin-top: 0; 387 | padding-bottom: 0; 388 | padding-left: 0; 389 | padding-right: 0; 390 | padding-top: 0; 391 | margin-bottom: 0; 392 | font-size: 1rem; 393 | line-height: 1; 394 | border-collapse: collapse; 395 | width: 100%; 396 | } 397 | fieldset { 398 | margin-left: 0; 399 | margin-right: 0; 400 | margin-top: 0; 401 | padding-bottom: 0; 402 | padding-left: 0; 403 | padding-right: 0; 404 | padding-top: 0; 405 | margin-bottom: 0; 406 | } 407 | blockquote { 408 | margin-left: 0; 409 | margin-right: 0; 410 | margin-top: 0; 411 | padding-bottom: 0; 412 | padding-left: 0; 413 | padding-right: 0; 414 | padding-top: 0; 415 | margin-bottom: 0; 416 | } 417 | form { 418 | margin-left: 0; 419 | margin-right: 0; 420 | margin-top: 0; 421 | padding-bottom: 0; 422 | padding-left: 0; 423 | padding-right: 0; 424 | padding-top: 0; 425 | margin-bottom: 0; 426 | } 427 | noscript { 428 | margin-left: 0; 429 | margin-right: 0; 430 | margin-top: 0; 431 | padding-bottom: 0; 432 | padding-left: 0; 433 | padding-right: 0; 434 | padding-top: 0; 435 | margin-bottom: 0; 436 | } 437 | iframe { 438 | margin-left: 0; 439 | margin-right: 0; 440 | margin-top: 0; 441 | padding-bottom: 0; 442 | padding-left: 0; 443 | padding-right: 0; 444 | padding-top: 0; 445 | margin-bottom: 0; 446 | } 447 | hr { 448 | margin-left: 0; 449 | margin-right: 0; 450 | margin-top: 0; 451 | padding-bottom: 0; 452 | padding-left: 0; 453 | padding-right: 0; 454 | padding-top: 0; 455 | margin-bottom: 0; 456 | background: hsla(0, 0%, 0%, 0.2); 457 | border: none; 458 | height: 1px; 459 | } 460 | address { 461 | margin-left: 0; 462 | margin-right: 0; 463 | margin-top: 0; 464 | padding-bottom: 0; 465 | padding-left: 0; 466 | padding-right: 0; 467 | padding-top: 0; 468 | margin-bottom: 0; 469 | } 470 | b { 471 | font-weight: normal; 472 | } 473 | strong { 474 | font-weight: normal; 475 | } 476 | dt { 477 | font-weight: normal; 478 | } 479 | th { 480 | font-weight: normal; 481 | } 482 | li { 483 | margin-bottom: 0; 484 | } 485 | ol li { 486 | padding-left: 0; 487 | } 488 | ul li { 489 | padding-left: 0; 490 | } 491 | li > ol { 492 | } 493 | li > ul { 494 | } 495 | blockquote *:last-child { 496 | } 497 | li *:last-child { 498 | } 499 | p *:last-child { 500 | } 501 | li > p { 502 | } 503 | code { 504 | font-size: 0.85rem; 505 | line-height: 1.45rem; 506 | } 507 | kbd { 508 | font-size: 0.85rem; 509 | line-height: 1.45rem; 510 | } 511 | samp { 512 | font-size: 0.85rem; 513 | line-height: 1.45rem; 514 | } 515 | abbr { 516 | border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5); 517 | cursor: help; 518 | } 519 | acronym { 520 | border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5); 521 | cursor: help; 522 | } 523 | abbr[title] { 524 | border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5); 525 | cursor: help; 526 | text-decoration: none; 527 | } 528 | thead { 529 | text-align: left; 530 | } 531 | td, 532 | th { 533 | text-align: left; 534 | border-bottom: 1px solid hsla(0, 0%, 0%, 0.12); 535 | font-feature-settings: "tnum"; 536 | -moz-font-feature-settings: "tnum"; 537 | -ms-font-feature-settings: "tnum"; 538 | -webkit-font-feature-settings: "tnum"; 539 | padding-left: 0.96667rem; 540 | padding-right: 0.96667rem; 541 | padding-top: 0.725rem; 542 | padding-bottom: calc(0.725rem - 1px); 543 | } 544 | th:first-child, 545 | td:first-child { 546 | padding-left: 0; 547 | } 548 | th:last-child, 549 | td:last-child { 550 | padding-right: 0; 551 | } 552 | tt, 553 | code { 554 | background-color: hsla(0, 0%, 0%, 0.04); 555 | border-radius: 3px; 556 | font-family: "SFMono-Regular", Consolas, "Roboto Mono", "Droid Sans Mono", 557 | "Liberation Mono", Menlo, Courier, monospace; 558 | padding: 0; 559 | padding-top: 0.2em; 560 | padding-bottom: 0.2em; 561 | } 562 | pre code { 563 | background: none; 564 | line-height: 1.42; 565 | } 566 | code:before, 567 | code:after, 568 | tt:before, 569 | tt:after { 570 | letter-spacing: -0.2em; 571 | content: " "; 572 | } 573 | pre code:before, 574 | pre code:after, 575 | pre tt:before, 576 | pre tt:after { 577 | content: ""; 578 | } 579 | @media only screen and (max-width: 480px) { 580 | html { 581 | font-size: 100%; 582 | } 583 | } 584 | -------------------------------------------------------------------------------- /pages/framer.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Link from "next/link"; 3 | import Box from "../src"; 4 | import { motion, AnimatePresence } from "framer-motion"; 5 | 6 | const ExamplePage = () => { 7 | const [opacity, setOpacity] = React.useState(0); 8 | function onClick() { 9 | setOpacity((current) => (!current ? 1 : 0)); 10 | } 11 | return ( 12 | <> 13 | 20 | Click Me! 21 | 22 | 23 | {opacity && ( 24 | 34 | } 35 | > 36 | Hallo ich bin ein langer Text!!! 37 | 38 | )} 39 | 40 | 41 | ); 42 | }; 43 | 44 | export default ExamplePage; 45 | -------------------------------------------------------------------------------- /pages/getting-started.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Box from "../src"; 3 | 4 | const ExamplePage = () => { 5 | return ( 6 | 13 | {/* 14 | Press ESC to see the Grid 15 | 16 | 17 | 28 | 37 | Hello World! 38 | 39 | */} 40 | 41 | Hallo! 42 | {/* 53 | Stop 54 | */} 55 | {/* 66 | Wars 67 | */} 68 | 69 | 70 | ); 71 | }; 72 | 73 | export default ExamplePage; 74 | -------------------------------------------------------------------------------- /pages/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Link from "next/link"; 3 | import Box from "../src"; 4 | import SpecialBox from "../components/SpecialBox"; 5 | import { motion, AnimatePresence } from "framer-motion"; 6 | 7 | const buildThresholdArray = () => Array.from(Array(100).keys(), (i) => i / 100); 8 | 9 | const boxPadding = ["2rem 1", "2rem 1", "1"]; 10 | 11 | const ExamplePage = () => { 12 | const [opacity, setOpacity] = React.useState(0); 13 | function onIntersect(entry, observer) { 14 | // console.log("INTERSECT"); 15 | // console.log(entry.intersectionRatio); 16 | // console.log(entry); 17 | // console.log(observer); 18 | if (entry.isIntersecting) { 19 | // observer.unobserve(entry.target); 20 | } 21 | setOpacity(entry.intersectionRatio); 22 | } 23 | 24 | return ( 25 | <> 26 | setOpacity((prev) => !prev)} 35 | > 36 | Hallo 37 | 38 | setOpacity((prev) => !prev)} 47 | > 48 | {/* Getting Started */} 49 | onIntersect, [])} 54 | // onIntersect={onIntersect} 55 | marginLeft={2} 56 | marginRight={2} 57 | padding={"0 1"} 58 | > 59 | Hallo 60 | 61 | {/* 75 | 76 | 77 | Hallo! 78 | 79 | 80 | 81 | 94 | 95 | Hallo! 96 | 97 | */} 98 | 99 | 100 | ); 101 | }; 102 | 103 | export default ExamplePage; 104 | -------------------------------------------------------------------------------- /pages/intersection.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Link from "next/link"; 3 | import Box from "../src"; 4 | import { motion, AnimatePresence } from "framer-motion"; 5 | 6 | const buildThresholdArray = () => Array.from(Array(100).keys(), (i) => i / 100); 7 | 8 | const ExamplePage = () => { 9 | const [opacity, setOpacity] = React.useState(0); 10 | function onIntersect(entry, observer) { 11 | console.log("INTERSECT"); 12 | console.log(entry.intersectionRatio); 13 | // console.log(entry); 14 | // console.log(observer); 15 | if (entry.isIntersecting) { 16 | // observer.unobserve(entry.target); 17 | } 18 | setOpacity(entry.intersectionRatio); 19 | } 20 | return ( 21 | setOpacity((prev) => !prev)} 30 | > 31 | 39 | Intersection!!! 40 | 41 | {/* 42 | {opacity && ( 43 | 52 | } 53 | > 54 | Hallo ich bin ein langer Text!!! 55 | 56 | )} 57 | 58 | */} 59 | 60 | ); 61 | }; 62 | 63 | export default ExamplePage; 64 | -------------------------------------------------------------------------------- /pages/test.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { NextPage } from "next"; 3 | import { Box, useRaster } from "../src"; 4 | import SpecialBox from "../components/SpecialBox"; 5 | 6 | interface Props {} 7 | 8 | const Testpage: NextPage = (props) => { 9 | const boxRef = React.useRef(null); 10 | useEffect(() => { 11 | console.log(boxRef.current); 12 | }, []); 13 | return ( 14 | 15 | 22 | Too wide 23 | 24 | Hallo! 25 | 34 | console.log(e)} 42 | // height={["50vh", "50vh", "50vh", "100vh"]} 43 | onResize={(element) => { 44 | console.log(element.offsetWidth); 45 | }} 46 | > 47 |

Hello,

48 | {/* Hallo */} 49 |
50 | {/* */} 51 | 57 | 64 |
65 | ); 66 | }; 67 | 68 | export default Testpage; 69 | -------------------------------------------------------------------------------- /react-raster.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | } 6 | ], 7 | "settings": { 8 | "editor.defaultFormatter": "esbenp.prettier-vscode", 9 | "editor.formatOnSave": true, 10 | "search.exclude": { 11 | "**/node_modules": true, 12 | "**/dist": true 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from "rollup-plugin-typescript2"; 2 | import css from "rollup-plugin-css-only"; 3 | import commonjs from "@rollup/plugin-commonjs"; 4 | import resolve from "@rollup/plugin-node-resolve"; 5 | import external from "rollup-plugin-peer-deps-external"; 6 | 7 | import pkg from "./package.json"; 8 | 9 | export default { 10 | input: "src/index.ts", 11 | output: [ 12 | { 13 | file: pkg.main, 14 | format: "cjs", 15 | exports: "named", 16 | sourcemap: true, 17 | }, 18 | { 19 | file: pkg.module, 20 | format: "es", 21 | exports: "named", 22 | sourcemap: true, 23 | }, 24 | ], 25 | plugins: [ 26 | external(), 27 | resolve({ 28 | browser: true, 29 | }), 30 | typescript({ 31 | tsconfig: "tsconfig.rollup.json", 32 | rollupCommonJSResolveHack: true, 33 | exclude: "**/__tests__/**", 34 | clean: true, 35 | }), 36 | commonjs({ 37 | include: ["node_modules/**"], 38 | exclude: ["**/*.stories.js"], 39 | // namedExports: { 40 | // "node_modules/react/react.js": [ 41 | // "Children", 42 | // "Component", 43 | // "PropTypes", 44 | // "createElement", 45 | // ], 46 | // "node_modules/react-dom/index.js": ["render"], 47 | // }, 48 | }), 49 | css({ output: "./dist/main.css" }), 50 | ], 51 | external: ["styled-components"], 52 | }; 53 | -------------------------------------------------------------------------------- /src/Box/Container.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | interface Props { 4 | className: string; 5 | attrs?: any; 6 | tag?: string; 7 | children: React.ReactNode; 8 | component?: React.ReactElement; 9 | } 10 | 11 | const Container = React.forwardRef( 12 | ({ className, children, component, attrs = {}, tag = "div" }, ref) => { 13 | if (component) { 14 | return React.cloneElement(component, { 15 | children, 16 | className, 17 | ...attrs, 18 | }); 19 | } 20 | return React.createElement( 21 | tag, 22 | { 23 | ...attrs, 24 | className, 25 | ref, 26 | }, 27 | tag !== "img" && !attrs.dangerouslySetInnerHTML ? children : null 28 | ); 29 | } 30 | ); 31 | 32 | Container.displayName = "Container"; 33 | 34 | export default Container; 35 | -------------------------------------------------------------------------------- /src/Box/StyledBox.tsx: -------------------------------------------------------------------------------- 1 | import styled, { css } from "styled-components"; 2 | import React from "react"; 3 | import Container from "./Container"; 4 | 5 | type ValidProp = string | number; 6 | 7 | interface Props { 8 | position: ValidProp; 9 | zIndex: ValidProp; 10 | display: ValidProp; 11 | colsTotal: ValidProp; 12 | colsEffective: ValidProp; 13 | 14 | width: ValidProp; 15 | minWidth?: ValidProp; 16 | maxWidth?: ValidProp; 17 | height: ValidProp; 18 | minHeight?: ValidProp; 19 | maxHeight?: ValidProp; 20 | 21 | padding: { 22 | left: string; 23 | right: string; 24 | top: string; 25 | bottom: string; 26 | }; 27 | margin: { 28 | left: string; 29 | right: string; 30 | top: string; 31 | bottom: string; 32 | }; 33 | 34 | order: ValidProp; 35 | 36 | top: ValidProp; 37 | bottom: ValidProp; 38 | left: ValidProp; 39 | right: ValidProp; 40 | 41 | alignItems: ValidProp; 42 | alignContent: ValidProp; 43 | alignSelf: ValidProp; 44 | justifyItems: ValidProp; 45 | justifyContent: ValidProp; 46 | justifySelf: ValidProp; 47 | 48 | background: ValidProp; 49 | backgroundColor: ValidProp; 50 | backgroundImage: ValidProp; 51 | backgroundPosition: ValidProp; 52 | backgroundSize: ValidProp; 53 | backgroundAttachment: ValidProp; 54 | 55 | filter: ValidProp; 56 | backdropFilter: ValidProp; 57 | mixBlendMode: ValidProp; 58 | backgroundBlendMode: ValidProp; 59 | textShadow: ValidProp; 60 | boxShadow: ValidProp; 61 | textStroke: ValidProp; 62 | 63 | color: ValidProp; 64 | fontFamily: ValidProp; 65 | fontSize: ValidProp; 66 | fontWeight: ValidProp; 67 | fontStyle: ValidProp; 68 | textAlign: ValidProp; 69 | lineHeight: ValidProp; 70 | letterSpacing: ValidProp; 71 | textDecoration: ValidProp; 72 | hyphens: ValidProp; 73 | 74 | border: ValidProp; 75 | borderLeft: ValidProp; 76 | borderRight: ValidProp; 77 | borderTop: ValidProp; 78 | borderBottom: ValidProp; 79 | 80 | gridColumn: ValidProp; 81 | gridRow: ValidProp; 82 | gridAutoRows: ValidProp; 83 | gridTemplateRows: ValidProp; 84 | gridTemplateColumns: ValidProp; 85 | autoFlow: ValidProp; 86 | 87 | gap: { 88 | row: string; 89 | column: string; 90 | }; 91 | 92 | flexDirection: ValidProp; 93 | flexWrap: ValidProp; 94 | flexGrow: ValidProp; 95 | flexShrink: ValidProp; 96 | 97 | transition: ValidProp; 98 | animation: ValidProp; 99 | transform: ValidProp; 100 | opacity: ValidProp; 101 | willChange: ValidProp; 102 | 103 | controlColor: ValidProp; 104 | 105 | pointerEvents: ValidProp; 106 | cursor: ValidProp; 107 | 108 | overflow?: ValidProp; 109 | overflowX?: ValidProp; 110 | overflowY?: ValidProp; 111 | 112 | tag?: string; 113 | controlIsVisible: boolean; 114 | component?: React.ReactElement; 115 | className: string; 116 | styles: string; 117 | attrs: any; 118 | children: React.ReactNode; 119 | isControl: boolean; 120 | } 121 | 122 | const StyledBoxStyles = styled(Container)` 123 | box-sizing: border-box; 124 | 125 | ${(props) => css` 126 | position: ${props.position}; 127 | z-index: ${props.zIndex}; 128 | display: ${props.display}; 129 | pointer-events: ${props.pointerEvents}; 130 | cursor: ${props.cursor}; 131 | 132 | width: ${props.width}; 133 | min-width: ${props.minWidth}; 134 | max-width: ${props.maxWidth}; 135 | height: ${props.height}; 136 | min-height: ${props.minHeight}; 137 | max-height: ${props.maxHeight}; 138 | 139 | padding-left: ${props.padding.left}; 140 | padding-right: ${props.padding.right}; 141 | padding-top: ${props.padding.top}; 142 | padding-bottom: ${props.padding.bottom}; 143 | 144 | margin-left: ${props.margin.left}; 145 | margin-right: ${props.margin.right}; 146 | margin-top: ${props.margin.top}; 147 | margin-bottom: ${props.margin.bottom}; 148 | 149 | order: ${props.order}; 150 | 151 | top: ${props.top}; 152 | bottom: ${props.bottom}; 153 | left: ${props.left}; 154 | right: ${props.right}; 155 | 156 | align-items: ${props.alignItems}; 157 | align-content: ${props.alignContent}; 158 | align-self: ${props.alignSelf}; 159 | justify-content: ${props.justifyContent}; 160 | justify-items: ${props.justifyItems}; 161 | justify-self: ${props.justifySelf}; 162 | 163 | flex-direction: ${props.flexDirection}; 164 | flex-wrap: ${props.flexWrap}; 165 | flex-shrink: ${props.flexShrink}; 166 | flex-grow: ${props.flexGrow}; 167 | 168 | background: ${props.background}; 169 | background-color: ${props.backgroundColor}; 170 | background-image: ${props.backgroundImage}; 171 | background-position: ${props.backgroundPosition}; 172 | background-size: ${props.backgroundSize}; 173 | background-attachment: ${props.backgroundAttachment}; 174 | 175 | filter: ${props.filter}; 176 | backdrop-filter: ${props.backdropFilter}; 177 | mix-blend-mode: ${props.mixBlendMode}; 178 | background-blend-mode: ${props.backgroundBlendMode}; 179 | text-shadow: ${props.textShadow}; 180 | box-shadow: ${props.boxShadow}; 181 | -webkit-text-stroke: ${props.textStroke}; 182 | text-stroke: ${props.textStroke}; 183 | 184 | border: ${props.border}; 185 | border-left: ${props.borderLeft}; 186 | border-right: ${props.borderRight}; 187 | border-top: ${props.borderTop}; 188 | border-bottom: ${props.borderBottom}; 189 | 190 | font-family: ${props.fontFamily}; 191 | font-size: ${props.fontSize}; 192 | font-weight: ${props.fontWeight}; 193 | font-style: ${props.fontStyle}; 194 | text-align: ${props.textAlign}; 195 | color: ${props.color}; 196 | line-height: ${props.lineHeight}; 197 | letter-spacing: ${props.letterSpacing}; 198 | text-decoration: ${props.textDecoration}; 199 | hyphens: ${props.hyphens}; 200 | 201 | transition: ${props.transition}; 202 | transform: ${props.transform}; 203 | animation: ${props.animation}; 204 | opacity: ${props.opacity}; 205 | will-change: ${props.willChange}; 206 | 207 | overflow: ${props.overflow}; 208 | overflow-x: ${props.overflowX}; 209 | overflow-y: ${props.overflowY}; 210 | 211 | ${props.styles ? props.styles : ""} 212 | `} 213 | 214 | ${(props) => 215 | props.display === "grid" && 216 | css` 217 | grid-template-columns: repeat(${props.colsEffective}, 1fr); 218 | 219 | grid-auto-rows: ${props.gridAutoRows}; 220 | grid-template-rows: ${props.gridTemplateRows}; 221 | grid-template-columns: ${props.gridTemplateColumns}; 222 | grid-auto-flow: ${props.autoFlow}; 223 | 224 | grid-gap: ${props.gap.row} ${props.gap.column}; 225 | 226 | ${props.isControl && 227 | (props.gap.column === "0px" ? "grid-column-gap: 1px;" : "")} 228 | `} 229 | 230 | ${(props) => 231 | props.display === "flex" && 232 | css` 233 | gap: ${props.gap.row} ${props.gap.column}; 234 | `} 235 | 236 | ${(props) => css` 237 | grid-column: auto / span ${props.colsTotal}; 238 | grid-column: ${props.gridColumn}; 239 | grid-row: ${props.gridRow}; 240 | `} 241 | 242 | ${(props) => 243 | props.tag === "img" && 244 | props.controlIsVisible && 245 | css` 246 | box-shadow: 0 0 999em ${props.controlColor} inset; 247 | `} 248 | `; 249 | const StyledBox = React.forwardRef((props, ref) => { 250 | return ; 251 | }); 252 | 253 | StyledBox.displayName = "StyledBox"; 254 | 255 | export default React.memo(StyledBox); 256 | -------------------------------------------------------------------------------- /src/Box/hooks/useBreakpoint.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import debounce from "../utils/debounce"; 3 | import useIsomorphicLayoutEffect from "../utils/useIsomorphicLayoutEffect"; 4 | 5 | export default function useBreakpoint( 6 | breakpoints: number[], 7 | contextBreakpoint?: number, 8 | propsBreakpoints?: number[], 9 | propsColspan?: number[] 10 | ): number { 11 | const [currentBp, setCurrentBp] = React.useState(contextBreakpoint); 12 | 13 | useIsomorphicLayoutEffect(() => { 14 | function onResize() { 15 | const w = window.innerWidth; 16 | const bp = breakpoints.findIndex((breakpoint) => breakpoint > w) - 1; 17 | setCurrentBp(bp === -2 ? breakpoints.length - 1 : bp); 18 | } 19 | if (propsBreakpoints || propsColspan) { 20 | onResize(); 21 | const dOnResize = debounce(onResize, 100); 22 | window.addEventListener("resize", dOnResize); 23 | return () => window.removeEventListener("resize", dOnResize); 24 | } 25 | }, []); 26 | 27 | React.useEffect(() => { 28 | if (propsBreakpoints || propsColspan) return; 29 | setCurrentBp(contextBreakpoint); 30 | }, [contextBreakpoint, propsBreakpoints, propsColspan]); 31 | 32 | return currentBp; 33 | } 34 | -------------------------------------------------------------------------------- /src/Box/hooks/useBreakpoints.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function useBreakpoints( 4 | propsBreakpoints?: number[], 5 | contextBreakpoints?: number[] 6 | ): number[] { 7 | const [breakpoints] = React.useState( 8 | propsBreakpoints || contextBreakpoints || [0, 432, 768, 1024, 1200, 1400] 9 | ); 10 | return breakpoints; 11 | } 12 | -------------------------------------------------------------------------------- /src/Box/hooks/useClassName.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | 3 | interface Props { 4 | currentBreakpoint: { 5 | index: number; 6 | value: number; 7 | }; 8 | className?: string; 9 | } 10 | 11 | export default function useClassName({ 12 | className, 13 | currentBreakpoint, 14 | }: Props): string { 15 | const classNameComplete = useMemo(() => { 16 | const classArray = [ 17 | "Grid", 18 | `bp-${currentBreakpoint.index}`, 19 | `bp-${currentBreakpoint.value}`, 20 | ]; 21 | if (className) classArray.push(className); 22 | return classArray.join(" "); 23 | }, [className, currentBreakpoint.index]); 24 | return classNameComplete; 25 | } 26 | -------------------------------------------------------------------------------- /src/Box/hooks/useColsEffective.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import spacingObject from "./useSpacing/spacingObject"; 3 | 4 | export default function useColsEffective( 5 | colspan: number, 6 | margin: spacingObject, 7 | padding: spacingObject, 8 | cols?: number 9 | ): number { 10 | return React.useMemo(() => { 11 | const paddingLeft = typeof padding.left === "number" ? padding.left : 0; 12 | const paddingRight = typeof padding.right === "number" ? padding.right : 0; 13 | const marginLeft = typeof margin.left === "number" ? margin.left : 0; 14 | const marginRight = typeof margin.right === "number" ? margin.right : 0; 15 | 16 | if (typeof cols === "number") return cols - paddingLeft - paddingRight; 17 | return colspan - paddingLeft - paddingRight - marginLeft - marginRight; 18 | }, [cols, colspan, padding.left, padding.right, margin.left, margin.right]); 19 | } 20 | -------------------------------------------------------------------------------- /src/Box/hooks/useColsTotal.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import SpacingObject from "./useSpacing/spacingObject"; 3 | 4 | export default function useColsTotal( 5 | colspanTotal: number, 6 | margin: SpacingObject, 7 | cols?: number 8 | ): number { 9 | return React.useMemo(() => { 10 | const left = typeof margin.left === "number" ? margin.left : 0; 11 | const right = typeof margin.right === "number" ? margin.right : 0; 12 | 13 | if (typeof cols === "number") { 14 | return cols + left + right; 15 | } 16 | return colspanTotal; 17 | }, [cols, colspanTotal, margin.left, margin.right]); 18 | } 19 | -------------------------------------------------------------------------------- /src/Box/hooks/useCombinedRefs.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function useCombinedRefs( 4 | ref: React.ForwardedRef 5 | ) { 6 | const targetRef = React.useRef(); 7 | 8 | React.useEffect(() => { 9 | if (!ref) return; 10 | if (typeof ref === "function") { 11 | ref(targetRef.current); 12 | } else { 13 | ref.current = targetRef.current; 14 | } 15 | }, [ref]); 16 | 17 | return targetRef; 18 | } 19 | -------------------------------------------------------------------------------- /src/Box/hooks/useControl.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const useControl = (control?: boolean, controlIsVisible?: boolean): boolean => { 4 | const [isVisible, setIsVisible] = React.useState(false); 5 | React.useEffect(() => { 6 | setIsVisible(!!controlIsVisible); 7 | }, [controlIsVisible]); 8 | 9 | React.useEffect(() => { 10 | function onKeyup(event) { 11 | if (event.keyCode !== 27) return; 12 | setIsVisible((prevState) => !prevState); 13 | } 14 | if (control) { 15 | document.addEventListener("keyup", onKeyup); 16 | return () => document.removeEventListener("keyup", onKeyup); 17 | } 18 | }, []); 19 | 20 | return isVisible; 21 | }; 22 | 23 | export default useControl; 24 | -------------------------------------------------------------------------------- /src/Box/hooks/useDisplay.ts: -------------------------------------------------------------------------------- 1 | import useProps from "./useProp"; 2 | 3 | export default function useDisplay( 4 | breakpoint: number, 5 | display: string | string[], 6 | hasChildBoxes: boolean 7 | ): string { 8 | const displayNormalized = useProps(breakpoint, display); 9 | return (displayNormalized as string) || (hasChildBoxes ? "grid" : "block"); 10 | } 11 | -------------------------------------------------------------------------------- /src/Box/hooks/useGap/getGap.ts: -------------------------------------------------------------------------------- 1 | interface Gap { 2 | row?: string; 3 | column?: string; 4 | } 5 | 6 | interface Props { 7 | contextGap?: { 8 | row: string; 9 | column: string; 10 | }; 11 | gap: Gap; 12 | gridGap: Gap; 13 | rowGap?: string; 14 | columnGap?: string; 15 | gridColumnGap?: string; 16 | gridRowGap?: string; 17 | } 18 | 19 | export default function getGap({ 20 | contextGap, 21 | gap, 22 | gridGap, 23 | rowGap, 24 | columnGap, 25 | gridColumnGap, 26 | gridRowGap, 27 | }: Props): { row: string; column: string } { 28 | if ( 29 | !gap.row && 30 | !gap.column && 31 | !gridGap.row && 32 | !gridGap.column && 33 | !rowGap && 34 | !columnGap && 35 | !gridColumnGap && 36 | !gridRowGap 37 | ) { 38 | return contextGap || { row: "0px", column: "0px" }; 39 | } 40 | return { 41 | row: gridRowGap || rowGap || gap.row || gridGap.row || "0px", 42 | column: columnGap || gridColumnGap || gap.column || gridGap.column || "0px", 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /src/Box/hooks/useGap/index.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import useProp from "../useProp"; 3 | import useGapShort from "./useGapShort"; 4 | import getGap from "./getGap"; 5 | 6 | interface Props { 7 | contextGap?: { 8 | row: string; 9 | column: string; 10 | }; 11 | propsGap?: string | string[]; 12 | gridGap?: string | string[]; 13 | rowGap?: string | string[]; 14 | columnGap?: string | string[]; 15 | gridColumnGap?: string | string[]; 16 | gridRowGap?: string | string[]; 17 | breakpoint: number; 18 | } 19 | 20 | const useGap = ( 21 | props: Props 22 | ): { 23 | row: string; 24 | column: string; 25 | } => { 26 | const gap = useGapShort(props.breakpoint, props.propsGap); 27 | const gridGap = useGapShort(props.breakpoint, props.gridGap); 28 | const rowGap = useProp(props.breakpoint, props.rowGap); 29 | const columnGap = useProp(props.breakpoint, props.columnGap); 30 | const gridColumnGap = useProp(props.breakpoint, props.gridColumnGap); 31 | const gridRowGap = useProp(props.breakpoint, props.gridRowGap); 32 | 33 | return React.useMemo( 34 | () => 35 | getGap({ 36 | contextGap: props.contextGap, 37 | gap, 38 | gridGap, 39 | rowGap: rowGap as string, 40 | columnGap: columnGap as string, 41 | gridColumnGap: gridColumnGap as string, 42 | gridRowGap: gridRowGap as string, 43 | }), 44 | [ 45 | props.contextGap, 46 | gap, 47 | gridGap, 48 | rowGap, 49 | columnGap, 50 | gridColumnGap, 51 | gridRowGap, 52 | ] 53 | ); 54 | }; 55 | 56 | export default useGap; 57 | -------------------------------------------------------------------------------- /src/Box/hooks/useGap/useGapShort.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import useProp from "../useProp"; 3 | 4 | function getGapObject(gap?: string): { row?: string; column?: string } { 5 | if (!gap) return { row: null, column: null }; 6 | const [row, column] = gap.split(" "); 7 | return { row, column }; 8 | } 9 | 10 | export default function useGapShort( 11 | breakpoint: number, 12 | gap?: string | string[] 13 | ): { row?: string; column?: string } { 14 | const gapNormalized = useProp(breakpoint, gap); 15 | const [gapObject, setGapObject] = React.useState( 16 | getGapObject(gapNormalized as string) 17 | ); 18 | React.useEffect(() => { 19 | setGapObject(getGapObject(gapNormalized as string)); 20 | }, [gapNormalized]); 21 | 22 | return gapObject; 23 | } 24 | -------------------------------------------------------------------------------- /src/Box/hooks/useIntersect.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from "react"; 2 | 3 | interface Props { 4 | ref?: React.MutableRefObject; 5 | root?: null | HTMLElement; 6 | rootMargin?: string; 7 | threshold?: number | number[]; 8 | onIntersect?: ( 9 | IntersectionObserverEntry: IntersectionObserverEntry, 10 | observer: IntersectionObserver 11 | ) => void; 12 | } 13 | 14 | export default function onIntersect({ 15 | ref, 16 | root = null, 17 | rootMargin, 18 | threshold = 0, 19 | onIntersect, 20 | }: Props) { 21 | const observer = useRef(null); 22 | 23 | useEffect(() => { 24 | if (typeof onIntersect !== "function") return; 25 | 26 | observer.current = new IntersectionObserver( 27 | ([entry], observer) => onIntersect(entry, observer), 28 | { 29 | root, 30 | rootMargin, 31 | threshold, 32 | } 33 | ); 34 | 35 | if (ref.current && observer.current) observer.current.observe(ref.current); 36 | return () => observer.current && observer.current.disconnect(); 37 | }, []); 38 | } 39 | -------------------------------------------------------------------------------- /src/Box/hooks/useNormalize.ts: -------------------------------------------------------------------------------- 1 | import useColsTotal from "./useColsTotal"; 2 | import useColsEffective from "./useColsEffective"; 3 | import useProp from "./useProp"; 4 | import useSpacing from "./useSpacing"; 5 | import useBreakpoint from "./useBreakpoint"; 6 | import useDisplay from "./useDisplay"; 7 | import useGap from "./useGap"; 8 | import useBreakpoints from "./useBreakpoints"; 9 | import useSpacingCSS from "./useSpacingCSS"; 10 | 11 | import { ContextProps } from "../../context"; 12 | 13 | export default function useNormalize( 14 | props, 15 | context: ContextProps, 16 | hasChildBoxes: boolean 17 | ) { 18 | const breakpoints = useBreakpoints(props.breakpoints, context.breakpoints); 19 | const breakpoint = useBreakpoint( 20 | breakpoints, 21 | context.breakpoint, 22 | props.breakpoints, 23 | props.colspan 24 | ); 25 | const display = useDisplay(breakpoint, props.display, hasChildBoxes); 26 | const gap = useGap({ 27 | contextGap: context.gap, 28 | propsGap: props.gap, 29 | gridGap: props.gridGap, 30 | rowGap: props.rowGap, 31 | columnGap: props.columnGap, 32 | gridColumnGap: props.gridColumnGap, 33 | gridRowGap: props.gridRowGap, 34 | breakpoint, 35 | }); 36 | const marginRaw = useSpacing( 37 | breakpoint, 38 | props.margin, 39 | props.marginLeft, 40 | props.marginRight, 41 | props.marginTop, 42 | props.marginBottom 43 | ); 44 | const paddingRaw = useSpacing( 45 | breakpoint, 46 | props.padding, 47 | props.paddingLeft, 48 | props.paddingRight, 49 | props.paddingTop, 50 | props.paddingBottom 51 | ); 52 | 53 | const colspanTotal = useProp( 54 | breakpoint, 55 | props.colspan || context.colspan || 1 56 | ); 57 | const cols = useProp(breakpoint, props.cols); 58 | 59 | // gets applied to StyledBox 60 | const colsEffective = useColsEffective( 61 | colspanTotal as number, 62 | marginRaw, 63 | paddingRaw, 64 | cols as number 65 | ); 66 | const colsTotal = useColsTotal( 67 | colspanTotal as number, 68 | marginRaw, 69 | cols as number 70 | ); 71 | 72 | const margin = useSpacingCSS(gap, colsTotal as number, marginRaw); 73 | const padding = useSpacingCSS(gap, colsTotal as number, paddingRaw); 74 | 75 | const styles = useProp(breakpoint, props.styles); 76 | 77 | const width = useProp(breakpoint, props.width); 78 | const minWidth = useProp(breakpoint, props.minWidth); 79 | const maxWidth = useProp(breakpoint, props.maxWidth); 80 | const height = useProp(breakpoint, props.height); 81 | const minHeight = useProp(breakpoint, props.minHeight); 82 | const maxHeight = useProp(breakpoint, props.maxHeight); 83 | const position = useProp(breakpoint, props.position, "relative"); 84 | const zIndex = useProp(breakpoint, props.zIndex); 85 | 86 | const left = useProp(breakpoint, props.left); 87 | const right = useProp(breakpoint, props.right); 88 | const top = useProp(breakpoint, props.top); 89 | const bottom = useProp(breakpoint, props.bottom); 90 | 91 | const pointerEvents = useProp(breakpoint, props.pointerEvents); 92 | const cursor = useProp(breakpoint, props.cursor); 93 | 94 | const gridTemplateRows = useProp(breakpoint, props.gridTemplateRows); 95 | const gridColumn = useProp(breakpoint, props.gridColumn); 96 | const gridRow = useProp(breakpoint, props.gridRow); 97 | const gridAutoRows = useProp(breakpoint, props.gridAutoRows); 98 | const gridTemplateColumns = useProp(breakpoint, props.gridTemplateColumns); 99 | const autoFlow = useProp(breakpoint, props.autoFlow); 100 | 101 | const order = useProp(breakpoint, props.order); 102 | const alignItems = useProp(breakpoint, props.alignItems); 103 | const alignContent = useProp(breakpoint, props.alignContent); 104 | const alignSelf = useProp(breakpoint, props.alignSelf); 105 | const justifyContent = useProp(breakpoint, props.justifyContent); 106 | const justifyItems = useProp(breakpoint, props.justifyItems); 107 | const justifySelf = useProp(breakpoint, props.justifySelf); 108 | 109 | const flexDirection = useProp(breakpoint, props.flexDirection); 110 | const flexWrap = useProp(breakpoint, props.flexWrap); 111 | const flexShrink = useProp(breakpoint, props.flexShrink); 112 | const flexGrow = useProp(breakpoint, props.flexGrow); 113 | 114 | const border = useProp(breakpoint, props.border); 115 | const borderLeft = useProp(breakpoint, props.borderLeft); 116 | const borderRight = useProp(breakpoint, props.borderRight); 117 | const borderTop = useProp(breakpoint, props.borderTop); 118 | const borderBottom = useProp(breakpoint, props.borderBottom); 119 | 120 | const background = useProp(breakpoint, props.background); 121 | const backgroundColor = useProp(breakpoint, props.backgroundColor); 122 | const backgroundImage = useProp(breakpoint, props.backgroundImage); 123 | const backgroundPosition = useProp(breakpoint, props.backgroundPosition); 124 | const backgroundAttachment = useProp(breakpoint, props.backgroundAttachment); 125 | const backgroundSize = useProp(breakpoint, props.backgroundSize); 126 | 127 | const filter = useProp(breakpoint, props.filter); 128 | const backdropFilter = useProp(breakpoint, props.backdropFilter); 129 | const mixBlendMode = useProp(breakpoint, props.mixBlendMode); 130 | const backgroundBlendMode = useProp(breakpoint, props.backgroundBlendMode); 131 | const textShadow = useProp(breakpoint, props.textShadow); 132 | const boxShadow = useProp(breakpoint, props.boxShadow); 133 | const textStroke = useProp(breakpoint, props.textStroke); 134 | 135 | const fontFamily = useProp(breakpoint, props.fontFamily); 136 | const fontSize = useProp(breakpoint, props.fontSize); 137 | const fontWeight = useProp(breakpoint, props.fontWeight); 138 | const fontStyle = useProp(breakpoint, props.fontStyle); 139 | const textAlign = useProp(breakpoint, props.textAlign); 140 | const color = useProp(breakpoint, props.color); 141 | const lineHeight = useProp(breakpoint, props.lineHeight); 142 | const letterSpacing = useProp(breakpoint, props.letterSpacing); 143 | const textDecoration = useProp(breakpoint, props.textDecoration); 144 | const hyphens = useProp(breakpoint, props.hyphens); 145 | 146 | const transform = useProp(breakpoint, props.transform); 147 | const transition = useProp(breakpoint, props.transition); 148 | const animation = useProp(breakpoint, props.animation); 149 | const opacity = useProp(breakpoint, props.opacity); 150 | const willChange = useProp(breakpoint, props.willChange); 151 | 152 | const overflow = useProp(breakpoint, props.overflow); 153 | const overflowX = useProp(breakpoint, props.overflowX); 154 | const overflowY = useProp(breakpoint, props.overflowY); 155 | 156 | const rootMargin = useProp(breakpoint, props.rootMargin); 157 | 158 | return { 159 | breakpoints, 160 | breakpoint, 161 | colsTotal, 162 | colspanTotal, 163 | colsEffective, 164 | margin, 165 | padding, 166 | marginRaw, 167 | paddingRaw, 168 | display, 169 | gap, 170 | controlColor: props.controlColor || context.controlColor, 171 | 172 | styles, 173 | 174 | width, 175 | minWidth, 176 | maxWidth, 177 | height, 178 | minHeight, 179 | maxHeight, 180 | position, 181 | zIndex, 182 | 183 | left, 184 | right, 185 | top, 186 | bottom, 187 | 188 | pointerEvents, 189 | cursor, 190 | 191 | gridTemplateRows, 192 | gridColumn, 193 | gridRow, 194 | gridAutoRows, 195 | gridTemplateColumns, 196 | autoFlow, 197 | 198 | order, 199 | alignItems, 200 | alignContent, 201 | alignSelf, 202 | justifyContent, 203 | justifyItems, 204 | justifySelf, 205 | 206 | flexDirection, 207 | flexWrap, 208 | flexShrink, 209 | flexGrow, 210 | 211 | border, 212 | borderLeft, 213 | borderRight, 214 | borderTop, 215 | borderBottom, 216 | 217 | background, 218 | backgroundColor, 219 | backgroundImage, 220 | backgroundPosition, 221 | backgroundAttachment, 222 | backgroundSize, 223 | 224 | filter, 225 | backdropFilter, 226 | mixBlendMode, 227 | backgroundBlendMode, 228 | textShadow, 229 | boxShadow, 230 | textStroke, 231 | 232 | fontFamily, 233 | fontSize, 234 | fontWeight, 235 | fontStyle, 236 | textAlign, 237 | color, 238 | lineHeight, 239 | letterSpacing, 240 | textDecoration, 241 | hyphens, 242 | 243 | transform, 244 | transition, 245 | animation, 246 | opacity, 247 | willChange, 248 | 249 | overflow, 250 | overflowX, 251 | overflowY, 252 | 253 | rootMargin, 254 | }; 255 | } 256 | -------------------------------------------------------------------------------- /src/Box/hooks/useProp.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | type Prop = number | string | (number | string)[]; 4 | type ValidProp = number | string | undefined; 5 | 6 | function convertStringToNumber(prop: ValidProp): ValidProp { 7 | if (typeof prop !== "string") return prop; 8 | const parsed = +prop; 9 | if (Object.is(NaN, parsed)) return prop; 10 | return parsed; 11 | } 12 | 13 | function checkForStringNotation(prop: string | number, breakpoint: number) { 14 | if (typeof prop !== "string") return prop; 15 | if (prop.includes(" | ")) { 16 | const propArray = prop.split(" | "); 17 | return normalizePropArray(propArray, breakpoint); 18 | } 19 | return prop; 20 | } 21 | 22 | function normalizePropArray(prop: (string | number)[], breakpoint: number) { 23 | if (breakpoint < prop.length) return prop[breakpoint]; 24 | return prop[prop.length - 1]; 25 | } 26 | 27 | function getProp(prop: Prop, breakpoint: number): ValidProp { 28 | if (!Array.isArray(prop)) { 29 | return checkForStringNotation(prop, breakpoint); 30 | } 31 | return normalizePropArray(prop, breakpoint); 32 | } 33 | 34 | function normalizeProp( 35 | breakpoint: number, 36 | prop?: Prop, 37 | defaultValue?: ValidProp 38 | ): ValidProp { 39 | if (typeof prop === "undefined" || prop === null) { 40 | return defaultValue; 41 | } 42 | return convertStringToNumber(getProp(prop, breakpoint)); 43 | } 44 | 45 | export default function useProp( 46 | breakpoint: number, 47 | prop?: Prop, 48 | defaultValue?: ValidProp 49 | ): ValidProp { 50 | return React.useMemo( 51 | () => normalizeProp(breakpoint, prop, defaultValue), 52 | [breakpoint, prop, defaultValue] 53 | ); 54 | } 55 | -------------------------------------------------------------------------------- /src/Box/hooks/useResizeObserver.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import debounce from "../utils/debounce"; 3 | 4 | export default function useResizeObserver( 5 | ref: React.RefObject, 6 | onResize: (element: HTMLElement) => void 7 | ) { 8 | React.useEffect(() => { 9 | if (!ref.current || !onResize) return; 10 | 11 | const dOnResize = debounce(() => { 12 | if (onResize && ref.current) onResize(ref.current); 13 | }, 150); 14 | 15 | const observer = new ResizeObserver(dOnResize); 16 | 17 | observer.observe(ref.current); 18 | 19 | return () => { 20 | if (ref.current) observer.unobserve(ref.current); 21 | }; 22 | }, [ref.current]); 23 | } 24 | -------------------------------------------------------------------------------- /src/Box/hooks/useSpacing/convertIfNumber.ts: -------------------------------------------------------------------------------- 1 | export default function convertIfNumber(string: string): string | number { 2 | const parsed = +string; 3 | if (Object.is(NaN, parsed)) return string; 4 | return parsed; 5 | } 6 | -------------------------------------------------------------------------------- /src/Box/hooks/useSpacing/index.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import useProp from "../useProp"; 3 | import useSpacingShort from "./useSpacingShort"; 4 | 5 | export default function useSpacing( 6 | breakpoint: number, 7 | short?: string | string[], 8 | left?: string | number | (string | number)[], 9 | right?: string | number | (string | number)[], 10 | top?: string | number | (string | number)[], 11 | bottom?: string | number | (string | number)[] 12 | ): { 13 | top: string | number; 14 | bottom: string | number; 15 | left: string | number; 16 | right: string | number; 17 | } { 18 | const shortNormalized = useSpacingShort(breakpoint, short); 19 | const leftNormalized = useProp(breakpoint, left); 20 | const rightNormalized = useProp(breakpoint, right); 21 | const topNormalized = useProp(breakpoint, top); 22 | const bottomNormalized = useProp(breakpoint, bottom); 23 | 24 | return React.useMemo( 25 | () => ({ 26 | left: (leftNormalized || shortNormalized.left) as string | number, 27 | right: (rightNormalized || shortNormalized.right) as string | number, 28 | top: (topNormalized || shortNormalized.top) as string | number, 29 | bottom: (bottomNormalized || shortNormalized.bottom) as string | number, 30 | }), 31 | [ 32 | shortNormalized, 33 | leftNormalized, 34 | rightNormalized, 35 | topNormalized, 36 | bottomNormalized, 37 | ] 38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /src/Box/hooks/useSpacing/spacingObject.ts: -------------------------------------------------------------------------------- 1 | export default interface spacingObject { 2 | top?: number | string; 3 | right?: number | string; 4 | bottom?: number | string; 5 | left?: number | string; 6 | } 7 | -------------------------------------------------------------------------------- /src/Box/hooks/useSpacing/useSpacingShort.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import useProp from "../useProp"; 3 | import SpacingObject from "./spacingObject"; 4 | import convertIfNumber from "./convertIfNumber"; 5 | 6 | function getShortArray(spacing: string | number): (string | number)[] { 7 | if (typeof spacing === "number") { 8 | return [spacing]; 9 | } 10 | return spacing.split(" ").map((string) => convertIfNumber(string)); 11 | } 12 | 13 | function getShortObject(spacing?: string): SpacingObject { 14 | if (typeof spacing === "undefined" || spacing === "null" || spacing === "") { 15 | return { top: null, bottom: null, left: null, right: null }; 16 | } 17 | const shortArray = getShortArray(spacing); 18 | 19 | switch (shortArray.length) { 20 | case 1: 21 | return { 22 | top: shortArray[0], 23 | right: shortArray[0], 24 | bottom: shortArray[0], 25 | left: shortArray[0], 26 | }; 27 | case 2: 28 | return { 29 | top: shortArray[0], 30 | right: shortArray[1], 31 | bottom: shortArray[0], 32 | left: shortArray[1], 33 | }; 34 | case 3: 35 | return { 36 | top: shortArray[0], 37 | right: shortArray[1], 38 | bottom: shortArray[2], 39 | left: shortArray[1], 40 | }; 41 | default: 42 | return { 43 | top: shortArray[0], 44 | right: shortArray[1], 45 | bottom: shortArray[2], 46 | left: shortArray[3], 47 | }; 48 | } 49 | } 50 | 51 | export default function useSpacingShort( 52 | breakpoint: number, 53 | spacing?: string | number | (string | number)[] 54 | ): SpacingObject { 55 | const spacingNormalized = useProp(breakpoint, spacing); 56 | const spacingObject = React.useMemo( 57 | () => getShortObject(spacingNormalized as string), 58 | [breakpoint, spacing] 59 | ); 60 | return spacingObject; 61 | } 62 | -------------------------------------------------------------------------------- /src/Box/hooks/useSpacingCSS.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import SpacingObject from "./useSpacing/spacingObject"; 3 | 4 | function useSpacingValue( 5 | gap: string, 6 | colspan: number, 7 | prop: string | number, 8 | counterProp: string | number 9 | ) { 10 | return React.useMemo(() => { 11 | switch (typeof prop) { 12 | case "number": 13 | const counter = counterProp === "string" ? counterProp : "0px"; 14 | return `calc(((100% + ${gap} - ${counter}) / ${colspan}) * ${prop})`; 15 | default: 16 | return prop; 17 | } 18 | }, [gap, colspan, prop, counterProp]); 19 | } 20 | 21 | export default function useSpacingCSS( 22 | gap: { row: string; column: string }, 23 | colspan: number, 24 | spacing: SpacingObject 25 | ) { 26 | const left = useSpacingValue( 27 | gap.column, 28 | colspan, 29 | spacing.left, 30 | spacing.right 31 | ); 32 | const right = useSpacingValue( 33 | gap.column, 34 | colspan, 35 | spacing.right, 36 | spacing.left 37 | ); 38 | const top = useSpacingValue(gap.row, colspan, spacing.top, spacing.bottom); 39 | const bottom = useSpacingValue(gap.row, colspan, spacing.bottom, spacing.top); 40 | return { left, right, top, bottom }; 41 | } 42 | -------------------------------------------------------------------------------- /src/Box/hooks/useUndefinedProps.ts: -------------------------------------------------------------------------------- 1 | export default function useUndefinedProps(props) { 2 | const { 3 | display, 4 | breakpoints, 5 | width, 6 | minWidth, 7 | maxWidth, 8 | height, 9 | minHeight, 10 | maxHeight, 11 | colspan, 12 | cols, 13 | margin, 14 | marginLeft, 15 | marginRight, 16 | marginTop, 17 | marginBottom, 18 | padding, 19 | paddingLeft, 20 | paddingRight, 21 | paddingTop, 22 | paddingBottom, 23 | 24 | gap, 25 | gridRowGap, 26 | rowGap, 27 | gridColumnGap, 28 | columnGap, 29 | 30 | gridTemplateRows, 31 | gridAutoRows, 32 | gridTemplateColumns, 33 | gridRow, 34 | gridColumn, 35 | autoFlow, 36 | component, 37 | innerHTML, 38 | 39 | cursor, 40 | pointerEvents, 41 | 42 | onResize, 43 | onIntersect, 44 | root, 45 | rootMargin, 46 | threshold, 47 | 48 | styles, 49 | as, 50 | control, 51 | controlColor, 52 | order, 53 | position, 54 | zIndex, 55 | top, 56 | bottom, 57 | left, 58 | right, 59 | alignItems, 60 | alignContent, 61 | alignSelf, 62 | justifyContent, 63 | justifyItems, 64 | justifySelf, 65 | flexDirection, 66 | flexWrap, 67 | flexShrink, 68 | flexGrow, 69 | background, 70 | backgroundColor, 71 | backgroundImage, 72 | backgroundPosition, 73 | backgroundSize, 74 | backgroundAttachment, 75 | 76 | filter, 77 | backdropFilter, 78 | mixBlendMode, 79 | backgroundBlendMode, 80 | textShadow, 81 | boxShadow, 82 | textStroke, 83 | 84 | border, 85 | borderLeft, 86 | borderRight, 87 | borderTop, 88 | borderBottom, 89 | fontFamily, 90 | fontSize, 91 | fontWeight, 92 | fontStyle, 93 | textAlign, 94 | color, 95 | lineHeight, 96 | letterSpacing, 97 | textDecoration, 98 | hyphens, 99 | 100 | overflow, 101 | overflowX, 102 | overflowY, 103 | 104 | transition, 105 | animation, 106 | opacity, 107 | transform, 108 | willChange, 109 | 110 | className, 111 | children, 112 | isControl, 113 | ref, 114 | ...rest 115 | } = props; 116 | return rest; 117 | } 118 | -------------------------------------------------------------------------------- /src/Box/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | 3 | import useCombinedRefs from "./hooks/useCombinedRefs"; 4 | import useResizeObserver from "./hooks/useResizeObserver"; 5 | import useNormalize from "./hooks/useNormalize"; 6 | import useControl from "./hooks/useControl"; 7 | import useUndefinedProps from "./hooks/useUndefinedProps"; 8 | import useIntersect from "./hooks/useIntersect"; 9 | 10 | import Context from "../context"; 11 | import StyledBox from "./StyledBox"; 12 | import Control from "../Control"; 13 | import { Props } from "./props"; 14 | 15 | const Box = React.forwardRef((props, ref) => { 16 | const context = useContext(Context); 17 | 18 | const [hasChildBoxes, registerChildBox] = React.useState(false); 19 | React.useEffect(() => { 20 | if (typeof context.registerChildBox === "function") { 21 | context.registerChildBox(); 22 | } 23 | }, []); 24 | 25 | const propsNormalized = useNormalize(props, context, hasChildBoxes); 26 | 27 | const controlIsVisible = useControl(props.control, context.controlIsVisible); 28 | const boxRef = useCombinedRefs(ref); 29 | const undefinedProps = useUndefinedProps(props); 30 | 31 | const breakpoint = { 32 | index: propsNormalized.breakpoint + 1, 33 | value: propsNormalized.breakpoints[propsNormalized.breakpoint], 34 | }; 35 | 36 | const defaultClass = `Box bp-${breakpoint.value} bp-${breakpoint.index}`; 37 | 38 | useResizeObserver(boxRef, props.onResize); 39 | useIntersect({ 40 | ref: boxRef, 41 | root: props.root, 42 | rootMargin: propsNormalized.rootMargin as string, 43 | threshold: props.threshold, 44 | onIntersect: props.onIntersect, 45 | }); 46 | 47 | return ( 48 | 68 | {controlIsVisible && ( 69 | 70 | )} 71 | registerChildBox(true), 81 | }} 82 | > 83 | {props.children} 84 | 85 | 86 | ); 87 | }); 88 | 89 | Box.displayName = "Box"; 90 | 91 | export default React.memo(Box); 92 | -------------------------------------------------------------------------------- /src/Box/props.ts: -------------------------------------------------------------------------------- 1 | import React, { HTMLProps } from "react"; 2 | 3 | export interface Props 4 | extends Omit, "cols" | "height" | "width" | "color"> { 5 | //////////////////////////////////////// 6 | // Core 7 | display?: string | string[]; 8 | breakpoints?: number[]; 9 | width?: string | string[]; 10 | minWidth?: string | string[]; 11 | maxWidth?: string | string[]; 12 | height?: string | string[]; 13 | minHeight?: string | string[]; 14 | maxHeight?: string | string[]; 15 | colspan?: string | number | (string | number)[]; 16 | cols?: string | number | (string | number)[]; 17 | 18 | margin?: string | number | (string | number)[]; 19 | marginLeft?: string | number | (string | number)[]; 20 | marginRight?: string | number | (string | number)[]; 21 | marginTop?: string | number | (string | number)[]; 22 | marginBottom?: string | number | (string | number)[]; 23 | 24 | padding?: string | number | (string | number)[]; 25 | paddingLeft?: string | number | (string | number)[]; 26 | paddingRight?: string | number | (string | number)[]; 27 | paddingTop?: string | number | (string | number)[]; 28 | paddingBottom?: string | number | (string | number)[]; 29 | 30 | gap?: string | string[]; 31 | gridGap?: string | string[]; 32 | gridRowGap?: string | string[]; 33 | rowGap?: string | string[]; 34 | gridColumnGap?: string | string[]; 35 | columnGap?: string | string[]; 36 | 37 | gridTemplateRows?: string | string[]; 38 | gridAutoRows?: string | string[]; 39 | gridTemplateColumns?: string | string[]; 40 | gridColumn?: string | string[]; 41 | gridRow?: string | string[]; 42 | autoFlow?: string | string[]; 43 | 44 | overflow?: string | string[]; 45 | overflowX?: string | string[]; 46 | overflowY?: string | string[]; 47 | pointerEvents?: string | string[]; 48 | cursor?: string | string[]; 49 | 50 | //////////////////////////////////////// 51 | // Advanced 52 | component?: React.ReactElement; 53 | innerHTML?: string; 54 | onResize?: (element: HTMLElement) => void; 55 | onIntersect?: ( 56 | IntersectionObserverEntry: IntersectionObserverEntry, 57 | observer: IntersectionObserver 58 | ) => void; 59 | root?: null | HTMLElement; 60 | rootMargin?: string; 61 | threshold?: number | number[]; 62 | 63 | styles?: string | string[]; 64 | as?: string; 65 | control?: boolean; 66 | controlColor?: string; 67 | 68 | //////////////////////////////////////// 69 | // basic CSS 70 | order?: number | number[]; 71 | 72 | position?: string | string[]; 73 | zIndex?: string | number | (string | number)[]; 74 | top?: string | number | (string | number)[]; 75 | bottom?: string | number | (string | number)[]; 76 | left?: string | number | (string | number)[]; 77 | right?: string | number | (string | number)[]; 78 | 79 | alignItems?: string | string[]; 80 | alignContent?: string | string[]; 81 | alignSelf?: string | string[]; 82 | justifyContent?: string | string[]; 83 | justifyItems?: string | string[]; 84 | justifySelf?: string | string[]; 85 | 86 | flexShrink?: string | number | (string | number)[]; 87 | flexGrow?: string | number | (string | number)[]; 88 | flexDirection?: string | string[]; 89 | flexWrap?: string | string[]; 90 | 91 | background?: string | string[]; 92 | backgroundColor?: string | string[]; 93 | backgroundImage?: string | string[]; 94 | backgroundPosition?: string | string[]; 95 | backgroundSize?: string | string[]; 96 | backgroundAttachment?: string | string[]; 97 | 98 | filter?: string | string[]; 99 | backdropFilter?: string | string[]; 100 | mixBlendMode?: string | string[]; 101 | backgroundBlendMode?: string | string[]; 102 | textShadow?: string | string[]; 103 | boxShadow?: string | string[]; 104 | textStroke?: string | string[]; 105 | 106 | color?: string | string[]; 107 | fontFamily?: string | string[]; 108 | fontSize?: string | string[]; 109 | fontWeight?: string | string[]; 110 | fontStyle?: string | string[]; 111 | textAlign?: string | string[]; 112 | lineHeight?: string | string[]; 113 | letterSpacing?: string | string[]; 114 | textDecoration?: string | string[]; 115 | hyphens?: string | string[]; 116 | 117 | border?: string | string[]; 118 | borderLeft?: string | string[]; 119 | borderRight?: string | string[]; 120 | borderTop?: string | string[]; 121 | borderBottom?: string | string[]; 122 | 123 | transition?: string | string[]; 124 | animation?: string | string[]; 125 | transform?: string | string[]; 126 | opacity?: string | number | (string | number)[]; 127 | willChange?: string | string[]; 128 | 129 | //////////////////////////////////////// 130 | // utility 131 | className?: string; 132 | children?: React.ReactNode; 133 | isControl?: boolean; 134 | // No use. Just to prevent TypeScript-error, when spreading props into a Grid-component. 135 | ref?: React.MutableRefObject; 136 | } 137 | -------------------------------------------------------------------------------- /src/Box/utils/debounce.ts: -------------------------------------------------------------------------------- 1 | export default function debounce(func: () => any, delay = 300) { 2 | let timer: ReturnType; 3 | return (...args) => { 4 | clearTimeout(timer); 5 | timer = setTimeout(() => { 6 | func.apply(this, args); 7 | }, delay); 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /src/Box/utils/useIsomorphicLayoutEffect.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const useIsomorphicLayoutEffect = 4 | typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect; 5 | 6 | export default useIsomorphicLayoutEffect; 7 | -------------------------------------------------------------------------------- /src/Control/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "styled-components"; 3 | 4 | import Box from "../Box"; 5 | 6 | function getSideBearing(padding: string | number): string | number { 7 | return typeof padding === "number" ? 0 : padding; 8 | } 9 | 10 | const ControlGrid: React.FC = (props) => { 11 | const { colspanTotal } = props; 12 | return ( 13 | 31 | {[...Array(colspanTotal)].map((_, index) => ( 32 | 39 | ))} 40 | 41 | ); 42 | }; 43 | 44 | const ControlBox = styled("span")<{ controlColor: string }>` 45 | position: absolute; 46 | z-index: 10000; 47 | left: 0; 48 | top: 0; 49 | right: 0; 50 | bottom: 0; 51 | background-color: ${(props) => props.controlColor || "rgba(0,0,0,0.12)"}; 52 | pointer-events: none; 53 | `; 54 | 55 | const Control: React.FC = (props) => { 56 | return props.isNewGrid ? ( 57 | 58 | ) : ( 59 | 60 | ); 61 | }; 62 | 63 | export default Control; 64 | -------------------------------------------------------------------------------- /src/context.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export interface ContextProps { 4 | breakpoint?: number; 5 | breakpoints?: number[]; 6 | currentBreakpoint?: { 7 | index: number; 8 | value: number; 9 | }; 10 | gap?: { 11 | row: string; 12 | column: string; 13 | }; 14 | colspan?: number; 15 | controlIsVisible?: boolean; 16 | controlColor?: string; 17 | registerChildBox?: () => void; 18 | } 19 | 20 | const Context = React.createContext({}); 21 | 22 | function useRaster(): ContextProps { 23 | return React.useContext(Context); 24 | } 25 | 26 | export { useRaster }; 27 | 28 | export default Context; 29 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { useRaster } from "./context"; 2 | export type { Props } from "./Box/props"; 3 | export { default } from "./Box"; 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "strict": false, 12 | "forceConsistentCasingInFileNames": true, 13 | "noEmit": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "jsx": "preserve" 20 | }, 21 | "exclude": [ 22 | "node_modules" 23 | ], 24 | "include": [ 25 | "next-env.d.ts", 26 | "**/*.ts", 27 | "**/*.tsx", "grid/Box/index.js", "grid/Grid/index.jsx" 28 | ] 29 | } -------------------------------------------------------------------------------- /tsconfig.rollup.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "module": "esnext", 5 | "target": "es5", 6 | "lib": ["es6", "dom", "es2016", "es2017"], 7 | "sourceMap": true, 8 | "allowJs": false, 9 | "jsx": "react", 10 | "declaration": true, 11 | "moduleResolution": "node", 12 | "allowSyntheticDefaultImports": true, 13 | "esModuleInterop": true 14 | }, 15 | "include": ["src/**/*"], 16 | "exclude": ["node_modules", "dist"] 17 | } 18 | --------------------------------------------------------------------------------