import { useCallback } from 'react' import { Geometry2d, Rectangle2d, SVGContainer, ShapeProps, ShapeUtil, T, TLBaseShape, TLOnResizeHandler, resizeBox, useValue, } from 'tldraw' import { getPerfectDashProps } from 'tldraw/src/lib/shapes/shared/getPerfectDashProps' import { moveToSlide, useSlides } from './useSlides' export type SlideShape = TLBaseShape< 'slide', { w: number h: number } > export class SlideShapeUtil extends ShapeUtil { static override type = 'slide' as const static override props: ShapeProps = { w: T.number, h: T.number, } override canBind = () => false override hideRotateHandle = () => true getDefaultProps(): SlideShape['props'] { return { w: 720, h: 480, } } getGeometry(shape: SlideShape): Geometry2d { return new Rectangle2d({ width: shape.props.w, height: shape.props.h, isFilled: false, }) } override onRotate = (initial: SlideShape) => initial override onResize: TLOnResizeHandler = (shape, info) => { return resizeBox(shape, info) } override onDoubleClick = (shape: SlideShape) => { moveToSlide(this.editor, shape) this.editor.selectNone() } override onDoubleClickEdge = (shape: SlideShape) => { moveToSlide(this.editor, shape) this.editor.selectNone() } component(shape: SlideShape) { const bounds = this.editor.getShapeGeometry(shape).bounds // eslint-disable-next-line react-hooks/rules-of-hooks const zoomLevel = useValue('zoom level', () => this.editor.getZoomLevel(), [this.editor]) // eslint-disable-next-line react-hooks/rules-of-hooks const slides = useSlides() const index = slides.findIndex((s) => s.id === shape.id) // eslint-disable-next-line react-hooks/rules-of-hooks const handleLabelPointerDown = useCallback(() => this.editor.select(shape.id), [shape.id]) if (!bounds) return null return ( <>
{`Slide ${index + 1}`}
{bounds.sides.map((side, i) => { const { strokeDasharray, strokeDashoffset } = getPerfectDashProps( side[0].dist(side[1]), 1 / zoomLevel, { style: 'dashed', lengthRatio: 6, } ) return ( ) })} ) } indicator(shape: SlideShape) { return } }