Add optional generic to updateShapes
/ createShapes
(#1579)
This PR adds a generic that we can use with `updateShapes` and `createShapes` in order to type the partials being passed into those methods. By default, the partials are typed as `TLUnknownShape`, which accepts any props. ### Change Type - [x] `minor` — New feature ### Test Plan - [x] Unit Tests ### Release Notes - [editor] adds an optional shape generic to `updateShapes` and `createShapes`
This commit is contained in:
parent
69e5b248ca
commit
ce1cf82029
20 changed files with 436 additions and 274 deletions
|
@ -1,4 +1,11 @@
|
||||||
import { createShapeId, Editor, Tldraw, TLGeoShape, useEditor } from '@tldraw/tldraw'
|
import {
|
||||||
|
createShapeId,
|
||||||
|
Editor,
|
||||||
|
Tldraw,
|
||||||
|
TLGeoShape,
|
||||||
|
TLShapePartial,
|
||||||
|
useEditor,
|
||||||
|
} from '@tldraw/tldraw'
|
||||||
import '@tldraw/tldraw/editor.css'
|
import '@tldraw/tldraw/editor.css'
|
||||||
import '@tldraw/tldraw/ui.css'
|
import '@tldraw/tldraw/ui.css'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
|
@ -18,7 +25,7 @@ export default function APIExample() {
|
||||||
editor.focus()
|
editor.focus()
|
||||||
|
|
||||||
// Create a shape
|
// Create a shape
|
||||||
editor.createShapes([
|
editor.createShapes<TLGeoShape>([
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
type: 'geo',
|
type: 'geo',
|
||||||
|
@ -38,17 +45,17 @@ export default function APIExample() {
|
||||||
// Get the created shape
|
// Get the created shape
|
||||||
const shape = editor.getShapeById<TLGeoShape>(id)!
|
const shape = editor.getShapeById<TLGeoShape>(id)!
|
||||||
|
|
||||||
// Update the shape
|
const shapeUpdate: TLShapePartial<TLGeoShape> = {
|
||||||
editor.updateShapes([
|
id,
|
||||||
{
|
type: 'geo',
|
||||||
id,
|
props: {
|
||||||
type: 'geo',
|
h: shape.props.h * 3,
|
||||||
props: {
|
text: 'hello world!',
|
||||||
h: shape.props.h * 3,
|
|
||||||
text: 'hello world!',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
])
|
}
|
||||||
|
|
||||||
|
// Update the shape
|
||||||
|
editor.updateShapes([shapeUpdate])
|
||||||
|
|
||||||
// Select the shape
|
// Select the shape
|
||||||
editor.select(id)
|
editor.select(id)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { createShapeId, Tldraw } from '@tldraw/tldraw'
|
import { createShapeId, Tldraw, TLShapePartial } from '@tldraw/tldraw'
|
||||||
import '@tldraw/tldraw/editor.css'
|
import '@tldraw/tldraw/editor.css'
|
||||||
import '@tldraw/tldraw/ui.css'
|
import '@tldraw/tldraw/ui.css'
|
||||||
import { ErrorShape } from './ErrorShape'
|
import { ErrorShape } from './ErrorShape'
|
||||||
|
@ -16,16 +16,16 @@ export default function ErrorBoundaryExample() {
|
||||||
ShapeErrorFallback: ({ error }) => <div>Shape error! {String(error)}</div>, // use a custom error fallback for shapes
|
ShapeErrorFallback: ({ error }) => <div>Shape error! {String(error)}</div>, // use a custom error fallback for shapes
|
||||||
}}
|
}}
|
||||||
onMount={(editor) => {
|
onMount={(editor) => {
|
||||||
|
const errorShapePartial: TLShapePartial<ErrorShape> = {
|
||||||
|
type: 'error',
|
||||||
|
id: createShapeId(),
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
props: { message: 'Something has gone wrong' },
|
||||||
|
}
|
||||||
|
|
||||||
// When the app starts, create our error shape so we can see.
|
// When the app starts, create our error shape so we can see.
|
||||||
editor.createShapes([
|
editor.createShapes<ErrorShape>([errorShapePartial])
|
||||||
{
|
|
||||||
type: 'error',
|
|
||||||
id: createShapeId(),
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
props: { message: 'Something has gone wrong' },
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
// Center the camera on the error shape
|
// Center the camera on the error shape
|
||||||
editor.zoomToFit()
|
editor.zoomToFit()
|
||||||
|
|
|
@ -424,7 +424,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
createPage(title: string, id?: TLPageId, belowPageIndex?: string): this;
|
createPage(title: string, id?: TLPageId, belowPageIndex?: string): this;
|
||||||
createShapes(partials: TLShapePartial[], select?: boolean): this;
|
createShapes<T extends TLUnknownShape>(partials: TLShapePartial<T>[], select?: boolean): this;
|
||||||
get croppingId(): null | TLShapeId;
|
get croppingId(): null | TLShapeId;
|
||||||
get cullingBounds(): Box2d;
|
get cullingBounds(): Box2d;
|
||||||
// @internal (undocumented)
|
// @internal (undocumented)
|
||||||
|
@ -760,7 +760,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
||||||
updateDocumentSettings(settings: Partial<TLDocument>): void;
|
updateDocumentSettings(settings: Partial<TLDocument>): void;
|
||||||
updateInstanceState(partial: Partial<Omit<TLInstance, 'currentPageId'>>, ephemeral?: boolean, squashing?: boolean): this;
|
updateInstanceState(partial: Partial<Omit<TLInstance, 'currentPageId'>>, ephemeral?: boolean, squashing?: boolean): this;
|
||||||
updatePage(partial: RequiredKeys<TLPage, 'id'>, squashing?: boolean): this;
|
updatePage(partial: RequiredKeys<TLPage, 'id'>, squashing?: boolean): this;
|
||||||
updateShapes(partials: (null | TLShapePartial | undefined)[], squashing?: boolean): this;
|
updateShapes<T extends TLUnknownShape>(partials: (null | TLShapePartial<T> | undefined)[], squashing?: boolean): this;
|
||||||
updateViewportScreenBounds(center?: boolean): this;
|
updateViewportScreenBounds(center?: boolean): this;
|
||||||
// (undocumented)
|
// (undocumented)
|
||||||
readonly user: UserPreferencesManager;
|
readonly user: UserPreferencesManager;
|
||||||
|
|
|
@ -1348,7 +1348,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finalIndex !== reparentedArrow.index) {
|
if (finalIndex !== reparentedArrow.index) {
|
||||||
this.updateShapes([{ id: arrowId, type: 'arrow', index: finalIndex }])
|
this.updateShapes<TLArrowShape>([{ id: arrowId, type: 'arrow', index: finalIndex }])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4636,14 +4636,14 @@ export class Editor extends EventEmitter<TLEventMap> {
|
||||||
* @example
|
* @example
|
||||||
*
|
*
|
||||||
* ```ts
|
* ```ts
|
||||||
* editor.createShapes([{ id: 'box1', type: 'box' }])
|
* editor.createShapes([{ id: 'box1', type: 'text', props: { text: "ok" } }])
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param partials - The shape partials to create.
|
* @param partials - The shape partials to create.
|
||||||
* @param select - Whether to select the created shapes. Defaults to false.
|
* @param select - Whether to select the created shapes. Defaults to false.
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
createShapes(partials: TLShapePartial[], select = false) {
|
createShapes<T extends TLUnknownShape>(partials: TLShapePartial<T>[], select = false) {
|
||||||
this._createShapes(partials, select)
|
this._createShapes(partials, select)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -4934,14 +4934,17 @@ export class Editor extends EventEmitter<TLEventMap> {
|
||||||
* @example
|
* @example
|
||||||
*
|
*
|
||||||
* ```ts
|
* ```ts
|
||||||
* editor.updateShapes([{ id: 'box1', type: 'box', x: 100, y: 100 }])
|
* editor.updateShapes([{ id: 'box1', type: 'geo', props: { w: 100, h: 100 } }])
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param partials - The shape partials to update.
|
* @param partials - The shape partials to update.
|
||||||
* @param squashing - Whether the change is ephemeral.
|
* @param squashing - Whether the change is ephemeral.
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
updateShapes(partials: (TLShapePartial | null | undefined)[], squashing = false) {
|
updateShapes<T extends TLUnknownShape>(
|
||||||
|
partials: (TLShapePartial<T> | null | undefined)[],
|
||||||
|
squashing = false
|
||||||
|
) {
|
||||||
let compactedPartials = compact(partials)
|
let compactedPartials = compact(partials)
|
||||||
if (this.animatingShapes.size > 0) {
|
if (this.animatingShapes.size > 0) {
|
||||||
compactedPartials.forEach((p) => this.animatingShapes.delete(p.id))
|
compactedPartials.forEach((p) => this.animatingShapes.delete(p.id))
|
||||||
|
@ -8985,7 +8988,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
||||||
const highestIndex = shapesWithRootParent[shapesWithRootParent.length - 1]?.index
|
const highestIndex = shapesWithRootParent[shapesWithRootParent.length - 1]?.index
|
||||||
|
|
||||||
this.batch(() => {
|
this.batch(() => {
|
||||||
this.createShapes([
|
this.createShapes<TLGroupShape>([
|
||||||
{
|
{
|
||||||
id: groupId,
|
id: groupId,
|
||||||
type: 'group',
|
type: 'group',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { TLShapeId } from '@tldraw/tlschema'
|
import { TLArrowShape, TLShapeId } from '@tldraw/tlschema'
|
||||||
import { TestEditor } from '../../test/TestEditor'
|
import { TestEditor } from '../../test/TestEditor'
|
||||||
import { TL } from '../../test/jsx'
|
import { TL } from '../../test/jsx'
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ describe('arrowBindingsIndex', () => {
|
||||||
)
|
)
|
||||||
|
|
||||||
// move arrowA from box2 to box3
|
// move arrowA from box2 to box3
|
||||||
editor.updateShapes([
|
editor.updateShapes<TLArrowShape>([
|
||||||
{
|
{
|
||||||
id: arrowAId,
|
id: arrowAId,
|
||||||
type: 'arrow',
|
type: 'arrow',
|
||||||
|
|
|
@ -6,6 +6,8 @@ import {
|
||||||
TLAssetId,
|
TLAssetId,
|
||||||
TLEmbedShape,
|
TLEmbedShape,
|
||||||
TLShapePartial,
|
TLShapePartial,
|
||||||
|
TLTextShape,
|
||||||
|
TLTextShapeProps,
|
||||||
createShapeId,
|
createShapeId,
|
||||||
} from '@tldraw/tlschema'
|
} from '@tldraw/tlschema'
|
||||||
import { compact, getHashForString } from '@tldraw/utils'
|
import { compact, getHashForString } from '@tldraw/utils'
|
||||||
|
@ -248,7 +250,7 @@ export class ExternalContentManager {
|
||||||
let w: number
|
let w: number
|
||||||
let h: number
|
let h: number
|
||||||
let autoSize: boolean
|
let autoSize: boolean
|
||||||
let align = 'middle'
|
let align = 'middle' as TLTextShapeProps['align']
|
||||||
|
|
||||||
const isMultiLine = textToPaste.split('\n').length > 1
|
const isMultiLine = textToPaste.split('\n').length > 1
|
||||||
|
|
||||||
|
@ -293,7 +295,7 @@ export class ExternalContentManager {
|
||||||
p.y = editor.viewportPageBounds.minY + 40 + h / 2
|
p.y = editor.viewportPageBounds.minY + 40 + h / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.createShapes([
|
editor.createShapes<TLTextShape>([
|
||||||
{
|
{
|
||||||
id: createShapeId(),
|
id: createShapeId(),
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
|
|
@ -907,7 +907,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
|
||||||
} = shape
|
} = shape
|
||||||
|
|
||||||
if (text.trimEnd() !== shape.props.text) {
|
if (text.trimEnd() !== shape.props.text) {
|
||||||
this.editor.updateShapes([
|
this.editor.updateShapes<TLArrowShape>([
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
type,
|
type,
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { createShapeId, TLArrowShape } from '@tldraw/tlschema'
|
||||||
import { ArrowShapeUtil } from '../../../shapes/arrow/ArrowShapeUtil'
|
import { ArrowShapeUtil } from '../../../shapes/arrow/ArrowShapeUtil'
|
||||||
import { StateNode } from '../../../tools/StateNode'
|
import { StateNode } from '../../../tools/StateNode'
|
||||||
import { TLEventHandlers } from '../../../types/event-types'
|
import { TLEventHandlers } from '../../../types/event-types'
|
||||||
import { ArrowShapeTool } from '../ArrowShapeTool'
|
|
||||||
|
|
||||||
export class Pointing extends StateNode {
|
export class Pointing extends StateNode {
|
||||||
static override id = 'pointing'
|
static override id = 'pointing'
|
||||||
|
@ -31,16 +30,14 @@ export class Pointing extends StateNode {
|
||||||
|
|
||||||
this.didTimeout = false
|
this.didTimeout = false
|
||||||
|
|
||||||
const shapeType = (this.parent as ArrowShapeTool).shapeType
|
|
||||||
|
|
||||||
this.editor.mark('creating')
|
this.editor.mark('creating')
|
||||||
|
|
||||||
const id = createShapeId()
|
const id = createShapeId()
|
||||||
|
|
||||||
this.editor.createShapes([
|
this.editor.createShapes<TLArrowShape>([
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
type: shapeType,
|
type: 'arrow',
|
||||||
x: currentPagePoint.x,
|
x: currentPagePoint.x,
|
||||||
y: currentPagePoint.y,
|
y: currentPagePoint.y,
|
||||||
},
|
},
|
||||||
|
|
|
@ -139,7 +139,7 @@ function updateBookmarkAssetOnUrlChange(editor: Editor, shape: TLBookmarkShape)
|
||||||
if (editor.getAssetById(assetId)) {
|
if (editor.getAssetById(assetId)) {
|
||||||
// Existing asset for this URL?
|
// Existing asset for this URL?
|
||||||
if (shape.props.assetId !== assetId) {
|
if (shape.props.assetId !== assetId) {
|
||||||
editor.updateShapes([
|
editor.updateShapes<TLBookmarkShape>([
|
||||||
{
|
{
|
||||||
id: shape.id,
|
id: shape.id,
|
||||||
type: shape.type,
|
type: shape.type,
|
||||||
|
@ -151,7 +151,7 @@ function updateBookmarkAssetOnUrlChange(editor: Editor, shape: TLBookmarkShape)
|
||||||
// No asset for this URL?
|
// No asset for this URL?
|
||||||
|
|
||||||
// First, clear out the existing asset reference
|
// First, clear out the existing asset reference
|
||||||
editor.updateShapes([
|
editor.updateShapes<TLBookmarkShape>([
|
||||||
{
|
{
|
||||||
id: shape.id,
|
id: shape.id,
|
||||||
type: shape.type,
|
type: shape.type,
|
||||||
|
@ -181,7 +181,7 @@ const createBookmarkAssetOnUrlChange = debounce(async (editor: Editor, shape: TL
|
||||||
editor.createAssets([asset])
|
editor.createAssets([asset])
|
||||||
|
|
||||||
// And update the shape
|
// And update the shape
|
||||||
editor.updateShapes([
|
editor.updateShapes<TLBookmarkShape>([
|
||||||
{
|
{
|
||||||
id: shape.id,
|
id: shape.id,
|
||||||
type: shape.type,
|
type: shape.type,
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
TLDrawShape,
|
TLDrawShape,
|
||||||
TLDrawShapeSegment,
|
TLDrawShapeSegment,
|
||||||
TLHighlightShape,
|
TLHighlightShape,
|
||||||
|
TLShapePartial,
|
||||||
TLSizeType,
|
TLSizeType,
|
||||||
Vec2dModel,
|
Vec2dModel,
|
||||||
} from '@tldraw/tlschema'
|
} from '@tldraw/tlschema'
|
||||||
|
@ -25,7 +26,7 @@ export class Drawing extends StateNode {
|
||||||
|
|
||||||
initialShape?: DrawableShape
|
initialShape?: DrawableShape
|
||||||
|
|
||||||
shapeType: 'draw' | 'highlight' = this.parent.id === 'highlight' ? 'highlight' : 'draw'
|
shapeType: DrawableShape['type'] = this.parent.id === 'highlight' ? 'highlight' : 'draw'
|
||||||
|
|
||||||
util =
|
util =
|
||||||
this.shapeType === 'highlight'
|
this.shapeType === 'highlight'
|
||||||
|
@ -219,16 +220,22 @@ export class Drawing extends StateNode {
|
||||||
|
|
||||||
this.currentLineLength = this.getLineLength(segments)
|
this.currentLineLength = this.getLineLength(segments)
|
||||||
|
|
||||||
this.editor.updateShapes([
|
const shapePartial: TLShapePartial<DrawableShape> = {
|
||||||
{
|
id: shape.id,
|
||||||
id: shape.id,
|
type: this.shapeType,
|
||||||
type: this.shapeType,
|
props: {
|
||||||
props: {
|
segments,
|
||||||
segments,
|
|
||||||
isClosed: this.canClose() ? this.getIsClosed(segments, shape.props.size) : undefined,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
])
|
}
|
||||||
|
|
||||||
|
if (this.canClose()) {
|
||||||
|
;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(
|
||||||
|
segments,
|
||||||
|
shape.props.size
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editor.updateShapes<TLDrawShape | TLHighlightShape>([shapePartial])
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -238,7 +245,8 @@ export class Drawing extends StateNode {
|
||||||
|
|
||||||
this.pagePointWhereCurrentSegmentChanged = originPagePoint.clone()
|
this.pagePointWhereCurrentSegmentChanged = originPagePoint.clone()
|
||||||
const id = createShapeId()
|
const id = createShapeId()
|
||||||
this.editor.createShapes([
|
|
||||||
|
this.editor.createShapes<DrawableShape>([
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
type: this.shapeType,
|
type: this.shapeType,
|
||||||
|
@ -261,7 +269,6 @@ export class Drawing extends StateNode {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
this.currentLineLength = 0
|
this.currentLineLength = 0
|
||||||
this.initialShape = this.editor.getShapeById<DrawableShape>(id)
|
this.initialShape = this.editor.getShapeById<DrawableShape>(id)
|
||||||
}
|
}
|
||||||
|
@ -343,19 +350,22 @@ export class Drawing extends StateNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.editor.updateShapes(
|
const shapePartial: TLShapePartial<DrawableShape> = {
|
||||||
[
|
id,
|
||||||
{
|
type: this.shapeType,
|
||||||
id,
|
props: {
|
||||||
type: this.shapeType,
|
segments: [...segments, newSegment],
|
||||||
props: {
|
},
|
||||||
segments: [...segments, newSegment],
|
}
|
||||||
isClosed: this.canClose() ? this.getIsClosed(segments, size) : undefined,
|
|
||||||
},
|
if (this.canClose()) {
|
||||||
},
|
;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(
|
||||||
],
|
segments,
|
||||||
true
|
size
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editor.updateShapes<TLDrawShape | TLHighlightShape>([shapePartial], true)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -400,19 +410,22 @@ export class Drawing extends StateNode {
|
||||||
const finalSegments = [...newSegments, newFreeSegment]
|
const finalSegments = [...newSegments, newFreeSegment]
|
||||||
this.currentLineLength = this.getLineLength(finalSegments)
|
this.currentLineLength = this.getLineLength(finalSegments)
|
||||||
|
|
||||||
this.editor.updateShapes(
|
const shapePartial: TLShapePartial<DrawableShape> = {
|
||||||
[
|
id,
|
||||||
{
|
type: this.shapeType,
|
||||||
id,
|
props: {
|
||||||
type: this.shapeType,
|
segments: finalSegments,
|
||||||
props: {
|
},
|
||||||
segments: finalSegments,
|
}
|
||||||
isClosed: this.canClose() ? this.getIsClosed(finalSegments, size) : undefined,
|
|
||||||
},
|
if (this.canClose()) {
|
||||||
},
|
;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(
|
||||||
],
|
finalSegments,
|
||||||
true
|
size
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editor.updateShapes([shapePartial], true)
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
|
@ -539,19 +552,22 @@ export class Drawing extends StateNode {
|
||||||
points: [newSegment.points[0], newPoint],
|
points: [newSegment.points[0], newPoint],
|
||||||
}
|
}
|
||||||
|
|
||||||
this.editor.updateShapes(
|
const shapePartial: TLShapePartial<DrawableShape> = {
|
||||||
[
|
id,
|
||||||
{
|
type: this.shapeType,
|
||||||
id,
|
props: {
|
||||||
type: this.shapeType,
|
segments: newSegments,
|
||||||
props: {
|
},
|
||||||
segments: newSegments,
|
}
|
||||||
isClosed: this.canClose() ? this.getIsClosed(segments, size) : undefined,
|
|
||||||
},
|
if (this.canClose()) {
|
||||||
},
|
;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(
|
||||||
],
|
segments,
|
||||||
true
|
size
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editor.updateShapes([shapePartial], true)
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -581,19 +597,22 @@ export class Drawing extends StateNode {
|
||||||
|
|
||||||
this.currentLineLength = this.getLineLength(newSegments)
|
this.currentLineLength = this.getLineLength(newSegments)
|
||||||
|
|
||||||
this.editor.updateShapes(
|
const shapePartial: TLShapePartial<DrawableShape> = {
|
||||||
[
|
id,
|
||||||
{
|
type: this.shapeType,
|
||||||
id,
|
props: {
|
||||||
type: this.shapeType,
|
segments: newSegments,
|
||||||
props: {
|
},
|
||||||
segments: newSegments,
|
}
|
||||||
isClosed: this.canClose() ? this.getIsClosed(segments, size) : undefined,
|
|
||||||
},
|
if (this.canClose()) {
|
||||||
},
|
;(shapePartial as TLShapePartial<TLDrawShape>).props!.isClosed = this.getIsClosed(
|
||||||
],
|
newSegments,
|
||||||
true
|
size
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editor.updateShapes([shapePartial], true)
|
||||||
|
|
||||||
// Set a maximum length for the lines array; after 200 points, complete the line.
|
// Set a maximum length for the lines array; after 200 points, complete the line.
|
||||||
if (newPoints.length > 500) {
|
if (newPoints.length > 500) {
|
||||||
|
@ -603,7 +622,7 @@ export class Drawing extends StateNode {
|
||||||
|
|
||||||
const newShapeId = createShapeId()
|
const newShapeId = createShapeId()
|
||||||
|
|
||||||
this.editor.createShapes([
|
this.editor.createShapes<DrawableShape>([
|
||||||
{
|
{
|
||||||
id: newShapeId,
|
id: newShapeId,
|
||||||
type: this.shapeType,
|
type: this.shapeType,
|
||||||
|
|
|
@ -14,7 +14,7 @@ export class Pointing extends StateNode {
|
||||||
|
|
||||||
this.editor.mark('creating')
|
this.editor.mark('creating')
|
||||||
|
|
||||||
this.editor.createShapes([
|
this.editor.createShapes<TLGeoShape>([
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
type: 'geo',
|
type: 'geo',
|
||||||
|
@ -63,7 +63,7 @@ export class Pointing extends StateNode {
|
||||||
|
|
||||||
this.editor.mark('creating')
|
this.editor.mark('creating')
|
||||||
|
|
||||||
this.editor.createShapes([
|
this.editor.createShapes<TLGeoShape>([
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
type: 'geo',
|
type: 'geo',
|
||||||
|
@ -85,7 +85,7 @@ export class Pointing extends StateNode {
|
||||||
const delta = this.editor.getDeltaInParentSpace(shape, bounds.center)
|
const delta = this.editor.getDeltaInParentSpace(shape, bounds.center)
|
||||||
|
|
||||||
this.editor.select(id)
|
this.editor.select(id)
|
||||||
this.editor.updateShapes([
|
this.editor.updateShapes<TLGeoShape>([
|
||||||
{
|
{
|
||||||
id: shape.id,
|
id: shape.id,
|
||||||
type: 'geo',
|
type: 'geo',
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { TLHandle, TLLineShape, TLShapeId, createShapeId } from '@tldraw/tlschem
|
||||||
import { last, structuredClone } from '@tldraw/utils'
|
import { last, structuredClone } from '@tldraw/utils'
|
||||||
import { StateNode } from '../../../tools/StateNode'
|
import { StateNode } from '../../../tools/StateNode'
|
||||||
import { TLEventHandlers, TLInterruptEvent } from '../../../types/event-types'
|
import { TLEventHandlers, TLInterruptEvent } from '../../../types/event-types'
|
||||||
import { LineShapeTool } from '../LineShapeTool'
|
|
||||||
|
|
||||||
export class Pointing extends StateNode {
|
export class Pointing extends StateNode {
|
||||||
static override id = 'pointing'
|
static override id = 'pointing'
|
||||||
|
@ -79,10 +78,10 @@ export class Pointing extends StateNode {
|
||||||
} else {
|
} else {
|
||||||
const id = createShapeId()
|
const id = createShapeId()
|
||||||
|
|
||||||
this.editor.createShapes([
|
this.editor.createShapes<TLLineShape>([
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
type: (this.parent as LineShapeTool).shapeType,
|
type: 'line',
|
||||||
x: currentPagePoint.x,
|
x: currentPagePoint.x,
|
||||||
y: currentPagePoint.y,
|
y: currentPagePoint.y,
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* eslint-disable no-inner-declarations */
|
/* eslint-disable no-inner-declarations */
|
||||||
import { TLShape } from '@tldraw/tlschema'
|
import { TLShape, TLUnknownShape } from '@tldraw/tlschema'
|
||||||
import React, { useCallback, useEffect, useRef } from 'react'
|
import React, { useCallback, useEffect, useRef } from 'react'
|
||||||
import { useValue } from 'signia-react'
|
import { useValue } from 'signia-react'
|
||||||
import { useEditor } from '../../../hooks/useEditor'
|
import { useEditor } from '../../../hooks/useEditor'
|
||||||
|
@ -145,7 +145,9 @@ export function useEditableText<T extends Extract<TLShape, { props: { text: stri
|
||||||
}
|
}
|
||||||
// ----------------------------
|
// ----------------------------
|
||||||
|
|
||||||
editor.updateShapes([{ id, type, props: { text } }])
|
editor.updateShapes<TLUnknownShape & { props: { text: string } }>([
|
||||||
|
{ id, type, props: { text } },
|
||||||
|
])
|
||||||
},
|
},
|
||||||
[editor, id, type]
|
[editor, id, type]
|
||||||
)
|
)
|
||||||
|
|
|
@ -21,7 +21,7 @@ export class Pointing extends StateNode {
|
||||||
|
|
||||||
this.editor.mark('creating')
|
this.editor.mark('creating')
|
||||||
|
|
||||||
this.editor.createShapes([
|
this.editor.createShapes<TLTextShape>([
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
|
|
@ -27,20 +27,21 @@ export class Pointing extends StateNode {
|
||||||
|
|
||||||
this.editor.mark(this.markId)
|
this.editor.mark(this.markId)
|
||||||
|
|
||||||
this.editor.createShapes([
|
this.editor.createShapes<TLBaseBoxShape>(
|
||||||
{
|
[
|
||||||
id,
|
{
|
||||||
type: shapeType,
|
id,
|
||||||
x: originPagePoint.x,
|
type: shapeType,
|
||||||
y: originPagePoint.y,
|
x: originPagePoint.x,
|
||||||
props: {
|
y: originPagePoint.y,
|
||||||
w: 1,
|
props: {
|
||||||
h: 1,
|
w: 1,
|
||||||
|
h: 1,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
],
|
||||||
])
|
true
|
||||||
|
)
|
||||||
this.editor.setSelectedIds([id])
|
|
||||||
this.editor.setSelectedTool('select.resizing', {
|
this.editor.setSelectedTool('select.resizing', {
|
||||||
...info,
|
...info,
|
||||||
target: 'selection',
|
target: 'selection',
|
||||||
|
@ -83,7 +84,7 @@ export class Pointing extends StateNode {
|
||||||
|
|
||||||
this.editor.mark(this.markId)
|
this.editor.mark(this.markId)
|
||||||
|
|
||||||
this.editor.createShapes([
|
this.editor.createShapes<TLBaseBoxShape>([
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
type: shapeType,
|
type: shapeType,
|
||||||
|
@ -96,7 +97,7 @@ export class Pointing extends StateNode {
|
||||||
const { w, h } = this.editor.getShapeUtil(shape).defaultProps() as TLBaseBoxShape['props']
|
const { w, h } = this.editor.getShapeUtil(shape).defaultProps() as TLBaseBoxShape['props']
|
||||||
const delta = this.editor.getDeltaInParentSpace(shape, new Vec2d(w / 2, h / 2))
|
const delta = this.editor.getDeltaInParentSpace(shape, new Vec2d(w / 2, h / 2))
|
||||||
|
|
||||||
this.editor.updateShapes([
|
this.editor.updateShapes<TLBaseBoxShape>([
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
type: shapeType,
|
type: shapeType,
|
||||||
|
|
|
@ -185,7 +185,7 @@ export class Idle extends StateNode {
|
||||||
this.editor.mark('translate crop')
|
this.editor.mark('translate crop')
|
||||||
}
|
}
|
||||||
|
|
||||||
this.editor.updateShapes([partial])
|
this.editor.updateShapes<ShapeWithCrop>([partial])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Vec2d } from '@tldraw/primitives'
|
import { Vec2d } from '@tldraw/primitives'
|
||||||
import { TLGeoShape, TLShape, createShapeId } from '@tldraw/tlschema'
|
import { TLGeoShape, TLShape, TLTextShape, createShapeId } from '@tldraw/tlschema'
|
||||||
import { debugFlags } from '../../../../utils/debug-flags'
|
import { debugFlags } from '../../../../utils/debug-flags'
|
||||||
import {
|
import {
|
||||||
TLClickEventInfo,
|
TLClickEventInfo,
|
||||||
|
@ -382,7 +382,7 @@ export class Idle extends StateNode {
|
||||||
|
|
||||||
const { x, y } = this.editor.inputs.currentPagePoint
|
const { x, y } = this.editor.inputs.currentPagePoint
|
||||||
|
|
||||||
this.editor.createShapes([
|
this.editor.createShapes<TLTextShape>([
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
type: 'text',
|
type: 'text',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { TLGeoShape, createShapeId } from '@tldraw/tlschema'
|
import { TLArrowShape, TLGeoShape, createShapeId } from '@tldraw/tlschema'
|
||||||
import { TestEditor } from '../TestEditor'
|
import { TestEditor } from '../TestEditor'
|
||||||
|
|
||||||
let editor: TestEditor
|
let editor: TestEditor
|
||||||
|
@ -16,6 +16,72 @@ beforeEach(() => {
|
||||||
editor = new TestEditor()
|
editor = new TestEditor()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Uses typescript generics', () => {
|
||||||
|
expect(() => {
|
||||||
|
// No error here because no generic, the editor doesn't know what this guy is
|
||||||
|
editor.createShapes([
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
type: 'geo',
|
||||||
|
props: { w: 'OH NO' },
|
||||||
|
},
|
||||||
|
])
|
||||||
|
// Yep error here because we are giving the wrong props to the shape
|
||||||
|
editor.createShapes<TLGeoShape>([
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
type: 'geo',
|
||||||
|
//@ts-expect-error
|
||||||
|
props: { w: 'OH NO' },
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// Yep error here because we are giving the wrong generic
|
||||||
|
editor.createShapes<TLArrowShape>([
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
//@ts-expect-error
|
||||||
|
type: 'geo',
|
||||||
|
//@ts-expect-error
|
||||||
|
props: { w: 'OH NO' },
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// All good, correct match of generic and shape type
|
||||||
|
editor.createShapes<TLGeoShape>([
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
type: 'geo',
|
||||||
|
props: { w: 100 },
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
editor.createShapes<TLGeoShape>([
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
type: 'geo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
// @ts-expect-error - wrong type
|
||||||
|
type: 'arrow',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// Unions are supported just fine
|
||||||
|
editor.createShapes<TLGeoShape | TLArrowShape>([
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
type: 'geo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
type: 'arrow',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}).toThrowError()
|
||||||
|
})
|
||||||
|
|
||||||
it('Parents shapes to the current page if the parent is not found', () => {
|
it('Parents shapes to the current page if the parent is not found', () => {
|
||||||
editor.createShapes([{ id: ids.box1, parentId: ids.missing, type: 'geo' }])
|
editor.createShapes([{ id: ids.box1, parentId: ids.missing, type: 'geo' }])
|
||||||
expect(editor.getShapeById(ids.box1)!.parentId).toEqual(editor.currentPageId)
|
expect(editor.getShapeById(ids.box1)!.parentId).toEqual(editor.currentPageId)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { createShapeId } from '@tldraw/tlschema'
|
import { createShapeId, TLArrowShape, TLGeoShape } from '@tldraw/tlschema'
|
||||||
import { createDefaultShapes, TestEditor } from '../TestEditor'
|
import { createDefaultShapes, TestEditor } from '../TestEditor'
|
||||||
|
|
||||||
let editor: TestEditor
|
let editor: TestEditor
|
||||||
|
@ -13,6 +13,73 @@ beforeEach(() => {
|
||||||
editor.createShapes(createDefaultShapes())
|
editor.createShapes(createDefaultShapes())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Uses typescript generics', () => {
|
||||||
|
expect(() => {
|
||||||
|
// No error here because no generic, the editor doesn't know what this guy is
|
||||||
|
editor.updateShapes([
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
type: 'geo',
|
||||||
|
props: { w: 'OH NO' },
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// Yep error here because we are giving the wrong props to the shape
|
||||||
|
editor.updateShapes<TLGeoShape>([
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
type: 'geo',
|
||||||
|
//@ts-expect-error
|
||||||
|
props: { w: 'OH NO' },
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// Yep error here because we are giving the wrong generic
|
||||||
|
editor.updateShapes<TLArrowShape>([
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
//@ts-expect-error
|
||||||
|
type: 'geo',
|
||||||
|
//@ts-expect-error
|
||||||
|
props: { w: 'OH NO' },
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// All good, correct match of generic and shape type
|
||||||
|
editor.updateShapes<TLGeoShape>([
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
type: 'geo',
|
||||||
|
props: { w: 100 },
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
editor.updateShapes<TLGeoShape>([
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
type: 'geo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
// @ts-expect-error - wrong type
|
||||||
|
type: 'arrow',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
// Unions are supported just fine
|
||||||
|
editor.updateShapes<TLGeoShape | TLArrowShape>([
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
type: 'geo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: ids.box1,
|
||||||
|
type: 'arrow',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}).toThrowError()
|
||||||
|
})
|
||||||
|
|
||||||
it('updates shapes', () => {
|
it('updates shapes', () => {
|
||||||
editor.mark('update shapes')
|
editor.mark('update shapes')
|
||||||
editor.updateShapes([
|
editor.updateShapes([
|
||||||
|
|
|
@ -19,7 +19,6 @@ import {
|
||||||
TLNoteShape,
|
TLNoteShape,
|
||||||
TLPageId,
|
TLPageId,
|
||||||
TLShapeId,
|
TLShapeId,
|
||||||
TLShapePartial,
|
|
||||||
TLSizeType,
|
TLSizeType,
|
||||||
TLTextShape,
|
TLTextShape,
|
||||||
TLVideoShape,
|
TLVideoShape,
|
||||||
|
@ -182,41 +181,41 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
|
||||||
|
|
||||||
switch (v1Shape.type) {
|
switch (v1Shape.type) {
|
||||||
case TDShapeType.Sticky: {
|
case TDShapeType.Sticky: {
|
||||||
const partial: TLShapePartial<TLNoteShape> = {
|
editor.createShapes<TLNoteShape>([
|
||||||
...inCommon,
|
{
|
||||||
type: 'note',
|
...inCommon,
|
||||||
props: {
|
type: 'note',
|
||||||
text: v1Shape.text ?? '',
|
props: {
|
||||||
color: getV2Color(v1Shape.style.color),
|
text: v1Shape.text ?? '',
|
||||||
size: getV2Size(v1Shape.style.size),
|
color: getV2Color(v1Shape.style.color),
|
||||||
font: getV2Font(v1Shape.style.font),
|
size: getV2Size(v1Shape.style.size),
|
||||||
align: getV2Align(v1Shape.style.textAlign),
|
font: getV2Font(v1Shape.style.font),
|
||||||
|
align: getV2Align(v1Shape.style.textAlign),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
])
|
||||||
|
|
||||||
editor.createShapes([partial])
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case TDShapeType.Rectangle: {
|
case TDShapeType.Rectangle: {
|
||||||
const partial: TLShapePartial<TLGeoShape> = {
|
editor.createShapes<TLGeoShape>([
|
||||||
...inCommon,
|
{
|
||||||
type: 'geo',
|
...inCommon,
|
||||||
props: {
|
type: 'geo',
|
||||||
geo: 'rectangle',
|
props: {
|
||||||
w: coerceDimension(v1Shape.size[0]),
|
geo: 'rectangle',
|
||||||
h: coerceDimension(v1Shape.size[1]),
|
w: coerceDimension(v1Shape.size[0]),
|
||||||
text: v1Shape.label ?? '',
|
h: coerceDimension(v1Shape.size[1]),
|
||||||
fill: getV2Fill(v1Shape.style.isFilled, v1Shape.style.color),
|
text: v1Shape.label ?? '',
|
||||||
labelColor: getV2Color(v1Shape.style.color),
|
fill: getV2Fill(v1Shape.style.isFilled, v1Shape.style.color),
|
||||||
color: getV2Color(v1Shape.style.color),
|
labelColor: getV2Color(v1Shape.style.color),
|
||||||
size: getV2Size(v1Shape.style.size),
|
color: getV2Color(v1Shape.style.color),
|
||||||
font: getV2Font(v1Shape.style.font),
|
size: getV2Size(v1Shape.style.size),
|
||||||
dash: getV2Dash(v1Shape.style.dash),
|
font: getV2Font(v1Shape.style.font),
|
||||||
align: 'middle',
|
dash: getV2Dash(v1Shape.style.dash),
|
||||||
|
align: 'middle',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
])
|
||||||
|
|
||||||
editor.createShapes([partial])
|
|
||||||
|
|
||||||
const pageBoundsBeforeLabel = editor.getPageBoundsById(inCommon.id)!
|
const pageBoundsBeforeLabel = editor.getPageBoundsById(inCommon.id)!
|
||||||
|
|
||||||
|
@ -254,24 +253,24 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case TDShapeType.Triangle: {
|
case TDShapeType.Triangle: {
|
||||||
const partial: TLShapePartial<TLGeoShape> = {
|
editor.createShapes<TLGeoShape>([
|
||||||
...inCommon,
|
{
|
||||||
type: 'geo',
|
...inCommon,
|
||||||
props: {
|
type: 'geo',
|
||||||
geo: 'triangle',
|
props: {
|
||||||
w: coerceDimension(v1Shape.size[0]),
|
geo: 'triangle',
|
||||||
h: coerceDimension(v1Shape.size[1]),
|
w: coerceDimension(v1Shape.size[0]),
|
||||||
fill: getV2Fill(v1Shape.style.isFilled, v1Shape.style.color),
|
h: coerceDimension(v1Shape.size[1]),
|
||||||
labelColor: getV2Color(v1Shape.style.color),
|
fill: getV2Fill(v1Shape.style.isFilled, v1Shape.style.color),
|
||||||
color: getV2Color(v1Shape.style.color),
|
labelColor: getV2Color(v1Shape.style.color),
|
||||||
size: getV2Size(v1Shape.style.size),
|
color: getV2Color(v1Shape.style.color),
|
||||||
font: getV2Font(v1Shape.style.font),
|
size: getV2Size(v1Shape.style.size),
|
||||||
dash: getV2Dash(v1Shape.style.dash),
|
font: getV2Font(v1Shape.style.font),
|
||||||
align: 'middle',
|
dash: getV2Dash(v1Shape.style.dash),
|
||||||
|
align: 'middle',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
])
|
||||||
|
|
||||||
editor.createShapes([partial])
|
|
||||||
|
|
||||||
const pageBoundsBeforeLabel = editor.getPageBoundsById(inCommon.id)!
|
const pageBoundsBeforeLabel = editor.getPageBoundsById(inCommon.id)!
|
||||||
|
|
||||||
|
@ -309,24 +308,24 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case TDShapeType.Ellipse: {
|
case TDShapeType.Ellipse: {
|
||||||
const partial: TLShapePartial<TLGeoShape> = {
|
editor.createShapes<TLGeoShape>([
|
||||||
...inCommon,
|
{
|
||||||
type: 'geo',
|
...inCommon,
|
||||||
props: {
|
type: 'geo',
|
||||||
geo: 'ellipse',
|
props: {
|
||||||
w: coerceDimension(v1Shape.radius[0]) * 2,
|
geo: 'ellipse',
|
||||||
h: coerceDimension(v1Shape.radius[1]) * 2,
|
w: coerceDimension(v1Shape.radius[0]) * 2,
|
||||||
fill: getV2Fill(v1Shape.style.isFilled, v1Shape.style.color),
|
h: coerceDimension(v1Shape.radius[1]) * 2,
|
||||||
labelColor: getV2Color(v1Shape.style.color),
|
fill: getV2Fill(v1Shape.style.isFilled, v1Shape.style.color),
|
||||||
color: getV2Color(v1Shape.style.color),
|
labelColor: getV2Color(v1Shape.style.color),
|
||||||
size: getV2Size(v1Shape.style.size),
|
color: getV2Color(v1Shape.style.color),
|
||||||
font: getV2Font(v1Shape.style.font),
|
size: getV2Size(v1Shape.style.size),
|
||||||
dash: getV2Dash(v1Shape.style.dash),
|
font: getV2Font(v1Shape.style.font),
|
||||||
align: 'middle',
|
dash: getV2Dash(v1Shape.style.dash),
|
||||||
|
align: 'middle',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
])
|
||||||
|
|
||||||
editor.createShapes([partial])
|
|
||||||
|
|
||||||
const pageBoundsBeforeLabel = editor.getPageBoundsById(inCommon.id)!
|
const pageBoundsBeforeLabel = editor.getPageBoundsById(inCommon.id)!
|
||||||
|
|
||||||
|
@ -370,21 +369,21 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
const partial: TLShapePartial<TLDrawShape> = {
|
editor.createShapes<TLDrawShape>([
|
||||||
...inCommon,
|
{
|
||||||
type: 'draw',
|
...inCommon,
|
||||||
props: {
|
type: 'draw',
|
||||||
fill: getV2Fill(v1Shape.style.isFilled, v1Shape.style.color),
|
props: {
|
||||||
color: getV2Color(v1Shape.style.color),
|
fill: getV2Fill(v1Shape.style.isFilled, v1Shape.style.color),
|
||||||
size: getV2Size(v1Shape.style.size),
|
color: getV2Color(v1Shape.style.color),
|
||||||
dash: getV2Dash(v1Shape.style.dash),
|
size: getV2Size(v1Shape.style.size),
|
||||||
isPen: false,
|
dash: getV2Dash(v1Shape.style.dash),
|
||||||
isComplete: v1Shape.isComplete,
|
isPen: false,
|
||||||
segments: [{ type: 'free', points: v1Shape.points.map(getV2Point) }],
|
isComplete: v1Shape.isComplete,
|
||||||
|
segments: [{ type: 'free', points: v1Shape.points.map(getV2Point) }],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
])
|
||||||
|
|
||||||
editor.createShapes([partial])
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case TDShapeType.Arrow: {
|
case TDShapeType.Arrow: {
|
||||||
|
@ -395,51 +394,51 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
|
||||||
const v2Bend = (dist * -v1Bend) / 2
|
const v2Bend = (dist * -v1Bend) / 2
|
||||||
|
|
||||||
// Could also be a line... but we'll use it as an arrow anyway
|
// Could also be a line... but we'll use it as an arrow anyway
|
||||||
const partial: TLShapePartial<TLArrowShape> = {
|
editor.createShapes<TLArrowShape>([
|
||||||
...inCommon,
|
{
|
||||||
type: 'arrow',
|
...inCommon,
|
||||||
props: {
|
type: 'arrow',
|
||||||
text: v1Shape.label ?? '',
|
props: {
|
||||||
color: getV2Color(v1Shape.style.color),
|
text: v1Shape.label ?? '',
|
||||||
labelColor: getV2Color(v1Shape.style.color),
|
color: getV2Color(v1Shape.style.color),
|
||||||
size: getV2Size(v1Shape.style.size),
|
labelColor: getV2Color(v1Shape.style.color),
|
||||||
font: getV2Font(v1Shape.style.font),
|
size: getV2Size(v1Shape.style.size),
|
||||||
dash: getV2Dash(v1Shape.style.dash),
|
font: getV2Font(v1Shape.style.font),
|
||||||
arrowheadStart: getV2Arrowhead(v1Shape.decorations?.start),
|
dash: getV2Dash(v1Shape.style.dash),
|
||||||
arrowheadEnd: getV2Arrowhead(v1Shape.decorations?.end),
|
arrowheadStart: getV2Arrowhead(v1Shape.decorations?.start),
|
||||||
start: {
|
arrowheadEnd: getV2Arrowhead(v1Shape.decorations?.end),
|
||||||
type: 'point',
|
start: {
|
||||||
x: coerceNumber(v1Shape.handles.start.point[0]),
|
type: 'point',
|
||||||
y: coerceNumber(v1Shape.handles.start.point[1]),
|
x: coerceNumber(v1Shape.handles.start.point[0]),
|
||||||
|
y: coerceNumber(v1Shape.handles.start.point[1]),
|
||||||
|
},
|
||||||
|
end: {
|
||||||
|
type: 'point',
|
||||||
|
x: coerceNumber(v1Shape.handles.end.point[0]),
|
||||||
|
y: coerceNumber(v1Shape.handles.end.point[1]),
|
||||||
|
},
|
||||||
|
bend: v2Bend,
|
||||||
},
|
},
|
||||||
end: {
|
|
||||||
type: 'point',
|
|
||||||
x: coerceNumber(v1Shape.handles.end.point[0]),
|
|
||||||
y: coerceNumber(v1Shape.handles.end.point[1]),
|
|
||||||
},
|
|
||||||
bend: v2Bend,
|
|
||||||
},
|
},
|
||||||
}
|
])
|
||||||
|
|
||||||
editor.createShapes([partial])
|
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case TDShapeType.Text: {
|
case TDShapeType.Text: {
|
||||||
const partial: TLShapePartial<TLTextShape> = {
|
editor.createShapes<TLTextShape>([
|
||||||
...inCommon,
|
{
|
||||||
type: 'text',
|
...inCommon,
|
||||||
props: {
|
type: 'text',
|
||||||
text: v1Shape.text ?? ' ',
|
props: {
|
||||||
color: getV2Color(v1Shape.style.color),
|
text: v1Shape.text ?? ' ',
|
||||||
size: getV2TextSize(v1Shape.style.size),
|
color: getV2Color(v1Shape.style.color),
|
||||||
font: getV2Font(v1Shape.style.font),
|
size: getV2TextSize(v1Shape.style.size),
|
||||||
align: getV2Align(v1Shape.style.textAlign),
|
font: getV2Font(v1Shape.style.font),
|
||||||
scale: v1Shape.style.scale ?? 1,
|
align: getV2Align(v1Shape.style.textAlign),
|
||||||
|
scale: v1Shape.style.scale ?? 1,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
])
|
||||||
|
|
||||||
editor.createShapes([partial])
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case TDShapeType.Image: {
|
case TDShapeType.Image: {
|
||||||
|
@ -450,17 +449,17 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const partial: TLShapePartial<TLImageShape> = {
|
editor.createShapes<TLImageShape>([
|
||||||
...inCommon,
|
{
|
||||||
type: 'image',
|
...inCommon,
|
||||||
props: {
|
type: 'image',
|
||||||
w: coerceDimension(v1Shape.size[0]),
|
props: {
|
||||||
h: coerceDimension(v1Shape.size[1]),
|
w: coerceDimension(v1Shape.size[0]),
|
||||||
assetId,
|
h: coerceDimension(v1Shape.size[1]),
|
||||||
|
assetId,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
])
|
||||||
|
|
||||||
editor.createShapes([partial])
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case TDShapeType.Video: {
|
case TDShapeType.Video: {
|
||||||
|
@ -471,17 +470,17 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const partial: TLShapePartial<TLVideoShape> = {
|
editor.createShapes<TLVideoShape>([
|
||||||
...inCommon,
|
{
|
||||||
type: 'video',
|
...inCommon,
|
||||||
props: {
|
type: 'video',
|
||||||
w: coerceDimension(v1Shape.size[0]),
|
props: {
|
||||||
h: coerceDimension(v1Shape.size[1]),
|
w: coerceDimension(v1Shape.size[0]),
|
||||||
assetId,
|
h: coerceDimension(v1Shape.size[1]),
|
||||||
|
assetId,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
])
|
||||||
|
|
||||||
editor.createShapes([partial])
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue