[feature] Include sources
in TLExternalContent
(#1925)
This PR adds the source items from a paste event to the data shared with external content handlers. This allows developers to customize the way certain content is handled. For example, pasting text sometimes incudes additional clipboard items, such as the HTML representation of that text. We wouldn't want to create two shapes—one for the text and one for the HTML—so we still treat this as a single text paste. The `registerExternalContentHandler` API allows a developer to change how that text is handled, and the new `sources` API will now allow the developer to take into consideration all of the items that were on the clipboard.  ### Change Type - [x] `minor` — New feature ### Test Plan 1. Try the external content source example. 2. Paste text that includes HTML (e.g. from VS Code) ### Release Notes - [editor / tldraw] add `sources` to `TLExternalContent`
This commit is contained in:
parent
b6ebe1e274
commit
5cd74f4bd6
9 changed files with 171 additions and 101 deletions
|
@ -623,16 +623,16 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
get erasingShapes(): NonNullable<TLShape | undefined>[];
|
||||
// @internal (undocumented)
|
||||
externalAssetContentHandlers: {
|
||||
[K in TLExternalAssetContent_2['type']]: {
|
||||
[Key in K]: ((info: TLExternalAssetContent_2 & {
|
||||
[K in TLExternalAssetContent['type']]: {
|
||||
[Key in K]: ((info: TLExternalAssetContent & {
|
||||
type: Key;
|
||||
}) => Promise<TLAsset | undefined>) | null;
|
||||
}[K];
|
||||
};
|
||||
// @internal (undocumented)
|
||||
externalContentHandlers: {
|
||||
[K in TLExternalContent_2['type']]: {
|
||||
[Key in K]: ((info: TLExternalContent_2 & {
|
||||
[K in TLExternalContent['type']]: {
|
||||
[Key in K]: ((info: TLExternalContent & {
|
||||
type: Key;
|
||||
}) => void) | null;
|
||||
}[K];
|
||||
|
@ -649,7 +649,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
handleId: "end" | "start";
|
||||
}[];
|
||||
getAsset(asset: TLAsset | TLAssetId): TLAsset | undefined;
|
||||
getAssetForExternalContent(info: TLExternalAssetContent_2): Promise<TLAsset | undefined>;
|
||||
getAssetForExternalContent(info: TLExternalAssetContent): Promise<TLAsset | undefined>;
|
||||
getContainer: () => HTMLElement;
|
||||
getContentFromCurrentPage(shapes: TLShape[] | TLShapeId[]): TLContent | undefined;
|
||||
getDroppingOverShape(point: VecLike, droppingShapes?: TLShape[]): TLShape | undefined;
|
||||
|
@ -770,14 +770,14 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
preservePosition?: boolean;
|
||||
preserveIds?: boolean;
|
||||
}): this;
|
||||
putExternalContent(info: TLExternalContent_2): Promise<void>;
|
||||
putExternalContent(info: TLExternalContent): Promise<void>;
|
||||
redo(): this;
|
||||
registerExternalAssetHandler<T extends TLExternalAssetContent_2['type']>(type: T, handler: ((info: TLExternalAssetContent_2 & {
|
||||
registerExternalAssetHandler<T extends TLExternalAssetContent['type']>(type: T, handler: ((info: TLExternalAssetContent & {
|
||||
type: T;
|
||||
}) => Promise<TLAsset>) | null): this;
|
||||
registerExternalContentHandler<T extends TLExternalContent_2['type']>(type: T, handler: ((info: T extends TLExternalContent_2['type'] ? TLExternalContent_2 & {
|
||||
registerExternalContentHandler<T extends TLExternalContent['type']>(type: T, handler: ((info: T extends TLExternalContent['type'] ? TLExternalContent & {
|
||||
type: T;
|
||||
} : TLExternalContent_2) => void) | null): this;
|
||||
} : TLExternalContent) => void) | null): this;
|
||||
renamePage(page: TLPage | TLPageId, name: string, historyOptions?: TLCommandHistoryOptions): this;
|
||||
get renderingBounds(): Box2d;
|
||||
get renderingBoundsExpanded(): Box2d;
|
||||
|
@ -2147,27 +2147,42 @@ export type TLExternalAssetContent = {
|
|||
|
||||
// @public (undocumented)
|
||||
export type TLExternalContent = {
|
||||
sources?: TLExternalContentSource[];
|
||||
point?: VecLike;
|
||||
} & ({
|
||||
type: 'embed';
|
||||
url: string;
|
||||
point?: VecLike;
|
||||
embed: EmbedDefinition;
|
||||
} | {
|
||||
type: 'files';
|
||||
files: File[];
|
||||
point?: VecLike;
|
||||
ignoreParent: boolean;
|
||||
} | {
|
||||
type: 'svg-text';
|
||||
text: string;
|
||||
point?: VecLike;
|
||||
} | {
|
||||
type: 'text';
|
||||
point?: VecLike;
|
||||
text: string;
|
||||
} | {
|
||||
type: 'url';
|
||||
url: string;
|
||||
point?: VecLike;
|
||||
});
|
||||
|
||||
// @public (undocumented)
|
||||
export type TLExternalContentSource = {
|
||||
type: 'error';
|
||||
data: null | string;
|
||||
reason: string;
|
||||
} | {
|
||||
type: 'excalidraw';
|
||||
data: any;
|
||||
} | {
|
||||
type: 'text';
|
||||
data: string;
|
||||
subtype: 'html' | 'json' | 'text' | 'url';
|
||||
} | {
|
||||
type: 'tldraw';
|
||||
data: TLContent;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
|
|
|
@ -230,6 +230,7 @@ export {
|
|||
export {
|
||||
type TLExternalAssetContent,
|
||||
type TLExternalContent,
|
||||
type TLExternalContentSource,
|
||||
} from './lib/editor/types/external-content'
|
||||
export {
|
||||
type TLCommand,
|
||||
|
|
|
@ -2,7 +2,6 @@ import { EMPTY_ARRAY, atom, computed, transact } from '@tldraw/state'
|
|||
import { ComputedCache, RecordType } from '@tldraw/store'
|
||||
import {
|
||||
CameraRecordType,
|
||||
EmbedDefinition,
|
||||
InstancePageStateRecordType,
|
||||
PageRecordType,
|
||||
StyleProp,
|
||||
|
@ -122,6 +121,7 @@ import { SvgExportContext, SvgExportDef } from './types/SvgExportContext'
|
|||
import { TLContent } from './types/clipboard-types'
|
||||
import { TLEventMap } from './types/emit-types'
|
||||
import { TLEventInfo, TLPinchEventInfo, TLPointerEventInfo } from './types/event-types'
|
||||
import { TLExternalAssetContent, TLExternalContent } from './types/external-content'
|
||||
import { TLCommandHistoryOptions } from './types/history-types'
|
||||
import { OptionalKeys, RequiredKeys } from './types/misc-types'
|
||||
import { TLResizeHandle } from './types/selection-types'
|
||||
|
@ -8908,36 +8908,3 @@ function alertMaxShapes(editor: Editor, pageId = editor.currentPageId) {
|
|||
const name = editor.getPage(pageId)!.name
|
||||
editor.emit('max-shapes', { name, pageId, count: MAX_SHAPES_PER_PAGE })
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export type TLExternalContent =
|
||||
| {
|
||||
type: 'text'
|
||||
point?: VecLike
|
||||
text: string
|
||||
}
|
||||
| {
|
||||
type: 'files'
|
||||
files: File[]
|
||||
point?: VecLike
|
||||
ignoreParent: boolean
|
||||
}
|
||||
| {
|
||||
type: 'url'
|
||||
url: string
|
||||
point?: VecLike
|
||||
}
|
||||
| {
|
||||
type: 'svg-text'
|
||||
text: string
|
||||
point?: VecLike
|
||||
}
|
||||
| {
|
||||
type: 'embed'
|
||||
url: string
|
||||
point?: VecLike
|
||||
embed: EmbedDefinition
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export type TLExternalAssetContent = { type: 'file'; file: File } | { type: 'url'; url: string }
|
||||
|
|
|
@ -1,35 +1,56 @@
|
|||
import { EmbedDefinition } from '@tldraw/tlschema'
|
||||
import { VecLike } from '../../primitives/Vec2d'
|
||||
import { TLContent } from './clipboard-types'
|
||||
|
||||
/** @public */
|
||||
export type TLExternalContent =
|
||||
export type TLExternalContentSource =
|
||||
| {
|
||||
type: 'tldraw'
|
||||
data: TLContent
|
||||
}
|
||||
| {
|
||||
type: 'excalidraw'
|
||||
data: any
|
||||
}
|
||||
| {
|
||||
type: 'text'
|
||||
data: string
|
||||
subtype: 'json' | 'html' | 'text' | 'url'
|
||||
}
|
||||
| {
|
||||
type: 'error'
|
||||
data: string | null
|
||||
reason: string
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export type TLExternalContent = {
|
||||
sources?: TLExternalContentSource[]
|
||||
point?: VecLike
|
||||
} & (
|
||||
| {
|
||||
type: 'text'
|
||||
point?: VecLike
|
||||
text: string
|
||||
}
|
||||
| {
|
||||
type: 'files'
|
||||
files: File[]
|
||||
point?: VecLike
|
||||
ignoreParent: boolean
|
||||
}
|
||||
| {
|
||||
type: 'url'
|
||||
url: string
|
||||
point?: VecLike
|
||||
}
|
||||
| {
|
||||
type: 'svg-text'
|
||||
text: string
|
||||
point?: VecLike
|
||||
}
|
||||
| {
|
||||
type: 'embed'
|
||||
url: string
|
||||
point?: VecLike
|
||||
embed: EmbedDefinition
|
||||
}
|
||||
)
|
||||
|
||||
/** @public */
|
||||
export type TLExternalAssetContent = { type: 'file'; file: File } | { type: 'url'; url: string }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue