Skip to content

Commit

Permalink
fix #10, #17, bump 1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
smastrom committed Dec 11, 2023
1 parent c18c1b9 commit e1f7cf8
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 23 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@smastrom/react-rating",
"version": "1.3.3",
"version": "1.4.0",
"private": false,
"keywords": [
"react",
Expand Down
89 changes: 67 additions & 22 deletions src/RatingItem.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useId, useRef, useState } from 'react'
import { useCallback, useId, useRef, useState } from 'react'
import {
areNum,
getNewPosition,
getNewPosition as getNewPos,
getDefsTestId,
toSecondDecimal,
toSecondDecimal as toSecondDec,
useIsomorphicLayoutEffect,
getHiddenParent,
} from './utils'
import { RatingClasses, OrientationProps } from './constants'
import { RatingItemProps, SvgData } from './internalTypes'
Expand All @@ -19,34 +20,78 @@ export function RatingItem({
const strokeOffset = itemStrokeWidth > 0 ? -(itemStrokeWidth / 2) : 0
const translateOffset = itemStrokeWidth > 0 ? `${strokeOffset} ${strokeOffset}` : '0 0'

const svgRef = useRef<SVGPathElement | null>(null)
const uniqId = useId()

const [svgData, setSvgData] = useState<SvgData | null>(null)
const groupRef = useRef<SVGPathElement | null>(null)
const [svgData, _setSvgData] = useState<SvgData | null>(null)

useIsomorphicLayoutEffect(() => {
if (svgRef.current) {
const {
width: svgWidth,
height: svgHeight,
x: svgXPos,
y: svgYPos,
} = svgRef.current.getBBox()

if (areNum(svgWidth, svgHeight, svgXPos, svgYPos)) {
const viewBox = `${translateOffset} ${toSecondDecimal(
svgWidth + itemStrokeWidth
)} ${toSecondDecimal(svgHeight + itemStrokeWidth)}`
const translateData = `${getNewPosition(svgXPos)} ${getNewPosition(svgYPos)}`

setSvgData({
const [isHiddenParentDetected, setIsHiddenParentDetected] = useState(false)
const mutationObserver = useRef<MutationObserver | null>(null)
const hiddenParent = useRef<HTMLElement | SVGElement | null>(null)

const setSvgData = useCallback(
(el: SVGPathElement) => {
const { width: w, height: h, x, y } = el.getBBox()

if (areNum(w, h, x, y)) {
const viewBox = `${translateOffset} ${toSecondDec(w + itemStrokeWidth)} ${toSecondDec(
h + itemStrokeWidth
)}`
const translateData = `${getNewPos(x)} ${getNewPos(y)}`

_setSvgData({
viewBox,
translateData,
})
}
},
[itemStrokeWidth, translateOffset]
)

useIsomorphicLayoutEffect(() => {
if (groupRef.current) {
const { width: w, height: h, x, y } = groupRef.current.getBBox()

const isHidden = w === 0 && h === 0 && x === 0 && y === 0

if (isHidden) {
const _hiddenParent = getHiddenParent(groupRef.current)
if (_hiddenParent) {
hiddenParent.current = _hiddenParent
setIsHiddenParentDetected(true)
}
} else {
setIsHiddenParentDetected(false)
}

setSvgData(groupRef.current)
}
}, [itemShapes, itemStrokeWidth, hasHF])

useIsomorphicLayoutEffect(() => {
if (isHiddenParentDetected && hiddenParent.current) {
mutationObserver.current = new MutationObserver((mutations, observer) => {
mutations.forEach(() => {
const isDisplayNone =
window.getComputedStyle(hiddenParent.current as Element).display === 'none'

if (!isDisplayNone) {
setSvgData(groupRef.current as SVGPathElement)
observer.disconnect()
}
})
})

mutationObserver.current.observe(hiddenParent.current, {
attributes: true,
})

return () => {
mutationObserver.current?.disconnect()
}
}
}, [isHiddenParentDetected, setSvgData])

/* Props */

function getHFAttr() {
Expand Down Expand Up @@ -106,7 +151,7 @@ export function RatingItem({
</defs>
)}

<g ref={svgRef} shapeRendering="geometricPrecision" {...getTransform()} {...getHFAttr()}>
<g ref={groupRef} shapeRendering="geometricPrecision" {...getTransform()} {...getHFAttr()}>
{itemShapes}
</g>
</svg>
Expand Down
20 changes: 20 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,23 @@ export function getDefsTestId() {
} /* c8 ignore next */
return {}
}

export function getHiddenParent(
el: HTMLElement | SVGElement | null
): SVGElement | HTMLElement | null {
if (!el || !el.parentElement) return null

let nextParent = el?.parentElement as HTMLElement | SVGElement | null

// eslint-disable-next-line no-constant-condition
while (true) {
if (!nextParent) break

const isParentDisplayNone = window.getComputedStyle(nextParent).display === 'none'
if (isParentDisplayNone) break

nextParent = nextParent.parentElement
}

return nextParent
}

0 comments on commit e1f7cf8

Please sign in to comment.