Move SVG container to shape implementations
This commit is contained in:
parent
4c41d98c8e
commit
5359e92771
10 changed files with 138 additions and 106 deletions
|
@ -1,2 +1,3 @@
|
||||||
export * from './renderer'
|
export * from './renderer'
|
||||||
export { brushUpdater } from './brush'
|
export { brushUpdater } from './brush'
|
||||||
|
export * from './svg-container'
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { usePosition, useShapeEvents } from '+hooks'
|
import { useShapeEvents } from '+hooks'
|
||||||
import type { IShapeTreeNode, TLBounds, TLShape, TLShapeUtil } from '+types'
|
import type { IShapeTreeNode, TLShape, TLShapeUtil } from '+types'
|
||||||
import { RenderedShape } from './rendered-shape'
|
import { RenderedShape } from './rendered-shape'
|
||||||
import { EditingTextShape } from './editing-text-shape'
|
import { EditingTextShape } from './editing-text-shape'
|
||||||
import { Container } from '+components/container'
|
import { Container } from '+components/container'
|
||||||
import { SVGContainer } from '+components/svg-container'
|
|
||||||
|
|
||||||
// function setTransform(elm: HTMLDivElement, bounds: TLBounds, rotation = 0) {
|
// function setTransform(elm: HTMLDivElement, bounds: TLBounds, rotation = 0) {
|
||||||
// const transform = `
|
// const transform = `
|
||||||
|
@ -43,33 +42,31 @@ export const Shape = <
|
||||||
bounds={bounds}
|
bounds={bounds}
|
||||||
rotation={shape.rotation}
|
rotation={shape.rotation}
|
||||||
>
|
>
|
||||||
<SVGContainer>
|
{isEditing && utils.isEditableText ? (
|
||||||
{isEditing && utils.isEditableText ? (
|
<EditingTextShape
|
||||||
<EditingTextShape
|
shape={shape}
|
||||||
shape={shape}
|
isBinding={false}
|
||||||
isBinding={false}
|
isCurrentParent={false}
|
||||||
isCurrentParent={false}
|
isEditing={true}
|
||||||
isEditing={true}
|
isHovered={isHovered}
|
||||||
isHovered={isHovered}
|
isSelected={isSelected}
|
||||||
isSelected={isSelected}
|
utils={utils as any}
|
||||||
utils={utils as any}
|
meta={meta as any}
|
||||||
meta={meta as any}
|
events={events}
|
||||||
events={events}
|
/>
|
||||||
/>
|
) : (
|
||||||
) : (
|
<RenderedShape
|
||||||
<RenderedShape
|
shape={shape}
|
||||||
shape={shape}
|
isBinding={isBinding}
|
||||||
isBinding={isBinding}
|
isCurrentParent={isCurrentParent}
|
||||||
isCurrentParent={isCurrentParent}
|
isEditing={isEditing}
|
||||||
isEditing={isEditing}
|
isHovered={isHovered}
|
||||||
isHovered={isHovered}
|
isSelected={isSelected}
|
||||||
isSelected={isSelected}
|
utils={utils as any}
|
||||||
utils={utils as any}
|
meta={meta as any}
|
||||||
meta={meta as any}
|
events={events}
|
||||||
events={events}
|
/>
|
||||||
/>
|
)}
|
||||||
)}
|
|
||||||
</SVGContainer>
|
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
|
|
||||||
interface SvgContainerProps {
|
interface SvgContainerProps extends React.SVGProps<SVGSVGElement> {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SVGContainer = React.memo(({ children }: SvgContainerProps) => {
|
export const SVGContainer = React.memo(
|
||||||
return (
|
React.forwardRef<SVGSVGElement, SvgContainerProps>(({ children, ...rest }, ref) => {
|
||||||
<svg className="tl-positioned-svg">
|
return (
|
||||||
<g className="tl-centered-g">{children}</g>
|
<svg ref={ref} className="tl-positioned-svg" {...rest}>
|
||||||
</svg>
|
<g className="tl-centered-g">{children}</g>
|
||||||
)
|
</svg>
|
||||||
})
|
)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
|
@ -151,7 +151,6 @@ const tlcss = css`
|
||||||
.tl-positioned-svg {
|
.tl-positioned-svg {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
pointer-events: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tl-layer {
|
.tl-layer {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import {
|
import {
|
||||||
|
SVGContainer,
|
||||||
TLBounds,
|
TLBounds,
|
||||||
Utils,
|
Utils,
|
||||||
Vec,
|
Vec,
|
||||||
|
@ -20,10 +21,9 @@ import {
|
||||||
DashStyle,
|
DashStyle,
|
||||||
TLDrawShape,
|
TLDrawShape,
|
||||||
ArrowBinding,
|
ArrowBinding,
|
||||||
TLDrawRenderInfo,
|
|
||||||
} from '~types'
|
} from '~types'
|
||||||
|
|
||||||
export class Arrow extends TLDrawShapeUtil<ArrowShape, SVGGElement> {
|
export class Arrow extends TLDrawShapeUtil<ArrowShape, SVGSVGElement> {
|
||||||
type = TLDrawShapeType.Arrow as const
|
type = TLDrawShapeType.Arrow as const
|
||||||
toolType = TLDrawToolType.Handle
|
toolType = TLDrawToolType.Handle
|
||||||
canStyleFill = false
|
canStyleFill = false
|
||||||
|
@ -71,7 +71,7 @@ export class Arrow extends TLDrawShapeUtil<ArrowShape, SVGGElement> {
|
||||||
return next.handles !== prev.handles || next.style !== prev.style
|
return next.handles !== prev.handles || next.style !== prev.style
|
||||||
}
|
}
|
||||||
|
|
||||||
render = React.forwardRef<SVGGElement, TLShapeProps<ArrowShape, SVGGElement>>(
|
render = React.forwardRef<SVGSVGElement, TLShapeProps<ArrowShape, SVGSVGElement>>(
|
||||||
({ shape, meta, events }, ref) => {
|
({ shape, meta, events }, ref) => {
|
||||||
const {
|
const {
|
||||||
handles: { start, bend, end },
|
handles: { start, bend, end },
|
||||||
|
@ -220,7 +220,7 @@ export class Arrow extends TLDrawShapeUtil<ArrowShape, SVGGElement> {
|
||||||
const sw = strokeWidth * 1.618
|
const sw = strokeWidth * 1.618
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g ref={ref} {...events}>
|
<SVGContainer ref={ref} {...events}>
|
||||||
<g pointerEvents="none">
|
<g pointerEvents="none">
|
||||||
{shaftPath}
|
{shaftPath}
|
||||||
{startArrowHead && (
|
{startArrowHead && (
|
||||||
|
@ -250,7 +250,7 @@ export class Arrow extends TLDrawShapeUtil<ArrowShape, SVGGElement> {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</SVGContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { TLBounds, Utils, Vec, TLTransformInfo, Intersect, TLShapeProps } from '@tldraw/core'
|
import {
|
||||||
|
SVGContainer,
|
||||||
|
TLBounds,
|
||||||
|
Utils,
|
||||||
|
Vec,
|
||||||
|
TLTransformInfo,
|
||||||
|
Intersect,
|
||||||
|
TLShapeProps,
|
||||||
|
} from '@tldraw/core'
|
||||||
import getStroke, { getStrokePoints } from 'perfect-freehand'
|
import getStroke, { getStrokePoints } from 'perfect-freehand'
|
||||||
import { defaultStyle, getShapeStyle } from '~shape/shape-styles'
|
import { defaultStyle, getShapeStyle } from '~shape/shape-styles'
|
||||||
import { DrawShape, DashStyle, TLDrawShapeUtil, TLDrawShapeType, TLDrawToolType } from '~types'
|
import { DrawShape, DashStyle, TLDrawShapeUtil, TLDrawShapeType, TLDrawToolType } from '~types'
|
||||||
|
|
||||||
export class Draw extends TLDrawShapeUtil<DrawShape, SVGGElement> {
|
export class Draw extends TLDrawShapeUtil<DrawShape, SVGSVGElement> {
|
||||||
type = TLDrawShapeType.Draw as const
|
type = TLDrawShapeType.Draw as const
|
||||||
toolType = TLDrawToolType.Draw
|
toolType = TLDrawToolType.Draw
|
||||||
|
|
||||||
|
@ -30,7 +38,7 @@ export class Draw extends TLDrawShapeUtil<DrawShape, SVGGElement> {
|
||||||
return next.points !== prev.points || next.style !== prev.style
|
return next.points !== prev.points || next.style !== prev.style
|
||||||
}
|
}
|
||||||
|
|
||||||
render = React.forwardRef<SVGGElement, TLShapeProps<DrawShape, SVGGElement>>(
|
render = React.forwardRef<SVGSVGElement, TLShapeProps<DrawShape, SVGSVGElement>>(
|
||||||
({ shape, meta, events, isEditing }, ref) => {
|
({ shape, meta, events, isEditing }, ref) => {
|
||||||
const { points, style } = shape
|
const { points, style } = shape
|
||||||
|
|
||||||
|
@ -47,7 +55,7 @@ export class Draw extends TLDrawShapeUtil<DrawShape, SVGGElement> {
|
||||||
const sw = strokeWidth * 0.618
|
const sw = strokeWidth * 0.618
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g ref={ref} {...events}>
|
<SVGContainer ref={ref} {...events}>
|
||||||
<circle
|
<circle
|
||||||
r={strokeWidth * 0.618}
|
r={strokeWidth * 0.618}
|
||||||
fill={styles.stroke}
|
fill={styles.stroke}
|
||||||
|
@ -55,7 +63,7 @@ export class Draw extends TLDrawShapeUtil<DrawShape, SVGGElement> {
|
||||||
strokeWidth={sw}
|
strokeWidth={sw}
|
||||||
pointerEvents="all"
|
pointerEvents="all"
|
||||||
/>
|
/>
|
||||||
</g>
|
</SVGContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +84,7 @@ export class Draw extends TLDrawShapeUtil<DrawShape, SVGGElement> {
|
||||||
: Utils.getFromCache(this.drawPathCache, points, () => getDrawStrokePath(shape, false))
|
: Utils.getFromCache(this.drawPathCache, points, () => getDrawStrokePath(shape, false))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g ref={ref} {...events}>
|
<SVGContainer ref={ref} {...events}>
|
||||||
{shouldFill && (
|
{shouldFill && (
|
||||||
<path
|
<path
|
||||||
d={polygonPathData}
|
d={polygonPathData}
|
||||||
|
@ -96,7 +104,7 @@ export class Draw extends TLDrawShapeUtil<DrawShape, SVGGElement> {
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
pointerEvents="all"
|
pointerEvents="all"
|
||||||
/>
|
/>
|
||||||
</g>
|
</SVGContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +129,7 @@ export class Draw extends TLDrawShapeUtil<DrawShape, SVGGElement> {
|
||||||
const sw = strokeWidth * 1.618
|
const sw = strokeWidth * 1.618
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g ref={ref} {...events}>
|
<SVGContainer ref={ref} {...events}>
|
||||||
<path
|
<path
|
||||||
d={path}
|
d={path}
|
||||||
fill={shouldFill ? styles.fill : 'none'}
|
fill={shouldFill ? styles.fill : 'none'}
|
||||||
|
@ -142,7 +150,7 @@ export class Draw extends TLDrawShapeUtil<DrawShape, SVGGElement> {
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
pointerEvents="stroke"
|
pointerEvents="stroke"
|
||||||
/>
|
/>
|
||||||
</g>
|
</SVGContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { Utils, TLTransformInfo, TLBounds, Intersect, TLShapeProps, Vec } from '@tldraw/core'
|
import {
|
||||||
|
SVGContainer,
|
||||||
|
Utils,
|
||||||
|
TLTransformInfo,
|
||||||
|
TLBounds,
|
||||||
|
Intersect,
|
||||||
|
TLShapeProps,
|
||||||
|
Vec,
|
||||||
|
} from '@tldraw/core'
|
||||||
import {
|
import {
|
||||||
ArrowShape,
|
ArrowShape,
|
||||||
DashStyle,
|
DashStyle,
|
||||||
EllipseShape,
|
EllipseShape,
|
||||||
TLDrawRenderInfo,
|
|
||||||
TLDrawShapeType,
|
TLDrawShapeType,
|
||||||
TLDrawShapeUtil,
|
TLDrawShapeUtil,
|
||||||
TLDrawToolType,
|
TLDrawToolType,
|
||||||
|
@ -15,7 +22,7 @@ import getStroke from 'perfect-freehand'
|
||||||
// TODO
|
// TODO
|
||||||
// [ ] Improve indicator shape for drawn shapes
|
// [ ] Improve indicator shape for drawn shapes
|
||||||
|
|
||||||
export class Ellipse extends TLDrawShapeUtil<EllipseShape, SVGGElement> {
|
export class Ellipse extends TLDrawShapeUtil<EllipseShape, SVGSVGElement> {
|
||||||
type = TLDrawShapeType.Ellipse as const
|
type = TLDrawShapeType.Ellipse as const
|
||||||
toolType = TLDrawToolType.Bounds
|
toolType = TLDrawToolType.Bounds
|
||||||
pathCache = new WeakMap<EllipseShape, string>([])
|
pathCache = new WeakMap<EllipseShape, string>([])
|
||||||
|
@ -37,7 +44,7 @@ export class Ellipse extends TLDrawShapeUtil<EllipseShape, SVGGElement> {
|
||||||
return next.radius !== prev.radius || next.style !== prev.style
|
return next.radius !== prev.radius || next.style !== prev.style
|
||||||
}
|
}
|
||||||
|
|
||||||
render = React.forwardRef<SVGGElement, TLShapeProps<EllipseShape, SVGGElement>>(
|
render = React.forwardRef<SVGSVGElement, TLShapeProps<EllipseShape, SVGSVGElement>>(
|
||||||
({ shape, meta, isBinding, events }, ref) => {
|
({ shape, meta, isBinding, events }, ref) => {
|
||||||
const {
|
const {
|
||||||
radius: [radiusX, radiusY],
|
radius: [radiusX, radiusY],
|
||||||
|
@ -56,7 +63,7 @@ export class Ellipse extends TLDrawShapeUtil<EllipseShape, SVGGElement> {
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g ref={ref} {...events}>
|
<SVGContainer ref={ref} {...events}>
|
||||||
{isBinding && (
|
{isBinding && (
|
||||||
<ellipse
|
<ellipse
|
||||||
className="tl-binding-indicator"
|
className="tl-binding-indicator"
|
||||||
|
@ -84,7 +91,7 @@ export class Ellipse extends TLDrawShapeUtil<EllipseShape, SVGGElement> {
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
/>
|
/>
|
||||||
</g>
|
</SVGContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +109,7 @@ export class Ellipse extends TLDrawShapeUtil<EllipseShape, SVGGElement> {
|
||||||
const sw = strokeWidth * 1.618
|
const sw = strokeWidth * 1.618
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g ref={ref} {...events}>
|
<SVGContainer ref={ref} {...events}>
|
||||||
{isBinding && (
|
{isBinding && (
|
||||||
<ellipse
|
<ellipse
|
||||||
className="tl-binding-indicator"
|
className="tl-binding-indicator"
|
||||||
|
@ -126,7 +133,7 @@ export class Ellipse extends TLDrawShapeUtil<EllipseShape, SVGGElement> {
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
/>
|
/>
|
||||||
</g>
|
</SVGContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { TLBounds, Utils, Vec, Intersect, TLShapeProps } from '@tldraw/core'
|
import { SVGContainer, TLBounds, Utils, Vec, Intersect, TLShapeProps } from '@tldraw/core'
|
||||||
import { defaultStyle, getPerfectDashProps } from '~shape/shape-styles'
|
import { defaultStyle, getPerfectDashProps } from '~shape/shape-styles'
|
||||||
import {
|
import {
|
||||||
GroupShape,
|
GroupShape,
|
||||||
|
@ -14,7 +14,7 @@ import {
|
||||||
// TODO
|
// TODO
|
||||||
// [ ] - Find bounds based on common bounds of descendants
|
// [ ] - Find bounds based on common bounds of descendants
|
||||||
|
|
||||||
export class Group extends TLDrawShapeUtil<GroupShape, SVGGElement> {
|
export class Group extends TLDrawShapeUtil<GroupShape, SVGSVGElement> {
|
||||||
type = TLDrawShapeType.Group as const
|
type = TLDrawShapeType.Group as const
|
||||||
toolType = TLDrawToolType.Bounds
|
toolType = TLDrawToolType.Bounds
|
||||||
canBind = true
|
canBind = true
|
||||||
|
@ -38,7 +38,7 @@ export class Group extends TLDrawShapeUtil<GroupShape, SVGGElement> {
|
||||||
return next.size !== prev.size || next.style !== prev.style
|
return next.size !== prev.size || next.style !== prev.style
|
||||||
}
|
}
|
||||||
|
|
||||||
render = React.forwardRef<SVGGElement, TLShapeProps<GroupShape, SVGGElement>>(
|
render = React.forwardRef<SVGSVGElement, TLShapeProps<GroupShape, SVGSVGElement>>(
|
||||||
({ shape, isBinding, isHovered, isSelected, events }, ref) => {
|
({ shape, isBinding, isHovered, isSelected, events }, ref) => {
|
||||||
const { id, size } = shape
|
const { id, size } = shape
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ export class Group extends TLDrawShapeUtil<GroupShape, SVGGElement> {
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g ref={ref} {...events}>
|
<SVGContainer ref={ref} {...events}>
|
||||||
{isBinding && (
|
{isBinding && (
|
||||||
<rect
|
<rect
|
||||||
className="tl-binding-indicator"
|
className="tl-binding-indicator"
|
||||||
|
@ -96,7 +96,7 @@ export class Group extends TLDrawShapeUtil<GroupShape, SVGGElement> {
|
||||||
pointerEvents="all"
|
pointerEvents="all"
|
||||||
/>
|
/>
|
||||||
<g pointerEvents="stroke">{paths}</g>
|
<g pointerEvents="stroke">{paths}</g>
|
||||||
</g>
|
</SVGContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { TLBounds, Utils, Vec, TLTransformInfo, Intersect, TLShapeProps } from '@tldraw/core'
|
import {
|
||||||
|
TLBounds,
|
||||||
|
Utils,
|
||||||
|
Vec,
|
||||||
|
TLTransformInfo,
|
||||||
|
Intersect,
|
||||||
|
TLShapeProps,
|
||||||
|
SVGContainer,
|
||||||
|
} from '@tldraw/core'
|
||||||
import getStroke from 'perfect-freehand'
|
import getStroke from 'perfect-freehand'
|
||||||
import { getPerfectDashProps, defaultStyle, getShapeStyle } from '~shape/shape-styles'
|
import { getPerfectDashProps, defaultStyle, getShapeStyle } from '~shape/shape-styles'
|
||||||
import {
|
import {
|
||||||
|
@ -14,7 +22,7 @@ import {
|
||||||
// TODO
|
// TODO
|
||||||
// [ ] - Make sure that fill does not extend drawn shape at corners
|
// [ ] - Make sure that fill does not extend drawn shape at corners
|
||||||
|
|
||||||
export class Rectangle extends TLDrawShapeUtil<RectangleShape, SVGGElement> {
|
export class Rectangle extends TLDrawShapeUtil<RectangleShape, SVGSVGElement> {
|
||||||
type = TLDrawShapeType.Rectangle as const
|
type = TLDrawShapeType.Rectangle as const
|
||||||
toolType = TLDrawToolType.Bounds
|
toolType = TLDrawToolType.Bounds
|
||||||
canBind = true
|
canBind = true
|
||||||
|
@ -36,7 +44,7 @@ export class Rectangle extends TLDrawShapeUtil<RectangleShape, SVGGElement> {
|
||||||
return next.size !== prev.size || next.style !== prev.style
|
return next.size !== prev.size || next.style !== prev.style
|
||||||
}
|
}
|
||||||
|
|
||||||
render = React.forwardRef<SVGGElement, TLShapeProps<RectangleShape, SVGGElement>>(
|
render = React.forwardRef<SVGSVGElement, TLShapeProps<RectangleShape, SVGSVGElement>>(
|
||||||
({ shape, isBinding, meta, events }, ref) => {
|
({ shape, isBinding, meta, events }, ref) => {
|
||||||
const { id, size, style } = shape
|
const { id, size, style } = shape
|
||||||
const styles = getShapeStyle(style, meta.isDarkMode)
|
const styles = getShapeStyle(style, meta.isDarkMode)
|
||||||
|
@ -46,7 +54,7 @@ export class Rectangle extends TLDrawShapeUtil<RectangleShape, SVGGElement> {
|
||||||
const pathData = Utils.getFromCache(this.pathCache, shape.size, () => renderPath(shape))
|
const pathData = Utils.getFromCache(this.pathCache, shape.size, () => renderPath(shape))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<g ref={ref} {...events}>
|
<SVGContainer ref={ref} {...events}>
|
||||||
{isBinding && (
|
{isBinding && (
|
||||||
<rect
|
<rect
|
||||||
className="tl-binding-indicator"
|
className="tl-binding-indicator"
|
||||||
|
@ -72,7 +80,7 @@ export class Rectangle extends TLDrawShapeUtil<RectangleShape, SVGGElement> {
|
||||||
strokeWidth={styles.strokeWidth}
|
strokeWidth={styles.strokeWidth}
|
||||||
pointerEvents="all"
|
pointerEvents="all"
|
||||||
/>
|
/>
|
||||||
</g>
|
</SVGContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { TLBounds, Utils, Vec, TLTransformInfo, Intersect, TLShapeProps } from '@tldraw/core'
|
import {
|
||||||
|
SVGContainer,
|
||||||
|
TLBounds,
|
||||||
|
Utils,
|
||||||
|
Vec,
|
||||||
|
TLTransformInfo,
|
||||||
|
Intersect,
|
||||||
|
TLShapeProps,
|
||||||
|
} from '@tldraw/core'
|
||||||
import { getShapeStyle, getFontSize, getFontStyle, defaultStyle } from '~shape/shape-styles'
|
import { getShapeStyle, getFontSize, getFontStyle, defaultStyle } from '~shape/shape-styles'
|
||||||
import { TextShape, TLDrawShapeUtil, TLDrawShapeType, TLDrawToolType, ArrowShape } from '~types'
|
import { TextShape, TLDrawShapeUtil, TLDrawShapeType, TLDrawToolType, ArrowShape } from '~types'
|
||||||
import styled from '~styles'
|
import styled from '~styles'
|
||||||
|
@ -49,7 +57,7 @@ if (typeof window !== 'undefined') {
|
||||||
melm = getMeasurementDiv()
|
melm = getMeasurementDiv()
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Text extends TLDrawShapeUtil<TextShape, SVGGElement> {
|
export class Text extends TLDrawShapeUtil<TextShape, SVGSVGElement> {
|
||||||
type = TLDrawShapeType.Text as const
|
type = TLDrawShapeType.Text as const
|
||||||
toolType = TLDrawToolType.Text
|
toolType = TLDrawToolType.Text
|
||||||
isAspectRatioLocked = true
|
isAspectRatioLocked = true
|
||||||
|
@ -83,7 +91,7 @@ export class Text extends TLDrawShapeUtil<TextShape, SVGGElement> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
render = React.forwardRef<SVGGElement, TLShapeProps<TextShape, SVGGElement>>(
|
render = React.forwardRef<SVGSVGElement, TLShapeProps<TextShape, SVGSVGElement>>(
|
||||||
({ shape, meta, isEditing, isBinding, events }, ref) => {
|
({ shape, meta, isEditing, isBinding, events }, ref) => {
|
||||||
const rInput = React.useRef<HTMLTextAreaElement>(null)
|
const rInput = React.useRef<HTMLTextAreaElement>(null)
|
||||||
const { id, text, style } = shape
|
const { id, text, style } = shape
|
||||||
|
@ -151,7 +159,7 @@ export class Text extends TLDrawShapeUtil<TextShape, SVGGElement> {
|
||||||
|
|
||||||
if (!isEditing) {
|
if (!isEditing) {
|
||||||
return (
|
return (
|
||||||
<g ref={ref} {...events}>
|
<SVGContainer ref={ref} {...events}>
|
||||||
{isBinding && (
|
{isBinding && (
|
||||||
<rect
|
<rect
|
||||||
className="tl-binding-indicator"
|
className="tl-binding-indicator"
|
||||||
|
@ -183,41 +191,43 @@ export class Text extends TLDrawShapeUtil<TextShape, SVGGElement> {
|
||||||
{str}
|
{str}
|
||||||
</text>
|
</text>
|
||||||
))}
|
))}
|
||||||
</g>
|
</SVGContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<foreignObject
|
<SVGContainer ref={ref} {...events}>
|
||||||
width={bounds.width}
|
<foreignObject
|
||||||
height={bounds.height}
|
width={bounds.width}
|
||||||
pointerEvents="none"
|
height={bounds.height}
|
||||||
onPointerDown={(e) => e.stopPropagation()}
|
pointerEvents="none"
|
||||||
>
|
onPointerDown={(e) => e.stopPropagation()}
|
||||||
<StyledTextArea
|
>
|
||||||
ref={rInput}
|
<StyledTextArea
|
||||||
style={{
|
ref={rInput}
|
||||||
font,
|
style={{
|
||||||
color: styles.stroke,
|
font,
|
||||||
}}
|
color: styles.stroke,
|
||||||
name="text"
|
}}
|
||||||
defaultValue={text}
|
name="text"
|
||||||
tabIndex={-1}
|
defaultValue={text}
|
||||||
autoComplete="false"
|
tabIndex={-1}
|
||||||
autoCapitalize="false"
|
autoComplete="false"
|
||||||
autoCorrect="false"
|
autoCapitalize="false"
|
||||||
autoSave="false"
|
autoCorrect="false"
|
||||||
placeholder=""
|
autoSave="false"
|
||||||
color={styles.stroke}
|
placeholder=""
|
||||||
autoFocus={true}
|
color={styles.stroke}
|
||||||
onFocus={handleFocus}
|
autoFocus={true}
|
||||||
onBlur={handleBlur}
|
onFocus={handleFocus}
|
||||||
onKeyDown={handleKeyDown}
|
onBlur={handleBlur}
|
||||||
onKeyUp={handleKeyUp}
|
onKeyDown={handleKeyDown}
|
||||||
onChange={handleChange}
|
onKeyUp={handleKeyUp}
|
||||||
onPointerDown={handlePointerDown}
|
onChange={handleChange}
|
||||||
/>
|
onPointerDown={handlePointerDown}
|
||||||
</foreignObject>
|
/>
|
||||||
|
</foreignObject>
|
||||||
|
</SVGContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue