import useShapeEvents from 'hooks/useShapeEvents' import { Shape as _Shape, ShapeType, TextShape } from 'types' import { getShapeUtils } from 'state/shape-utils' import { shallowEqual } from 'utils' import { memo, useRef } from 'react' import styled from 'styles' interface ShapeProps { shape: _Shape isEditing: boolean isHovered: boolean isSelected: boolean isDarkMode: boolean isCurrentParent: boolean } const Shape = memo( ({ shape, isEditing, isHovered, isSelected, isDarkMode, isCurrentParent, }: ShapeProps) => { const rGroup = useRef(null) const events = useShapeEvents(shape.id, isCurrentParent, rGroup) const utils = getShapeUtils(shape) const center = utils.getCenter(shape) const rotation = shape.rotation * (180 / Math.PI) const transform = `rotate(${rotation}, ${center}) translate(${shape.point})` return ( {isEditing && shape.type === ShapeType.Text ? ( ) : ( )} ) }, shallowEqual ) export default Shape interface RenderedShapeProps { shape: _Shape isEditing: boolean isHovered: boolean isSelected: boolean isDarkMode: boolean isCurrentParent: boolean } const RenderedShape = memo( function RenderedShape({ shape, isEditing, isHovered, isSelected, isDarkMode, isCurrentParent, }: RenderedShapeProps) { return getShapeUtils(shape).render(shape, { isEditing, isHovered, isSelected, isDarkMode, isCurrentParent, }) }, (prev, next) => { if ( prev.isEditing !== next.isEditing || prev.isHovered !== next.isHovered || prev.isSelected !== next.isSelected || prev.isDarkMode !== next.isDarkMode || prev.isCurrentParent !== next.isCurrentParent ) { return false } if (next.shape !== prev.shape) { return !getShapeUtils(next.shape).shouldRender(next.shape, prev.shape) } return true } ) function EditingTextShape({ shape, isDarkMode, }: { shape: TextShape isDarkMode: boolean }) { const ref = useRef(null) return getShapeUtils(shape).render(shape, { ref, isEditing: true, isHovered: false, isSelected: false, isDarkMode, isCurrentParent: false, }) } const ShapeGroup = styled('g', { outline: 'none', '& > *[data-shy=true]': { opacity: 0, }, '&:hover': { '& > *[data-shy=true]': { opacity: 1, }, }, variants: { isCurrentParent: { true: { '& > *[data-shy=true]': { opacity: 1, }, }, }, }, })