No impure getters pt4 (#2206)
follow up to #2189 and #2203 ### Change Type - [x] `patch` — Bug fix
This commit is contained in:
parent
7ffda2335c
commit
daf729d45c
45 changed files with 610 additions and 274 deletions
|
@ -51,7 +51,7 @@ function MyComponent() {
|
|||
// The "InFrontOfTheCanvas" component is rendered on top of the canvas, but behind the UI.
|
||||
const MyComponentInFront = track(() => {
|
||||
const editor = useEditor()
|
||||
const { selectionRotatedPageBounds } = editor
|
||||
const selectionRotatedPageBounds = editor.getSelectionRotatedPageBounds()
|
||||
|
||||
if (!selectionRotatedPageBounds) return null
|
||||
|
||||
|
|
|
@ -642,7 +642,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
get documentSettings(): TLDocument;
|
||||
duplicatePage(page: TLPage | TLPageId, createId?: TLPageId): this;
|
||||
duplicateShapes(shapes: TLShape[] | TLShapeId[], offset?: VecLike): this;
|
||||
// @deprecated (undocumented)
|
||||
get editingShape(): TLShape | undefined;
|
||||
// @deprecated (undocumented)
|
||||
get editingShapeId(): null | TLShapeId;
|
||||
readonly environment: EnvironmentManager;
|
||||
get erasingShapeIds(): TLShapeId[];
|
||||
|
@ -666,7 +668,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
findCommonAncestor(shapes: TLShape[] | TLShapeId[], predicate?: (shape: TLShape) => boolean): TLShapeId | undefined;
|
||||
findShapeAncestor(shape: TLShape | TLShapeId, predicate: (parent: TLShape) => boolean): TLShape | undefined;
|
||||
flipShapes(shapes: TLShape[] | TLShapeId[], operation: 'horizontal' | 'vertical'): this;
|
||||
// @deprecated (undocumented)
|
||||
get focusedGroup(): TLShape | undefined;
|
||||
// @deprecated (undocumented)
|
||||
get focusedGroupId(): TLPageId | TLShapeId;
|
||||
getAncestorPageId(shape?: TLShape | TLShapeId): TLPageId | undefined;
|
||||
getArrowInfo(shape: TLArrowShape | TLShapeId): TLArrowInfo | undefined;
|
||||
|
@ -685,6 +689,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
getCurrentToolId(): string;
|
||||
getDocumentSettings(): TLDocument;
|
||||
getDroppingOverShape(point: VecLike, droppingShapes?: TLShape[]): TLUnknownShape | undefined;
|
||||
getEditingShape(): TLShape | undefined;
|
||||
getEditingShapeId(): null | TLShapeId;
|
||||
getFocusedGroup(): TLShape | undefined;
|
||||
getFocusedGroupId(): TLPageId | TLShapeId;
|
||||
getHighestIndexForParent(parent: TLPage | TLParentId | TLShape): string;
|
||||
getInitialMetaForShape(_shape: TLShape): JsonObject;
|
||||
getInstanceState(): TLInstance;
|
||||
|
@ -700,6 +708,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
getSelectedShapeAtPoint(point: VecLike): TLShape | undefined;
|
||||
getSelectedShapeIds(): TLShapeId[];
|
||||
getSelectedShapes(): TLShape[];
|
||||
getSelectionPageBounds(): Box2d | null;
|
||||
getSelectionRotatedPageBounds(): Box2d | undefined;
|
||||
getSelectionRotation(): number;
|
||||
getShape<T extends TLShape = TLShape>(shape: TLParentId | TLShape): T | undefined;
|
||||
getShapeAncestors(shape: TLShape | TLShapeId, acc?: TLShape[]): TLShape[];
|
||||
getShapeAndDescendantIds(ids: TLShapeId[]): Set<TLShapeId>;
|
||||
|
@ -854,8 +865,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
get selectedShapeIds(): TLShapeId[];
|
||||
// @deprecated (undocumented)
|
||||
get selectedShapes(): TLShape[];
|
||||
// @deprecated (undocumented)
|
||||
get selectionPageBounds(): Box2d | null;
|
||||
// @deprecated (undocumented)
|
||||
get selectionRotatedPageBounds(): Box2d | undefined;
|
||||
// @deprecated (undocumented)
|
||||
get selectionRotation(): number;
|
||||
selectNone(): this;
|
||||
sendBackward(shapes: TLShape[] | TLShapeId[]): this;
|
||||
|
|
|
@ -9147,7 +9147,7 @@
|
|||
{
|
||||
"kind": "Property",
|
||||
"canonicalReference": "@tldraw/editor!Editor#editingShape:member",
|
||||
"docComment": "/**\n * The current editing shape.\n *\n * @public\n */\n",
|
||||
"docComment": "/**\n * @deprecated\n *\n * Use `getEditingShape` instead.\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
|
@ -9182,7 +9182,7 @@
|
|||
{
|
||||
"kind": "Property",
|
||||
"canonicalReference": "@tldraw/editor!Editor#editingShapeId:member",
|
||||
"docComment": "/**\n * The current editing shape's id.\n *\n * @public\n */\n",
|
||||
"docComment": "/**\n * @deprecated\n *\n * Use `getEditingShapeId` instead.\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
|
@ -9585,7 +9585,7 @@
|
|||
{
|
||||
"kind": "Property",
|
||||
"canonicalReference": "@tldraw/editor!Editor#focusedGroup:member",
|
||||
"docComment": "/**\n * The current focused group.\n *\n * @public\n */\n",
|
||||
"docComment": "/**\n * @deprecated\n *\n * Use `getFocusedGroup` instead.\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
|
@ -9620,7 +9620,7 @@
|
|||
{
|
||||
"kind": "Property",
|
||||
"canonicalReference": "@tldraw/editor!Editor#focusedGroupId:member",
|
||||
"docComment": "/**\n * The current focused group id.\n *\n * @public\n */\n",
|
||||
"docComment": "/**\n * @deprecated\n *\n * Use `getFocusedGroupId` instead.\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
|
@ -10337,6 +10337,155 @@
|
|||
"isAbstract": false,
|
||||
"name": "getDroppingOverShape"
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!Editor#getEditingShape:member(1)",
|
||||
"docComment": "/**\n * The current editing shape.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "getEditingShape(): "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLShape",
|
||||
"canonicalReference": "@tldraw/tlschema!TLShape:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": " | undefined"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"isStatic": false,
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 3
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"isProtected": false,
|
||||
"overloadIndex": 1,
|
||||
"parameters": [],
|
||||
"isOptional": false,
|
||||
"isAbstract": false,
|
||||
"name": "getEditingShape"
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!Editor#getEditingShapeId:member(1)",
|
||||
"docComment": "/**\n * The current editing shape's id.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "getEditingShapeId(): "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLShapeId",
|
||||
"canonicalReference": "@tldraw/tlschema!TLShapeId:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"isStatic": false,
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 3
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"isProtected": false,
|
||||
"overloadIndex": 1,
|
||||
"parameters": [],
|
||||
"isOptional": false,
|
||||
"isAbstract": false,
|
||||
"name": "getEditingShapeId"
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!Editor#getFocusedGroup:member(1)",
|
||||
"docComment": "/**\n * The current focused group.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "getFocusedGroup(): "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLShape",
|
||||
"canonicalReference": "@tldraw/tlschema!TLShape:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": " | undefined"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"isStatic": false,
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 3
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"isProtected": false,
|
||||
"overloadIndex": 1,
|
||||
"parameters": [],
|
||||
"isOptional": false,
|
||||
"isAbstract": false,
|
||||
"name": "getFocusedGroup"
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!Editor#getFocusedGroupId:member(1)",
|
||||
"docComment": "/**\n * The current focused group id.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "getFocusedGroupId(): "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLPageId",
|
||||
"canonicalReference": "@tldraw/tlschema!TLPageId:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": " | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLShapeId",
|
||||
"canonicalReference": "@tldraw/tlschema!TLShapeId:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"isStatic": false,
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 4
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"isProtected": false,
|
||||
"overloadIndex": 1,
|
||||
"parameters": [],
|
||||
"isOptional": false,
|
||||
"isAbstract": false,
|
||||
"name": "getFocusedGroupId"
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!Editor#getHighestIndexForParent:member(1)",
|
||||
|
@ -11117,6 +11266,109 @@
|
|||
"isAbstract": false,
|
||||
"name": "getSelectedShapes"
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!Editor#getSelectionPageBounds:member(1)",
|
||||
"docComment": "/**\n * The current page bounds of all the selected shapes. If the selection is rotated, then these bounds are the axis-aligned box that the rotated bounds would fit inside of.\n *\n * @readonly @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "getSelectionPageBounds(): "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Box2d",
|
||||
"canonicalReference": "@tldraw/editor!Box2d:class"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": " | null"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"isStatic": false,
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 3
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"isProtected": false,
|
||||
"overloadIndex": 1,
|
||||
"parameters": [],
|
||||
"isOptional": false,
|
||||
"isAbstract": false,
|
||||
"name": "getSelectionPageBounds"
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!Editor#getSelectionRotatedPageBounds:member(1)",
|
||||
"docComment": "/**\n * The bounds of the selection bounding box in the current page space.\n *\n * @readonly @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "getSelectionRotatedPageBounds(): "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Box2d",
|
||||
"canonicalReference": "@tldraw/editor!Box2d:class"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": " | undefined"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"isStatic": false,
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 3
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"isProtected": false,
|
||||
"overloadIndex": 1,
|
||||
"parameters": [],
|
||||
"isOptional": false,
|
||||
"isAbstract": false,
|
||||
"name": "getSelectionRotatedPageBounds"
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!Editor#getSelectionRotation:member(1)",
|
||||
"docComment": "/**\n * The rotation of the selection bounding box in the current page space.\n *\n * @readonly @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "getSelectionRotation(): "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "number"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"isStatic": false,
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 2
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"isProtected": false,
|
||||
"overloadIndex": 1,
|
||||
"parameters": [],
|
||||
"isOptional": false,
|
||||
"isAbstract": false,
|
||||
"name": "getSelectionRotation"
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!Editor#getShape:member(1)",
|
||||
|
@ -15882,7 +16134,7 @@
|
|||
{
|
||||
"kind": "Property",
|
||||
"canonicalReference": "@tldraw/editor!Editor#selectionPageBounds:member",
|
||||
"docComment": "/**\n * The current page bounds of all the selected shapes. If the selection is rotated, then these bounds are the axis-aligned box that the rotated bounds would fit inside of.\n *\n * @readonly @public\n */\n",
|
||||
"docComment": "/**\n * @deprecated\n *\n * Use `getSelectionPageBounds` instead.\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
|
@ -15917,7 +16169,7 @@
|
|||
{
|
||||
"kind": "Property",
|
||||
"canonicalReference": "@tldraw/editor!Editor#selectionRotatedPageBounds:member",
|
||||
"docComment": "/**\n * The bounds of the selection bounding box in the current page space.\n *\n * @readonly @public\n */\n",
|
||||
"docComment": "/**\n * @deprecated\n *\n * Use `getSelectionRotatedPageBounds` instead.\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
|
@ -15952,7 +16204,7 @@
|
|||
{
|
||||
"kind": "Property",
|
||||
"canonicalReference": "@tldraw/editor!Editor#selectionRotation:member",
|
||||
"docComment": "/**\n * The rotation of the selection bounding box in the current page space.\n *\n * @readonly @public\n */\n",
|
||||
"docComment": "/**\n * @deprecated\n *\n * Use `getSelectionRotation` instead.\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
|
|
|
@ -522,10 +522,14 @@ function UiLogger() {
|
|||
|
||||
export function SelectionForegroundWrapper() {
|
||||
const editor = useEditor()
|
||||
const selectionRotation = useValue('selection rotation', () => editor.selectionRotation, [editor])
|
||||
const selectionBounds = useValue('selection bounds', () => editor.selectionRotatedPageBounds, [
|
||||
const selectionRotation = useValue('selection rotation', () => editor.getSelectionRotation(), [
|
||||
editor,
|
||||
])
|
||||
const selectionBounds = useValue(
|
||||
'selection bounds',
|
||||
() => editor.getSelectionRotatedPageBounds(),
|
||||
[editor]
|
||||
)
|
||||
const { SelectionForeground } = useEditorComponents()
|
||||
if (!selectionBounds || !SelectionForeground) return null
|
||||
return <SelectionForeground bounds={selectionBounds} rotation={selectionRotation} />
|
||||
|
@ -533,10 +537,14 @@ export function SelectionForegroundWrapper() {
|
|||
|
||||
export function SelectionBackgroundWrapper() {
|
||||
const editor = useEditor()
|
||||
const selectionRotation = useValue('selection rotation', () => editor.selectionRotation, [editor])
|
||||
const selectionBounds = useValue('selection bounds', () => editor.selectionRotatedPageBounds, [
|
||||
const selectionRotation = useValue('selection rotation', () => editor.getSelectionRotation(), [
|
||||
editor,
|
||||
])
|
||||
const selectionBounds = useValue(
|
||||
'selection bounds',
|
||||
() => editor.getSelectionRotatedPageBounds(),
|
||||
[editor]
|
||||
)
|
||||
const { SelectionBackground } = useEditorComponents()
|
||||
if (!selectionBounds || !SelectionBackground) return null
|
||||
return <SelectionBackground bounds={selectionBounds} rotation={selectionRotation} />
|
||||
|
|
|
@ -995,6 +995,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
}
|
||||
} {
|
||||
try {
|
||||
const editingShapeId = this.getEditingShapeId()
|
||||
return {
|
||||
tags: {
|
||||
origin: origin,
|
||||
|
@ -1003,7 +1004,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
extras: {
|
||||
activeStateNode: this.root.path.get(),
|
||||
selectedShapes: this.getSelectedShapes(),
|
||||
editingShape: this.editingShapeId ? this.getShape(this.editingShapeId) : undefined,
|
||||
editingShape: editingShapeId ? this.getShape(editingShapeId) : undefined,
|
||||
inputs: this.inputs,
|
||||
},
|
||||
}
|
||||
|
@ -1681,20 +1682,27 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
@computed get selectionPageBounds(): Box2d | null {
|
||||
@computed getSelectionPageBounds(): Box2d | null {
|
||||
const selectedShapeIds = this.getCurrentPageState().selectedShapeIds
|
||||
if (selectedShapeIds.length === 0) return null
|
||||
|
||||
return Box2d.Common(compact(selectedShapeIds.map((id) => this.getShapePageBounds(id))))
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `getSelectionPageBounds` instead.
|
||||
*/
|
||||
get selectionPageBounds() {
|
||||
return this.getSelectionPageBounds()
|
||||
}
|
||||
|
||||
/**
|
||||
* The rotation of the selection bounding box in the current page space.
|
||||
*
|
||||
* @readonly
|
||||
* @public
|
||||
*/
|
||||
@computed get selectionRotation(): number {
|
||||
@computed getSelectionRotation(): number {
|
||||
const selectedShapeIds = this.getSelectedShapeIds()
|
||||
if (selectedShapeIds.length === 0) {
|
||||
return 0
|
||||
|
@ -1711,22 +1719,29 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
return 0
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `getSelectionRotation` instead.
|
||||
*/
|
||||
get selectionRotation() {
|
||||
return this.getSelectionRotation()
|
||||
}
|
||||
|
||||
/**
|
||||
* The bounds of the selection bounding box in the current page space.
|
||||
*
|
||||
* @readonly
|
||||
* @public
|
||||
*/
|
||||
@computed get selectionRotatedPageBounds(): Box2d | undefined {
|
||||
@computed getSelectionRotatedPageBounds(): Box2d | undefined {
|
||||
const selectedShapeIds = this.getSelectedShapeIds()
|
||||
|
||||
if (selectedShapeIds.length === 0) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const { selectionRotation } = this
|
||||
const selectionRotation = this.getSelectionRotation()
|
||||
if (selectionRotation === 0) {
|
||||
return this.selectionPageBounds!
|
||||
return this.getSelectionPageBounds()!
|
||||
}
|
||||
|
||||
if (selectedShapeIds.length === 1) {
|
||||
|
@ -1751,6 +1766,13 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
return boxFromRotatedVertices
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `getSelectionRotatedPageBounds` instead.
|
||||
*/
|
||||
get selectionRotatedPageBounds() {
|
||||
return this.getSelectionRotatedPageBounds()
|
||||
}
|
||||
|
||||
// Focus Group
|
||||
|
||||
/**
|
||||
|
@ -1758,20 +1780,34 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
@computed get focusedGroupId(): TLShapeId | TLPageId {
|
||||
@computed getFocusedGroupId(): TLShapeId | TLPageId {
|
||||
return this.getCurrentPageState().focusedGroupId ?? this.currentPageId
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `getFocusedGroupId` instead.
|
||||
*/
|
||||
get focusedGroupId() {
|
||||
return this.getFocusedGroupId()
|
||||
}
|
||||
|
||||
/**
|
||||
* The current focused group.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
@computed get focusedGroup(): TLShape | undefined {
|
||||
const { focusedGroupId } = this
|
||||
@computed getFocusedGroup(): TLShape | undefined {
|
||||
const focusedGroupId = this.getFocusedGroupId()
|
||||
return focusedGroupId ? this.getShape(focusedGroupId) : undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `getFocusedGroup` instead.
|
||||
*/
|
||||
get focusedGroup() {
|
||||
return this.getFocusedGroup()
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current focused group shape.
|
||||
*
|
||||
|
@ -1795,7 +1831,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
}
|
||||
}
|
||||
|
||||
if (id === this.focusedGroupId) return this
|
||||
if (id === this.getFocusedGroupId()) return this
|
||||
this._setFocusedGroupId(id)
|
||||
return this
|
||||
}
|
||||
|
@ -1834,7 +1870,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
* @public
|
||||
*/
|
||||
popFocusedGroupId(): this {
|
||||
const { focusedGroup } = this
|
||||
const focusedGroup = this.getFocusedGroup()
|
||||
|
||||
if (focusedGroup) {
|
||||
// If we have a focused layer, look for an ancestor of the focused shape that is a group
|
||||
|
@ -1858,20 +1894,34 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
@computed get editingShapeId() {
|
||||
@computed getEditingShapeId(): TLShapeId | null {
|
||||
return this.getCurrentPageState().editingShapeId
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `getEditingShapeId` instead.
|
||||
*/
|
||||
get editingShapeId() {
|
||||
return this.getEditingShapeId()
|
||||
}
|
||||
|
||||
/**
|
||||
* The current editing shape.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
@computed get editingShape(): TLShape | undefined {
|
||||
const { editingShapeId } = this
|
||||
@computed getEditingShape(): TLShape | undefined {
|
||||
const editingShapeId = this.getEditingShapeId()
|
||||
return editingShapeId ? this.getShape(editingShapeId) : undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `getEditingShape` instead.
|
||||
*/
|
||||
get editingShape() {
|
||||
return this.getEditingShape()
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current editing shape.
|
||||
*
|
||||
|
@ -1887,7 +1937,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*/
|
||||
setEditingShape(shape: TLShapeId | TLShape | null): this {
|
||||
const id = typeof shape === 'string' ? shape : shape?.id ?? null
|
||||
if (id !== this.editingShapeId) {
|
||||
if (id !== this.getEditingShapeId()) {
|
||||
if (id) {
|
||||
const shape = this.getShape(id)
|
||||
if (shape && this.getShapeUtil(shape).canEdit(shape)) {
|
||||
|
@ -2226,7 +2276,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
* @public
|
||||
*/
|
||||
zoomToContent(): this {
|
||||
const bounds = this.selectionPageBounds ?? this.currentPageBounds
|
||||
const bounds = this.getSelectionPageBounds() ?? this.currentPageBounds
|
||||
|
||||
if (bounds) {
|
||||
this.zoomToBounds(bounds, Math.min(1, this.zoomLevel), { duration: 220 })
|
||||
|
@ -2383,7 +2433,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
zoomToSelection(animation?: TLAnimationOptions): this {
|
||||
if (!this.getInstanceState().canMoveCamera) return this
|
||||
|
||||
const { selectionPageBounds } = this
|
||||
const selectionPageBounds = this.getSelectionPageBounds()
|
||||
if (!selectionPageBounds) return this
|
||||
|
||||
this.zoomToBounds(selectionPageBounds, Math.max(1, this.zoomLevel), animation)
|
||||
|
@ -3112,7 +3162,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
let nextBackgroundIndex = MAX_SHAPES_PER_PAGE
|
||||
|
||||
// We only really need these if we're using editor state, but that's ok
|
||||
const editingShapeId = this.editingShapeId
|
||||
const editingShapeId = this.getEditingShapeId()
|
||||
const selectedShapeIds = this.getSelectedShapeIds()
|
||||
const erasingShapeIds = this.erasingShapeIds
|
||||
const renderingBoundsExpanded = this.renderingBoundsExpanded
|
||||
|
@ -5087,7 +5137,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
let match = freshShape
|
||||
let node = freshShape as TLShape | undefined
|
||||
|
||||
const { focusedGroup } = this
|
||||
const focusedGroup = this.getFocusedGroup()
|
||||
|
||||
while (node) {
|
||||
if (
|
||||
|
@ -5378,7 +5428,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
// If we've offset the duplicated shapes, check to see whether their new bounds is entirely
|
||||
// contained in the current viewport. If not, then animate the camera to be centered on the
|
||||
// new shapes.
|
||||
const { viewportPageBounds, selectionPageBounds: selectionPageBounds } = this
|
||||
const selectionPageBounds = this.getSelectionPageBounds()
|
||||
const { viewportPageBounds } = this
|
||||
if (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {
|
||||
this.centerOnPoint(selectionPageBounds.center, {
|
||||
duration: ANIMATION_MEDIUM_MS,
|
||||
|
@ -5454,7 +5505,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
// "from" page's camera, then center the "to" page's camera on the
|
||||
// pasted shapes
|
||||
this.setCamera({ ...this.camera, z: fromPageZ })
|
||||
this.centerOnPoint(this.selectionRotatedPageBounds!.center)
|
||||
this.centerOnPoint(this.getSelectionRotatedPageBounds()!.center)
|
||||
})
|
||||
|
||||
return this
|
||||
|
@ -6581,7 +6632,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
},
|
||||
{
|
||||
do: ({ partials }) => {
|
||||
const { focusedGroupId } = this
|
||||
const focusedGroupId = this.getFocusedGroupId()
|
||||
|
||||
// 1. Parents
|
||||
|
||||
|
@ -6601,7 +6652,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
!partial.parentId ||
|
||||
!(this.store.has(partial.parentId) || partials.some((p) => p.id === partial.parentId))
|
||||
) {
|
||||
let parentId: TLParentId = this.focusedGroupId
|
||||
let parentId: TLParentId = this.getFocusedGroupId()
|
||||
|
||||
for (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {
|
||||
const parent = currentPageShapesSorted[i]
|
||||
|
|
|
@ -126,7 +126,7 @@ export function useDocumentEvents() {
|
|||
// escape de-selects them. Only when the user's selection is empty
|
||||
// should we allow escape to do its normal thing.
|
||||
|
||||
if (editor.editingShape || editor.getSelectedShapeIds().length > 0) {
|
||||
if (editor.getEditingShape() || editor.getSelectedShapeIds().length > 0) {
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
|
|
|
@ -97,12 +97,13 @@ export function useGestureEvents(ref: React.RefObject<HTMLDivElement>) {
|
|||
// default on the evnet) if the user is wheeling over an a shape
|
||||
// that is scrollable which they're currently editing.
|
||||
|
||||
if (editor.editingShapeId) {
|
||||
const shape = editor.getShape(editor.editingShapeId)
|
||||
const editingShapeId = editor.getEditingShapeId()
|
||||
if (editingShapeId) {
|
||||
const shape = editor.getShape(editingShapeId)
|
||||
if (shape) {
|
||||
const util = editor.getShapeUtil(shape)
|
||||
if (util.canScroll(shape)) {
|
||||
const bounds = editor.getShapePageBounds(editor.editingShapeId)
|
||||
const bounds = editor.getShapePageBounds(editingShapeId)
|
||||
if (bounds?.containsPoint(editor.inputs.currentPagePoint)) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -5,5 +5,5 @@ import { useEditor } from './useEditor'
|
|||
/** @public */
|
||||
export function useIsEditing(shapeId: TLShapeId) {
|
||||
const editor = useEditor()
|
||||
return useValue('isEditing', () => editor.editingShapeId === shapeId, [editor, shapeId])
|
||||
return useValue('isEditing', () => editor.getEditingShapeId() === shapeId, [editor, shapeId])
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ import { Vec2d } from '../primitives/Vec2d'
|
|||
/** @internal */
|
||||
export function getRotationSnapshot({ editor }: { editor: Editor }): TLRotationSnapshot | null {
|
||||
const selectedShapes = editor.getSelectedShapes()
|
||||
const selectionRotation = editor.getSelectionRotation()
|
||||
const selectionBounds = editor.getSelectionRotatedPageBounds()
|
||||
const {
|
||||
selectionRotation,
|
||||
selectionRotatedPageBounds: selectionBounds,
|
||||
inputs: { originPagePoint },
|
||||
} = editor
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ import { SelectionEdge } from '@tldraw/editor';
|
|||
import { SelectionHandle } from '@tldraw/editor';
|
||||
import { SerializedSchema } from '@tldraw/editor';
|
||||
import { ShapeUtil } from '@tldraw/editor';
|
||||
import { SnapPoint } from '@tldraw/editor';
|
||||
import { StateNode } from '@tldraw/editor';
|
||||
import { StoreSnapshot } from '@tldraw/editor';
|
||||
import { SvgExportContext } from '@tldraw/editor';
|
||||
|
|
|
@ -14,7 +14,7 @@ export const TldrawHoveredShapeIndicator: TLHoveredShapeIndicatorComponent = ({
|
|||
// When the editor is editing a shape and hovering that shape,
|
||||
// don't show its indicator; but DO show other hover indicators
|
||||
if (editor.isIn('select.editing_shape')) {
|
||||
return editor.hoveredShapeId !== editor.editingShapeId
|
||||
return editor.hoveredShapeId !== editor.getEditingShapeId()
|
||||
}
|
||||
|
||||
// Otherise, only show the hovered indicator when the editor
|
||||
|
|
|
@ -46,7 +46,7 @@ export const TldrawSelectionForeground: TLSelectionForegroundComponent = track(
|
|||
? editor.getShapeUtil(onlyShape).expandSelectionOutlinePx(onlyShape)
|
||||
: 0
|
||||
|
||||
useTransform(rSvg, bounds?.x, bounds?.y, 1, editor.selectionRotation, {
|
||||
useTransform(rSvg, bounds?.x, bounds?.y, 1, editor.getSelectionRotation(), {
|
||||
x: -expandOutlineBy,
|
||||
y: -expandOutlineBy,
|
||||
})
|
||||
|
|
|
@ -461,16 +461,16 @@ export async function createShapesForAssets(
|
|||
editor.createShapes(partials).select(...partials.map((p) => p.id))
|
||||
|
||||
// Re-position shapes so that the center of the group is at the provided point
|
||||
centerSelecitonAroundPoint(editor, position)
|
||||
centerSelectionAroundPoint(editor, position)
|
||||
})
|
||||
|
||||
return partials.map((p) => p.id)
|
||||
}
|
||||
|
||||
function centerSelecitonAroundPoint(editor: Editor, position: VecLike) {
|
||||
function centerSelectionAroundPoint(editor: Editor, position: VecLike) {
|
||||
// Re-position shapes so that the center of the group is at the provided point
|
||||
const { viewportPageBounds } = editor
|
||||
let { selectionPageBounds } = editor
|
||||
let selectionPageBounds = editor.getSelectionPageBounds()
|
||||
|
||||
if (selectionPageBounds) {
|
||||
const offset = selectionPageBounds!.center.sub(position)
|
||||
|
@ -490,7 +490,7 @@ function centerSelecitonAroundPoint(editor: Editor, position: VecLike) {
|
|||
}
|
||||
|
||||
// Zoom out to fit the shapes, if necessary
|
||||
selectionPageBounds = editor.selectionPageBounds
|
||||
selectionPageBounds = editor.getSelectionPageBounds()
|
||||
if (selectionPageBounds && !viewportPageBounds.contains(selectionPageBounds)) {
|
||||
editor.zoomToSelection()
|
||||
}
|
||||
|
@ -515,7 +515,7 @@ export function createEmptyBookmarkShape(
|
|||
|
||||
editor.batch(() => {
|
||||
editor.createShapes([partial]).select(partial.id)
|
||||
centerSelecitonAroundPoint(editor, position)
|
||||
centerSelectionAroundPoint(editor, position)
|
||||
})
|
||||
|
||||
return editor.getShape(partial.id) as TLBookmarkShape
|
||||
|
|
|
@ -143,7 +143,7 @@ describe('When translating the arrow', () => {
|
|||
|
||||
it('retains all handles if either bound shape is also translating', () => {
|
||||
editor.select(ids.arrow1, ids.box2)
|
||||
expect(editor.selectionPageBounds).toMatchObject({
|
||||
expect(editor.getSelectionPageBounds()).toMatchObject({
|
||||
x: 200,
|
||||
y: 200,
|
||||
w: 200,
|
||||
|
|
|
@ -38,7 +38,7 @@ export const FrameHeading = function FrameHeading({
|
|||
const event = getPointerInfo(e)
|
||||
|
||||
// If we're editing the frame label, we shouldn't hijack the pointer event
|
||||
if (editor.editingShapeId === id) return
|
||||
if (editor.getEditingShapeId() === id) return
|
||||
|
||||
editor.dispatch({
|
||||
type: 'pointer',
|
||||
|
|
|
@ -23,7 +23,7 @@ export function useEditableText<T extends Extract<TLShape, { props: { text: stri
|
|||
const rSkipSelectOnFocus = useRef(false)
|
||||
const rSelectionRanges = useRef<Range[] | null>()
|
||||
|
||||
const isEditing = useValue('isEditing', () => editor.editingShapeId === id, [editor, id])
|
||||
const isEditing = useValue('isEditing', () => editor.getEditingShapeId() === id, [editor, id])
|
||||
|
||||
// If the shape is editing but the input element not focused, focus the element
|
||||
useEffect(() => {
|
||||
|
@ -63,7 +63,7 @@ export function useEditableText<T extends Extract<TLShape, { props: { text: stri
|
|||
|
||||
requestAnimationFrame(() => {
|
||||
const elm = rInput.current
|
||||
const { editingShapeId } = editor
|
||||
const editingShapeId = editor.getEditingShapeId()
|
||||
// Did we move to a different shape?
|
||||
if (elm && editingShapeId) {
|
||||
// important! these ^v are two different things
|
||||
|
|
|
@ -143,7 +143,7 @@ export class TextShapeUtil extends ShapeUtil<TLTextShape> {
|
|||
indicator(shape: TLTextShape) {
|
||||
const bounds = this.editor.getShapeGeometry(shape).bounds
|
||||
const editor = useEditor()
|
||||
if (shape.props.autoSize && editor.editingShapeId === shape.id) return null
|
||||
if (shape.props.autoSize && editor.getEditingShapeId() === shape.id) return null
|
||||
return <rect width={toDomPrecision(bounds.width)} height={toDomPrecision(bounds.height)} />
|
||||
}
|
||||
|
||||
|
|
|
@ -224,14 +224,14 @@ export class Cropping extends StateNode {
|
|||
}
|
||||
|
||||
private createSnapshot() {
|
||||
const selectionRotation = this.editor.getSelectionRotation()
|
||||
const {
|
||||
selectionRotation,
|
||||
inputs: { originPagePoint },
|
||||
} = this.editor
|
||||
|
||||
const shape = this.editor.getOnlySelectedShape() as TLImageShape
|
||||
|
||||
const selectionBounds = this.editor.selectionRotatedPageBounds!
|
||||
const selectionBounds = this.editor.getSelectionRotatedPageBounds()!
|
||||
|
||||
const dragHandlePoint = Vec2d.RotWith(
|
||||
selectionBounds.getHandlePoint(this.info.handle!),
|
||||
|
|
|
@ -13,7 +13,7 @@ export class EditingShape extends StateNode {
|
|||
static override id = 'editing_shape'
|
||||
|
||||
override onEnter = () => {
|
||||
const { editingShape } = this.editor
|
||||
const editingShape = this.editor.getEditingShape()
|
||||
if (!editingShape) throw Error('Entered editing state without an editing shape')
|
||||
updateHoveredId(this.editor)
|
||||
this.editor.select(editingShape)
|
||||
|
@ -62,7 +62,7 @@ export class EditingShape extends StateNode {
|
|||
}
|
||||
case 'shape': {
|
||||
const { shape } = info
|
||||
const { editingShape } = this.editor
|
||||
const editingShape = this.editor.getEditingShape()
|
||||
|
||||
if (!editingShape) {
|
||||
throw Error('Expected an editing shape!')
|
||||
|
|
|
@ -180,7 +180,7 @@ export class Idle extends StateNode {
|
|||
hitInside: false,
|
||||
})
|
||||
|
||||
const { focusedGroupId } = this.editor
|
||||
const focusedGroupId = this.editor.getFocusedGroupId()
|
||||
|
||||
if (hitShape) {
|
||||
if (this.editor.isShapeOfType<TLGroupShape>(hitShape, 'group')) {
|
||||
|
@ -388,7 +388,7 @@ export class Idle extends StateNode {
|
|||
|
||||
override onCancel: TLEventHandlers['onCancel'] = () => {
|
||||
if (
|
||||
this.editor.focusedGroupId !== this.editor.currentPageId &&
|
||||
this.editor.getFocusedGroupId() !== this.editor.currentPageId &&
|
||||
this.editor.getSelectedShapeIds().length > 0
|
||||
) {
|
||||
this.editor.popFocusedGroupId()
|
||||
|
@ -562,10 +562,10 @@ export const MINOR_NUDGE_FACTOR = 1
|
|||
export const GRID_INCREMENT = 5
|
||||
|
||||
function isPointInRotatedSelectionBounds(editor: Editor, point: VecLike) {
|
||||
const { selectionRotatedPageBounds: selectionBounds } = editor
|
||||
const selectionBounds = editor.getSelectionRotatedPageBounds()
|
||||
if (!selectionBounds) return false
|
||||
|
||||
const { selectionRotation } = editor
|
||||
const selectionRotation = editor.getSelectionRotation()
|
||||
if (!selectionRotation) return selectionBounds.containsPoint(point)
|
||||
|
||||
return pointInPolygon(
|
||||
|
|
|
@ -11,7 +11,7 @@ export class PointingRotateHandle extends StateNode {
|
|||
private info = {} as PointingRotateHandleInfo
|
||||
|
||||
private updateCursor() {
|
||||
const { selectionRotation } = this.editor
|
||||
const selectionRotation = this.editor.getSelectionRotation()
|
||||
this.editor.updateInstanceState({
|
||||
cursor: {
|
||||
type: CursorTypeMap[this.info.handle as RotateCorner],
|
||||
|
|
|
@ -19,9 +19,9 @@ export class PointingShape extends StateNode {
|
|||
|
||||
override onEnter = (info: TLPointerEventInfo & { target: 'shape' }) => {
|
||||
const selectedShapeIds = this.editor.getSelectedShapeIds()
|
||||
const selectionBounds = this.editor.getSelectionRotatedPageBounds()
|
||||
const focusedGroupId = this.editor.getFocusedGroupId()
|
||||
const {
|
||||
focusedGroupId,
|
||||
selectionRotatedPageBounds: selectionBounds,
|
||||
inputs: { currentPagePoint, shiftKey, altKey },
|
||||
} = this.editor
|
||||
|
||||
|
@ -61,9 +61,9 @@ export class PointingShape extends StateNode {
|
|||
|
||||
override onPointerUp: TLEventHandlers['onPointerUp'] = (info) => {
|
||||
const selectedShapeIds = this.editor.getSelectedShapeIds()
|
||||
const focusedGroupId = this.editor.getFocusedGroupId()
|
||||
const {
|
||||
zoomLevel,
|
||||
focusedGroupId,
|
||||
inputs: { currentPagePoint, shiftKey },
|
||||
} = this.editor
|
||||
|
||||
|
|
|
@ -368,12 +368,12 @@ export class Resizing extends StateNode {
|
|||
|
||||
_createSnapshot = () => {
|
||||
const selectedShapeIds = this.editor.getSelectedShapeIds()
|
||||
const selectionRotation = this.editor.getSelectionRotation()
|
||||
const {
|
||||
selectionRotation,
|
||||
inputs: { originPagePoint },
|
||||
} = this.editor
|
||||
|
||||
const selectionBounds = this.editor.selectionRotatedPageBounds!
|
||||
const selectionBounds = this.editor.getSelectionRotatedPageBounds()!
|
||||
|
||||
const dragHandlePoint = Vec2d.RotWith(
|
||||
selectionBounds.getHandlePoint(this.info.handle!),
|
||||
|
@ -418,7 +418,7 @@ export class Resizing extends StateNode {
|
|||
selectionRotation,
|
||||
selectedShapeIds,
|
||||
canShapesDeform,
|
||||
initialSelectionPageBounds: this.editor.selectionPageBounds!,
|
||||
initialSelectionPageBounds: this.editor.getSelectionPageBounds()!,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -139,9 +139,9 @@ export class Rotating extends StateNode {
|
|||
}
|
||||
|
||||
_getRotationFromPointerPosition({ snapToNearestDegree }: { snapToNearestDegree: boolean }) {
|
||||
const selectionRotation = this.editor.getSelectionRotation()
|
||||
const selectionBounds = this.editor.getSelectionRotatedPageBounds()
|
||||
const {
|
||||
selectionRotatedPageBounds: selectionBounds,
|
||||
selectionRotation,
|
||||
inputs: { shiftKey, currentPagePoint },
|
||||
} = this.editor
|
||||
const { initialCursorAngle, initialSelectionRotation } = this.snapshot
|
||||
|
|
|
@ -306,21 +306,26 @@ function getTranslatingSnapshot(editor: Editor) {
|
|||
})
|
||||
)
|
||||
|
||||
let initialSnapPoints: SnapPoint[] = []
|
||||
if (editor.getSelectedShapeIds().length === 1) {
|
||||
initialSnapPoints = editor.snaps.snapPointsCache.get(editor.getSelectedShapeIds()[0])!
|
||||
} else {
|
||||
const selectionPageBounds = editor.getSelectionPageBounds()
|
||||
if (selectionPageBounds) {
|
||||
initialSnapPoints = selectionPageBounds.snapPoints.map((p, i) => ({
|
||||
id: 'selection:' + i,
|
||||
x: p.x,
|
||||
y: p.y,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
averagePagePoint: Vec2d.Average(pagePoints),
|
||||
movingShapes,
|
||||
shapeSnapshots,
|
||||
initialPageBounds: editor.selectionPageBounds!,
|
||||
initialSnapPoints:
|
||||
editor.getSelectedShapeIds().length === 1
|
||||
? editor.snaps.snapPointsCache.get(editor.getSelectedShapeIds()[0])!
|
||||
: editor.selectionPageBounds
|
||||
? editor.selectionPageBounds.snapPoints.map((p, i) => ({
|
||||
id: 'selection:' + i,
|
||||
x: p.x,
|
||||
y: p.y,
|
||||
}))
|
||||
: [],
|
||||
initialPageBounds: editor.getSelectionPageBounds()!,
|
||||
initialSnapPoints,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ export function selectOnCanvasPointerUp(editor: Editor) {
|
|||
// Otherwise, if the group isn't selected and isn't our current
|
||||
// focus layer, then we need to select the group instead.
|
||||
if (
|
||||
outermostSelectableShape.id === editor.focusedGroupId ||
|
||||
outermostSelectableShape.id === editor.getFocusedGroupId() ||
|
||||
selectedShapeIds.includes(outermostSelectableShape.id)
|
||||
) {
|
||||
shapeToSelect = hitShape
|
||||
|
@ -81,7 +81,7 @@ export function selectOnCanvasPointerUp(editor: Editor) {
|
|||
// If the click was inside of the current focused group, then
|
||||
// we keep that focused group; otherwise we clear the focused
|
||||
// group (reset it to the page)
|
||||
const { focusedGroupId } = editor
|
||||
const focusedGroupId = editor.getFocusedGroupId()
|
||||
|
||||
if (isShapeId(focusedGroupId)) {
|
||||
const groupShape = editor.getShape(focusedGroupId)!
|
||||
|
|
|
@ -19,7 +19,7 @@ export function updateHoveredId(editor: Editor) {
|
|||
shapeToHover = hitShape
|
||||
} else {
|
||||
if (
|
||||
outermostShape.id === editor.focusedGroupId ||
|
||||
outermostShape.id === editor.getFocusedGroupId() ||
|
||||
editor.getSelectedShapeIds().includes(outermostShape.id)
|
||||
) {
|
||||
shapeToHover = hitShape
|
||||
|
|
|
@ -835,7 +835,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
|
|||
|
||||
trackEvent('rotate-cw', { source })
|
||||
editor.mark('rotate-cw')
|
||||
const offset = editor.selectionRotation % (TAU / 2)
|
||||
const offset = editor.getSelectionRotation() % (TAU / 2)
|
||||
const dontUseOffset = approximately(offset, 0) || approximately(offset, TAU / 2)
|
||||
editor.rotateShapesBy(
|
||||
editor.getSelectedShapeIds(),
|
||||
|
@ -854,7 +854,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
|
|||
|
||||
trackEvent('rotate-ccw', { source })
|
||||
editor.mark('rotate-ccw')
|
||||
const offset = editor.selectionRotation % (TAU / 2)
|
||||
const offset = editor.getSelectionRotation() % (TAU / 2)
|
||||
const offsetCloseToZero = approximately(offset, 0)
|
||||
editor.rotateShapesBy(
|
||||
editor.getSelectedShapeIds(),
|
||||
|
|
|
@ -195,7 +195,7 @@ const handlePasteFromEventClipboardData = async (
|
|||
point?: VecLike
|
||||
) => {
|
||||
// Do not paste while in any editing state
|
||||
if (editor.editingShapeId !== null) return
|
||||
if (editor.getEditingShapeId() !== null) return
|
||||
|
||||
if (!clipboardData) {
|
||||
throw Error('No clipboard data')
|
||||
|
@ -598,7 +598,7 @@ export function useMenuClipboardEvents() {
|
|||
// If we're editing a shape, or we are focusing an editable input, then
|
||||
// we would want the user's paste interaction to go to that element or
|
||||
// input instead; e.g. when pasting text into a text shape's content
|
||||
if (editor.editingShapeId !== null || disallowClipboardEvents(editor)) return
|
||||
if (editor.getEditingShapeId() !== null || disallowClipboardEvents(editor)) return
|
||||
|
||||
if (Array.isArray(data) && data[0] instanceof ClipboardItem) {
|
||||
handlePasteFromClipboardApi(editor, data, point)
|
||||
|
@ -634,7 +634,7 @@ export function useNativeClipboardEvents() {
|
|||
const copy = () => {
|
||||
if (
|
||||
editor.getSelectedShapeIds().length === 0 ||
|
||||
editor.editingShapeId !== null ||
|
||||
editor.getEditingShapeId() !== null ||
|
||||
disallowClipboardEvents(editor)
|
||||
)
|
||||
return
|
||||
|
@ -645,7 +645,7 @@ export function useNativeClipboardEvents() {
|
|||
function cut() {
|
||||
if (
|
||||
editor.getSelectedShapeIds().length === 0 ||
|
||||
editor.editingShapeId !== null ||
|
||||
editor.getEditingShapeId() !== null ||
|
||||
disallowClipboardEvents(editor)
|
||||
)
|
||||
return
|
||||
|
@ -673,7 +673,7 @@ export function useNativeClipboardEvents() {
|
|||
// If we're editing a shape, or we are focusing an editable input, then
|
||||
// we would want the user's paste interaction to go to that element or
|
||||
// input instead; e.g. when pasting text into a text shape's content
|
||||
if (editor.editingShapeId !== null || disallowClipboardEvents(editor)) return
|
||||
if (editor.getEditingShapeId() !== null || disallowClipboardEvents(editor)) return
|
||||
|
||||
// First try to use the clipboard data on the event
|
||||
if (event.clipboardData && !editor.inputs.shiftKey) {
|
||||
|
|
|
@ -37,7 +37,7 @@ export function useKeyboardShortcuts() {
|
|||
// Add hotkeys for actions and tools.
|
||||
// Except those that in SKIP_KBDS!
|
||||
const areShortcutsDisabled = () =>
|
||||
editor.getIsMenuOpen() || editor.editingShapeId !== null || editor.crashingError
|
||||
editor.getIsMenuOpen() || editor.getEditingShapeId() !== null || editor.crashingError
|
||||
|
||||
for (const action of Object.values(actions)) {
|
||||
if (!action.kbd) continue
|
||||
|
|
|
@ -53,9 +53,9 @@ const moveShapesToPage2 = () => {
|
|||
describe('shapes that are moved to another page', () => {
|
||||
it("should be excluded from the previous page's focusedGroupId", () => {
|
||||
editor.setFocusedGroup(ids.group1)
|
||||
expect(editor.focusedGroupId).toBe(ids.group1)
|
||||
expect(editor.getFocusedGroupId()).toBe(ids.group1)
|
||||
moveShapesToPage2()
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
})
|
||||
|
||||
describe("should be excluded from the previous page's hintingShapeIds", () => {
|
||||
|
@ -76,27 +76,27 @@ describe('shapes that are moved to another page', () => {
|
|||
describe("should be excluded from the previous page's editingShapeId", () => {
|
||||
test('[root shape]', () => {
|
||||
editor.setEditingShape(ids.box1)
|
||||
expect(editor.editingShapeId).toBe(ids.box1)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.box1)
|
||||
moveShapesToPage2()
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
})
|
||||
test('[child of frame]', () => {
|
||||
editor.setEditingShape(ids.box2)
|
||||
expect(editor.editingShapeId).toBe(ids.box2)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.box2)
|
||||
moveShapesToPage2()
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
})
|
||||
test('[child of group]', () => {
|
||||
editor.setEditingShape(ids.box3)
|
||||
expect(editor.editingShapeId).toBe(ids.box3)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.box3)
|
||||
moveShapesToPage2()
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
})
|
||||
test('[frame that doesnt move]', () => {
|
||||
editor.setEditingShape(ids.frame1)
|
||||
expect(editor.editingShapeId).toBe(ids.frame1)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.frame1)
|
||||
moveShapesToPage2()
|
||||
expect(editor.editingShapeId).toBe(ids.frame1)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.frame1)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -263,12 +263,12 @@ describe('When double clicking the selection edge', () => {
|
|||
.doubleClick(100, 100, { target: 'selection', handle: 'left' })
|
||||
.doubleClick(100, 100, { target: 'selection', handle: 'left' })
|
||||
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
editor.expectShapeToMatch({ id, props: { scale: 1, autoSize: true } })
|
||||
|
||||
editor.doubleClick(100, 100, { target: 'selection', handle: 'left' })
|
||||
|
||||
expect(editor.editingShapeId).toBe(id)
|
||||
expect(editor.getEditingShapeId()).toBe(id)
|
||||
})
|
||||
|
||||
it('Selects a geo shape when double clicking on its edge', () => {
|
||||
|
@ -284,11 +284,11 @@ describe('When double clicking the selection edge', () => {
|
|||
},
|
||||
])
|
||||
.select(id)
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
|
||||
editor.doubleClick(100, 100, { target: 'selection', handle: 'left' })
|
||||
|
||||
expect(editor.editingShapeId).toBe(id)
|
||||
expect(editor.getEditingShapeId()).toBe(id)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -312,51 +312,51 @@ describe('When editing shapes', () => {
|
|||
})
|
||||
|
||||
it('Pointing a shape of a different type selects it and leaves editing', () => {
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
expect(editor.getSelectedShapeIds().length).toBe(0)
|
||||
|
||||
// start editing the geo shape
|
||||
editor.doubleClick(50, 50, { target: 'shape', shape: editor.getShape(ids.geo1) })
|
||||
expect(editor.editingShapeId).toBe(ids.geo1)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.geo1)
|
||||
expect(editor.getOnlySelectedShape()?.id).toBe(ids.geo1)
|
||||
// point the text shape
|
||||
editor.pointerDown(50, 50, { target: 'shape', shape: editor.getShape(ids.text1) })
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
expect(editor.getOnlySelectedShape()?.id).toBe(ids.text1)
|
||||
})
|
||||
|
||||
// The behavior described here will only work end to end, not with the library,
|
||||
// because useEditableText implements the behavior in React
|
||||
it.skip('Pointing a shape of a different type selects it and leaves editing', () => {
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
expect(editor.getSelectedShapeIds().length).toBe(0)
|
||||
|
||||
// start editing the geo shape
|
||||
editor.doubleClick(50, 50, { target: 'shape', shape: editor.getShape(ids.geo1) })
|
||||
expect(editor.editingShapeId).toBe(ids.geo1)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.geo1)
|
||||
expect(editor.getOnlySelectedShape()?.id).toBe(ids.geo1)
|
||||
// point the other geo shape
|
||||
editor.pointerDown(50, 50, { target: 'shape', shape: editor.getShape(ids.geo2) })
|
||||
// that other shape should now be editing and selected!
|
||||
expect(editor.editingShapeId).toBe(ids.geo2)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.geo2)
|
||||
expect(editor.getOnlySelectedShape()?.id).toBe(ids.geo2)
|
||||
})
|
||||
|
||||
// This works but only end to end — the logic had to move to React
|
||||
it.skip('Works with text, too', () => {
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
expect(editor.getSelectedShapeIds().length).toBe(0)
|
||||
|
||||
// start editing the geo shape
|
||||
editor.doubleClick(50, 50, { target: 'shape', shape: editor.getShape(ids.text1) })
|
||||
editor.pointerDown(50, 50, { target: 'shape', shape: editor.getShape(ids.text2) })
|
||||
// that other shape should now be editing and selected!
|
||||
expect(editor.editingShapeId).toBe(ids.text2)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.text2)
|
||||
expect(editor.getOnlySelectedShape()?.id).toBe(ids.text2)
|
||||
})
|
||||
|
||||
it('Double clicking the canvas creates a new text shape', () => {
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
expect(editor.getSelectedShapeIds().length).toBe(0)
|
||||
expect(editor.currentPageShapes.length).toBe(5)
|
||||
editor.doubleClick(750, 750)
|
||||
|
@ -365,7 +365,7 @@ describe('When editing shapes', () => {
|
|||
})
|
||||
|
||||
it('It deletes an empty text shape when your click away', () => {
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
expect(editor.getSelectedShapeIds().length).toBe(0)
|
||||
expect(editor.currentPageShapes.length).toBe(5)
|
||||
|
||||
|
@ -383,7 +383,7 @@ describe('When editing shapes', () => {
|
|||
})
|
||||
|
||||
it('It deletes an empty text shape when your click another text shape', () => {
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
expect(editor.getSelectedShapeIds().length).toBe(0)
|
||||
expect(editor.currentPageShapes.length).toBe(5)
|
||||
|
||||
|
@ -422,17 +422,17 @@ describe('When in readonly mode', () => {
|
|||
})
|
||||
|
||||
it('Begins editing embed when double clicked', () => {
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
expect(editor.getSelectedShapeIds().length).toBe(0)
|
||||
expect(editor.getInstanceState().isReadonly).toBe(true)
|
||||
|
||||
const shape = editor.getShape(ids.embed1)
|
||||
editor.doubleClick(100, 100, { target: 'shape', shape })
|
||||
expect(editor.editingShapeId).toBe(ids.embed1)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.embed1)
|
||||
})
|
||||
|
||||
it('Begins editing embed when pressing Enter on a selected embed', () => {
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
expect(editor.getSelectedShapeIds().length).toBe(0)
|
||||
expect(editor.getInstanceState().isReadonly).toBe(true)
|
||||
|
||||
|
@ -440,6 +440,6 @@ describe('When in readonly mode', () => {
|
|||
expect(editor.getSelectedShapeIds().length).toBe(1)
|
||||
|
||||
editor.keyUp('Enter')
|
||||
expect(editor.editingShapeId).toBe(ids.embed1)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.embed1)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -477,11 +477,10 @@ export class TestEditor extends Editor {
|
|||
|
||||
this.setCurrentTool('select')
|
||||
|
||||
const handlePoint = this.selectionRotatedPageBounds!.getHandlePoint(
|
||||
ROTATE_CORNER_TO_SELECTION_CORNER[handle]
|
||||
)
|
||||
const handlePoint = this.getSelectionRotatedPageBounds()!
|
||||
.getHandlePoint(ROTATE_CORNER_TO_SELECTION_CORNER[handle])
|
||||
.clone()
|
||||
.rotWith(this.selectionRotatedPageBounds!.point, this.selectionRotation)
|
||||
.rotWith(this.getSelectionRotatedPageBounds()!.point, this.getSelectionRotation())
|
||||
|
||||
const targetHandlePoint = Vec2d.RotWith(handlePoint, this.selectionPageCenter!, angleRadians)
|
||||
|
||||
|
@ -498,7 +497,8 @@ export class TestEditor extends Editor {
|
|||
* @public
|
||||
*/
|
||||
get selectionPageCenter() {
|
||||
const { selectionRotatedPageBounds: selectionBounds, selectionRotation } = this
|
||||
const selectionRotation = this.getSelectionRotation()
|
||||
const selectionBounds = this.getSelectionRotatedPageBounds()
|
||||
if (!selectionBounds) return null
|
||||
return Vec2d.RotWith(selectionBounds.center, selectionBounds.point, selectionRotation)
|
||||
}
|
||||
|
@ -529,7 +529,7 @@ export class TestEditor extends Editor {
|
|||
throw new Error('No selection')
|
||||
}
|
||||
this.setCurrentTool('select')
|
||||
const bounds = this.selectionRotatedPageBounds!
|
||||
const bounds = this.getSelectionRotatedPageBounds()!
|
||||
const preRotationHandlePoint = bounds.getHandlePoint(handle)
|
||||
|
||||
const preRotationScaleOriginPoint = options?.altKey
|
||||
|
@ -541,11 +541,15 @@ export class TestEditor extends Editor {
|
|||
preRotationScaleOriginPoint
|
||||
)
|
||||
|
||||
const handlePoint = Vec2d.RotWith(preRotationHandlePoint, bounds.point, this.selectionRotation)
|
||||
const handlePoint = Vec2d.RotWith(
|
||||
preRotationHandlePoint,
|
||||
bounds.point,
|
||||
this.getSelectionRotation()
|
||||
)
|
||||
const targetHandlePoint = Vec2d.RotWith(
|
||||
preRotationTargetHandlePoint,
|
||||
bounds.point,
|
||||
this.selectionRotation
|
||||
this.getSelectionRotation()
|
||||
)
|
||||
|
||||
this.pointerDown(handlePoint.x, handlePoint.y, { target: 'selection', handle }, options)
|
||||
|
|
|
@ -64,7 +64,7 @@ it('Does not get an SVG when no ids are provided', async () => {
|
|||
|
||||
it('Gets the bounding box at the correct size', async () => {
|
||||
const svg = await editor.getSvg(editor.getSelectedShapeIds())
|
||||
const bbox = editor.selectionRotatedPageBounds!
|
||||
const bbox = editor.getSelectionRotatedPageBounds()!
|
||||
const expanded = bbox.expandBy(SVG_PADDING) // adds 32px padding
|
||||
|
||||
expect(svg!.getAttribute('width')).toMatch(expanded.width + '')
|
||||
|
@ -73,7 +73,7 @@ it('Gets the bounding box at the correct size', async () => {
|
|||
|
||||
it('Gets the bounding box at the correct size', async () => {
|
||||
const svg = (await editor.getSvg(editor.getSelectedShapeIds()))!
|
||||
const bbox = editor.selectionRotatedPageBounds!
|
||||
const bbox = editor.getSelectionRotatedPageBounds()!
|
||||
const expanded = bbox.expandBy(SVG_PADDING) // adds 32px padding
|
||||
|
||||
expect(svg!.getAttribute('width')).toMatch(expanded.width + '')
|
||||
|
|
|
@ -240,7 +240,7 @@ describe('arrows', () => {
|
|||
editor.setCurrentTool('arrow').pointerDown(250, 250).pointerMove(450, 450).pointerUp(450, 450)
|
||||
|
||||
editor.moveShapesToPage([ids.box1, ids.box2], ids.page2)
|
||||
const { selectionPageBounds } = editor
|
||||
const selectionPageBounds = editor.getSelectionPageBounds()
|
||||
expect(editor.viewportPageCenter).toMatchObject(selectionPageBounds!.center)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -73,14 +73,14 @@ describe('When a shape is selected...', () => {
|
|||
editor.setSelectedShapes([ids.boxA])
|
||||
|
||||
editor.keyDown('ArrowUp')
|
||||
expect(editor.selectionPageBounds).toMatchObject({ x: 10, y: 9 })
|
||||
expect(editor.getSelectionPageBounds()).toMatchObject({ x: 10, y: 9 })
|
||||
editor.keyUp('ArrowUp')
|
||||
|
||||
editor.undo()
|
||||
expect(editor.selectionPageBounds).toMatchObject({ x: 10, y: 10 })
|
||||
expect(editor.getSelectionPageBounds()).toMatchObject({ x: 10, y: 10 })
|
||||
|
||||
editor.redo()
|
||||
expect(editor.selectionPageBounds).toMatchObject({ x: 10, y: 9 })
|
||||
expect(editor.getSelectionPageBounds()).toMatchObject({ x: 10, y: 9 })
|
||||
})
|
||||
|
||||
it('nudges and holds', () => {
|
||||
|
@ -93,34 +93,34 @@ describe('When a shape is selected...', () => {
|
|||
editor.keyRepeat('ArrowUp')
|
||||
editor.keyUp('ArrowUp')
|
||||
|
||||
expect(editor.selectionPageBounds).toMatchObject({ x: 10, y: 5 })
|
||||
expect(editor.getSelectionPageBounds()).toMatchObject({ x: 10, y: 5 })
|
||||
|
||||
// Undoing should go back to the keydown state, all those
|
||||
// repeats should be ephemeral and squashed down
|
||||
editor.undo()
|
||||
expect(editor.selectionPageBounds).toMatchObject({ x: 10, y: 10 })
|
||||
expect(editor.getSelectionPageBounds()).toMatchObject({ x: 10, y: 10 })
|
||||
|
||||
editor.redo()
|
||||
expect(editor.selectionPageBounds).toMatchObject({ x: 10, y: 5 })
|
||||
expect(editor.getSelectionPageBounds()).toMatchObject({ x: 10, y: 5 })
|
||||
})
|
||||
|
||||
it('nudges a shape correctly', () => {
|
||||
editor.setSelectedShapes([ids.boxA])
|
||||
|
||||
editor.keyDown('ArrowUp')
|
||||
expect(editor.selectionPageBounds).toMatchObject({ x: 10, y: 9 })
|
||||
expect(editor.getSelectionPageBounds()).toMatchObject({ x: 10, y: 9 })
|
||||
editor.keyUp('ArrowUp')
|
||||
|
||||
editor.keyDown('ArrowRight')
|
||||
expect(editor.selectionPageBounds).toMatchObject({ x: 11, y: 9 })
|
||||
expect(editor.getSelectionPageBounds()).toMatchObject({ x: 11, y: 9 })
|
||||
editor.keyUp('ArrowRight')
|
||||
|
||||
editor.keyDown('ArrowDown')
|
||||
expect(editor.selectionPageBounds).toMatchObject({ x: 11, y: 10 })
|
||||
expect(editor.getSelectionPageBounds()).toMatchObject({ x: 11, y: 10 })
|
||||
editor.keyUp('ArrowDown')
|
||||
|
||||
editor.keyDown('ArrowLeft')
|
||||
expect(editor.selectionPageBounds).toMatchObject({ x: 10, y: 10 })
|
||||
expect(editor.getSelectionPageBounds()).toMatchObject({ x: 10, y: 10 })
|
||||
editor.keyUp('ArrowLeft')
|
||||
})
|
||||
})
|
||||
|
@ -141,13 +141,13 @@ describe('When a shape is rotated...', () => {
|
|||
|
||||
// Here's the selection page bounds and shape before we nudge it
|
||||
editor.setSelectedShapes([ids.boxA])
|
||||
expect(editor.selectionPageBounds).toCloselyMatchObject({ x: 10, y: 10, w: 100, h: 100 })
|
||||
expect(editor.getSelectionPageBounds()).toCloselyMatchObject({ x: 10, y: 10, w: 100, h: 100 })
|
||||
expect(editor.getShape(ids.boxA)).toCloselyMatchObject({ x: 10, y: -10 })
|
||||
|
||||
// Select box A and move it up. The page bounds should move up, but the
|
||||
// shape should move left (since its parent is rotated 90 degrees)
|
||||
editor.keyDown('ArrowUp')
|
||||
expect(editor.selectionPageBounds).toMatchObject({ x: 10, y: 9, w: 100, h: 100 })
|
||||
expect(editor.getSelectionPageBounds()).toMatchObject({ x: 10, y: 9, w: 100, h: 100 })
|
||||
expect(editor.getShape(ids.boxA)).toMatchObject({ x: 9, y: -10 })
|
||||
editor.keyUp('ArrowUp')
|
||||
})
|
||||
|
|
|
@ -41,13 +41,13 @@ beforeEach(() => {
|
|||
describe('editor.packShapes', () => {
|
||||
it('packs shapes', () => {
|
||||
editor.selectAll()
|
||||
const centerBefore = editor.selectionRotatedPageBounds!.center.clone()
|
||||
const centerBefore = editor.getSelectionRotatedPageBounds()!.center.clone()
|
||||
editor.packShapes(editor.getSelectedShapeIds(), 16)
|
||||
jest.advanceTimersByTime(1000)
|
||||
expect(editor.currentPageShapes.map((s) => ({ ...s, parentId: 'wahtever' }))).toMatchSnapshot(
|
||||
'packed shapes'
|
||||
)
|
||||
const centerAfter = editor.selectionRotatedPageBounds!.center.clone()
|
||||
const centerAfter = editor.getSelectionRotatedPageBounds()!.center.clone()
|
||||
expect(centerBefore).toMatchObject(centerAfter)
|
||||
})
|
||||
|
||||
|
|
|
@ -176,9 +176,9 @@ describe('When duplicating shapes that include arrows', () => {
|
|||
it('Preserves the same selection bounds', () => {
|
||||
editor.selectAll().deleteShapes(editor.getSelectedShapeIds()).createShapes(shapes).selectAll()
|
||||
|
||||
const boundsBefore = editor.selectionRotatedPageBounds!
|
||||
const boundsBefore = editor.getSelectionRotatedPageBounds()!
|
||||
editor.duplicateShapes(editor.getSelectedShapeIds())
|
||||
expect(editor.selectionRotatedPageBounds).toCloselyMatchObject(boundsBefore)
|
||||
expect(editor.getSelectionRotatedPageBounds()).toCloselyMatchObject(boundsBefore)
|
||||
})
|
||||
|
||||
it('Preserves the same selection bounds when only duplicating the arrows', () => {
|
||||
|
@ -192,9 +192,9 @@ describe('When duplicating shapes that include arrows', () => {
|
|||
.map((s) => s.id)
|
||||
)
|
||||
|
||||
const boundsBefore = editor.selectionRotatedPageBounds!
|
||||
const boundsBefore = editor.getSelectionRotatedPageBounds()!
|
||||
editor.duplicateShapes(editor.getSelectedShapeIds())
|
||||
const boundsAfter = editor.selectionRotatedPageBounds!
|
||||
const boundsAfter = editor.getSelectionRotatedPageBounds()!
|
||||
|
||||
// It's not exactly exact, but close enough is plenty close
|
||||
expect(Math.abs(boundsAfter.x - boundsBefore.x)).toBeLessThan(1)
|
||||
|
|
|
@ -104,11 +104,11 @@ describe('When flipping horizontally', () => {
|
|||
it('Flips rotated shapes', () => {
|
||||
editor.updateShapes([{ id: ids.boxA, type: 'geo', rotation: PI }])
|
||||
editor.select(ids.boxA, ids.boxB)
|
||||
const a = editor.selectionPageBounds
|
||||
const a = editor.getSelectionPageBounds()
|
||||
editor.mark('flipped')
|
||||
editor.flipShapes(editor.getSelectedShapeIds(), 'horizontal')
|
||||
|
||||
const b = editor.selectionPageBounds
|
||||
const b = editor.getSelectionPageBounds()
|
||||
expect(a!).toCloselyMatchObject(b!)
|
||||
|
||||
editor.expectShapeToMatch(
|
||||
|
@ -129,11 +129,11 @@ describe('When flipping horizontally', () => {
|
|||
editor.reparentShapes([ids.boxB], ids.boxA)
|
||||
editor.updateShapes([{ id: ids.boxA, type: 'geo', rotation: PI }])
|
||||
editor.select(ids.boxB, ids.boxC)
|
||||
const a = editor.selectionPageBounds
|
||||
const a = editor.getSelectionPageBounds()
|
||||
editor.mark('flipped')
|
||||
editor.flipShapes(editor.getSelectedShapeIds(), 'horizontal')
|
||||
|
||||
const b = editor.selectionPageBounds
|
||||
const b = editor.getSelectionPageBounds()
|
||||
expect(a).toCloselyMatchObject(b!)
|
||||
})
|
||||
})
|
||||
|
@ -184,11 +184,11 @@ describe('When flipping vertically', () => {
|
|||
it('Flips rotated shapes', () => {
|
||||
editor.updateShapes([{ id: ids.boxA, type: 'geo', rotation: PI }])
|
||||
editor.select(ids.boxA, ids.boxB)
|
||||
const a = editor.selectionPageBounds
|
||||
const a = editor.getSelectionPageBounds()
|
||||
editor.mark('flipped')
|
||||
editor.flipShapes(editor.getSelectedShapeIds(), 'vertical')
|
||||
|
||||
const b = editor.selectionPageBounds
|
||||
const b = editor.getSelectionPageBounds()
|
||||
expect(a).toCloselyMatchObject(b!)
|
||||
editor.expectShapeToMatch(
|
||||
{
|
||||
|
@ -208,27 +208,27 @@ describe('When flipping vertically', () => {
|
|||
editor.reparentShapes([ids.boxB], ids.boxA)
|
||||
editor.updateShapes([{ id: ids.boxA, type: 'geo', rotation: PI }])
|
||||
editor.select(ids.boxB, ids.boxC)
|
||||
const a = editor.selectionPageBounds
|
||||
const a = editor.getSelectionPageBounds()
|
||||
editor.mark('flipped')
|
||||
editor.flipShapes(editor.getSelectedShapeIds(), 'vertical')
|
||||
|
||||
const b = editor.selectionPageBounds
|
||||
const b = editor.getSelectionPageBounds()
|
||||
expect(a).toCloselyMatchObject(b!)
|
||||
})
|
||||
})
|
||||
|
||||
it('Preserves the selection bounds.', () => {
|
||||
editor.selectAll()
|
||||
const a = editor.selectionPageBounds
|
||||
const a = editor.getSelectionPageBounds()
|
||||
editor.mark('flipped')
|
||||
editor.flipShapes(editor.getSelectedShapeIds(), 'horizontal')
|
||||
|
||||
const b = editor.selectionPageBounds
|
||||
const b = editor.getSelectionPageBounds()
|
||||
expect(a).toMatchObject(b!)
|
||||
editor.mark('flipped')
|
||||
editor.flipShapes(editor.getSelectedShapeIds(), 'vertical')
|
||||
|
||||
const c = editor.selectionPageBounds
|
||||
const c = editor.getSelectionPageBounds()
|
||||
expect(a).toMatchObject(c!)
|
||||
})
|
||||
|
||||
|
@ -560,16 +560,16 @@ describe('When flipping shapes that include arrows', () => {
|
|||
it('Flips horizontally', () => {
|
||||
editor.selectAll().deleteShapes(editor.getSelectedShapeIds()).createShapes(shapes)
|
||||
|
||||
const boundsBefore = editor.selectionRotatedPageBounds!
|
||||
const boundsBefore = editor.getSelectionRotatedPageBounds()!
|
||||
editor.flipShapes(editor.getSelectedShapeIds(), 'horizontal')
|
||||
expect(editor.selectionRotatedPageBounds).toCloselyMatchObject(boundsBefore)
|
||||
expect(editor.getSelectionRotatedPageBounds()).toCloselyMatchObject(boundsBefore)
|
||||
})
|
||||
|
||||
it('Flips vertically', () => {
|
||||
editor.selectAll().deleteShapes(editor.getSelectedShapeIds()).createShapes(shapes)
|
||||
|
||||
const boundsBefore = editor.selectionRotatedPageBounds!
|
||||
const boundsBefore = editor.getSelectionRotatedPageBounds()!
|
||||
editor.flipShapes(editor.getSelectedShapeIds(), 'vertical')
|
||||
expect(editor.selectionRotatedPageBounds).toCloselyMatchObject(boundsBefore)
|
||||
expect(editor.getSelectionRotatedPageBounds()).toCloselyMatchObject(boundsBefore)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -761,7 +761,7 @@ describe('When dragging a shape inside a group inside a frame', () => {
|
|||
editor.pointerMove(100, 100).click().click()
|
||||
|
||||
expect(editor.getOnlySelectedShape()?.id).toBe(ids.box1)
|
||||
expect(editor.focusedGroupId).toBe(ids.group1)
|
||||
expect(editor.getFocusedGroupId()).toBe(ids.group1)
|
||||
|
||||
editor
|
||||
.pointerMove(150, 150)
|
||||
|
|
|
@ -825,39 +825,39 @@ describe('focus layers', () => {
|
|||
editor.selectNone()
|
||||
})
|
||||
it('should adjust to the parent layer of any selected shape', () => {
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId).toBe(groupAId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupAId)
|
||||
editor.select(ids.boxB)
|
||||
expect(editor.focusedGroupId).toBe(groupAId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupAId)
|
||||
editor.select(ids.boxC)
|
||||
expect(editor.focusedGroupId).toBe(groupBId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupBId)
|
||||
editor.select(ids.boxD)
|
||||
expect(editor.focusedGroupId).toBe(groupBId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupBId)
|
||||
editor.select(groupAId)
|
||||
expect(editor.focusedGroupId).toBe(groupCId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupCId)
|
||||
})
|
||||
it('should adjust to the common ancestor of selected shapes in multiple groups', () => {
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId).toBe(groupAId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupAId)
|
||||
editor.setSelectedShapes([...editor.getSelectedShapeIds(), ids.boxC])
|
||||
expect(editor.focusedGroupId).toBe(groupCId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupCId)
|
||||
editor.deselect(ids.boxA)
|
||||
expect(editor.focusedGroupId).toBe(groupBId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupBId)
|
||||
editor.setSelectedShapes([...editor.getSelectedShapeIds(), ids.boxB])
|
||||
expect(editor.focusedGroupId).toBe(groupCId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupCId)
|
||||
})
|
||||
it('should not adjust the focus layer when clearing the selection', () => {
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId).toBe(groupAId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupAId)
|
||||
editor.deselect(ids.boxA)
|
||||
expect(editor.focusedGroupId).toBe(groupAId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupAId)
|
||||
editor.select(ids.boxB, ids.boxC)
|
||||
expect(editor.focusedGroupId).toBe(groupCId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupCId)
|
||||
editor.selectNone()
|
||||
expect(editor.focusedGroupId).toBe(groupCId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupCId)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -922,14 +922,14 @@ describe('the select tool', () => {
|
|||
it('should select the outermost non-selected group when you click on one of the shapes in that group', () => {
|
||||
editor.pointerDown(0, 0, ids.boxA).pointerUp(0, 0)
|
||||
expect(onlySelectedId()).toBe(groupCId)
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
editor.pointerDown(0, 0, ids.boxA)
|
||||
editor.pointerUp(0, 0, ids.boxA)
|
||||
expect(onlySelectedId()).toBe(groupAId)
|
||||
expect(editor.focusedGroupId).toBe(groupCId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupCId)
|
||||
editor.pointerDown(0, 0, ids.boxA).pointerUp(0, 0, ids.boxA)
|
||||
expect(onlySelectedId()).toBe(ids.boxA)
|
||||
expect(editor.focusedGroupId).toBe(groupAId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupAId)
|
||||
})
|
||||
|
||||
it('should select the outermost non-selected group when you right-click on one of the shapes in that group', () => {
|
||||
|
@ -939,17 +939,17 @@ describe('the select tool', () => {
|
|||
.pointerDown(0, 0, { target: 'shape', shape: boxA, button: 2 })
|
||||
.pointerUp(0, 0, { button: 2 })
|
||||
expect(onlySelectedId()).toBe(groupCId)
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
editor
|
||||
.pointerDown(0, 0, { target: 'shape', shape: boxA, button: 2 })
|
||||
.pointerUp(0, 0, { button: 2 })
|
||||
expect(onlySelectedId()).toBe(groupAId)
|
||||
expect(editor.focusedGroupId).toBe(groupCId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupCId)
|
||||
editor
|
||||
.pointerDown(0, 0, { target: 'shape', shape: boxA, button: 2 })
|
||||
.pointerUp(0, 0, { button: 2 })
|
||||
expect(onlySelectedId()).toBe(ids.boxA)
|
||||
expect(editor.focusedGroupId).toBe(groupAId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupAId)
|
||||
})
|
||||
|
||||
it('should allow to shift-select other shapes outside of the current focus layer', () => {
|
||||
|
@ -957,37 +957,37 @@ describe('the select tool', () => {
|
|||
editor.pointerDown(0, 0, ids.boxA).pointerUp(0, 0)
|
||||
editor.pointerDown(0, 0, ids.boxA).pointerUp(0, 0)
|
||||
expect(onlySelectedId()).toBe(ids.boxA)
|
||||
expect(editor.focusedGroupId).toBe(groupAId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupAId)
|
||||
|
||||
editor
|
||||
.pointerDown(60, 0, ids.boxC, { shiftKey: true })
|
||||
.pointerUp(0, 0, ids.boxC, { shiftKey: true })
|
||||
expect(editor.getSelectedShapeIds().includes(ids.boxA)).toBe(true)
|
||||
expect(editor.getSelectedShapeIds().includes(groupBId)).toBe(true)
|
||||
expect(editor.focusedGroupId).toBe(groupCId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupCId)
|
||||
|
||||
editor.pointerDown(60, 0, ids.boxC, { shiftKey: true }).pointerUp()
|
||||
expect(editor.getSelectedShapeIds().includes(ids.boxA)).toBe(true)
|
||||
expect(editor.getSelectedShapeIds().includes(groupBId)).toBe(false)
|
||||
expect(editor.getSelectedShapeIds().includes(ids.boxC)).toBe(true)
|
||||
expect(editor.focusedGroupId).toBe(groupCId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupCId)
|
||||
})
|
||||
|
||||
it('if a shape inside a focused group is selected and you click outside the group it should clear the selection and focus the page', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId).toBe(groupAId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupAId)
|
||||
|
||||
// click outside the focused group, but inside another group
|
||||
editor.pointerDown(-235, 5, { target: 'canvas' }).pointerUp(-235, 5)
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
expect(editor.getSelectedShapeIds()).toHaveLength(0)
|
||||
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId).toBe(groupAId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupAId)
|
||||
|
||||
// click the empty canvas
|
||||
editor.pointerDown(-235, 50, { target: 'canvas' }).pointerUp(-235, 50)
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
expect(editor.getSelectedShapeIds()).toHaveLength(0)
|
||||
})
|
||||
|
||||
|
@ -1016,18 +1016,18 @@ describe('the select tool', () => {
|
|||
it('should pop the focus layer when escape is pressed in idle state', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.getSelectedShapeIds()).toMatchObject([ids.boxA]) // box1
|
||||
expect(editor.focusedGroupId).toBe(groupAId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupAId)
|
||||
// deselct
|
||||
editor.cancel()
|
||||
expect(editor.getSelectedShapeIds()).toMatchObject([groupAId]) // groupA
|
||||
expect(editor.focusedGroupId).toBe(groupCId)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupCId)
|
||||
// pop focus layer
|
||||
editor.cancel()
|
||||
expect(editor.getSelectedShapeIds().length).toBe(1) // Group C
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
editor.cancel()
|
||||
expect(editor.getSelectedShapeIds().length).toBe(0)
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
})
|
||||
|
||||
// ! Removed: pointing a group is impossible; you'd be pointing the selection instead.
|
||||
|
@ -1172,7 +1172,7 @@ describe('creating new shapes', () => {
|
|||
|
||||
it('does create inside the group if the group is focused', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupA.id).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupA.id).toBe(true)
|
||||
|
||||
editor.setCurrentTool('geo')
|
||||
editor.pointerDown(20, 20).pointerMove(80, 80).pointerUp(80, 80)
|
||||
|
@ -1185,12 +1185,12 @@ describe('creating new shapes', () => {
|
|||
w: 60,
|
||||
h: 60,
|
||||
})
|
||||
expect(editor.focusedGroupId === groupA.id).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupA.id).toBe(true)
|
||||
})
|
||||
|
||||
it('will reisze the group appropriately if the new shape changes the group bounds', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupA.id).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupA.id).toBe(true)
|
||||
|
||||
editor.setCurrentTool('geo')
|
||||
editor.pointerDown(20, 20).pointerMove(-10, -10)
|
||||
|
@ -1219,7 +1219,7 @@ describe('creating new shapes', () => {
|
|||
|
||||
it('works if the shape drawing begins outside of the current group bounds', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupA.id).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupA.id).toBe(true)
|
||||
|
||||
editor.setCurrentTool('geo')
|
||||
editor.pointerDown(-50, -50).pointerMove(-100, -100).pointerUp()
|
||||
|
@ -1254,7 +1254,7 @@ describe('creating new shapes', () => {
|
|||
|
||||
it('does draw inside the group if the group is focused', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupA.id).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupA.id).toBe(true)
|
||||
|
||||
editor.setCurrentTool('draw')
|
||||
editor.pointerDown(20, 20).pointerMove(80, 80).pointerUp(80, 80)
|
||||
|
@ -1265,7 +1265,7 @@ describe('creating new shapes', () => {
|
|||
|
||||
it('will resize the group appropriately if the new shape changes the group bounds', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupA.id).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupA.id).toBe(true)
|
||||
|
||||
editor.setCurrentTool('draw')
|
||||
editor.pointerDown(20, 20)
|
||||
|
@ -1293,7 +1293,7 @@ describe('creating new shapes', () => {
|
|||
|
||||
it('works if the shape drawing begins outside of the current group bounds', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupA.id).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupA.id).toBe(true)
|
||||
|
||||
editor.setCurrentTool('draw')
|
||||
editor.pointerDown(-20, -20)
|
||||
|
@ -1335,7 +1335,7 @@ describe('creating new shapes', () => {
|
|||
|
||||
it('does draw inside the group if the group is focused', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupA.id).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupA.id).toBe(true)
|
||||
|
||||
editor.setCurrentTool('line')
|
||||
editor.pointerDown(20, 20).pointerMove(80, 80).pointerUp(80, 80)
|
||||
|
@ -1347,7 +1347,7 @@ describe('creating new shapes', () => {
|
|||
|
||||
it('will reisze the group appropriately if the new shape changes the group bounds', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupA.id).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupA.id).toBe(true)
|
||||
|
||||
editor.setCurrentTool('line')
|
||||
editor.pointerDown(20, 20).pointerMove(-10, -10)
|
||||
|
@ -1363,7 +1363,7 @@ describe('creating new shapes', () => {
|
|||
|
||||
it('works if the shape drawing begins outside of the current group bounds', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupA.id).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupA.id).toBe(true)
|
||||
|
||||
editor.setCurrentTool('line')
|
||||
editor.pointerDown(-50, -50).pointerMove(-100, -100).pointerUp()
|
||||
|
@ -1378,7 +1378,7 @@ describe('creating new shapes', () => {
|
|||
describe('sticky notes', () => {
|
||||
it('does not draw inside the group if the group is only selected and not focused', () => {
|
||||
editor.select(groupA.id)
|
||||
expect(editor.focusedGroupId === editor.currentPageId).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === editor.currentPageId).toBe(true)
|
||||
|
||||
editor.setCurrentTool('note')
|
||||
editor.pointerDown(20, 20).pointerUp()
|
||||
|
@ -1389,7 +1389,7 @@ describe('creating new shapes', () => {
|
|||
|
||||
it('does draw inside the group if the group is focused', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupA.id).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupA.id).toBe(true)
|
||||
|
||||
editor.setCurrentTool('note')
|
||||
editor.pointerDown(20, 20).pointerUp()
|
||||
|
@ -1400,7 +1400,7 @@ describe('creating new shapes', () => {
|
|||
|
||||
it('will reisze the group appropriately if the new shape changes the group bounds', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupA.id).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupA.id).toBe(true)
|
||||
|
||||
expect(editor.getShapePageBounds(groupA.id)).toCloselyMatchObject({
|
||||
x: 0,
|
||||
|
@ -1432,7 +1432,7 @@ describe('creating new shapes', () => {
|
|||
|
||||
it('works if the shape drawing begins outside of the current group bounds', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupA.id).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupA.id).toBe(true)
|
||||
|
||||
editor.setCurrentTool('note')
|
||||
expect(editor.getShapePageBounds(groupA.id)).toCloselyMatchObject({
|
||||
|
@ -1510,7 +1510,7 @@ describe('erasing', () => {
|
|||
|
||||
it('works inside of groups', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupAId).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupAId).toBe(true)
|
||||
const groupA = editor.getShape(groupAId)!
|
||||
|
||||
editor.setCurrentTool('eraser')
|
||||
|
@ -1527,7 +1527,7 @@ describe('erasing', () => {
|
|||
|
||||
it('works outside of the focus layer', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId === groupAId).toBe(true)
|
||||
expect(editor.getFocusedGroupId() === groupAId).toBe(true)
|
||||
|
||||
editor.setCurrentTool('eraser')
|
||||
|
||||
|
@ -1710,7 +1710,7 @@ describe('moving handles within a group', () => {
|
|||
})
|
||||
it('resizes the group appropriately', () => {
|
||||
editor.select(ids.boxA)
|
||||
expect(editor.focusedGroupId).toBe(groupA.id)
|
||||
expect(editor.getFocusedGroupId()).toBe(groupA.id)
|
||||
|
||||
editor.setCurrentTool('arrow')
|
||||
|
||||
|
|
|
@ -243,9 +243,9 @@ describe('When resizing a rotated shape...', () => {
|
|||
const initialPagePoint = editor.getShapePageTransform(ids.boxA)!.point()
|
||||
|
||||
const pt0 = Vec2d.From(initialPagePoint)
|
||||
const pt1 = Vec2d.RotWith(initialPagePoint, editor.selectionPageBounds!.center, rotation)
|
||||
const pt1 = Vec2d.RotWith(initialPagePoint, editor.getSelectionPageBounds()!.center, rotation)
|
||||
const pt2 = Vec2d.Sub(initialPagePoint, offset).rotWith(
|
||||
editor.selectionPageBounds!.center!,
|
||||
editor.getSelectionPageBounds()!.center!,
|
||||
rotation
|
||||
)
|
||||
|
||||
|
@ -332,7 +332,7 @@ describe('When resizing mulitple shapes...', () => {
|
|||
.select(ids.boxA)
|
||||
.pointerDown(rotateStart.x, rotateStart.y, {
|
||||
target: 'selection',
|
||||
handle: rotateRotateCorner('top_left_rotate', -editor.selectionRotation),
|
||||
handle: rotateRotateCorner('top_left_rotate', -editor.getSelectionRotation()),
|
||||
})
|
||||
.pointerMove(rotateEnd.x, rotateEnd.y)
|
||||
.pointerUp()
|
||||
|
@ -347,7 +347,7 @@ describe('When resizing mulitple shapes...', () => {
|
|||
|
||||
// Now drag to resize the selection bounds
|
||||
|
||||
const initialBounds = editor.selectionPageBounds!
|
||||
const initialBounds = editor.getSelectionPageBounds()!
|
||||
|
||||
// oddly rotated shapes maintain aspect ratio when being resized (for now)
|
||||
const aspectRatio = initialBounds.width / initialBounds.height
|
||||
|
@ -367,15 +367,15 @@ describe('When resizing mulitple shapes...', () => {
|
|||
editor
|
||||
.pointerDown(resizeStart.x, resizeStart.y, {
|
||||
target: 'selection',
|
||||
handle: rotateSelectionHandle('top_left', -editor.selectionRotation),
|
||||
handle: rotateSelectionHandle('top_left', -editor.getSelectionRotation()),
|
||||
})
|
||||
.pointerMove(resizeStart.x - 10, resizeStart.y - 10)
|
||||
.pointerMove(resizeEnd.x, resizeEnd.y)
|
||||
.pointerUp()
|
||||
|
||||
expect(editor.selectionPageBounds!.point).toCloselyMatchObject(resizeEnd)
|
||||
expect(editor.getSelectionPageBounds()!.point).toCloselyMatchObject(resizeEnd)
|
||||
expect(new Vec2d(initialBounds.maxX, initialBounds.maxY)).toCloselyMatchObject(
|
||||
new Vec2d(editor.selectionPageBounds!.maxX, editor.selectionPageBounds!.maxY)
|
||||
new Vec2d(editor.getSelectionPageBounds()!.maxX, editor.getSelectionPageBounds()!.maxY)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
@ -423,7 +423,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
editor.pointerDown(30, 30, { target: 'selection', handle: 'bottom_right' })
|
||||
editor.pointerMove(15, 15)
|
||||
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({ w: 15, h: 15 })
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({ w: 15, h: 15 })
|
||||
expect(roundedPageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 5, h: 5 })
|
||||
expect(roundedPageBounds(ids.boxB)).toMatchObject({ x: 10, y: 10, w: 5, h: 5 })
|
||||
|
||||
|
@ -447,7 +447,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
// └──────────────────────────────────────────────────────────────────O
|
||||
|
||||
editor.pointerMove(60, 30)
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({ w: 60, h: 30 })
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({ w: 60, h: 30 })
|
||||
expect(roundedPageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 20, h: 10 })
|
||||
expect(roundedPageBounds(ids.boxB)).toMatchObject({ x: 40, y: 20, w: 20, h: 10 })
|
||||
// stretch vertically
|
||||
|
@ -482,7 +482,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
// 60 │ └──────────┘ │
|
||||
// └─────────────────────────────────O
|
||||
editor.pointerMove(30, 60)
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({ w: 30, h: 60 })
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({ w: 30, h: 60 })
|
||||
expect(roundedPageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 10, h: 20 })
|
||||
expect(roundedPageBounds(ids.boxB)).toMatchObject({ x: 20, y: 40, w: 10, h: 20 })
|
||||
|
||||
|
@ -499,7 +499,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
// │ └───┘ │
|
||||
// └───────────────┘
|
||||
editor.pointerMove(-15, -15)
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({ w: 15, h: 15 })
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({ w: 15, h: 15 })
|
||||
expect(roundedPageBounds(ids.boxA)).toMatchObject({ x: -5, y: -5, w: 5, h: 5 })
|
||||
expect(roundedPageBounds(ids.boxB)).toMatchObject({ x: -15, y: -15, w: 5, h: 5 })
|
||||
|
||||
|
@ -523,7 +523,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
// └───────────────────────────────────O
|
||||
editor.pointerMove(45, 45, { altKey: true })
|
||||
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({
|
||||
w: 60,
|
||||
h: 60,
|
||||
x: -15,
|
||||
|
@ -548,7 +548,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
editor.pointerMove(15, 8, { altKey: false, shiftKey: true })
|
||||
jest.advanceTimersByTime(200)
|
||||
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({ w: 15, h: 15 })
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({ w: 15, h: 15 })
|
||||
expect(roundedPageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 5, h: 5 })
|
||||
expect(roundedPageBounds(ids.boxB)).toMatchObject({ x: 10, y: 10, w: 5, h: 5 })
|
||||
|
||||
|
@ -571,7 +571,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
// │ └──────────┘ │
|
||||
// └───────────────────────────────────O
|
||||
editor.pointerMove(45, 16, { altKey: true, shiftKey: true })
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({
|
||||
w: 60,
|
||||
h: 60,
|
||||
x: -15,
|
||||
|
@ -615,14 +615,14 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
|
||||
editor.pointerDown(30, 30, {
|
||||
target: 'selection',
|
||||
handle: rotateSelectionHandle('bottom_right', -editor.selectionRotation),
|
||||
handle: rotateSelectionHandle('bottom_right', -editor.getSelectionRotation()),
|
||||
})
|
||||
editor.pointerMove(15, 15)
|
||||
|
||||
expect(roundedPageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 5, h: 5 })
|
||||
expect(roundedPageBounds(ids.boxB)).toMatchObject({ x: 10, y: 10, w: 5, h: 5 })
|
||||
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({ w: 15, h: 15 })
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({ w: 15, h: 15 })
|
||||
|
||||
// strech horizontally
|
||||
|
||||
|
@ -644,7 +644,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
// └──────────────────────────────────────────────────────────────────O
|
||||
|
||||
editor.pointerMove(60, 30)
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({ w: 60, h: 30 })
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({ w: 60, h: 30 })
|
||||
expect(roundedPageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 20, h: 10 })
|
||||
expect(roundedPageBounds(ids.boxB)).toMatchObject({ x: 40, y: 20, w: 20, h: 10 })
|
||||
// stretch vertically
|
||||
|
@ -679,7 +679,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
// 60 │ └──────────┘ │
|
||||
// └─────────────────────────────────O
|
||||
editor.pointerMove(30, 60)
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({ w: 30, h: 60 })
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({ w: 30, h: 60 })
|
||||
expect(roundedPageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 10, h: 20 })
|
||||
expect(roundedPageBounds(ids.boxB)).toMatchObject({ x: 20, y: 40, w: 10, h: 20 })
|
||||
|
||||
|
@ -696,7 +696,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
// │ └───┘ │
|
||||
// └───────────────┘
|
||||
editor.pointerMove(-15, -15)
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({ w: 15, h: 15 })
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({ w: 15, h: 15 })
|
||||
expect(roundedPageBounds(ids.boxA)).toMatchObject({ x: -5, y: -5, w: 5, h: 5 })
|
||||
expect(roundedPageBounds(ids.boxB)).toMatchObject({ x: -15, y: -15, w: 5, h: 5 })
|
||||
|
||||
|
@ -719,7 +719,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
// │ └──────────┘ │
|
||||
// └───────────────────────────────────O
|
||||
editor.pointerMove(45, 45, { altKey: true })
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({
|
||||
w: 60,
|
||||
h: 60,
|
||||
x: -15,
|
||||
|
@ -744,7 +744,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
editor.pointerMove(15, 8, { altKey: false, shiftKey: true })
|
||||
jest.advanceTimersByTime(200)
|
||||
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({ w: 15, h: 15 })
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({ w: 15, h: 15 })
|
||||
expect(roundedPageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 5, h: 5 })
|
||||
expect(roundedPageBounds(ids.boxB)).toMatchObject({ x: 10, y: 10, w: 5, h: 5 })
|
||||
|
||||
|
@ -767,7 +767,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
// │ └──────────┘ │
|
||||
// └───────────────────────────────────O
|
||||
editor.pointerMove(45, 16, { altKey: true, shiftKey: true })
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({
|
||||
w: 60,
|
||||
h: 60,
|
||||
x: -15,
|
||||
|
@ -803,7 +803,7 @@ describe('Reisizing a selection of multiple shapes', () => {
|
|||
editor.select(ids.boxA, ids.boxB)
|
||||
editor.pointerDown(30, 30, { target: 'selection', handle: 'bottom_right' })
|
||||
editor.pointerMove(60, 30)
|
||||
expect(roundedBox(editor.selectionPageBounds!)).toMatchObject({ w: 60, h: 30 })
|
||||
expect(roundedBox(editor.getSelectionPageBounds()!)).toMatchObject({ w: 60, h: 30 })
|
||||
// A should stretch
|
||||
expect(roundedPageBounds(ids.boxA)).toMatchObject({ x: 0, y: 0, w: 20, h: 10 })
|
||||
// B should not
|
||||
|
|
|
@ -119,7 +119,7 @@ describe('When rotating...', () => {
|
|||
editor.select(ids.box1)
|
||||
|
||||
const shapeA = editor.getShape(ids.box1)!
|
||||
const box = editor.selectionPageBounds!
|
||||
const box = editor.getSelectionPageBounds()!
|
||||
const center = box.center.clone().toFixed()
|
||||
|
||||
expect(Vec2d.ToFixed(editor.getPageCenter(shapeA)!)).toMatchObject(center)
|
||||
|
@ -159,7 +159,7 @@ describe('When rotating...', () => {
|
|||
|
||||
editor.select(ids.box1, ids.box2)
|
||||
|
||||
const box = editor.selectionPageBounds!
|
||||
const box = editor.getSelectionPageBounds()!
|
||||
const center = box.center.clone()
|
||||
|
||||
editor.pointerDown(box.midX, box.minY, {
|
||||
|
@ -219,7 +219,7 @@ describe('When rotating...', () => {
|
|||
it('restores initial points / rotation when cancelled', () => {
|
||||
editor.select(ids.box1, ids.box2)
|
||||
|
||||
const box = editor.selectionPageBounds!
|
||||
const box = editor.getSelectionPageBounds()!
|
||||
const center = box.center.clone()
|
||||
|
||||
const shapeA = editor.getShape(ids.box1)!
|
||||
|
@ -246,7 +246,7 @@ describe('When rotating...', () => {
|
|||
it('uses the same selection box center when rotating multiple times', () => {
|
||||
editor.select(ids.box1, ids.box2)
|
||||
|
||||
const centerBefore = editor.selectionPageBounds!.center.clone()
|
||||
const centerBefore = editor.getSelectionPageBounds()!.center.clone()
|
||||
|
||||
editor
|
||||
.pointerDown(0, 0, {
|
||||
|
@ -256,7 +256,7 @@ describe('When rotating...', () => {
|
|||
.pointerMove(50, 100)
|
||||
.pointerUp()
|
||||
|
||||
const centerBetween = editor.selectionPageBounds!.center.clone()
|
||||
const centerBetween = editor.getSelectionPageBounds()!.center.clone()
|
||||
|
||||
expect(centerBefore.toFixed().toJson()).toMatchObject(centerBetween.toFixed().toJson())
|
||||
|
||||
|
@ -268,7 +268,7 @@ describe('When rotating...', () => {
|
|||
.pointerMove(0, 0)
|
||||
.pointerUp()
|
||||
|
||||
const centerAfter = editor.selectionPageBounds!.center.clone()
|
||||
const centerAfter = editor.getSelectionPageBounds()!.center.clone()
|
||||
|
||||
expect(centerBefore.toFixed().toJson()).toMatchObject(centerAfter.toFixed().toJson())
|
||||
})
|
||||
|
|
|
@ -985,7 +985,7 @@ describe('Selects inside of groups', () => {
|
|||
expect(editor.hoveredShapeId).toBe(ids.group1)
|
||||
editor.doubleClick()
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box2])
|
||||
expect(editor.focusedGroupId).toBe(ids.group1)
|
||||
expect(editor.getFocusedGroupId()).toBe(ids.group1)
|
||||
})
|
||||
|
||||
it('selects a solid shape in a group when double clicking its margin', () => {
|
||||
|
@ -993,7 +993,7 @@ describe('Selects inside of groups', () => {
|
|||
expect(editor.hoveredShapeId).toBe(ids.group1)
|
||||
editor.doubleClick()
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box2])
|
||||
expect(editor.focusedGroupId).toBe(ids.group1)
|
||||
expect(editor.getFocusedGroupId()).toBe(ids.group1)
|
||||
})
|
||||
|
||||
// it('selects a hollow shape in a group when double clicking it', () => {
|
||||
|
@ -1009,7 +1009,7 @@ describe('Selects inside of groups', () => {
|
|||
expect(editor.hoveredShapeId).toBe(ids.group1)
|
||||
editor.doubleClick()
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box1])
|
||||
expect(editor.focusedGroupId).toBe(ids.group1)
|
||||
expect(editor.getFocusedGroupId()).toBe(ids.group1)
|
||||
})
|
||||
|
||||
// it('double clicks a hollow shape when the focus layer is the shapes parent', () => {
|
||||
|
@ -1026,7 +1026,7 @@ describe('Selects inside of groups', () => {
|
|||
expect(editor.hoveredShapeId).toBe(ids.group1)
|
||||
editor.doubleClick()
|
||||
editor.doubleClick()
|
||||
expect(editor.editingShapeId).toBe(ids.box2)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.box2)
|
||||
editor.expectToBeIn('select.editing_shape')
|
||||
})
|
||||
|
||||
|
@ -1308,58 +1308,58 @@ describe('When children / descendants of a group are selected', () => {
|
|||
it('selects the child', () => {
|
||||
editor.select(ids.box1)
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box1])
|
||||
expect(editor.focusedGroupId).toBe(ids.group1)
|
||||
expect(editor.getFocusedGroupId()).toBe(ids.group1)
|
||||
})
|
||||
|
||||
it('selects the children', () => {
|
||||
editor.select(ids.box1, ids.box2)
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box1, ids.box2])
|
||||
expect(editor.focusedGroupId).toBe(ids.group1)
|
||||
expect(editor.getFocusedGroupId()).toBe(ids.group1)
|
||||
})
|
||||
|
||||
it('does not allow parents and children to be selected, picking the parent', () => {
|
||||
editor.select(ids.group1, ids.box1)
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.group1])
|
||||
expect(editor.focusedGroupId).toBe(ids.group3)
|
||||
expect(editor.getFocusedGroupId()).toBe(ids.group3)
|
||||
|
||||
editor.select(ids.group1, ids.box1, ids.box2)
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.group1])
|
||||
expect(editor.focusedGroupId).toBe(ids.group3)
|
||||
expect(editor.getFocusedGroupId()).toBe(ids.group3)
|
||||
})
|
||||
|
||||
it('does not allow ancestors and children to be selected, picking the ancestor', () => {
|
||||
editor.select(ids.group3, ids.box1)
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.group3])
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
|
||||
editor.select(ids.group3, ids.box1, ids.box2)
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.group3])
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
|
||||
editor.select(ids.group3, ids.group2, ids.box1)
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.group3])
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
})
|
||||
|
||||
it('picks the highest common focus layer id', () => {
|
||||
editor.select(ids.box1, ids.box4) // child of group1, child of group 2
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box1, ids.box4])
|
||||
expect(editor.focusedGroupId).toBe(ids.group3)
|
||||
expect(editor.getFocusedGroupId()).toBe(ids.group3)
|
||||
})
|
||||
|
||||
it('picks the highest common focus layer id', () => {
|
||||
editor.select(ids.box1, ids.box5) // child of group1 and child of the page
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box1, ids.box5])
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
})
|
||||
|
||||
it('sets the parent to the highest common ancestor', () => {
|
||||
editor.selectNone()
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
editor.select(ids.group3)
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
editor.select(ids.group3, ids.box1)
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.group3])
|
||||
})
|
||||
})
|
||||
|
@ -1382,10 +1382,10 @@ describe('When pressing the enter key with groups selected', () => {
|
|||
editor.select(ids.group1, ids.group2)
|
||||
editor.keyDown('Enter')
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.group1, ids.group2])
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
editor.keyUp('Enter')
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box1, ids.box2, ids.box3, ids.box4])
|
||||
expect(editor.focusedGroupId).toBe(editor.currentPageId)
|
||||
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
|
||||
})
|
||||
|
||||
it('repeats children of the groups on enter up', () => {
|
||||
|
@ -1394,10 +1394,10 @@ describe('When pressing the enter key with groups selected', () => {
|
|||
expect(editor.getSelectedShapeIds()).toEqual([ids.group3])
|
||||
editor.keyDown('Enter').keyUp('Enter')
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.group1, ids.group2])
|
||||
expect(editor.focusedGroupId).toBe(ids.group3)
|
||||
expect(editor.getFocusedGroupId()).toBe(ids.group3)
|
||||
editor.keyDown('Enter').keyUp('Enter')
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box1, ids.box2, ids.box3, ids.box4])
|
||||
expect(editor.focusedGroupId).toBe(ids.group3)
|
||||
expect(editor.getFocusedGroupId()).toBe(ids.group3)
|
||||
})
|
||||
|
||||
it('does not select the children of the group if a non-group is also selected', () => {
|
||||
|
@ -1429,14 +1429,14 @@ describe('When double clicking an editable shape', () => {
|
|||
it('starts editing on double click', () => {
|
||||
editor.pointerMove(50, 50).doubleClick()
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box1])
|
||||
expect(editor.editingShapeId).toBe(ids.box1)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.box1)
|
||||
editor.expectToBeIn('select.editing_shape')
|
||||
})
|
||||
|
||||
it('does not start editing on double click if shift is down', () => {
|
||||
editor.pointerMove(50, 50).keyDown('Shift').doubleClick()
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box1])
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
editor.expectToBeIn('select.idle')
|
||||
})
|
||||
|
||||
|
@ -1445,12 +1445,12 @@ describe('When double clicking an editable shape', () => {
|
|||
|
||||
editor.doubleClick()
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box2])
|
||||
expect(editor.editingShapeId).toBe(ids.box2)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.box2)
|
||||
editor.expectToBeIn('select.editing_shape')
|
||||
|
||||
editor.doubleClick()
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box2])
|
||||
expect(editor.editingShapeId).toBe(ids.box2)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.box2)
|
||||
editor.expectToBeIn('select.editing_shape')
|
||||
})
|
||||
|
||||
|
@ -1460,13 +1460,13 @@ describe('When double clicking an editable shape', () => {
|
|||
editor.selectNone()
|
||||
editor.pointerMove(50, 50).click() // clicks on the shape label
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.group1])
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
editor.pointerMove(50, 50).click() // clicks on the shape label
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box1])
|
||||
expect(editor.editingShapeId).toBe(null)
|
||||
expect(editor.getEditingShapeId()).toBe(null)
|
||||
editor.pointerMove(50, 50).click() // clicks on the shape label
|
||||
expect(editor.getSelectedShapeIds()).toEqual([ids.box1])
|
||||
expect(editor.editingShapeId).toBe(ids.box1)
|
||||
expect(editor.getEditingShapeId()).toBe(ids.box1)
|
||||
editor.expectToBeIn('select.editing_shape')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1819,6 +1819,6 @@ it('clones a single shape simply', () => {
|
|||
expect(editor.currentPageShapes).toHaveLength(2)
|
||||
const [, sticky2] = editor.currentPageShapes
|
||||
expect(editor.getOnlySelectedShape()).toBe(sticky2)
|
||||
expect(editor.editingShape).toBe(undefined)
|
||||
expect(editor.getEditingShape()).toBe(undefined)
|
||||
expect(editor.hoveredShape).toBe(sticky2)
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue