kopia lustrzana https://github.com/Tldraw/Tldraw
yessss
rodzic
c6ba621c11
commit
506cb04b64
|
@ -1,5 +1,5 @@
|
|||
import { react, useQuickReactor, useValue } from '@tldraw/state'
|
||||
import { TLHandle, TLShapeId } from '@tldraw/tlschema'
|
||||
import { react, track, useQuickReactor, useValue } from '@tldraw/state'
|
||||
import { TLHandle, TLShapeId, TLTextBinding } from '@tldraw/tlschema'
|
||||
import { dedupe, modulate, objectMapValues } from '@tldraw/utils'
|
||||
import classNames from 'classnames'
|
||||
import { Fragment, JSX, useEffect, useRef, useState } from 'react'
|
||||
|
@ -166,6 +166,7 @@ export function DefaultCanvas({ className }: TLCanvasComponentProps) {
|
|||
<ShapeIndicators />
|
||||
<HintedShapeIndicator />
|
||||
<SnapIndicatorWrapper />
|
||||
<TextLabelAlignmentIndicators />
|
||||
<SelectionForegroundWrapper />
|
||||
<LiveCollaborators />
|
||||
</div>
|
||||
|
@ -246,6 +247,118 @@ function SnapIndicatorWrapper() {
|
|||
)
|
||||
}
|
||||
|
||||
const TextLabelAlignmentIndicators = track(function TextLabelAlignmentIndicators() {
|
||||
const editor = useEditor()
|
||||
if (!editor.isIn('select.translating')) return null
|
||||
|
||||
const translatingShapes = editor.getSelectedShapes().filter((shape) => shape.type === 'text')
|
||||
const bindingsToRender = translatingShapes.flatMap((shape) =>
|
||||
editor.getBindingsFromShape<TLTextBinding>(shape.id, 'text')
|
||||
)
|
||||
|
||||
return (
|
||||
<svg className={classNames('tl-overlays__item')}>
|
||||
{bindingsToRender.map((binding) => (
|
||||
<TextBindingIndicator key={binding.id} binding={binding} />
|
||||
))}
|
||||
</svg>
|
||||
)
|
||||
})
|
||||
|
||||
const TextBindingIndicator = track(function TextBindingIndicator({
|
||||
binding,
|
||||
}: {
|
||||
binding: TLTextBinding
|
||||
}) {
|
||||
const editor = useEditor()
|
||||
const textShape = editor.getShape(binding.fromId)
|
||||
const geoShape = editor.getShape(binding.toId)
|
||||
if (!textShape || !geoShape) return null
|
||||
|
||||
const textShapeBounds = editor.getShapeGeometry(textShape).bounds
|
||||
const geoShapeBounds = editor.getShapeGeometry(geoShape).bounds
|
||||
|
||||
const textShapeTransform = editor.getShapePageTransform(textShape.id)
|
||||
const geoShapeTransform = editor.getShapePageTransform(geoShape.id)
|
||||
|
||||
const textShapeLeftEdgeCenter = editor.getPointInShapeSpace(
|
||||
geoShape.id,
|
||||
Mat.applyToPoint(textShapeTransform, new Vec(textShapeBounds.x, textShapeBounds.center.y))
|
||||
)
|
||||
const textShapeTopEdgeCenter = editor.getPointInShapeSpace(
|
||||
geoShape.id,
|
||||
Mat.applyToPoint(textShapeTransform, new Vec(textShapeBounds.center.x, textShapeBounds.y))
|
||||
)
|
||||
const textShapeRightEdgeCenter = editor.getPointInShapeSpace(
|
||||
geoShape.id,
|
||||
Mat.applyToPoint(textShapeTransform, new Vec(textShapeBounds.maxX, textShapeBounds.center.y))
|
||||
)
|
||||
const textShapeBottomEdgeCenter = editor.getPointInShapeSpace(
|
||||
geoShape.id,
|
||||
Mat.applyToPoint(textShapeTransform, new Vec(textShapeBounds.center.x, textShapeBounds.maxY))
|
||||
)
|
||||
|
||||
const linesInGeoSpace = []
|
||||
if (binding.props.x.type === 'center' || binding.props.x.edge === 'left') {
|
||||
if (textShapeLeftEdgeCenter.x > geoShapeBounds.minX) {
|
||||
linesInGeoSpace.push({
|
||||
hardcore: binding.props.x.type === 'center',
|
||||
start: textShapeLeftEdgeCenter,
|
||||
end: new Vec(geoShapeBounds.minX, textShapeLeftEdgeCenter.y),
|
||||
})
|
||||
}
|
||||
}
|
||||
if (binding.props.x.type === 'center' || binding.props.x.edge === 'right') {
|
||||
if (textShapeRightEdgeCenter.x < geoShapeBounds.maxX) {
|
||||
linesInGeoSpace.push({
|
||||
hardcore: binding.props.x.type === 'center',
|
||||
start: textShapeRightEdgeCenter,
|
||||
end: new Vec(geoShapeBounds.maxX, textShapeRightEdgeCenter.y),
|
||||
})
|
||||
}
|
||||
}
|
||||
if (binding.props.y.type === 'center' || binding.props.y.edge === 'top') {
|
||||
if (textShapeTopEdgeCenter.y > geoShapeBounds.minY) {
|
||||
linesInGeoSpace.push({
|
||||
hardcore: binding.props.y.type === 'center',
|
||||
start: textShapeTopEdgeCenter,
|
||||
end: new Vec(textShapeTopEdgeCenter.x, geoShapeBounds.minY),
|
||||
})
|
||||
}
|
||||
}
|
||||
if (binding.props.y.type === 'center' || binding.props.y.edge === 'bottom') {
|
||||
if (textShapeBottomEdgeCenter.y < geoShapeBounds.maxY) {
|
||||
linesInGeoSpace.push({
|
||||
hardcore: binding.props.y.type === 'center',
|
||||
start: textShapeBottomEdgeCenter,
|
||||
end: new Vec(textShapeBottomEdgeCenter.x, geoShapeBounds.maxY),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{linesInGeoSpace.map((l, i) => {
|
||||
const start = Mat.applyToPoint(geoShapeTransform, l.start)
|
||||
const end = Mat.applyToPoint(geoShapeTransform, l.end)
|
||||
const hardcore = l.hardcore
|
||||
return (
|
||||
<line
|
||||
key={i}
|
||||
x1={start.x}
|
||||
y1={start.y}
|
||||
x2={end.x}
|
||||
y2={end.y}
|
||||
strokeWidth={1}
|
||||
strokeDasharray={hardcore ? '0' : '4 2'}
|
||||
stroke={hardcore ? 'red' : 'grey'}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
function HandlesWrapper() {
|
||||
const editor = useEditor()
|
||||
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
import {
|
||||
BindingOnChangeOptions,
|
||||
BindingOnCreateOptions,
|
||||
BindingOnShapeChangeOptions,
|
||||
BindingOnShapeDeleteOptions,
|
||||
BindingUtil,
|
||||
Editor,
|
||||
Mat,
|
||||
TLShapeId,
|
||||
TLTextBinding,
|
||||
TLTextBindingProps,
|
||||
TLTextShape,
|
||||
Vec,
|
||||
approximately,
|
||||
getIndexAbove,
|
||||
getIndexBetween,
|
||||
textBindingMigrations,
|
||||
textBindingProps,
|
||||
} from '@tldraw/editor'
|
||||
|
||||
export class TextBindingUtil extends BindingUtil<TLTextBinding> {
|
||||
static override type = 'text'
|
||||
|
||||
static override props = textBindingProps
|
||||
static override migrations = textBindingMigrations
|
||||
|
||||
override getDefaultProps(): Partial<TLTextBindingProps> {
|
||||
return {
|
||||
x: { type: 'center' },
|
||||
y: { type: 'center' },
|
||||
}
|
||||
}
|
||||
|
||||
// when the binding itself changes
|
||||
override onAfterCreate({ binding }: BindingOnCreateOptions<TLTextBinding>): void {
|
||||
makeTextGood(this.editor, binding.fromId)
|
||||
}
|
||||
|
||||
// when the binding itself changes
|
||||
override onAfterChange({ bindingAfter }: BindingOnChangeOptions<TLTextBinding>): void {
|
||||
makeTextGood(this.editor, bindingAfter.fromId)
|
||||
}
|
||||
|
||||
// when the text itself changes
|
||||
override onAfterChangeFromShape({
|
||||
shapeBefore,
|
||||
shapeAfter,
|
||||
binding,
|
||||
}: BindingOnShapeChangeOptions<TLTextBinding>): void {
|
||||
const edgeSlop = 25
|
||||
if (shapeBefore.x !== shapeAfter.x || shapeBefore.y !== shapeAfter.y) {
|
||||
const textShapeTransform = this.editor.getShapePageTransform(shapeAfter)
|
||||
const textShapeCornersInToShapeSpace = Mat.applyToPoints(
|
||||
textShapeTransform,
|
||||
this.editor.getShapeGeometry(shapeAfter).bounds.cornersAndCenter
|
||||
).map((p) => this.editor.getPointInShapeSpace(binding.toId, p))
|
||||
const toShapeBounds = this.editor.getShapeGeometry(binding.toId).bounds
|
||||
const left = textShapeCornersInToShapeSpace[0].x
|
||||
const top = textShapeCornersInToShapeSpace[0].y
|
||||
const right = textShapeCornersInToShapeSpace[2].x
|
||||
const bottom = textShapeCornersInToShapeSpace[2].y
|
||||
const textShapeCenterInToShapeSpace = textShapeCornersInToShapeSpace.pop()!
|
||||
const toShapeCenter = this.editor.getShapeGeometry(binding.toId).bounds.center
|
||||
{
|
||||
// do x
|
||||
const dist = Math.abs(textShapeCenterInToShapeSpace.x - toShapeCenter.x)
|
||||
const distInScreenSpace = dist / this.editor.getZoomLevel()
|
||||
|
||||
if (distInScreenSpace > 10) {
|
||||
const wasRight = binding.props.x.type === 'offset' && binding.props.x.edge === 'right'
|
||||
const overrideRight = right > toShapeBounds.maxX - edgeSlop
|
||||
const overrideLeft = left < toShapeBounds.minX + edgeSlop
|
||||
this.editor.updateBinding({
|
||||
...binding,
|
||||
props: {
|
||||
...binding.props,
|
||||
x:
|
||||
(wasRight && !overrideLeft) || overrideRight
|
||||
? {
|
||||
type: 'offset',
|
||||
edge: 'right',
|
||||
offsetInToShapeSpace: toShapeBounds.maxX - right,
|
||||
}
|
||||
: {
|
||||
type: 'offset',
|
||||
edge: 'left',
|
||||
offsetInToShapeSpace: left - toShapeBounds.minX,
|
||||
},
|
||||
},
|
||||
})
|
||||
} else {
|
||||
this.editor.updateBinding({
|
||||
...binding,
|
||||
props: {
|
||||
...binding.props,
|
||||
x: { type: 'center' },
|
||||
},
|
||||
})
|
||||
}
|
||||
binding = this.editor.getBinding(binding.id) as TLTextBinding
|
||||
}
|
||||
{
|
||||
// do y
|
||||
const dist = Math.abs(textShapeCenterInToShapeSpace.y - toShapeCenter.y)
|
||||
const distInScreenSpace = dist / this.editor.getZoomLevel()
|
||||
if (distInScreenSpace > 10) {
|
||||
const wasBottom = binding.props.y.type === 'offset' && binding.props.y.edge === 'bottom'
|
||||
const overrideBottom = bottom > toShapeBounds.maxY - edgeSlop
|
||||
const overrideTop = top < toShapeBounds.minY + edgeSlop
|
||||
this.editor.updateBinding({
|
||||
...binding,
|
||||
props: {
|
||||
...binding.props,
|
||||
y:
|
||||
(wasBottom && !overrideTop) || overrideBottom
|
||||
? {
|
||||
type: 'offset',
|
||||
edge: 'bottom',
|
||||
offsetInToShapeSpace: toShapeBounds.maxY - bottom,
|
||||
}
|
||||
: { type: 'offset', edge: 'top', offsetInToShapeSpace: top - toShapeBounds.minY },
|
||||
},
|
||||
})
|
||||
} else {
|
||||
this.editor.updateBinding({
|
||||
...binding,
|
||||
props: {
|
||||
...binding.props,
|
||||
y: { type: 'center' },
|
||||
},
|
||||
})
|
||||
}
|
||||
binding = this.editor.getBinding(binding.id) as TLTextBinding
|
||||
}
|
||||
}
|
||||
makeTextGood(this.editor, shapeAfter.id)
|
||||
}
|
||||
|
||||
// when the shape an text is bound to changes
|
||||
override onAfterChangeToShape({ binding }: BindingOnShapeChangeOptions<TLTextBinding>): void {
|
||||
makeTextGood(this.editor, binding.fromId)
|
||||
}
|
||||
|
||||
// when the shape the text is pointing to is deleted
|
||||
override onBeforeDeleteToShape({ binding }: BindingOnShapeDeleteOptions<TLTextBinding>): void {
|
||||
const text = this.editor.getShape<TLTextShape>(binding.fromId)
|
||||
if (!text) return
|
||||
this.editor.deleteShape(text.id)
|
||||
}
|
||||
}
|
||||
|
||||
function makeTextGood(editor: Editor, textId: TLShapeId) {
|
||||
const textShape = editor.getShape<TLTextShape>(textId)
|
||||
if (!textShape) return
|
||||
const bindings = editor.getBindingsFromShape<TLTextBinding>(textId, 'text')
|
||||
if (!bindings.length) return
|
||||
if (bindings.length > 1) {
|
||||
editor.deleteBindings(bindings.slice(1))
|
||||
}
|
||||
|
||||
const binding = bindings[0]
|
||||
|
||||
// need to make sure this text is directly above the shape it is bound to and bound to the same parent
|
||||
const boundShape = editor.getShape(bindings[0].toId)
|
||||
if (!boundShape) return
|
||||
|
||||
const siblings = editor.getSortedChildIdsForParent(boundShape.parentId)
|
||||
const fromIndex = boundShape.index
|
||||
const nextSiblingId = siblings[siblings.findIndex((id) => id === boundShape.id) + 1]
|
||||
|
||||
if (textShape.parentId !== boundShape.parentId) {
|
||||
const toIndex = nextSiblingId ? editor.getShape(nextSiblingId)?.index : undefined
|
||||
editor.updateShape({
|
||||
...textShape,
|
||||
parentId: boundShape.parentId,
|
||||
index: getIndexBetween(fromIndex, toIndex),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!nextSiblingId) {
|
||||
editor.updateShape({ ...textShape, index: getIndexAbove(fromIndex) })
|
||||
return
|
||||
}
|
||||
if (textShape.index < fromIndex) {
|
||||
const toIndex = editor.getShape(nextSiblingId)?.index
|
||||
editor.updateShape({ ...textShape, index: getIndexBetween(fromIndex, toIndex) })
|
||||
return
|
||||
}
|
||||
|
||||
if (textShape.rotation !== boundShape.rotation) {
|
||||
editor.updateShape({ ...textShape, rotation: boundShape.rotation })
|
||||
return
|
||||
}
|
||||
|
||||
if (binding.props.x.type === 'center' && textShape.props.textAlign !== 'middle') {
|
||||
editor.updateShape({ ...textShape, props: { ...textShape.props, textAlign: 'middle' } })
|
||||
return
|
||||
}
|
||||
|
||||
// position the text shape
|
||||
const textBounds = editor.getShapeGeometry(textShape).bounds
|
||||
const geoBounds = editor.getShapeGeometry(boundShape).bounds
|
||||
|
||||
const offset = Vec.Sub(geoBounds.center, new Vec(textBounds.width / 2, textBounds.height / 2))
|
||||
if (binding.props.x.type === 'offset') {
|
||||
if (binding.props.x.edge === 'right') {
|
||||
offset.x = geoBounds.maxX - binding.props.x.offsetInToShapeSpace - textBounds.width
|
||||
} else {
|
||||
offset.x = geoBounds.minX + binding.props.x.offsetInToShapeSpace
|
||||
}
|
||||
}
|
||||
if (binding.props.y.type === 'offset') {
|
||||
if (binding.props.y.edge === 'bottom') {
|
||||
offset.y = geoBounds.maxY - binding.props.y.offsetInToShapeSpace - textBounds.height
|
||||
} else {
|
||||
offset.y = geoBounds.minY + binding.props.y.offsetInToShapeSpace
|
||||
}
|
||||
}
|
||||
|
||||
const geoTransform = editor.getShapePageTransform(boundShape)
|
||||
|
||||
const { x, y } = editor.getPointInParentSpace(boundShape, Mat.applyToPoint(geoTransform, offset))
|
||||
|
||||
if (!approximately(textShape.x, x) || !approximately(textShape.y, y)) {
|
||||
editor.updateShape({ ...textShape, x, y })
|
||||
}
|
||||
}
|
|
@ -1,5 +1,9 @@
|
|||
import { TLAnyBindingUtilConstructor } from '@tldraw/editor'
|
||||
import { ArrowBindingUtil } from './bindings/arrow/ArrowBindingUtil'
|
||||
import { TextBindingUtil } from './bindings/arrow/TextBindingUtil'
|
||||
|
||||
/** @public */
|
||||
export const defaultBindingUtils: TLAnyBindingUtilConstructor[] = [ArrowBindingUtil]
|
||||
export const defaultBindingUtils: TLAnyBindingUtilConstructor[] = [
|
||||
ArrowBindingUtil,
|
||||
TextBindingUtil,
|
||||
]
|
||||
|
|
|
@ -93,6 +93,20 @@ export class Pointing extends StateNode {
|
|||
])
|
||||
.select(id)
|
||||
|
||||
const boundShape = this.editor.getShapeAtPoint(this.editor.inputs.currentPagePoint, {
|
||||
filter: (shape) => shape.type === 'geo',
|
||||
hitInside: true,
|
||||
hitFrameInside: false,
|
||||
})
|
||||
|
||||
if (boundShape) {
|
||||
this.editor.createBinding({
|
||||
type: 'text',
|
||||
fromId: id,
|
||||
toId: boundShape.id,
|
||||
})
|
||||
}
|
||||
|
||||
this.editor.setEditingShape(id)
|
||||
this.editor.setCurrentTool('select')
|
||||
this.editor.root.getCurrent()?.transition('editing_shape')
|
||||
|
|
|
@ -818,6 +818,12 @@ export class StyleProp<Type> implements T.Validatable<Type> {
|
|||
// @public (undocumented)
|
||||
export type StylePropValue<T extends StyleProp<any>> = T extends StyleProp<infer U> ? U : never;
|
||||
|
||||
// @public (undocumented)
|
||||
export const textBindingMigrations: TLPropsMigrations;
|
||||
|
||||
// @public (undocumented)
|
||||
export const textBindingProps: RecordProps<TLTextBinding>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const textShapeMigrations: TLPropsMigrations;
|
||||
|
||||
|
@ -982,7 +988,7 @@ export interface TLCursor {
|
|||
export type TLCursorType = SetValue<typeof TL_CURSOR_TYPES>;
|
||||
|
||||
// @public
|
||||
export type TLDefaultBinding = TLArrowBinding;
|
||||
export type TLDefaultBinding = TLArrowBinding | TLTextBinding;
|
||||
|
||||
// @public (undocumented)
|
||||
export type TLDefaultColorStyle = T.TypeOf<typeof DefaultColorStyle>;
|
||||
|
@ -1344,6 +1350,27 @@ export type TLStoreSchema = StoreSchema<TLRecord, TLStoreProps>;
|
|||
// @public (undocumented)
|
||||
export type TLStoreSnapshot = StoreSnapshot<TLRecord>;
|
||||
|
||||
// @public (undocumented)
|
||||
export type TLTextBinding = TLBaseBinding<'text', TLTextBindingProps>;
|
||||
|
||||
// @public (undocumented)
|
||||
export type TLTextBindingProps = {
|
||||
x: {
|
||||
edge: 'left' | 'right';
|
||||
offsetInToShapeSpace: number;
|
||||
type: 'offset';
|
||||
} | {
|
||||
type: 'center';
|
||||
};
|
||||
y: {
|
||||
edge: 'bottom' | 'top';
|
||||
offsetInToShapeSpace: number;
|
||||
type: 'offset';
|
||||
} | {
|
||||
type: 'center';
|
||||
};
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export type TLTextShape = TLBaseShape<'text', TLTextShapeProps>;
|
||||
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
import { T } from '@tldraw/validate'
|
||||
import { createBindingPropsMigrationSequence } from '../records/TLBinding'
|
||||
import { RecordProps } from '../recordsWithProps'
|
||||
import { TLBaseBinding } from './TLBaseBinding'
|
||||
|
||||
/** @public */
|
||||
export type TLTextBindingProps = {
|
||||
y:
|
||||
| {
|
||||
type: 'offset'
|
||||
edge: 'top' | 'bottom'
|
||||
offsetInToShapeSpace: number
|
||||
}
|
||||
| { type: 'center' }
|
||||
x:
|
||||
| {
|
||||
type: 'offset'
|
||||
edge: 'left' | 'right'
|
||||
offsetInToShapeSpace: number
|
||||
}
|
||||
| { type: 'center' }
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export const textBindingProps: RecordProps<TLTextBinding> = {
|
||||
y: T.union('type', {
|
||||
offset: T.object({
|
||||
type: T.literal('offset'),
|
||||
edge: T.literalEnum('top', 'bottom'),
|
||||
offsetInToShapeSpace: T.number,
|
||||
}),
|
||||
center: T.object({ type: T.literal('center') }),
|
||||
}),
|
||||
|
||||
x: T.union('type', {
|
||||
offset: T.object({
|
||||
type: T.literal('offset'),
|
||||
edge: T.literalEnum('left', 'right'),
|
||||
offsetInToShapeSpace: T.number,
|
||||
}),
|
||||
center: T.object({ type: T.literal('center') }),
|
||||
}),
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export type TLTextBinding = TLBaseBinding<'text', TLTextBindingProps>
|
||||
|
||||
export const textBindingVersions = {} as const
|
||||
|
||||
/** @public */
|
||||
export const textBindingMigrations = createBindingPropsMigrationSequence({
|
||||
sequence: [],
|
||||
})
|
|
@ -5,6 +5,7 @@ import { bookmarkAssetMigrations } from './assets/TLBookmarkAsset'
|
|||
import { imageAssetMigrations } from './assets/TLImageAsset'
|
||||
import { videoAssetMigrations } from './assets/TLVideoAsset'
|
||||
import { arrowBindingMigrations, arrowBindingProps } from './bindings/TLArrowBinding'
|
||||
import { textBindingMigrations, textBindingProps } from './bindings/TLTextBinding'
|
||||
import { AssetRecordType, assetMigrations } from './records/TLAsset'
|
||||
import { TLBinding, TLDefaultBinding, createBindingRecordType } from './records/TLBinding'
|
||||
import { CameraRecordType, cameraMigrations } from './records/TLCamera'
|
||||
|
@ -74,6 +75,7 @@ export const defaultShapeSchemas: { [T in TLDefaultShape['type']]: SchemaPropsIn
|
|||
/** @public */
|
||||
export const defaultBindingSchemas: { [T in TLDefaultBinding['type']]: SchemaPropsInfo } = {
|
||||
arrow: { migrations: arrowBindingMigrations, props: arrowBindingProps },
|
||||
text: { migrations: textBindingMigrations, props: textBindingProps },
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,6 +20,12 @@ export {
|
|||
createBindingValidator,
|
||||
type TLBaseBinding,
|
||||
} from './bindings/TLBaseBinding'
|
||||
export {
|
||||
textBindingMigrations,
|
||||
textBindingProps,
|
||||
type TLTextBinding,
|
||||
type TLTextBindingProps,
|
||||
} from './bindings/TLTextBinding'
|
||||
export { createPresenceStateDerivation } from './createPresenceStateDerivation'
|
||||
export {
|
||||
createTLSchema,
|
||||
|
|
|
@ -10,6 +10,7 @@ import { T } from '@tldraw/validate'
|
|||
import { nanoid } from 'nanoid'
|
||||
import { TLArrowBinding } from '../bindings/TLArrowBinding'
|
||||
import { TLBaseBinding, createBindingValidator } from '../bindings/TLBaseBinding'
|
||||
import { TLTextBinding } from '../bindings/TLTextBinding'
|
||||
import { SchemaPropsInfo } from '../createTLSchema'
|
||||
import { TLPropsMigrations } from '../recordsWithProps'
|
||||
|
||||
|
@ -17,7 +18,7 @@ import { TLPropsMigrations } from '../recordsWithProps'
|
|||
* The default set of bindings that are available in the editor.
|
||||
*
|
||||
* @public */
|
||||
export type TLDefaultBinding = TLArrowBinding
|
||||
export type TLDefaultBinding = TLArrowBinding | TLTextBinding
|
||||
|
||||
/**
|
||||
* A type for a binding that is available in the editor but whose type is
|
||||
|
|
Ładowanie…
Reference in New Issue