| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 | 
							- import React, { useCallback, useRef, memo } from "react"
 - import state, { useSelector } from "state"
 - import inputs from "state/inputs"
 - import { getShapeUtils } from "lib/shapes"
 - import styled from "styles"
 - 
 - function Shape({ id }: { id: string }) {
 -   const rGroup = useRef<SVGGElement>(null)
 - 
 -   const isHovered = useSelector((state) => state.data.hoveredId === id)
 - 
 -   const isSelected = useSelector((state) => state.values.selectedIds.has(id))
 - 
 -   const shape = useSelector(
 -     ({ data }) => data.document.pages[data.currentPageId].shapes[id]
 -   )
 - 
 -   const handlePointerDown = useCallback(
 -     (e: React.PointerEvent) => {
 -       e.stopPropagation()
 -       rGroup.current.setPointerCapture(e.pointerId)
 -       state.send("POINTED_SHAPE", inputs.pointerDown(e, id))
 -     },
 -     [id]
 -   )
 - 
 -   const handlePointerUp = useCallback(
 -     (e: React.PointerEvent) => {
 -       e.stopPropagation()
 -       rGroup.current.releasePointerCapture(e.pointerId)
 -       state.send("STOPPED_POINTING", inputs.pointerUp(e))
 -     },
 -     [id]
 -   )
 - 
 -   const handlePointerEnter = useCallback(
 -     (e: React.PointerEvent) => {
 -       state.send("HOVERED_SHAPE", inputs.pointerEnter(e, id))
 -     },
 -     [id, shape]
 -   )
 - 
 -   const handlePointerMove = useCallback(
 -     (e: React.PointerEvent) => {
 -       state.send("MOVED_OVER_SHAPE", inputs.pointerEnter(e, id))
 -     },
 -     [id, shape]
 -   )
 - 
 -   const handlePointerLeave = useCallback(
 -     () => state.send("UNHOVERED_SHAPE", { target: id }),
 -     [id]
 -   )
 - 
 -   // This is a problem with deleted shapes. The hooks in this component
 -   // may sometimes run before the hook in the Page component, which means
 -   // a deleted shape will still be pulled here before the page component
 -   // detects the change and pulls this component.
 -   if (!shape) return null
 - 
 -   return (
 -     <StyledGroup
 -       ref={rGroup}
 -       isHovered={isHovered}
 -       isSelected={isSelected}
 -       transform={`rotate(${shape.rotation * (180 / Math.PI)},${getShapeUtils(
 -         shape
 -       ).getCenter(shape)}) translate(${shape.point})`}
 -       onPointerDown={handlePointerDown}
 -       onPointerUp={handlePointerUp}
 -       onPointerEnter={handlePointerEnter}
 -       onPointerLeave={handlePointerLeave}
 -       onPointerMove={handlePointerMove}
 -     >
 -       <defs>{getShapeUtils(shape).render(shape)}</defs>
 -       <HoverIndicator as="use" xlinkHref={"#" + id} />
 -       <MainShape as="use" xlinkHref={"#" + id} {...shape.style} />
 -       <Indicator as="use" xlinkHref={"#" + id} />
 -     </StyledGroup>
 -   )
 - }
 - 
 - const MainShape = styled("use", {
 -   zStrokeWidth: 1,
 - })
 - 
 - const Indicator = styled("path", {
 -   fill: "none",
 -   stroke: "transparent",
 -   zStrokeWidth: 1,
 -   pointerEvents: "none",
 -   strokeLineCap: "round",
 -   strokeLinejoin: "round",
 - })
 - 
 - const HoverIndicator = styled("path", {
 -   fill: "none",
 -   stroke: "transparent",
 -   zStrokeWidth: [8, 4],
 -   pointerEvents: "all",
 -   strokeLinecap: "round",
 -   strokeLinejoin: "round",
 -   transform: "all .2s",
 - })
 - 
 - const StyledGroup = styled("g", {
 -   [`& ${HoverIndicator}`]: {
 -     opacity: "0",
 -   },
 -   variants: {
 -     isSelected: {
 -       true: {
 -         [`& ${Indicator}`]: {
 -           stroke: "$selected",
 -         },
 -       },
 -       false: {},
 -     },
 -     isHovered: {
 -       true: {},
 -       false: {},
 -     },
 -   },
 -   compoundVariants: [
 -     {
 -       isSelected: true,
 -       isHovered: true,
 -       css: {
 -         [`& ${HoverIndicator}`]: {
 -           opacity: "1",
 -           stroke: "$hint",
 -           zStrokeWidth: [8, 4],
 -         },
 -       },
 -     },
 -     {
 -       isSelected: true,
 -       isHovered: false,
 -       css: {
 -         [`& ${HoverIndicator}`]: {
 -           opacity: "1",
 -           stroke: "$hint",
 -           zStrokeWidth: [6, 3],
 -         },
 -       },
 -     },
 -     {
 -       isSelected: false,
 -       isHovered: true,
 -       css: {
 -         [`& ${HoverIndicator}`]: {
 -           opacity: "1",
 -           stroke: "$hint",
 -           zStrokeWidth: [8, 4],
 -         },
 -       },
 -     },
 -   ],
 - })
 - 
 - export { Indicator, HoverIndicator }
 - 
 - export default memo(Shape)
 
 
  |