[fix] Allows boundsDragEvents to fire even when hidden (#115)

* Allows boundsDragEvents to fire even when hidden

* Fix failing test
This commit is contained in:
Steve Ruiz 2021-09-23 12:45:39 +01:00 committed by GitHub
parent 9ddf7d0dc4
commit 1e3e19199c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 93 additions and 81 deletions

View file

@ -11,6 +11,7 @@ describe('bounds', () => {
rotation={0} rotation={0}
viewportWidth={1000} viewportWidth={1000}
isLocked={false} isLocked={false}
isHidden={false}
/> />
) )
}) })

View file

@ -13,6 +13,7 @@ interface BoundsProps {
bounds: TLBounds bounds: TLBounds
rotation: number rotation: number
isLocked: boolean isLocked: boolean
isHidden: boolean
viewportWidth: number viewportWidth: number
} }
@ -21,6 +22,7 @@ export function Bounds({
bounds, bounds,
viewportWidth, viewportWidth,
rotation, rotation,
isHidden,
isLocked, isLocked,
}: BoundsProps): JSX.Element { }: BoundsProps): JSX.Element {
// Touch target size // Touch target size
@ -36,33 +38,35 @@ export function Bounds({
return ( return (
<Container bounds={bounds} rotation={rotation}> <Container bounds={bounds} rotation={rotation}>
<SVGContainer> <SVGContainer opacity={isHidden ? 0 : 1}>
<CenterHandle bounds={bounds} isLocked={isLocked} /> <CenterHandle bounds={bounds} isLocked={isLocked} />
{showHandles && (
<>
<EdgeHandle <EdgeHandle
targetSize={targetSize} targetSize={targetSize}
size={size} size={size}
bounds={bounds} bounds={bounds}
edge={TLBoundsEdge.Top} edge={TLBoundsEdge.Top}
isHidden={!showHandles}
/> />
<EdgeHandle <EdgeHandle
targetSize={targetSize} targetSize={targetSize}
size={size} size={size}
bounds={bounds} bounds={bounds}
edge={TLBoundsEdge.Right} edge={TLBoundsEdge.Right}
isHidden={!showHandles}
/> />
<EdgeHandle <EdgeHandle
targetSize={targetSize} targetSize={targetSize}
size={size} size={size}
bounds={bounds} bounds={bounds}
edge={TLBoundsEdge.Bottom} edge={TLBoundsEdge.Bottom}
isHidden={!showHandles}
/> />
<EdgeHandle <EdgeHandle
targetSize={targetSize} targetSize={targetSize}
size={size} size={size}
bounds={bounds} bounds={bounds}
edge={TLBoundsEdge.Left} edge={TLBoundsEdge.Left}
isHidden={!showHandles}
/> />
<CornerHandle <CornerHandle
targetSize={targetSize} targetSize={targetSize}
@ -88,11 +92,12 @@ export function Bounds({
bounds={bounds} bounds={bounds}
corner={TLBoundsCorner.BottomLeft} corner={TLBoundsCorner.BottomLeft}
/> />
{showRotateHandle && ( <RotateHandle
<RotateHandle targetSize={targetSize} size={size} bounds={bounds} /> targetSize={targetSize}
)} size={size}
</> bounds={bounds}
)} isHidden={!showHandles || !showRotateHandle}
/>
</SVGContainer> </SVGContainer>
</Container> </Container>
) )

View file

@ -14,25 +14,25 @@ interface CornerHandleProps {
targetSize: number targetSize: number
bounds: TLBounds bounds: TLBounds
corner: TLBoundsCorner corner: TLBoundsCorner
isHidden?: boolean
} }
export const CornerHandle = React.memo( export const CornerHandle = React.memo(
({ size, targetSize, corner, bounds }: CornerHandleProps): JSX.Element => { ({ size, targetSize, isHidden, corner, bounds }: CornerHandleProps): JSX.Element => {
const events = useBoundsHandleEvents(corner) const events = useBoundsHandleEvents(corner)
const isTop = corner === TLBoundsCorner.TopLeft || corner === TLBoundsCorner.TopRight const isTop = corner === TLBoundsCorner.TopLeft || corner === TLBoundsCorner.TopRight
const isLeft = corner === TLBoundsCorner.TopLeft || corner === TLBoundsCorner.BottomLeft const isLeft = corner === TLBoundsCorner.TopLeft || corner === TLBoundsCorner.BottomLeft
return ( return (
<g> <g opacity={isHidden ? 0 : 1}>
<rect <rect
className={cornerBgClassnames[corner]} className={cornerBgClassnames[corner]}
x={(isLeft ? -1 : bounds.width + 1) - targetSize} x={(isLeft ? -1 : bounds.width + 1) - targetSize}
y={(isTop ? -1 : bounds.height + 1) - targetSize} y={(isTop ? -1 : bounds.height + 1) - targetSize}
width={targetSize * 2} width={targetSize * 2}
height={targetSize * 2} height={targetSize * 2}
pointerEvents="all" pointerEvents={isHidden ? 'none' : 'all'}
fill="red"
{...events} {...events}
/> />
<rect <rect

View file

@ -14,9 +14,11 @@ interface EdgeHandleProps {
size: number size: number
bounds: TLBounds bounds: TLBounds
edge: TLBoundsEdge edge: TLBoundsEdge
isHidden: boolean
} }
export const EdgeHandle = React.memo(({ size, bounds, edge }: EdgeHandleProps): JSX.Element => { export const EdgeHandle = React.memo(
({ size, isHidden, bounds, edge }: EdgeHandleProps): JSX.Element => {
const events = useBoundsHandleEvents(edge) const events = useBoundsHandleEvents(edge)
const isHorizontal = edge === TLBoundsEdge.Top || edge === TLBoundsEdge.Bottom const isHorizontal = edge === TLBoundsEdge.Top || edge === TLBoundsEdge.Bottom
@ -26,8 +28,9 @@ export const EdgeHandle = React.memo(({ size, bounds, edge }: EdgeHandleProps):
return ( return (
<rect <rect
pointerEvents="all" pointerEvents={isHidden ? 'none' : 'all'}
className={edgeClassnames[edge]} className={edgeClassnames[edge]}
opacity={isHidden ? 0 : 1}
x={isHorizontal ? size / 2 : (isFarEdge ? width + 1 : -1) - size / 2} x={isHorizontal ? size / 2 : (isFarEdge ? width + 1 : -1) - size / 2}
y={isHorizontal ? (isFarEdge ? height + 1 : -1) - size / 2 : size / 2} y={isHorizontal ? (isFarEdge ? height + 1 : -1) - size / 2 : size / 2}
width={isHorizontal ? Math.max(0, width + 1 - size) : size} width={isHorizontal ? Math.max(0, width + 1 - size) : size}
@ -35,4 +38,5 @@ export const EdgeHandle = React.memo(({ size, bounds, edge }: EdgeHandleProps):
{...events} {...events}
/> />
) )
}) }
)

View file

@ -6,20 +6,21 @@ interface RotateHandleProps {
bounds: TLBounds bounds: TLBounds
size: number size: number
targetSize: number targetSize: number
isHidden: boolean
} }
export const RotateHandle = React.memo( export const RotateHandle = React.memo(
({ bounds, targetSize, size }: RotateHandleProps): JSX.Element => { ({ bounds, targetSize, size, isHidden }: RotateHandleProps): JSX.Element => {
const events = useBoundsHandleEvents('rotate') const events = useBoundsHandleEvents('rotate')
return ( return (
<g cursor="grab"> <g cursor="grab" opacity={isHidden ? 0 : 1}>
<circle <circle
className="tl-transparent" className="tl-transparent"
cx={bounds.width / 2} cx={bounds.width / 2}
cy={size * -2} cy={size * -2}
r={targetSize} r={targetSize}
pointerEvents="all" pointerEvents={isHidden ? 'none' : 'all'}
{...events} {...events}
/> />
<circle <circle

View file

@ -55,13 +55,14 @@ export function Page<T extends TLShape, M extends Record<string, unknown>>({
{shapeTree.map((node) => ( {shapeTree.map((node) => (
<ShapeNode key={node.shape.id} utils={shapeUtils} {...node} /> <ShapeNode key={node.shape.id} utils={shapeUtils} {...node} />
))} ))}
{bounds && !hideBounds && ( {bounds && (
<Bounds <Bounds
zoom={zoom} zoom={zoom}
bounds={bounds} bounds={bounds}
viewportWidth={inputs.bounds.width} viewportWidth={inputs.bounds.width}
isLocked={isLocked} isLocked={isLocked}
rotation={rotation} rotation={rotation}
isHidden={hideBounds}
/> />
)} )}
{!hideIndicators && {!hideIndicators &&