From 46ce13b1322761cd1aeec5a94dd68b07a9c888ac Mon Sep 17 00:00:00 2001 From: johannes Date: Mon, 21 Mar 2022 15:30:10 +0100 Subject: [PATCH] bugfixes and improvements add overflow support, prevent flash of sharp corners, better support for transitions in transform and height / width --- README.md | 10 +++++----- package-lock.json | 4 ++-- package.json | 2 +- src/main.js | 28 ++++++++++++++++++++++++---- src/updateStates.js | 40 +++++++++++++++++++++------------------- 5 files changed, 53 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index c9fc758..8430a6b 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,8 @@ npm i react-round-div | | Gzipped | Minified + Gzipped | |----------------------------------|---------:|-------------------:| -| `react-round-div` | 7.71 KB | 5.18 KB | -| `react-round-div` + dependencies | 14.88 KB | **9.07 KB** | +| `react-round-div` | 7.81 KB | 5.27 KB | +| `react-round-div` + dependencies | 21.01 KB | **9.45 KB** | ## Usage @@ -50,8 +50,6 @@ const App = () => { export default App; ``` -Also, [turn off or polyfill `url`, `path`, and `fs`](#webpack) - ### Options #### `dontConvertShadow` @@ -76,6 +74,7 @@ There are a couple of css properties, that you can't reliably set _inline_ with - the `background` property and all the properties it is a shorthand for - the `border`, `border-image`, and all the properties they are a shorthand for +- `overflow` - `box-shadow` - `filter`, if you haven't set [`dontConvertShadow`](#dontconvertshadow) @@ -85,4 +84,5 @@ set [`dontConvertShadow`](#dontconvertshadow). This may also change in future ve ### Intended differences to the html `
` -Unlike the html `
`, `RoundDiv` still rounds the corners of borders of there is a border image set. This looks great with gradients, but might clash with the use of actual images as borders. +Unlike the html `
`, `RoundDiv` still rounds the corners of borders if you have set a border image. This looks great with gradients, but might clash with the use of actual images as borders. +You may notice a flash of white in the border before the gradient is shown. To combat this, define a `border-color` for the element in addition to the `border-image` gradient. This gives the browser a fallback to show before the `RoundDiv` script generates the smooth corners. diff --git a/package-lock.json b/package-lock.json index a6053ca..f45e7a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "react-round-div", - "version": "1.3.0", + "version": "1.3.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "react-round-div", - "version": "1.3.0", + "version": "1.3.2", "license": "MIT", "dependencies": { "css": "^3.0.0", diff --git a/package.json b/package.json index 5ab9a01..da8b608 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-round-div", - "version": "1.3.0", + "version": "1.3.2", "description": "Make your rounded corners look phenomenal with g2 continuity.", "main": "dist/main.js", "scripts": { diff --git a/src/main.js b/src/main.js index 53f79bd..cba808f 100644 --- a/src/main.js +++ b/src/main.js @@ -20,6 +20,7 @@ export default function RoundDiv({style, children, dontConvertShadow, ...props}) const [width, setWidth] = useState(0) const [radius, setRadius] = useState(array(4, 0)) const [boxSizing, setBoxSizing] = useState('content-box') + const [overflow, setOverflow] = useState('visible') const [transition, setTransition] = useState(array(4, 0)) @@ -38,6 +39,7 @@ export default function RoundDiv({style, children, dontConvertShadow, ...props}) div, style, setBoxSizing, + setOverflow, setPadding, setHeight, setWidth, @@ -52,7 +54,11 @@ export default function RoundDiv({style, children, dontConvertShadow, ...props}) useEffect(() => { const watcherId = attachCSSWatcher(updateStatesWithArgs, div.current) // todo: make this a react hook - updateStatesWithArgs() + const waitForDocumentComplete = setInterval(() => { + if (document.readyState !== 'complete') return + clearInterval(waitForDocumentComplete) + updateStatesWithArgs() + }, 1) return () => { detachCSSWatcher(watcherId) } @@ -102,7 +108,9 @@ export default function RoundDiv({style, children, dontConvertShadow, ...props}) const pathIsEmpty = path.startsWith('Z') || path === '' const divStyle = { ...style, - ...(pathIsEmpty ? {} : { + ...(pathIsEmpty ? { + borderImage: 'none', + } : { ...invisibleBorderStyles, borderImage: 'none', background: 'transparent', @@ -112,6 +120,7 @@ export default function RoundDiv({style, children, dontConvertShadow, ...props}) : 'none', // drop shadow only filter: dontConvertShadow ? '' : shadows[0].map(shadowData => `drop-shadow(${shadowData})`).join(' '), + overflow: 'visible', }) } @@ -128,7 +137,10 @@ export default function RoundDiv({style, children, dontConvertShadow, ...props}) const widenedBorderWidth = border.width.map(v => v + Math.max(.5, v * .1)) - return
+ if (div.current) + div.current.rrdOverwritten = !pathIsEmpty + + return
{pathIsEmpty ? null :
- +
+ +
} {children} diff --git a/src/updateStates.js b/src/updateStates.js index 50f4dc9..a68a0a0 100644 --- a/src/updateStates.js +++ b/src/updateStates.js @@ -8,15 +8,8 @@ import ReactDOM from 'react-dom' import {lazySetArrayState, lazySetObjectsState} from './utils/react-utils' export default function updateStates(args) { - const {div, setHeight, setWidth} = args - const boundingClientRect = div.current?.getBoundingClientRect() - let height, width; - if (boundingClientRect) { - height = boundingClientRect.height - width = boundingClientRect.width - setHeight(height) - setWidth(width) - } + const {div} = args + if (!div.current) return const getNthStyle = (key, n, shorthand) => { const styles = getAllCssPropertyDeclarationsForElement(key, div.current, shorthand) @@ -33,7 +26,7 @@ export default function updateStates(args) { lazySetBorderImage = newState => lazySetObjectsState(states.setBorderImage, newState), lazySetShadows = newState => lazySetArrayState(states.setShadows, newState) - const oneIfStylesAreOverridden = args.div?.current?.dataset.rrdOverwritten === 'true' ? 1 : 0 + const oneIfStylesAreOverridden = args.div?.current?.rrdOverwritten ? 1 : 0 ReactDOM.unstable_batchedUpdates(() => { states.setPadding( @@ -42,15 +35,6 @@ export default function updateStates(args) { .map(n => toNumber(n, div.current) || 0) ) - lazySetRadius( - getBorderRadii(0) - .map(s => Math.min( - toNumber(s, div.current), - height / 2, - width / 2 - )) - ) - states.setTransition( getNthStyle('transition', 0) ) @@ -59,6 +43,10 @@ export default function updateStates(args) { getNthStyle('box-sizing', 0) || 'content-box' ) + states.setOverflow( + getNthStyle('overflow', oneIfStylesAreOverridden) || 'visible' + ) + lazySetBackground( Object.fromEntries([ 'attachment', @@ -94,6 +82,20 @@ export default function updateStates(args) { border.width = border.width ?? Array(4).fill(0) lazySetBorder(border) + const height = div.current?.clientHeight + border.width[0] + border.width[2], + width = div.current?.clientWidth + border.width[1] + border.width[3] + states.setHeight(height) + states.setWidth(width) + + lazySetRadius( + getBorderRadii(0) + .map(s => Math.min( + toNumber(s, div.current), + height / 2, + width / 2 + )) + ) + lazySetBorderImage( Object.fromEntries([ 'outset',