no impure getters pt 11 (#2236)

follow up to #2189 

adds runtime warnings for deprecated fields. cleans up remaining fields
and usages. Adds a lint rule to prevent access to deprecated fields.
Adds a lint rule to prevent using getters.

### Change Type

- [x] `patch` — Bug fix
This commit is contained in:
David Sheldrick 2023-11-16 15:34:56 +00:00 committed by GitHub
parent 431ce73476
commit 34cfb85169
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 651 additions and 272 deletions

View file

@ -6,13 +6,22 @@ module.exports = {
'plugin:@next/next/core-web-vitals',
],
ignorePatterns: [],
plugins: ['@typescript-eslint', 'no-only-tests', 'import', 'local', '@next/next', 'react-hooks'],
plugins: [
'@typescript-eslint',
'no-only-tests',
'import',
'local',
'@next/next',
'react-hooks',
'deprecation',
],
settings: {
next: {
rootDir: ['apps/*/', 'packages/*/'],
},
},
rules: {
'deprecation/deprecation': 'error',
'@next/next/no-html-link-for-pages': 'off',
'react/jsx-key': 'off',
'no-non-null-assertion': 'off',

View file

@ -198,7 +198,7 @@ test.describe('Export snapshots', () => {
editor
.updateInstanceState({ exportBackground: false })
.selectAll()
.deleteShapes(editor.selectedShapeIds)
.deleteShapes(editor.getSelectedShapeIds())
.createShapes(shapes)
}, shapes as any)

View file

@ -43,7 +43,7 @@ export default function ExternalContentSourcesExample() {
const htmlSource = sources?.find((s) => s.type === 'text' && s.subtype === 'html')
if (htmlSource) {
const center = point ?? editor.viewportPageCenter
const center = point ?? editor.getViewportPageCenter()
editor.createShape({
type: 'html',

View file

@ -61,10 +61,10 @@ export class ScreenshotDragging extends StateNode {
// [3]
override onPointerUp = () => {
const { editor } = this
const box = this.screenshotBox.value
const box = this.screenshotBox.get()
// get all shapes contained by or intersecting the box
const shapes = editor.currentPageShapes.filter((s) => {
const shapes = editor.getCurrentPageShapes().filter((s) => {
const pageBounds = editor.getShapeMaskedPageBounds(s)
if (!pageBounds) return false
return box.includes(pageBounds)
@ -77,7 +77,7 @@ export class ScreenshotDragging extends StateNode {
editor,
shapes.map((s) => s.id),
'png',
{ bounds: box, background: editor.instanceState.exportBackground }
{ bounds: box, background: editor.getInstanceState().exportBackground }
)
} else {
// Export the shapes as a png
@ -85,7 +85,7 @@ export class ScreenshotDragging extends StateNode {
editor,
shapes.map((s) => s.id),
'png',
{ bounds: box, background: editor.instanceState.exportBackground }
{ bounds: box, background: editor.getInstanceState().exportBackground }
)
}
}

View file

@ -67,7 +67,7 @@ function ScreenshotBox() {
// want to show it in front of the canvas, so we'll need to convert it to
// "page space", i.e. uneffected by scale, and relative to the tldraw
// page's top left corner.
const { zoomLevel } = editor
const zoomLevel = editor.getZoomLevel()
const { x, y } = editor.pageToScreen({ x: box.x, y: box.y })
return new Box2d(x, y, box.w * zoomLevel, box.h * zoomLevel)
},

View file

@ -26,7 +26,7 @@ export default function UserPresenceExample() {
const peerPresence = InstancePresenceRecordType.create({
id: InstancePresenceRecordType.createId(editor.store.id),
currentPageId: editor.currentPageId,
currentPageId: editor.getCurrentPageId(),
userId: 'peer-1',
userName: USER_NAME,
cursor: { x: 0, y: 0, type: 'default', rotation: 0 },

View file

@ -1,7 +1,5 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"packages": [
"packages/*"
],
"packages": ["packages/*"],
"version": "2.0.0-alpha.18"
}

View file

@ -74,6 +74,7 @@
"auto": "^10.46.0",
"eslint": "^8.37.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-deprecation": "^2.0.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-local": "^1.0.0",
"eslint-plugin-no-only-tests": "^3.1.0",

View file

@ -614,12 +614,15 @@ export class Editor extends EventEmitter<TLEventMap> {
createShapes<T extends TLUnknownShape>(shapes: OptionalKeys<TLShapePartial<T>, 'id'>[]): this;
// @deprecated (undocumented)
get croppingShapeId(): null | TLShapeId;
// @deprecated (undocumented)
get currentPage(): TLPage;
// @deprecated (undocumented)
get currentPageBounds(): Box2d | undefined;
// @deprecated (undocumented)
get currentPageId(): TLPageId;
// @deprecated (undocumented)
get currentPageRenderingShapesSorted(): TLShape[];
// @deprecated (undocumented)
get currentPageShapeIds(): Set<TLShapeId>;
// @deprecated (undocumented)
get currentPageShapes(): TLShape[];
@ -699,8 +702,11 @@ export class Editor extends EventEmitter<TLEventMap> {
// @internal
getCrashingError(): unknown;
getCroppingShapeId(): null | TLShapeId;
getCurrentPage(): TLPage;
getCurrentPageBounds(): Box2d | undefined;
getCurrentPageId(): TLPageId;
getCurrentPageRenderingShapesSorted(): TLShape[];
getCurrentPageShapeIds(): Set<TLShapeId>;
getCurrentPageShapes(): TLShape[];
getCurrentPageShapesSorted(): TLShape[];
getCurrentPageState(): TLInstancePageState;

View file

@ -8004,7 +8004,7 @@
{
"kind": "Property",
"canonicalReference": "@tldraw/editor!Editor#currentPage:member",
"docComment": "/**\n * The current page.\n *\n * @public\n */\n",
"docComment": "/**\n * @deprecated\n *\n * use `getCurrentPage` instead.\n */\n",
"excerptTokens": [
{
"kind": "Content",
@ -8070,7 +8070,7 @@
{
"kind": "Property",
"canonicalReference": "@tldraw/editor!Editor#currentPageId:member",
"docComment": "/**\n * The current page id.\n *\n * @public\n */\n",
"docComment": "/**\n * @deprecated\n *\n * Use `getCurrentPageId` instead.\n */\n",
"excerptTokens": [
{
"kind": "Content",
@ -8136,7 +8136,7 @@
{
"kind": "Property",
"canonicalReference": "@tldraw/editor!Editor#currentPageShapeIds:member",
"docComment": "/**\n * An array of all of the shapes on the current page.\n *\n * @public\n */\n",
"docComment": "/**\n * @deprecated\n *\n * Use `getCurrentPageShapeIds` instead.\n */\n",
"excerptTokens": [
{
"kind": "Content",
@ -8281,7 +8281,7 @@
{
"kind": "Property",
"canonicalReference": "@tldraw/editor!Editor#currentTool:member",
"docComment": "/**\n * @deprecated\n *\n * Use `getCurrentTool` instead.\n *\n * @public\n */\n",
"docComment": "/**\n * @deprecated\n *\n * Use `getCurrentTool` instead.\n */\n",
"excerptTokens": [
{
"kind": "Content",
@ -10289,6 +10289,38 @@
"isAbstract": false,
"name": "getCroppingShapeId"
},
{
"kind": "Method",
"canonicalReference": "@tldraw/editor!Editor#getCurrentPage:member(1)",
"docComment": "/**\n * The current page.\n *\n * @public\n */\n",
"excerptTokens": [
{
"kind": "Content",
"text": "getCurrentPage(): "
},
{
"kind": "Reference",
"text": "TLPage",
"canonicalReference": "@tldraw/tlschema!TLPage:interface"
},
{
"kind": "Content",
"text": ";"
}
],
"isStatic": false,
"returnTypeTokenRange": {
"startIndex": 1,
"endIndex": 2
},
"releaseTag": "Public",
"isProtected": false,
"overloadIndex": 1,
"parameters": [],
"isOptional": false,
"isAbstract": false,
"name": "getCurrentPage"
},
{
"kind": "Method",
"canonicalReference": "@tldraw/editor!Editor#getCurrentPageBounds:member(1)",
@ -10325,6 +10357,38 @@
"isAbstract": false,
"name": "getCurrentPageBounds"
},
{
"kind": "Method",
"canonicalReference": "@tldraw/editor!Editor#getCurrentPageId:member(1)",
"docComment": "/**\n * The current page id.\n *\n * @public\n */\n",
"excerptTokens": [
{
"kind": "Content",
"text": "getCurrentPageId(): "
},
{
"kind": "Reference",
"text": "TLPageId",
"canonicalReference": "@tldraw/tlschema!TLPageId:type"
},
{
"kind": "Content",
"text": ";"
}
],
"isStatic": false,
"returnTypeTokenRange": {
"startIndex": 1,
"endIndex": 2
},
"releaseTag": "Public",
"isProtected": false,
"overloadIndex": 1,
"parameters": [],
"isOptional": false,
"isAbstract": false,
"name": "getCurrentPageId"
},
{
"kind": "Method",
"canonicalReference": "@tldraw/editor!Editor#getCurrentPageRenderingShapesSorted:member(1)",
@ -10361,6 +10425,51 @@
"isAbstract": false,
"name": "getCurrentPageRenderingShapesSorted"
},
{
"kind": "Method",
"canonicalReference": "@tldraw/editor!Editor#getCurrentPageShapeIds:member(1)",
"docComment": "/**\n * An array of all of the shapes on the current page.\n *\n * @public\n */\n",
"excerptTokens": [
{
"kind": "Content",
"text": "getCurrentPageShapeIds(): "
},
{
"kind": "Reference",
"text": "Set",
"canonicalReference": "!Set:interface"
},
{
"kind": "Content",
"text": "<"
},
{
"kind": "Reference",
"text": "TLShapeId",
"canonicalReference": "@tldraw/tlschema!TLShapeId:type"
},
{
"kind": "Content",
"text": ">"
},
{
"kind": "Content",
"text": ";"
}
],
"isStatic": false,
"returnTypeTokenRange": {
"startIndex": 1,
"endIndex": 5
},
"releaseTag": "Public",
"isProtected": false,
"overloadIndex": 1,
"parameters": [],
"isOptional": false,
"isAbstract": false,
"name": "getCurrentPageShapeIds"
},
{
"kind": "Method",
"canonicalReference": "@tldraw/editor!Editor#getCurrentPageShapes:member(1)",

View file

@ -465,7 +465,7 @@ const DebugSvgCopy = track(function DupSvg({ id }: { id: TLShapeId }) {
const [html, setHtml] = React.useState('')
const isInRoot = shape?.parentId === editor.currentPageId
const isInRoot = shape?.parentId === editor.getCurrentPageId()
React.useEffect(() => {
if (!isInRoot) return

View file

@ -31,7 +31,7 @@ const CollaboratorGuard = track(function CollaboratorGuard({
const presence = usePresence(collaboratorId)
const collaboratorState = useCollaboratorState(presence)
if (!(presence && presence.currentPageId === editor.currentPageId)) {
if (!(presence && presence.currentPageId === editor.getCurrentPageId())) {
// No need to render if we don't have a presence or if they're on a different page
return null
}

View file

@ -86,6 +86,7 @@ export const DefaultErrorFallback: TLErrorFallbackComponent = ({ error, editor }
textarea.value = errorStack ?? errorMessage
document.body.appendChild(textarea)
textarea.select()
// eslint-disable-next-line deprecation/deprecation
document.execCommand('copy')
textarea.remove()
setDidCopy(true)

View file

@ -38,6 +38,7 @@ function iOS() {
if (!window) return false
return (
['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod'].includes(
// eslint-disable-next-line deprecation/deprecation
window.navigator.platform
) ||
// iPad on iOS 13 detection

View file

@ -49,6 +49,7 @@ import {
hasOwnProperty,
sortById,
structuredClone,
warnDeprecatedGetter,
} from '@tldraw/utils'
import { EventEmitter } from 'eventemitter3'
import { TLUser, createTLUser } from '../config/createTLUser'
@ -600,7 +601,9 @@ export class Editor extends EventEmitter<TLEventMap> {
}
})
this._currentPageShapeIds = deriveShapeIdsInCurrentPage(this.store, () => this.currentPageId)
this._currentPageShapeIds = deriveShapeIdsInCurrentPage(this.store, () =>
this.getCurrentPageId()
)
this._parentIdsToChildIds = parentsToChildren(this.store)
this.disposables.add(
@ -807,6 +810,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get canUndo(): boolean {
warnDeprecatedGetter('canUndo')
return this.getCanUndo()
}
@ -839,6 +843,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get canRedo(): boolean {
warnDeprecatedGetter('canRedo')
return this.getCanRedo()
}
@ -1141,10 +1146,10 @@ export class Editor extends EventEmitter<TLEventMap> {
/**
* @deprecated Use `getCurrentTool` instead.
* @public
*/
// eslint-disable-next-line no-restricted-syntax
get currentTool() {
warnDeprecatedGetter('currentTool')
return this.getCurrentTool()
}
@ -1164,6 +1169,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get currentToolId() {
warnDeprecatedGetter('currentToolId')
return this.getCurrentToolId()
}
@ -1209,6 +1215,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get documentSettings() {
warnDeprecatedGetter('documentSettings')
return this.getDocumentSettings()
}
@ -1238,6 +1245,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get instanceState() {
warnDeprecatedGetter('instanceState')
return this.getInstanceState()
}
@ -1323,6 +1331,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get openMenus() {
warnDeprecatedGetter('openMenus')
return this.getOpenMenus()
}
@ -1383,6 +1392,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get isMenuOpen() {
warnDeprecatedGetter('isMenuOpen')
return this.getIsMenuOpen()
}
@ -1420,6 +1430,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get pageStates() {
warnDeprecatedGetter('pageStates')
return this.getPageStates()
}
@ -1442,12 +1453,13 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get currentPageState() {
warnDeprecatedGetter('currentPageState')
return this.getCurrentPageState()
}
/** @internal */
@computed private _getCurrentPageStateId() {
return InstancePageStateRecordType.createId(this.currentPageId)
return InstancePageStateRecordType.createId(this.getCurrentPageId())
}
/**
@ -1508,6 +1520,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get selectedShapeIds() {
warnDeprecatedGetter('selectedShapeIds')
return this.getSelectedShapeIds()
}
@ -1527,6 +1540,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get selectedShapes() {
warnDeprecatedGetter('selectedShapes')
return this.getSelectedShapes()
}
@ -1659,7 +1673,7 @@ export class Editor extends EventEmitter<TLEventMap> {
* @public
*/
selectAll(): this {
const ids = this.getSortedChildIdsForParent(this.currentPageId)
const ids = this.getSortedChildIdsForParent(this.getCurrentPageId())
// page might have no shapes
if (ids.length <= 0) return this
this.setSelectedShapes(this._getUnlockedShapeIds(ids))
@ -1704,6 +1718,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get onlySelectedShape() {
warnDeprecatedGetter('onlySelectedShape')
return this.getOnlySelectedShape()
}
@ -1728,6 +1743,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get selectionPageBounds() {
warnDeprecatedGetter('selectionPageBounds')
return this.getSelectionPageBounds()
}
@ -1759,6 +1775,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get selectionRotation() {
warnDeprecatedGetter('selectionRotation')
return this.getSelectionRotation()
}
@ -1807,6 +1824,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get selectionRotatedPageBounds() {
warnDeprecatedGetter('selectionRotatedPageBounds')
return this.getSelectionRotatedPageBounds()
}
@ -1818,7 +1836,7 @@ export class Editor extends EventEmitter<TLEventMap> {
* @public
*/
@computed getFocusedGroupId(): TLShapeId | TLPageId {
return this.getCurrentPageState().focusedGroupId ?? this.currentPageId
return this.getCurrentPageState().focusedGroupId ?? this.getCurrentPageId()
}
/**
@ -1826,6 +1844,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get focusedGroupId() {
warnDeprecatedGetter('focusedGroupId')
return this.getFocusedGroupId()
}
@ -1844,6 +1863,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get focusedGroup() {
warnDeprecatedGetter('focusedGroup')
return this.getFocusedGroup()
}
@ -1942,6 +1962,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get editingShapeId() {
warnDeprecatedGetter('editingShapeId')
return this.getEditingShapeId()
}
@ -1960,6 +1981,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get editingShape() {
warnDeprecatedGetter('editingShape')
return this.getEditingShape()
}
@ -2010,6 +2032,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get hoveredShapeId() {
warnDeprecatedGetter('hoveredShapeId')
return this.getHoveredShapeId()
}
@ -2028,6 +2051,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get hoveredShape() {
warnDeprecatedGetter('hoveredShape')
return this.getHoveredShape()
}
@ -2067,6 +2091,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get hintingShapeIds() {
warnDeprecatedGetter('hintingShapeIds')
return this.getHintingShapeIds()
}
@ -2085,6 +2110,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get hintingShape() {
warnDeprecatedGetter('hintingShape')
return this.getHintingShape()
}
@ -2127,6 +2153,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get erasingShapeIds() {
warnDeprecatedGetter('erasingShapeIds')
return this.getErasingShapeIds()
}
@ -2145,6 +2172,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get erasingShapes() {
warnDeprecatedGetter('erasingShapes')
return this.getErasingShapes()
}
@ -2202,6 +2230,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get croppingShapeId() {
warnDeprecatedGetter('croppingShapeId')
return this.getCroppingShapeId()
}
@ -2240,7 +2269,7 @@ export class Editor extends EventEmitter<TLEventMap> {
/** @internal */
@computed
private getCameraId() {
return CameraRecordType.createId(this.currentPageId)
return CameraRecordType.createId(this.getCurrentPageId())
}
/**
@ -2266,6 +2295,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get zoomLevel() {
warnDeprecatedGetter('zoomLevel')
return this.getZoomLevel()
}
@ -2406,7 +2436,7 @@ export class Editor extends EventEmitter<TLEventMap> {
zoomToFit(animation?: TLAnimationOptions): this {
if (!this.getInstanceState().canMoveCamera) return this
const ids = [...this.currentPageShapeIds]
const ids = [...this.getCurrentPageShapeIds()]
if (ids.length <= 0) return this
const pageBounds = Box2d.Common(compact(ids.map((id) => this.getShapePageBounds(id))))
@ -2831,7 +2861,7 @@ export class Editor extends EventEmitter<TLEventMap> {
}
// If we're not on the same page, move to the page they're on
const isOnSamePage = presence.currentPageId === this.currentPageId
const isOnSamePage = presence.currentPageId === this.getCurrentPageId()
if (!isOnSamePage) {
this.setCurrentPage(presence.currentPageId)
}
@ -2978,6 +3008,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get viewportScreenBounds() {
warnDeprecatedGetter('viewportScreenBounds')
return this.getViewportScreenBounds()
}
@ -2995,6 +3026,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get viewportScreenCenter() {
warnDeprecatedGetter('viewportScreenCenter')
return this.getViewportScreenCenter()
}
@ -3014,6 +3046,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get viewportPageBounds() {
warnDeprecatedGetter('viewportPageBounds')
return this.getViewportPageBounds()
}
@ -3031,6 +3064,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get viewportPageCenter() {
warnDeprecatedGetter('viewportPageCenter')
return this.getViewportPageCenter()
}
@ -3130,7 +3164,7 @@ export class Editor extends EventEmitter<TLEventMap> {
}
// Change page if leader is on a different page
const isOnSamePage = leaderPresence.currentPageId === this.currentPageId
const isOnSamePage = leaderPresence.currentPageId === this.getCurrentPageId()
const chaseProportion = isOnSamePage ? FOLLOW_CHASE_PROPORTION : 1
if (!isOnSamePage) {
this.stopFollowingUser()
@ -3235,6 +3269,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get cameraState() {
warnDeprecatedGetter('cameraState')
return this.getCameraState()
}
@ -3378,7 +3413,7 @@ export class Editor extends EventEmitter<TLEventMap> {
}
}
for (const childId of this.getSortedChildIdsForParent(this.currentPageId)) {
for (const childId of this.getSortedChildIdsForParent(this.getCurrentPageId())) {
addShapeById(childId, 1, false)
}
@ -3411,6 +3446,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get renderingShapes() {
warnDeprecatedGetter('renderingShapes')
return this.getRenderingShapes()
}
@ -3426,9 +3462,9 @@ export class Editor extends EventEmitter<TLEventMap> {
/**
* @deprecated Use `getRenderingBounds` instead.
*/
// eslint-disable-next-line no-restricted-syntax
get renderingBounds() {
warnDeprecatedGetter('renderingBounds')
return this.getRenderingBounds()
}
@ -3450,6 +3486,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get renderingBoundsExpanded() {
warnDeprecatedGetter('renderingBoundsExpanded')
return this.getRenderingBoundsExpanded()
}
@ -3511,6 +3548,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get pages() {
warnDeprecatedGetter('pages')
return this.getPages()
}
@ -3519,10 +3557,17 @@ export class Editor extends EventEmitter<TLEventMap> {
*
* @public
*/
getCurrentPage(): TLPage {
return this.getPage(this.getCurrentPageId())!
}
/**
* @deprecated use `getCurrentPage` instead.
*/
// eslint-disable-next-line no-restricted-syntax
get currentPage(): TLPage {
const page = this.getPage(this.currentPageId)!
return page
get currentPage() {
warnDeprecatedGetter('currentPage')
return this.getCurrentPage()
}
/**
@ -3530,11 +3575,19 @@ export class Editor extends EventEmitter<TLEventMap> {
*
* @public
*/
// eslint-disable-next-line no-restricted-syntax
get currentPageId(): TLPageId {
getCurrentPageId(): TLPageId {
return this.getInstanceState().currentPageId
}
/**
* @deprecated Use `getCurrentPageId` instead.
*/
// eslint-disable-next-line no-restricted-syntax
get currentPageId() {
warnDeprecatedGetter('currentPageId')
return this.getCurrentPageId()
}
/**
* Get a page.
*
@ -3560,9 +3613,16 @@ export class Editor extends EventEmitter<TLEventMap> {
*
* @public
*/
getCurrentPageShapeIds() {
return this._currentPageShapeIds.get()
}
/**
* @deprecated Use `getCurrentPageShapeIds` instead.
*/
// eslint-disable-next-line no-restricted-syntax
get currentPageShapeIds() {
return this._currentPageShapeIds.get()
warnDeprecatedGetter('currentPageShapeIds')
return this.getCurrentPageShapeIds()
}
/**
@ -3615,7 +3675,7 @@ export class Editor extends EventEmitter<TLEventMap> {
this.stopFollowingUser()
return {
data: { toId: pageId, fromId: this.currentPageId },
data: { toId: pageId, fromId: this.getCurrentPageId() },
squashing: true,
preservesRedoStack: true,
...historyOptions,
@ -3806,7 +3866,7 @@ export class Editor extends EventEmitter<TLEventMap> {
if (!deletedPage) return null
if (id === this.currentPageId) {
if (id === this.getCurrentPageId()) {
const index = pages.findIndex((page) => page.id === id)
const next = pages[index - 1] ?? pages[index + 1]
this.setCurrentPage(next.id)
@ -3819,7 +3879,7 @@ export class Editor extends EventEmitter<TLEventMap> {
const pages = this.getPages()
if (pages.length === 1) return
if (deletedPage.id === this.currentPageId) {
if (deletedPage.id === this.getCurrentPageId()) {
const index = pages.findIndex((page) => page.id === deletedPage.id)
const next = pages[index - 1] ?? pages[index + 1]
this.setCurrentPage(next.id)
@ -3915,6 +3975,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get assets() {
warnDeprecatedGetter('assets')
return this.getAssets()
}
@ -4518,7 +4579,7 @@ export class Editor extends EventEmitter<TLEventMap> {
@computed getCurrentPageBounds(): Box2d | undefined {
let commonBounds: Box2d | undefined
this.currentPageShapeIds.forEach((shapeId) => {
this.getCurrentPageShapeIds().forEach((shapeId) => {
const bounds = this.getShapeMaskedPageBounds(shapeId)
if (!bounds) return
if (!commonBounds) {
@ -4536,6 +4597,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get currentPageBounds() {
warnDeprecatedGetter('currentPageBounds')
return this.getCurrentPageBounds()
}
@ -4845,7 +4907,7 @@ export class Editor extends EventEmitter<TLEventMap> {
* @public
*/
@computed getCurrentPageShapes(): TLShape[] {
return Array.from(this.currentPageShapeIds, (id) => this.store.get(id)! as TLShape)
return Array.from(this.getCurrentPageShapeIds(), (id) => this.store.get(id)! as TLShape)
}
/**
@ -4853,6 +4915,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get currentPageShapes() {
warnDeprecatedGetter('currentPageShapes')
return this.getCurrentPageShapes()
}
@ -4895,6 +4958,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get currentPageShapesSorted() {
warnDeprecatedGetter('currentPageShapesSorted')
return this.getCurrentPageShapesSorted()
}
@ -4916,6 +4980,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get currentPageRenderingShapesSorted() {
warnDeprecatedGetter('currentPageRenderingShapesSorted')
return this.getCurrentPageRenderingShapesSorted()
}
@ -5022,7 +5087,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*
* @public
*/
isShapeInPage(shape: TLShape | TLShapeId, pageId = this.currentPageId): boolean {
isShapeInPage(shape: TLShape | TLShapeId, pageId = this.getCurrentPageId()): boolean {
const id = typeof shape === 'string' ? shape : shape.id
const shapeToCheck = this.getShape(id)
if (!shapeToCheck) return false
@ -5510,7 +5575,7 @@ export class Editor extends EventEmitter<TLEventMap> {
oy = vec.y
}
const parentId = shape.parentId ?? this.currentPageId
const parentId = shape.parentId ?? this.getCurrentPageId()
const siblings = this.getSortedChildIdsForParent(parentId)
const currentIndex = siblings.indexOf(shape.id)
const siblingAboveId = siblings[currentIndex + 1]
@ -5613,14 +5678,14 @@ export class Editor extends EventEmitter<TLEventMap> {
this.history.batch(() => {
const maxShapesReached =
shapesToCreate.length + this.currentPageShapeIds.size > MAX_SHAPES_PER_PAGE
shapesToCreate.length + this.getCurrentPageShapeIds().size > MAX_SHAPES_PER_PAGE
if (maxShapesReached) {
alertMaxShapes(this)
}
const newShapes = maxShapesReached
? shapesToCreate.slice(0, MAX_SHAPES_PER_PAGE - this.currentPageShapeIds.size)
? shapesToCreate.slice(0, MAX_SHAPES_PER_PAGE - this.getCurrentPageShapeIds().size)
: shapesToCreate
const ids = newShapes.map((s) => s.id)
@ -5667,7 +5732,7 @@ export class Editor extends EventEmitter<TLEventMap> {
if (ids.length === 0) return this
if (this.getInstanceState().isReadonly) return this
const { currentPageId } = this
const currentPageId = this.getCurrentPageId()
if (pageId === currentPageId) return this
if (!this.store.has(pageId)) return this
@ -6813,7 +6878,7 @@ export class Editor extends EventEmitter<TLEventMap> {
if (this.getInstanceState().isReadonly) return null
if (partials.length <= 0) return null
const { currentPageShapeIds } = this
const currentPageShapeIds = this.getCurrentPageShapeIds()
const maxShapesReached = partials.length + currentPageShapeIds.size > MAX_SHAPES_PER_PAGE
@ -6827,7 +6892,7 @@ export class Editor extends EventEmitter<TLEventMap> {
return {
data: {
currentPageId: this.currentPageId,
currentPageId: this.getCurrentPageId(),
partials: partials.map((p) =>
p.id ? p : { ...p, id: createShapeId() }
) as TLShapePartial[],
@ -7151,7 +7216,7 @@ export class Editor extends EventEmitter<TLEventMap> {
const { x, y } = pageBounds.point
const parentId = this.findCommonAncestor(shapesToGroup) ?? this.currentPageId
const parentId = this.findCommonAncestor(shapesToGroup) ?? this.getCurrentPageId()
// Only group when the select tool is active
if (this.getCurrentToolId() !== 'select') return this
@ -7613,6 +7678,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get sharedStyles() {
warnDeprecatedGetter('sharedStyles')
return this.getSharedStyles()
}
@ -7663,6 +7729,7 @@ export class Editor extends EventEmitter<TLEventMap> {
*/
// eslint-disable-next-line no-restricted-syntax
get sharedOpacity() {
warnDeprecatedGetter('sharedOpacity')
return this.getSharedOpacity()
}
@ -8060,7 +8127,7 @@ export class Editor extends EventEmitter<TLEventMap> {
shape.x = pagePoint.x
shape.y = pagePoint.y
shape.rotation = pageRotation
shape.parentId = this.currentPageId
shape.parentId = this.getCurrentPageId()
rootShapeIds.push(shape.id)
}
@ -8114,13 +8181,13 @@ export class Editor extends EventEmitter<TLEventMap> {
// decide on a parent for the put shapes; if the parent is among the put shapes(?) then use its parent
const { currentPageId } = this
const currentPageId = this.getCurrentPageId()
const { assets, shapes, rootShapeIds } = content
const idMap = new Map<any, TLShapeId>(shapes.map((shape) => [shape.id, createShapeId()]))
// By default, the paste parent will be the current page.
let pasteParentId = this.currentPageId as TLPageId | TLShapeId
let pasteParentId = this.getCurrentPageId() as TLPageId | TLShapeId
let lowestDepth = Infinity
let lowestAncestors: TLShape[] = []
@ -8246,7 +8313,7 @@ export class Editor extends EventEmitter<TLEventMap> {
return newShape
})
if (newShapes.length + this.currentPageShapeIds.size > MAX_SHAPES_PER_PAGE) {
if (newShapes.length + this.getCurrentPageShapeIds().size > MAX_SHAPES_PER_PAGE) {
// There's some complexity here involving children
// that might be created without their parents, so
// if we're going over the limit then just don't paste.
@ -9311,7 +9378,7 @@ export class Editor extends EventEmitter<TLEventMap> {
}
}
function alertMaxShapes(editor: Editor, pageId = editor.currentPageId) {
function alertMaxShapes(editor: Editor, pageId = editor.getCurrentPageId()) {
const name = editor.getPage(pageId)!.name
editor.emit('max-shapes', { name, pageId, count: MAX_SHAPES_PER_PAGE })
}

View file

@ -1,5 +1,6 @@
import { atom, transact } from '@tldraw/state'
import { devFreeze } from '@tldraw/store'
import { warnDeprecatedGetter } from '@tldraw/utils'
import { uniqueId } from '../../utils/uniqueId'
import { TLCommandHandler, TLCommandHistoryOptions, TLHistoryEntry } from '../types/history-types'
import { Stack, stack } from './Stack'
@ -41,6 +42,7 @@ export class HistoryManager<
*/
// eslint-disable-next-line no-restricted-syntax
get numUndos() {
warnDeprecatedGetter('numUndos')
return this.getNumUndos()
}
@ -52,6 +54,7 @@ export class HistoryManager<
*/
// eslint-disable-next-line no-restricted-syntax
get numRedos() {
warnDeprecatedGetter('numRedos')
return this.getNumRedos()
}

View file

@ -1,6 +1,6 @@
import { atom, computed, EMPTY_ARRAY } from '@tldraw/state'
import { TLGroupShape, TLParentId, TLShape, TLShapeId, Vec2dModel } from '@tldraw/tlschema'
import { dedupe, deepCopy } from '@tldraw/utils'
import { dedupe, deepCopy, warnDeprecatedGetter } from '@tldraw/utils'
import {
Box2d,
flipSelectionHandleX,
@ -221,6 +221,7 @@ export class SnapManager {
*/
// eslint-disable-next-line no-restricted-syntax
get lines() {
warnDeprecatedGetter('lines')
return this.getLines()
}
@ -254,6 +255,7 @@ export class SnapManager {
*/
// eslint-disable-next-line no-restricted-syntax
get snapPointsCache() {
warnDeprecatedGetter('snapPointsCache')
return this.getSnapPointsCache()
}
@ -266,6 +268,7 @@ export class SnapManager {
*/
// eslint-disable-next-line no-restricted-syntax
get snapThreshold() {
warnDeprecatedGetter('snapThreshold')
return this.getSnapThreshold()
}
@ -303,7 +306,7 @@ export class SnapManager {
}
}
collectSnappableShapesFromParent(this.getCurrentCommonAncestor() ?? editor.currentPageId)
collectSnappableShapesFromParent(this.getCurrentCommonAncestor() ?? editor.getCurrentPageId())
return snappableShapes
}
@ -314,6 +317,7 @@ export class SnapManager {
// eslint-disable-next-line no-restricted-syntax
get snappableShapes() {
warnDeprecatedGetter('snappableShapes')
return this.getSnappableShapes()
}
@ -327,6 +331,7 @@ export class SnapManager {
*/
// eslint-disable-next-line no-restricted-syntax
get currentCommonAncestor() {
warnDeprecatedGetter('currentCommonAncestor')
return this.getCurrentCommonAncestor()
}
@ -351,6 +356,7 @@ export class SnapManager {
*/
// eslint-disable-next-line no-restricted-syntax
get snappablePoints() {
warnDeprecatedGetter('snappablePoints')
return this.getSnappablePoints()
}
@ -456,6 +462,7 @@ export class SnapManager {
*/
// eslint-disable-next-line no-restricted-syntax
get visibleGaps() {
warnDeprecatedGetter('visibleGaps')
return this.getVisibleGaps()
}
@ -567,6 +574,7 @@ export class SnapManager {
*/
// eslint-disable-next-line no-restricted-syntax
get outlinesInPageSpace() {
warnDeprecatedGetter('outlinesInPageSpace')
return this.getOutlinesInPageSpace()
}

View file

@ -1,4 +1,5 @@
import { computed } from '@tldraw/state'
import { warnDeprecatedGetter } from '@tldraw/utils'
import {
TLUserPreferences,
defaultUserPreferences,
@ -31,6 +32,7 @@ export class UserPreferencesManager {
*/
// eslint-disable-next-line no-restricted-syntax
get userPreferences() {
warnDeprecatedGetter('userPreferences')
return this.getUserPreferences()
}
@ -46,6 +48,7 @@ export class UserPreferencesManager {
*/
// eslint-disable-next-line no-restricted-syntax
get isDarkMode() {
warnDeprecatedGetter('isDarkMode')
return this.getIsDarkMode()
}
@ -58,6 +61,7 @@ export class UserPreferencesManager {
*/
// eslint-disable-next-line no-restricted-syntax
get animationSpeed() {
warnDeprecatedGetter('animationSpeed')
return this.getAnimationSpeed()
}
@ -70,6 +74,7 @@ export class UserPreferencesManager {
*/
// eslint-disable-next-line no-restricted-syntax
get id() {
warnDeprecatedGetter('id')
return this.getId()
}
@ -82,6 +87,7 @@ export class UserPreferencesManager {
*/
// eslint-disable-next-line no-restricted-syntax
get name() {
warnDeprecatedGetter('name')
return this.getName()
}
@ -94,6 +100,7 @@ export class UserPreferencesManager {
*/
// eslint-disable-next-line no-restricted-syntax
get locale() {
warnDeprecatedGetter('locale')
return this.getLocale()
}
@ -106,6 +113,7 @@ export class UserPreferencesManager {
*/
// eslint-disable-next-line no-restricted-syntax
get color() {
warnDeprecatedGetter('color')
return this.getColor()
}
@ -118,6 +126,7 @@ export class UserPreferencesManager {
*/
// eslint-disable-next-line no-restricted-syntax
get isSnapMode() {
warnDeprecatedGetter('isSnapMode')
return this.getIsSnapMode()
}
}

View file

@ -1,4 +1,5 @@
import { Atom, Computed, atom, computed } from '@tldraw/state'
import { warnDeprecatedGetter } from '@tldraw/utils'
import type { Editor } from '../Editor'
import {
EVENT_NAME_MAP,
@ -187,10 +188,12 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
*/
// eslint-disable-next-line no-restricted-syntax
get currentToolIdMask() {
warnDeprecatedGetter('currentToolIdMask')
return this._currentToolIdMask.get()
}
// eslint-disable-next-line no-restricted-syntax
set currentToolIdMask(id: string | undefined) {
warnDeprecatedGetter('currentToolIdMask')
this._currentToolIdMask.set(id)
}

View file

@ -30,13 +30,17 @@ export function useDocumentEvents() {
}
if (media.addEventListener) {
media.addEventListener('change', updatePixelRatio)
// eslint-disable-next-line deprecation/deprecation
} else if (media.addListener) {
// eslint-disable-next-line deprecation/deprecation
media.addListener(safariCb)
}
remove = () => {
if (media.removeEventListener) {
media.removeEventListener('change', updatePixelRatio)
// eslint-disable-next-line deprecation/deprecation
} else if (media.removeListener) {
// eslint-disable-next-line deprecation/deprecation
media.removeListener(safariCb)
}
}

View file

@ -13,7 +13,7 @@ export function useZoomCss() {
const setScaleDebounced = debounce(setScale, 100)
const scheduler = new EffectScheduler('useZoomCss', () => {
const numShapes = editor.currentPageShapeIds.size
const numShapes = editor.getCurrentPageShapeIds().size
if (numShapes < 300) {
setScale(editor.getZoomLevel())
} else {

View file

@ -1,6 +1,7 @@
// Reasonable defaults
const MAX_ZOOM_STEP = 10
const IS_DARWIN = /Mac|iPod|iPhone|iPad/.test(
// eslint-disable-next-line deprecation/deprecation
typeof window === 'undefined' ? 'node' : window.navigator.platform
)

View file

@ -1,13 +1,8 @@
let didWarnDotValue = false
const isDev = typeof process !== 'undefined' && process.env?.NODE_ENV === 'development'
const isProd = !isDev
// remove this once we've removed all getters from our app
const ROLLOUT_OVERRIDE_REMOVE_ME = true
export function logDotValueWarning() {
if (ROLLOUT_OVERRIDE_REMOVE_ME) return
if (isProd) return
if (didWarnDotValue) return
didWarnDotValue = true
console.warn(
@ -18,8 +13,6 @@ export function logDotValueWarning() {
let didWarnComputedGetter = false
export function logComputedGetterWarning() {
if (ROLLOUT_OVERRIDE_REMOVE_ME) return
if (isProd) return
if (didWarnComputedGetter) return
didWarnComputedGetter = true
console.warn(

View file

@ -513,7 +513,7 @@ describe("an arrow's parents", () => {
end: { type: 'binding', boundShapeId: frameId },
},
})
expect(editor.getShape(arrowId)?.parentId).toBe(editor.currentPageId)
expect(editor.getShape(arrowId)?.parentId).toBe(editor.getCurrentPageId())
// move arrow to b
editor.pointerMove(15, 85)
@ -527,7 +527,7 @@ describe("an arrow's parents", () => {
// move back to empty space
editor.pointerMove(50, 50)
expect(editor.getShape(arrowId)?.parentId).toBe(editor.currentPageId)
expect(editor.getShape(arrowId)?.parentId).toBe(editor.getCurrentPageId())
expect(editor.getShape(arrowId)).toMatchObject({
props: {
start: { type: 'binding', boundShapeId: boxAid },
@ -552,7 +552,7 @@ describe("an arrow's parents", () => {
// move b outside of frame
editor.select(boxBid).translateSelection(200, 0)
expect(editor.getShape(arrowId)).toMatchObject({
parentId: editor.currentPageId,
parentId: editor.getCurrentPageId(),
props: {
start: { type: 'binding', boundShapeId: boxAid },
end: { type: 'binding', boundShapeId: boxBid },
@ -566,7 +566,7 @@ describe("an arrow's parents", () => {
editor.pointerDown(15, 15).pointerMove(115, 15).pointerUp()
const arrowId = editor.getOnlySelectedShape()!.id
expect(editor.getShape(arrowId)).toMatchObject({
parentId: editor.currentPageId,
parentId: editor.getCurrentPageId(),
props: {
start: { type: 'binding', boundShapeId: boxAid },
end: { type: 'binding', boundShapeId: boxCid },

View file

@ -209,7 +209,7 @@ export class FrameShapeUtil extends BaseBoxShapeUtil<TLFrameShape> {
if (isInGroup) {
this.editor.reparentShapes(shapes, parent.id)
} else {
this.editor.reparentShapes(shapes, this.editor.currentPageId)
this.editor.reparentShapes(shapes, this.editor.getCurrentPageId())
}
}
@ -227,7 +227,7 @@ export class FrameShapeUtil extends BaseBoxShapeUtil<TLFrameShape> {
}
if (shapesToReparent.length > 0) {
this.editor.reparentShapes(shapesToReparent, this.editor.currentPageId)
this.editor.reparentShapes(shapesToReparent, this.editor.getCurrentPageId())
}
}
}

View file

@ -195,7 +195,7 @@ describe('Misc', () => {
editor.pointerMove(50, 50) // Move shape by 25, 25
editor.pointerUp().keyUp('Alt')
expect(Array.from(editor.currentPageShapeIds.values()).length).toEqual(2)
expect(Array.from(editor.getCurrentPageShapeIds().values()).length).toEqual(2)
})
it('deletes', () => {
@ -207,7 +207,7 @@ describe('Misc', () => {
editor.pointerMove(50, 50) // Move shape by 25, 25
editor.pointerUp().keyUp('Alt')
let ids = Array.from(editor.currentPageShapeIds.values())
let ids = Array.from(editor.getCurrentPageShapeIds().values())
expect(ids.length).toEqual(2)
const duplicate = ids.filter((i) => i !== id)[0]
@ -215,7 +215,7 @@ describe('Misc', () => {
editor.deleteShapes(editor.getSelectedShapeIds())
ids = Array.from(editor.currentPageShapeIds.values())
ids = Array.from(editor.getCurrentPageShapeIds().values())
expect(ids.length).toEqual(1)
expect(ids[0]).toEqual(id)
})

View file

@ -40,6 +40,7 @@ export class TextHelpers {
field.focus()
}
// eslint-disable-next-line deprecation/deprecation
if (!document.execCommand('insertText', false, text)) {
TextHelpers.insertTextFirefox(field, text)
}

View file

@ -96,8 +96,8 @@ export class Brushing extends StateNode {
private hitTestShapes() {
const zoomLevel = this.editor.getZoomLevel()
const currentPageShapes = this.editor.getCurrentPageShapes()
const currentPageId = this.editor.getCurrentPageId()
const {
currentPageId,
inputs: { originPagePoint, currentPagePoint, shiftKey, ctrlKey },
} = this.editor

View file

@ -388,7 +388,7 @@ export class Idle extends StateNode {
override onCancel: TLEventHandlers['onCancel'] = () => {
if (
this.editor.getFocusedGroupId() !== this.editor.currentPageId &&
this.editor.getFocusedGroupId() !== this.editor.getCurrentPageId() &&
this.editor.getSelectedShapeIds().length > 0
) {
this.editor.popFocusedGroupId()

View file

@ -208,8 +208,8 @@ export class DraggingHandle extends StateNode {
const { editor, shapeId, initialPagePoint } = this
const { initialHandle, initialPageRotation, initialAdjacentHandle } = this
const hintingShapeIds = this.editor.getHintingShapeIds()
const isSnapMode = this.editor.user.getIsSnapMode()
const {
user: { isSnapMode },
snaps,
inputs: { currentPagePoint, shiftKey, ctrlKey, altKey, pointerVelocity },
} = editor

View file

@ -8,7 +8,7 @@ export const MoveToPageMenu = track(function MoveToPageMenu() {
const editor = useEditor()
const container = useContainer()
const pages = editor.getPages()
const currentPageId = editor.currentPageId
const currentPageId = editor.getCurrentPageId()
const msg = useTranslation()
const { addToast } = useToasts()

View file

@ -57,7 +57,7 @@ export function Minimap({ shapeFill, selectFill, viewportFill }: MinimapProps) {
const onDoubleClick = React.useCallback(
(e: React.MouseEvent<HTMLCanvasElement>) => {
if (!editor.currentPageShapeIds.size) return
if (!editor.getCurrentPageShapeIds().size) return
const point = minimap.minimapScreenPointToPagePoint(e.clientX, e.clientY, false, false)
@ -75,7 +75,7 @@ export function Minimap({ shapeFill, selectFill, viewportFill }: MinimapProps) {
(e: React.PointerEvent<HTMLCanvasElement>) => {
const elm = e.currentTarget
setPointerCapture(elm, e)
if (!editor.currentPageShapeIds.size) return
if (!editor.getCurrentPageShapeIds().size) return
rPointing.current = true
@ -187,7 +187,7 @@ export function Minimap({ shapeFill, selectFill, viewportFill }: MinimapProps) {
useQuickReactor(
'minimap render when pagebounds or collaborators changes',
() => {
const { currentPageShapeIds: shapeIdsOnCurrentPage } = editor
const shapeIdsOnCurrentPage = editor.getCurrentPageShapeIds()
const commonBoundsOfAllShapesOnCurrentPage = editor.getCurrentPageBounds()
const viewportPageBounds = editor.getViewportPageBounds()

View file

@ -301,7 +301,7 @@ export class MinimapManager {
const px = 2.5 / sx
const py = 2.5 / sy
const { currentPageId } = editor
const currentPageId = editor.getCurrentPageId()
let collaborator: TLInstancePresence
for (let i = 0; i < this.collaborators.length; i++) {

View file

@ -12,7 +12,7 @@ export const ZoomMenu = track(function ZoomMenu() {
const breakpoint = useBreakpoint()
const zoom = editor.getZoomLevel()
const hasShapes = editor.currentPageShapeIds.size > 0
const hasShapes = editor.getCurrentPageShapeIds().size > 0
const hasSelected = editor.getSelectedShapeIds().length > 0
const isZoomedTo100 = editor.getZoomLevel() === 1

View file

@ -33,8 +33,8 @@ export const PageMenu = function PageMenu() {
const rSortableContainer = useRef<HTMLDivElement>(null)
const pages = useValue('pages', () => editor.getPages(), [editor])
const currentPage = useValue('currentPage', () => editor.currentPage, [editor])
const currentPageId = useValue('currentPageId', () => editor.currentPageId, [editor])
const currentPage = useValue('currentPage', () => editor.getCurrentPage(), [editor])
const currentPageId = useValue('currentPageId', () => editor.getCurrentPageId(), [editor])
// When in readonly mode, we don't allow a user to edit the pages
const isReadonlyMode = useReadonly()

View file

@ -35,6 +35,7 @@ export const Icon = memo(function Icon({
// HACK: Fix for <https://linear.app/tldraw/issue/TLD-1700/dragging-around-with-the-handtool-makes-lots-of-requests-for-icons>
// It seems that passing `WebkitMask` to react will cause a render on each call, no idea why... but this appears to be the fix.
// @ts-ignore
// eslint-disable-next-line deprecation/deprecation
ref.current.style.webkitMask = `url(${asset}) center 100% / 100% no-repeat`
}
}, [ref, asset, icon])

View file

@ -44,7 +44,7 @@ export async function pasteExcalidrawContent(editor: Editor, clipboard: any, poi
const groupShapeIdToChildren = new Map<string, TLShapeId[]>()
const rotatedElements = new Map<TLShapeId, number>()
const { currentPageId } = editor
const currentPageId = editor.getCurrentPageId()
const excElementIdsToTldrawShapeIds = new Map<string, TLShapeId>()
const rootShapeIds: TLShapeId[] = []

View file

@ -64,7 +64,7 @@ export const TLUiContextMenuSchemaProvider = track(function TLUiContextMenuSchem
const threeStackableItems = useThreeStackableItems()
const atLeastOneShapeOnPage = useValue(
'atLeastOneShapeOnPage',
() => editor.currentPageShapeIds.size > 0,
() => editor.getCurrentPageShapeIds().size > 0,
[]
)
const isTransparentBg = useValue(

View file

@ -14,7 +14,7 @@ export function useExportAs() {
(ids: TLShapeId[], format: TLExportType = 'png') => {
exportAs(editor, ids, format, {
scale: 1,
background: editor.instanceState.exportBackground,
background: editor.getInstanceState().exportBackground,
}).catch((e) => {
console.error(e.message)
addToast({

View file

@ -62,7 +62,9 @@ export function TLUiMenuSchemaProvider({ overrides, children }: TLUiMenuSchemaPr
[editor]
)
const emptyPage = useValue('emptyPage', () => editor.currentPageShapeIds.size === 0, [editor])
const emptyPage = useValue('emptyPage', () => editor.getCurrentPageShapeIds().size === 0, [
editor,
])
const selectedCount = useValue('selectedCount', () => editor.getSelectedShapeIds().length, [
editor,

View file

@ -165,6 +165,7 @@ export function usePrint() {
window.print()
} else if (editor.environment.isSafari) {
beforePrintHandler()
// eslint-disable-next-line deprecation/deprecation
document.execCommand('print', false)
} else {
window.print()
@ -172,7 +173,7 @@ export function usePrint() {
}
const selectedShapeIds = editor.getSelectedShapeIds()
const { currentPageId } = editor
const currentPageId = editor.getCurrentPageId()
const pages = editor.getPages()
const preserveAspectRatio = 'xMidYMid meet'
@ -205,7 +206,7 @@ export function usePrint() {
}
triggerPrint()
} else {
const page = editor.currentPage
const page = editor.getCurrentPage()
const svg = await editor.getSvg(editor.getSortedChildIdsForParent(page.id), svgOpts)
if (svg) {
addPageToPrint(`tldraw — ${page.name}`, null, svg)

View file

@ -26,9 +26,9 @@ export function copyAs(
const write = window.navigator.clipboard?.write
return editor
.getSvg(ids?.length ? ids : [...editor.currentPageShapeIds], {
.getSvg(ids?.length ? ids : [...editor.getCurrentPageShapeIds()], {
scale: 1,
background: editor.instanceState.exportBackground,
background: editor.getInstanceState().exportBackground,
...opts,
})
.then((svg) => {

View file

@ -122,6 +122,7 @@ export async function getSvgAsDataUrl(svg: SVGElement) {
const svgStr = new XMLSerializer().serializeToString(clone)
// NOTE: `unescape` works everywhere although deprecated
// eslint-disable-next-line deprecation/deprecation
const base64SVG = window.btoa(unescape(encodeURIComponent(svgStr)))
return `data:image/svg+xml;base64,${base64SVG}`
}

View file

@ -20,55 +20,57 @@ export function exportAs(
format: TLExportType = 'png',
opts = {} as Partial<TLSvgOptions>
) {
return editor.getSvg(ids?.length ? ids : [...editor.currentPageShapeIds], opts).then((svg) => {
if (!svg) {
throw new Error('Could not construct SVG.')
}
let name = 'shapes' + getTimestamp()
if (ids.length === 1) {
const first = editor.getShape(ids[0])!
if (editor.isShapeOfType<TLFrameShape>(first, 'frame')) {
name = first.props.name ?? 'frame'
} else {
name = first.id.replace(/:/, '_')
return editor
.getSvg(ids?.length ? ids : [...editor.getCurrentPageShapeIds()], opts)
.then((svg) => {
if (!svg) {
throw new Error('Could not construct SVG.')
}
}
switch (format) {
case 'svg': {
getSvgAsDataUrl(svg).then((dataURL) => downloadDataURLAsFile(dataURL, `${name}.svg`))
return
let name = 'shapes' + getTimestamp()
if (ids.length === 1) {
const first = editor.getShape(ids[0])!
if (editor.isShapeOfType<TLFrameShape>(first, 'frame')) {
name = first.props.name ?? 'frame'
} else {
name = first.id.replace(/:/, '_')
}
}
case 'webp':
case 'png': {
getSvgAsImage(svg, editor.environment.isSafari, {
type: format,
quality: 1,
scale: 2,
}).then((image) => {
if (!image) throw Error()
const dataURL = URL.createObjectURL(image)
downloadDataURLAsFile(dataURL, `${name}.${format}`)
switch (format) {
case 'svg': {
getSvgAsDataUrl(svg).then((dataURL) => downloadDataURLAsFile(dataURL, `${name}.svg`))
return
}
case 'webp':
case 'png': {
getSvgAsImage(svg, editor.environment.isSafari, {
type: format,
quality: 1,
scale: 2,
}).then((image) => {
if (!image) throw Error()
const dataURL = URL.createObjectURL(image)
downloadDataURLAsFile(dataURL, `${name}.${format}`)
URL.revokeObjectURL(dataURL)
})
return
}
case 'json': {
const data = editor.getContentFromCurrentPage(ids)
const blob = new Blob([JSON.stringify(data, null, 4)], { type: 'application/json' })
const dataURL = URL.createObjectURL(blob)
downloadDataURLAsFile(dataURL, `${name || 'shapes'}.json`)
URL.revokeObjectURL(dataURL)
})
return
}
return
}
case 'json': {
const data = editor.getContentFromCurrentPage(ids)
const blob = new Blob([JSON.stringify(data, null, 4)], { type: 'application/json' })
const dataURL = URL.createObjectURL(blob)
downloadDataURLAsFile(dataURL, `${name || 'shapes'}.json`)
URL.revokeObjectURL(dataURL)
return
default:
throw new Error(`Export type ${format} not supported.`)
}
default:
throw new Error(`Export type ${format} not supported.`)
}
})
})
}
function getTimestamp() {

View file

@ -109,7 +109,7 @@ export function buildFromV1Document(editor: Editor, document: LegacyTldrawDocume
.sort((a, b) => ((a.childIndex ?? 1) < (b.childIndex ?? 1) ? -1 : 1))
.forEach((v1Page, i) => {
if (i === 0) {
v1PageIdsToV2PageIds.set(v1Page.id, editor.currentPageId)
v1PageIdsToV2PageIds.set(v1Page.id, editor.getCurrentPageId())
} else {
const pageId = PageRecordType.createId()
v1PageIdsToV2PageIds.set(v1Page.id, pageId)

View file

@ -35,7 +35,7 @@ beforeEach(() => {
{ id: ids.box3, type: 'geo', x: 500, y: 500, props: { w: 100, h: 100 }, parentId: ids.group1 },
])
const page1 = editor.currentPageId
const page1 = editor.getCurrentPageId()
editor.createPage({ name: 'page 2', id: ids.page2 })
editor.setCurrentPage(page1)
})
@ -55,7 +55,7 @@ describe('shapes that are moved to another page', () => {
editor.setFocusedGroup(ids.group1)
expect(editor.getFocusedGroupId()).toBe(ids.group1)
moveShapesToPage2()
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
})
describe("should be excluded from the previous page's hintingShapeIds", () => {
@ -492,7 +492,7 @@ describe('getShapeUtil', () => {
editor.createShapes([
{ id: ids.box1, type: 'blorg', x: 100, y: 100, props: { w: 100, h: 100 } },
])
const page1 = editor.currentPageId
const page1 = editor.getCurrentPageId()
editor.createPage({ name: 'page 2', id: ids.page2 })
editor.setCurrentPage(page1)
})

View file

@ -47,7 +47,7 @@ describe('TLSelectTool.Translating', () => {
expect(editor.getCurrentPageShapes().length).toBe(1)
editor.expectShapeToMatch({ id: ids.box1, x: 150, y: 150 })
const t1 = [...editor.currentPageShapeIds.values()]
const t1 = [...editor.getCurrentPageShapeIds().values()]
editor.keyDown('Alt')
expect(editor.getCurrentPageShapes().length).toBe(2)
@ -67,7 +67,7 @@ describe('TLSelectTool.Translating', () => {
editor.expectShapeToMatch({ id: ids.box1, x: 150, y: 150 })
expect([...editor.currentPageShapeIds.values()]).toMatchObject(t1)
expect([...editor.getCurrentPageShapeIds().values()]).toMatchObject(t1)
// todo: Should cloning again duplicate new shapes, or restore the last clone?
// editor.keyDown('Alt')

View file

@ -95,7 +95,7 @@ describe('restoring bound arrows multiplayer', () => {
editor.undo() // undo creating the arrow
// arrow is gone too now
expect(editor.currentPageShapeIds.size).toBe(0)
expect(editor.getCurrentPageShapeIds().size).toBe(0)
editor.redo() // redo creating the arrow
@ -106,11 +106,11 @@ describe('restoring bound arrows multiplayer', () => {
editor.undo() // undo creating arrow
expect(editor.currentPageShapeIds.size).toBe(0)
expect(editor.getCurrentPageShapeIds().size).toBe(0)
editor.undo() // undo creating box
expect(editor.currentPageShapeIds.size).toBe(0)
expect(editor.getCurrentPageShapeIds().size).toBe(0)
editor.redo() // redo creating box

View file

@ -10,7 +10,7 @@ beforeEach(() => {
it('gets common bounds', () => {
// Put the ellipse back on the page to avoid a weird bounding box width
editor.reparentShapes([defaultShapesIds.ellipse1], editor.currentPageId)
editor.reparentShapes([defaultShapesIds.ellipse1], editor.getCurrentPageId())
editor.updateShapes([
{

View file

@ -8,26 +8,26 @@ beforeEach(() => {
})
it('Creates a page', () => {
const oldPageId = editor.currentPageId
const oldPageId = editor.getCurrentPageId()
const n = editor.getPages().length
editor.mark('creating new page')
editor.createPage({ name: 'Page 1' })
expect(editor.getPages().length).toBe(n + 1)
const newPageId = editor.getPages()[n].id
// does not move to the new page right away
expect(editor.currentPageId).toBe(oldPageId)
expect(editor.getCurrentPageId()).toBe(oldPageId)
// needs to be done manually
editor.setCurrentPage(newPageId)
expect(editor.currentPageId).toBe(newPageId)
expect(editor.getCurrentPageId()).toBe(newPageId)
editor.undo()
expect(editor.getPages().length).toBe(n)
expect(editor.currentPageId).toBe(oldPageId)
expect(editor.getCurrentPageId()).toBe(oldPageId)
editor.redo()
expect(editor.getPages().length).toBe(n + 1)
expect(editor.currentPageId).toBe(newPageId)
expect(editor.getCurrentPageId()).toBe(newPageId)
})
it("Doesn't create a page if max pages is reached", () => {

View file

@ -84,7 +84,7 @@ it('Uses typescript generics', () => {
it('Parents shapes to the current page if the parent is not found', () => {
editor.createShapes([{ id: ids.box1, parentId: ids.missing, type: 'geo' }])
expect(editor.getShape(ids.box1)!.parentId).toEqual(editor.currentPageId)
expect(editor.getShape(ids.box1)!.parentId).toEqual(editor.getCurrentPageId())
})
it('Creates shapes with the current style', () => {
@ -118,13 +118,13 @@ it('Creates shapes at the correct index', () => {
})
it('Throws out all shapes if any shape is invalid', () => {
const n = editor.currentPageShapeIds.size
const n = editor.getCurrentPageShapeIds().size
expect(() => {
editor.createShapes([{ id: ids.box1, type: 'geo' }])
}).not.toThrow()
expect(editor.currentPageShapeIds.size).toBe(n + 1)
expect(editor.getCurrentPageShapeIds().size).toBe(n + 1)
console.error = jest.fn()
@ -137,5 +137,5 @@ it('Throws out all shapes if any shape is invalid', () => {
])
}).toThrow()
expect(editor.currentPageShapeIds.size).toBe(n + 1)
expect(editor.getCurrentPageShapeIds().size).toBe(n + 1)
})

View file

@ -56,14 +56,14 @@ describe('deletePage', () => {
editor.mark('before creating page')
editor.createPage({ name: 'New Page 2', id: page2Id })
const currentPageId = editor.currentPageId
const currentPageId = editor.getCurrentPageId()
editor.deletePage(currentPageId)
expect(editor.getPages().length).toBe(1)
expect(editor.currentPageId).not.toBe(currentPageId)
expect(editor.currentPageId).toBe(editor.getPages()[0].id)
expect(editor.getCurrentPageId()).not.toBe(currentPageId)
expect(editor.getCurrentPageId()).toBe(editor.getPages()[0].id)
})
it('switches the page if another user or tab deletes the current page', () => {
const currentPageId = editor.currentPageId
const currentPageId = editor.getCurrentPageId()
const page2Id = PageRecordType.createId('page2')
editor.mark('before creating')
editor.createPage({ name: 'New Page 2', id: page2Id })
@ -73,7 +73,7 @@ describe('deletePage', () => {
})
expect(editor.getPages().length).toBe(1)
expect(editor.currentPageId).not.toBe(currentPageId)
expect(editor.currentPageId).toBe(editor.getPages()[0].id)
expect(editor.getCurrentPageId()).not.toBe(currentPageId)
expect(editor.getCurrentPageId()).toBe(editor.getPages()[0].id)
})
})

View file

@ -14,21 +14,21 @@ beforeEach(() => {
})
it('Duplicates a page', () => {
const oldPageId = editor.currentPageId
const oldPageId = editor.getCurrentPageId()
const camera = { ...editor.getCamera() }
const n = editor.getPages().length
expect(editor.getCurrentPageShapes().length).toBe(1)
const existingIds = new Set(editor.getPages().map((s) => s.id))
editor.duplicatePage(editor.currentPageId)
editor.duplicatePage(editor.getCurrentPageId())
// Creates the new page
expect(editor.getPages().length).toBe(n + 1)
// Navigates to the new page
const newPageId = editor.getPages().find((p) => !existingIds.has(p.id))!.id
expect(editor.currentPageId).toBe(newPageId)
expect(editor.getCurrentPageId()).toBe(newPageId)
// Duplicates the shapes
expect(editor.getCurrentPageShapes().length).toBe(1)
@ -40,16 +40,16 @@ it('Duplicates a page', () => {
editor.undo()
expect(editor.getPages().length).toBe(n)
expect(editor.currentPageId).toBe(oldPageId)
expect(editor.getCurrentPageId()).toBe(oldPageId)
editor.redo()
expect(editor.getPages().length).toBe(n + 1)
expect(editor.currentPageId).toBe(newPageId)
expect(editor.getCurrentPageId()).toBe(newPageId)
})
it("Doesn't duplicate the page if max pages is reached", () => {
for (let i = 0; i < MAX_PAGES; i++) {
editor.duplicatePage(editor.currentPageId)
editor.duplicatePage(editor.getCurrentPageId())
}
expect(editor.getPages().length).toBe(MAX_PAGES)
})

View file

@ -14,18 +14,18 @@ const ids = {
beforeEach(() => {
editor = new TestEditor()
const page0Id = editor.currentPageId
const page0Id = editor.getCurrentPageId()
editor.createPage({ name: ids.page1, id: ids.page1 })
expect(editor.currentPageId).toBe(page0Id)
expect(editor.getCurrentPageId()).toBe(page0Id)
editor.setCurrentPage(ids.page1)
expect(editor.currentPageId).toBe(ids.page1)
expect(editor.getCurrentPageId()).toBe(ids.page1)
editor.createShapes([
{ id: ids.ellipse1, type: 'geo', x: 0, y: 0, props: { geo: 'ellipse' } },
{ id: ids.box1, type: 'geo', x: 0, y: 0 },
{ id: ids.box2, parentId: ids.box1, type: 'geo', x: 150, y: 150 },
])
editor.createPage({ name: ids.page2, id: ids.page2 })
expect(editor.currentPageId).toBe(ids.page1)
expect(editor.getCurrentPageId()).toBe(ids.page1)
expect(editor.getShape(ids.box1)!.parentId).toEqual(ids.page1)
expect(editor.getShape(ids.box2)!.parentId).toEqual(ids.box1)
@ -34,7 +34,7 @@ beforeEach(() => {
describe('Editor.moveShapesToPage', () => {
it('Moves shapes to page', () => {
editor.moveShapesToPage([ids.box2, ids.ellipse1], ids.page2)
expect(editor.currentPageId).toBe(ids.page2)
expect(editor.getCurrentPageId()).toBe(ids.page2)
expect(editor.getShape(ids.box2)!.parentId).toBe(ids.page2)
expect(editor.getShape(ids.ellipse1)!.parentId).toBe(ids.page2)
@ -42,13 +42,13 @@ describe('Editor.moveShapesToPage', () => {
// box1 didn't get moved, still on page 1
expect(editor.getShape(ids.box1)!.parentId).toBe(ids.page1)
expect([...editor.currentPageShapeIds].sort()).toMatchObject([ids.box2, ids.ellipse1])
expect([...editor.getCurrentPageShapeIds()].sort()).toMatchObject([ids.box2, ids.ellipse1])
expect(editor.currentPageId).toBe(ids.page2)
expect(editor.getCurrentPageId()).toBe(ids.page2)
editor.setCurrentPage(ids.page1)
expect([...editor.currentPageShapeIds]).toEqual([ids.box1])
expect([...editor.getCurrentPageShapeIds()]).toEqual([ids.box1])
})
it('Moves children to page', () => {
@ -83,24 +83,32 @@ describe('Editor.moveShapesToPage', () => {
})
it('Restores on undo / redo', () => {
expect(editor.currentPageId).toBe(ids.page1)
expect([...editor.currentPageShapeIds].sort()).toMatchObject([ids.box1, ids.box2, ids.ellipse1])
expect(editor.getCurrentPageId()).toBe(ids.page1)
expect([...editor.getCurrentPageShapeIds()].sort()).toMatchObject([
ids.box1,
ids.box2,
ids.ellipse1,
])
editor.mark('move shapes to page')
editor.moveShapesToPage([ids.box2], ids.page2)
expect(editor.currentPageId).toBe(ids.page2)
expect([...editor.currentPageShapeIds].sort()).toMatchObject([ids.box2])
expect(editor.getCurrentPageId()).toBe(ids.page2)
expect([...editor.getCurrentPageShapeIds()].sort()).toMatchObject([ids.box2])
editor.undo()
expect(editor.currentPageId).toBe(ids.page1)
expect([...editor.currentPageShapeIds].sort()).toMatchObject([ids.box1, ids.box2, ids.ellipse1])
expect(editor.getCurrentPageId()).toBe(ids.page1)
expect([...editor.getCurrentPageShapeIds()].sort()).toMatchObject([
ids.box1,
ids.box2,
ids.ellipse1,
])
editor.redo()
expect(editor.currentPageId).toBe(ids.page2)
expect([...editor.currentPageShapeIds].sort()).toMatchObject([ids.box2])
expect(editor.getCurrentPageId()).toBe(ids.page2)
expect([...editor.getCurrentPageShapeIds()].sort()).toMatchObject([ids.box2])
})
it('Sets the correct indices', () => {
@ -109,7 +117,7 @@ describe('Editor.moveShapesToPage', () => {
editor.createPage({ name: 'New Page 2', id: page2Id })
editor.setCurrentPage(page2Id)
expect(editor.currentPageId).toBe(page2Id)
expect(editor.getCurrentPageId()).toBe(page2Id)
editor.createShapes([{ id: ids.box1, type: 'geo', x: 0, y: 0, props: { geo: 'ellipse' } }])
editor.expectShapeToMatch({
id: ids.box1,
@ -121,7 +129,7 @@ describe('Editor.moveShapesToPage', () => {
editor.createPage({ name: 'New Page 3', id: page3Id })
editor.setCurrentPage(page3Id)
expect(editor.currentPageId).toBe(page3Id)
expect(editor.getCurrentPageId()).toBe(page3Id)
editor.createShapes([{ id: ids.box2, type: 'geo', x: 0, y: 0, props: { geo: 'ellipse' } }])
editor.expectShapeToMatch({
id: ids.box2,
@ -133,7 +141,7 @@ describe('Editor.moveShapesToPage', () => {
editor.select(ids.box1)
editor.moveShapesToPage([ids.box1], page3Id)
expect(editor.currentPageId).toBe(page3Id)
expect(editor.getCurrentPageId()).toBe(page3Id)
editor.expectShapeToMatch(
{

View file

@ -30,11 +30,11 @@ beforeEach(() => {
})
it('reparents a shape', () => {
expect(editor.getShape(ids.box2)!.parentId).toBe(editor.currentPageId)
expect(editor.getShape(ids.box2)!.parentId).toBe(editor.getCurrentPageId())
editor.reparentShapes([ids.box2], ids.box1)
expect(editor.getShape(ids.box2)!.parentId).toBe(ids.box1)
editor.reparentShapes([ids.box2], editor.currentPageId)
expect(editor.getShape(ids.box2)!.parentId).toBe(editor.currentPageId)
editor.reparentShapes([ids.box2], editor.getCurrentPageId())
expect(editor.getShape(ids.box2)!.parentId).toBe(editor.getCurrentPageId())
})
it('preserves shape page transfors', () => {
@ -63,7 +63,7 @@ it('adds children to the top of the parents children by default', () => {
expect(editor.getShape(ids.box2)!.index).toBe('a1')
expect(editor.getShape(ids.box3)!.index).toBe('a2')
editor.reparentShapes([ids.box2], editor.currentPageId)
editor.reparentShapes([ids.box2], editor.getCurrentPageId())
// When moving back, place at the top of the stack
expect(editor.getShape(ids.box2)!.index).toBe('a6')
@ -143,7 +143,7 @@ it('adds children at a given index', () => {
// Handles collisions (trying to move boxes 2, 3, and 5 to a0, but box1 is there already)
// Should order them between box1 and box4
editor.reparentShapes([ids.box2, ids.box3, ids.box5], editor.currentPageId, 'a1')
editor.reparentShapes([ids.box2, ids.box3, ids.box5], editor.getCurrentPageId(), 'a1')
// Page
// - box1 a1

View file

@ -13,29 +13,29 @@ describe('setCurrentPage', () => {
const page2Id = PageRecordType.createId('page2')
editor.createPage({ name: 'New Page 2', id: page2Id })
expect(editor.currentPageId).toBe(page1Id)
expect(editor.getCurrentPageId()).toBe(page1Id)
editor.setCurrentPage(page2Id)
expect(editor.currentPageId).toEqual(page2Id)
expect(editor.getCurrentPageId()).toEqual(page2Id)
expect(editor.currentPage).toEqual(editor.getPages()[1])
expect(editor.getCurrentPage()).toEqual(editor.getPages()[1])
editor.setCurrentPage(page1Id)
expect(editor.currentPage).toEqual(editor.getPages()[0])
expect(editor.getCurrentPage()).toEqual(editor.getPages()[0])
const page3Id = PageRecordType.createId('page3')
editor.createPage({ name: 'New Page 3', id: page3Id })
expect(editor.currentPageId).toBe(page1Id)
expect(editor.getCurrentPageId()).toBe(page1Id)
editor.setCurrentPage(page3Id)
expect(editor.currentPageId).toEqual(page3Id)
expect(editor.currentPage).toEqual(editor.getPages()[2])
expect(editor.getCurrentPageId()).toEqual(page3Id)
expect(editor.getCurrentPage()).toEqual(editor.getPages()[2])
editor.setCurrentPage(editor.getPages()[0].id)
expect(editor.currentPageId).toEqual(editor.getPages()[0].id)
expect(editor.currentPage).toEqual(editor.getPages()[0])
expect(editor.getCurrentPageId()).toEqual(editor.getPages()[0].id)
expect(editor.getCurrentPage()).toEqual(editor.getPages()[0])
})
it("adding a page to the store by any means adds tab state for the page if it doesn't already exist", () => {
@ -74,8 +74,8 @@ describe('setCurrentPage', () => {
})
it('logs an error when trying to navigate to a page that does not exist', () => {
const initialPageId = editor.currentPageId
expect(editor.currentPageId).toBe(initialPageId)
const initialPageId = editor.getCurrentPageId()
expect(editor.getCurrentPageId()).toBe(initialPageId)
console.error = jest.fn()
expect(() => {
@ -83,6 +83,6 @@ describe('setCurrentPage', () => {
}).not.toThrow()
expect(console.error).toHaveBeenCalled()
expect(editor.currentPageId).toBe(initialPageId)
expect(editor.getCurrentPageId()).toBe(initialPageId)
})
})

View file

@ -245,7 +245,7 @@ describe('frame shapes', () => {
{ type: 'geo', id: ids.boxA, x: 250, y: 250, props: { w: 50, h: 50, fill: 'solid' } },
])
expect(editor.getOnlySelectedShape()!.parentId).toBe(editor.currentPageId)
expect(editor.getOnlySelectedShape()!.parentId).toBe(editor.getCurrentPageId())
editor.setCurrentTool('select')
editor.pointerDown(275, 275).pointerMove(150, 150)
@ -258,7 +258,7 @@ describe('frame shapes', () => {
editor.pointerMove(275, 275)
jest.advanceTimersByTime(250)
expect(editor.getOnlySelectedShape()!.parentId).toBe(editor.currentPageId)
expect(editor.getOnlySelectedShape()!.parentId).toBe(editor.getCurrentPageId())
editor.pointerMove(150, 150)
jest.advanceTimersByTime(250)
@ -282,14 +282,14 @@ describe('frame shapes', () => {
])
// It should be a child of the page
expect(editor.getOnlySelectedShape()!.parentId).toBe(editor.currentPageId)
expect(editor.getOnlySelectedShape()!.parentId).toBe(editor.getCurrentPageId())
// Drag the shape on top of the frame
editor.setCurrentTool('select')
editor.pointerDown(275, 275, ids.boxA).pointerMove(150, 150)
// The timeout has not fired yet, so the shape is still a child of the current page
expect(editor.getOnlySelectedShape()!.parentId).toBe(editor.currentPageId)
expect(editor.getOnlySelectedShape()!.parentId).toBe(editor.getCurrentPageId())
// On pointer up, the shape should be dropped into the frame
editor.pointerUp()
@ -384,7 +384,7 @@ describe('frame shapes', () => {
})
expect(editor.snaps.getLines()).toHaveLength(0)
// and if we unparent the box it should snap
editor.reparentShapes([innerBoxId], editor.currentPageId)
editor.reparentShapes([innerBoxId], editor.getCurrentPageId())
editor.pointerMove(287.5, 126.5).pointerMove(277.5, 126.5)
expect(editor.snaps.getLines()).toHaveLength(1)
@ -441,7 +441,7 @@ describe('frame shapes', () => {
`"polygon(-50px -50px,50px -50px,50px 50px,-50px 50px)"`
)
editor.reparentShapes([editor.getOnlySelectedShape()!.id], editor.currentPageId)
editor.reparentShapes([editor.getOnlySelectedShape()!.id], editor.getCurrentPageId())
expect(editor.getShapeClipPath(editor.getOnlySelectedShape()!.id)).toBeUndefined()
})
@ -481,7 +481,7 @@ describe('frame shapes', () => {
expect(arrow.props.start).toMatchObject({ boundShapeId: frameId })
expect(arrow.props.end).toMatchObject({ type: 'point' })
expect(arrow.parentId).toBe(editor.currentPageId)
expect(arrow.parentId).toBe(editor.getCurrentPageId())
})
it('arrows started within the frame can bind to a shape within the frame ', () => {
@ -506,7 +506,7 @@ describe('frame shapes', () => {
expect(arrow.props.start).toMatchObject({ boundShapeId: boxId })
expect(arrow.props.end).toMatchObject({ boundShapeId: frameId })
expect(arrow.parentId).toBe(editor.currentPageId)
expect(arrow.parentId).toBe(editor.getCurrentPageId())
})
it('can be edited', () => {
@ -706,9 +706,9 @@ test('arrows bound to a shape within a group within a frame are reparented if th
editor.translateSelection(200, 0)
// expect group parent to be the page
expect(editor.getShape(groupId)!.parentId).toBe(editor.currentPageId)
expect(editor.getShape(groupId)!.parentId).toBe(editor.getCurrentPageId())
// expect arrow parent to be the page
expect(editor.getShape(arrowId)!.parentId).toBe(editor.currentPageId)
expect(editor.getShape(arrowId)!.parentId).toBe(editor.getCurrentPageId())
// expect arrow index to be greater than group index
expect(editor.getShape(arrowId)?.index.localeCompare(editor.getShape(groupId)!.index)).toBe(1)
})
@ -772,6 +772,6 @@ describe('When dragging a shape inside a group inside a frame', () => {
jest.advanceTimersByTime(300)
expect(editor.getShape(ids.box1)!.parentId).toBe(editor.currentPageId)
expect(editor.getShape(ids.box1)!.parentId).toBe(editor.getCurrentPageId())
})
})

View file

@ -272,9 +272,9 @@ describe('creating groups', () => {
expect(children(groupB).size).toBe(2)
expect(children(groupC).size).toBe(2)
expect(groupA.parentId).toBe(editor.currentPageId)
expect(groupB.parentId).toBe(editor.currentPageId)
expect(groupC.parentId).toBe(editor.currentPageId)
expect(groupA.parentId).toBe(editor.getCurrentPageId())
expect(groupB.parentId).toBe(editor.getCurrentPageId())
expect(groupC.parentId).toBe(editor.getCurrentPageId())
expect(editor.getShape(ids.boxA)!.parentId).toBe(groupA.id)
expect(editor.getShape(ids.boxC)!.parentId).toBe(groupA.id)
@ -320,7 +320,7 @@ describe('creating groups', () => {
.sort(sortByIndex)
.map((shape) => shape.id)
const sortedIds = editor.getSortedChildIdsForParent(editor.currentPageId)
const sortedIds = editor.getSortedChildIdsForParent(editor.getCurrentPageId())
expect(sortedIds.length).toBe(3)
expect(sortedIds[0]).toBe(ids.boxA)
expect(sortedIds[1]).toBe(groupAId)
@ -354,7 +354,7 @@ describe('creating groups', () => {
.sort(sortByIndex)
.map((shape) => shape.id)
const sortedIds = editor.getSortedChildIdsForParent(editor.currentPageId)
const sortedIds = editor.getSortedChildIdsForParent(editor.getCurrentPageId())
expect(sortedIds.length).toBe(3)
expect(sortedIds[0]).toBe(ids.boxB)
expect(sortedIds[1]).toBe(groupAId)
@ -827,7 +827,7 @@ describe('focus layers', () => {
editor.selectNone()
})
it('should adjust to the parent layer of any selected shape', () => {
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
editor.select(ids.boxA)
expect(editor.getFocusedGroupId()).toBe(groupAId)
editor.select(ids.boxB)
@ -840,7 +840,7 @@ describe('focus layers', () => {
expect(editor.getFocusedGroupId()).toBe(groupCId)
})
it('should adjust to the common ancestor of selected shapes in multiple groups', () => {
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
editor.select(ids.boxA)
expect(editor.getFocusedGroupId()).toBe(groupAId)
editor.setSelectedShapes([...editor.getSelectedShapeIds(), ids.boxC])
@ -851,7 +851,7 @@ describe('focus layers', () => {
expect(editor.getFocusedGroupId()).toBe(groupCId)
})
it('should not adjust the focus layer when clearing the selection', () => {
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
editor.select(ids.boxA)
expect(editor.getFocusedGroupId()).toBe(groupAId)
editor.deselect(ids.boxA)
@ -924,7 +924,7 @@ 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.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
editor.pointerDown(0, 0, ids.boxA)
editor.pointerUp(0, 0, ids.boxA)
expect(onlySelectedId()).toBe(groupAId)
@ -941,7 +941,7 @@ describe('the select tool', () => {
.pointerDown(0, 0, { target: 'shape', shape: boxA, button: 2 })
.pointerUp(0, 0, { button: 2 })
expect(onlySelectedId()).toBe(groupCId)
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
editor
.pointerDown(0, 0, { target: 'shape', shape: boxA, button: 2 })
.pointerUp(0, 0, { button: 2 })
@ -981,7 +981,7 @@ describe('the select tool', () => {
// click outside the focused group, but inside another group
editor.pointerDown(-235, 5, { target: 'canvas' }).pointerUp(-235, 5)
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
expect(editor.getSelectedShapeIds()).toHaveLength(0)
editor.select(ids.boxA)
@ -989,7 +989,7 @@ describe('the select tool', () => {
// click the empty canvas
editor.pointerDown(-235, 50, { target: 'canvas' }).pointerUp(-235, 50)
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
expect(editor.getSelectedShapeIds()).toHaveLength(0)
})
@ -1026,10 +1026,10 @@ describe('the select tool', () => {
// pop focus layer
editor.cancel()
expect(editor.getSelectedShapeIds().length).toBe(1) // Group C
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
editor.cancel()
expect(editor.getSelectedShapeIds().length).toBe(0)
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
})
// ! Removed: pointing a group is impossible; you'd be pointing the selection instead.
@ -1163,7 +1163,7 @@ describe('creating new shapes', () => {
editor.pointerDown(20, 20).pointerMove(80, 80).pointerUp(80, 80)
const boxC = onlySelectedShape()
expect(boxC.parentId).toBe(editor.currentPageId)
expect(boxC.parentId).toBe(editor.getCurrentPageId())
expect(editor.getShapePageBounds(boxC.id)).toCloselyMatchObject({
x: 20,
y: 20,
@ -1251,7 +1251,7 @@ describe('creating new shapes', () => {
editor.pointerDown(20, 20).pointerMove(80, 80).pointerUp(80, 80)
const lineC = onlySelectedShape()
expect(lineC.parentId).toBe(editor.currentPageId)
expect(lineC.parentId).toBe(editor.getCurrentPageId())
})
it('does draw inside the group if the group is focused', () => {
@ -1332,7 +1332,7 @@ describe('creating new shapes', () => {
const lineC = onlySelectedShape()
expect(lineC.type).toBe('line')
expect(lineC.parentId).toBe(editor.currentPageId)
expect(lineC.parentId).toBe(editor.getCurrentPageId())
})
it('does draw inside the group if the group is focused', () => {
@ -1380,13 +1380,13 @@ 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.getFocusedGroupId() === editor.currentPageId).toBe(true)
expect(editor.getFocusedGroupId() === editor.getCurrentPageId()).toBe(true)
editor.setCurrentTool('note')
editor.pointerDown(20, 20).pointerUp()
const postit = onlySelectedShape()
expect(postit.parentId).toBe(editor.currentPageId)
expect(postit.parentId).toBe(editor.getCurrentPageId())
})
it('does draw inside the group if the group is focused', () => {
@ -1625,7 +1625,7 @@ describe('bindings', () => {
editor.pointerDown(5, 5).pointerMove(5, 25).pointerUp()
const arrow = onlySelectedShape() as TLArrowShape
expect(arrow.parentId).toBe(editor.currentPageId)
expect(arrow.parentId).toBe(editor.getCurrentPageId())
expect(arrow.props.start).toMatchObject({ boundShapeId: ids.boxA })
expect(arrow.props.end).toMatchObject({ boundShapeId: ids.boxE })
@ -1648,7 +1648,7 @@ describe('bindings', () => {
editor.pointerDown(5, 25).pointerMove(27, 7).pointerMove(25, 5).pointerUp()
const arrow = onlySelectedShape() as TLArrowShape
expect(arrow.parentId).toBe(editor.currentPageId)
expect(arrow.parentId).toBe(editor.getCurrentPageId())
expect(arrow.props.start).toMatchObject({ boundShapeId: ids.boxE })
expect(arrow.props.end).toMatchObject({ boundShapeId: ids.boxB })
})

View file

@ -47,7 +47,7 @@ describe('parentsToChildrenWithIndexes', () => {
{ type: 'geo', id: ids.box3 },
])
expect(editor.getSortedChildIdsForParent(editor.currentPageId)).toEqual([
expect(editor.getSortedChildIdsForParent(editor.getCurrentPageId())).toEqual([
ids.box1,
ids.box2,
ids.box3,
@ -61,7 +61,7 @@ describe('parentsToChildrenWithIndexes', () => {
{ type: 'geo', id: ids.box3 },
])
expect(editor.getSortedChildIdsForParent(editor.currentPageId)).toEqual([
expect(editor.getSortedChildIdsForParent(editor.getCurrentPageId())).toEqual([
ids.box1,
ids.box2,
ids.box3,
@ -74,7 +74,7 @@ describe('parentsToChildrenWithIndexes', () => {
index: getIndexBetween(editor.getShape(ids.box2)!.index, editor.getShape(ids.box3)!.index),
},
])
expect(editor.getSortedChildIdsForParent(editor.currentPageId)).toEqual([
expect(editor.getSortedChildIdsForParent(editor.getCurrentPageId())).toEqual([
ids.box2,
ids.box1,
ids.box3,
@ -84,7 +84,7 @@ describe('parentsToChildrenWithIndexes', () => {
{ id: ids.box2, type: 'geo', index: getIndexAbove(editor.getShape(ids.box3)!.index) },
])
expect(editor.getSortedChildIdsForParent(editor.currentPageId)).toEqual([
expect(editor.getSortedChildIdsForParent(editor.getCurrentPageId())).toEqual([
ids.box1,
ids.box3,
ids.box2,

View file

@ -171,8 +171,8 @@ describe('When pasting', () => {
editor.paste()
const shapes = getShapes()
expect(shapes.new.box1?.parentId).toBe(editor.currentPageId)
expect(shapes.new.box2?.parentId).toBe(editor.currentPageId)
expect(shapes.new.box1?.parentId).toBe(editor.getCurrentPageId())
expect(shapes.new.box2?.parentId).toBe(editor.getCurrentPageId())
expect(editor.getCurrentPageShapesSorted().map((m) => m.id)).toStrictEqual([
shapes.old.frame1.id,
@ -265,8 +265,8 @@ describe('When pasting', () => {
const shapes = getShapes()
// Should make the pasted shapes the children of the frame
expect(shapes.new.box1?.parentId).toBe(editor.currentPageId)
expect(shapes.new.box2?.parentId).toBe(editor.currentPageId)
expect(shapes.new.box1?.parentId).toBe(editor.getCurrentPageId())
expect(shapes.new.box2?.parentId).toBe(editor.getCurrentPageId())
// Should put the pasted shapes centered in the frame
editor.select(shapes.new.box1!.id, shapes.new.box1!.id)
@ -357,7 +357,7 @@ it('pastes shapes with children', () => {
// Should make the pasted shapes the children of the frame
expect(shapes.new.box1.parentId).toBe(shapes.new.frame3.id)
expect(shapes.new.box2.parentId).toBe(shapes.new.frame3.id)
expect(shapes.new.frame3.parentId).toBe(editor.currentPageId)
expect(shapes.new.frame3.parentId).toBe(editor.getCurrentPageId())
})
describe('When pasting into frames...', () => {

View file

@ -580,7 +580,7 @@ describe('when shape is inside of a frame', () => {
editor.deleteShape(ids.box1)
editor.createShape({
id: ids.box5,
parentId: editor.currentPageId,
parentId: editor.getCurrentPageId(),
type: 'geo',
props: {
w: 75,
@ -1330,15 +1330,15 @@ describe('When children / descendants of a group are selected', () => {
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.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
editor.select(ids.group3, ids.box1, ids.box2)
expect(editor.getSelectedShapeIds()).toEqual([ids.group3])
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
editor.select(ids.group3, ids.group2, ids.box1)
expect(editor.getSelectedShapeIds()).toEqual([ids.group3])
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
})
it('picks the highest common focus layer id', () => {
@ -1350,16 +1350,16 @@ describe('When children / descendants of a group are selected', () => {
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.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
})
it('sets the parent to the highest common ancestor', () => {
editor.selectNone()
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
editor.select(ids.group3)
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
editor.select(ids.group3, ids.box1)
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
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.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
editor.keyUp('Enter')
expect(editor.getSelectedShapeIds()).toEqual([ids.box1, ids.box2, ids.box3, ids.box4])
expect(editor.getFocusedGroupId()).toBe(editor.currentPageId)
expect(editor.getFocusedGroupId()).toBe(editor.getCurrentPageId())
})
it('repeats children of the groups on enter up', () => {

View file

@ -19,30 +19,32 @@ const ids = {
describe('shapeIdsInCurrentPage', () => {
it('keeps the shape ids in the current page', () => {
expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([]))
expect(new Set(editor.getCurrentPageShapeIds())).toEqual(new Set([]))
editor.createShapes([{ type: 'geo', id: ids.box1 }])
expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box1]))
expect(new Set(editor.getCurrentPageShapeIds())).toEqual(new Set([ids.box1]))
editor.createShapes([{ type: 'geo', id: ids.box2 }])
expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box1, ids.box2]))
expect(new Set(editor.getCurrentPageShapeIds())).toEqual(new Set([ids.box1, ids.box2]))
editor.createShapes([{ type: 'geo', id: ids.box3 }])
expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box1, ids.box2, ids.box3]))
expect(new Set(editor.getCurrentPageShapeIds())).toEqual(
new Set([ids.box1, ids.box2, ids.box3])
)
editor.deleteShapes([ids.box2])
expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box1, ids.box3]))
expect(new Set(editor.getCurrentPageShapeIds())).toEqual(new Set([ids.box1, ids.box3]))
editor.deleteShapes([ids.box1])
expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box3]))
expect(new Set(editor.getCurrentPageShapeIds())).toEqual(new Set([ids.box3]))
editor.deleteShapes([ids.box3])
expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([]))
expect(new Set(editor.getCurrentPageShapeIds())).toEqual(new Set([]))
})
it('changes when the current page changes', () => {
@ -60,10 +62,14 @@ describe('shapeIdsInCurrentPage', () => {
{ type: 'geo', id: ids.box6 },
])
expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box4, ids.box5, ids.box6]))
expect(new Set(editor.getCurrentPageShapeIds())).toEqual(
new Set([ids.box4, ids.box5, ids.box6])
)
editor.setCurrentPage(editor.getPages()[0].id)
expect(new Set(editor.currentPageShapeIds)).toEqual(new Set([ids.box1, ids.box2, ids.box3]))
expect(new Set(editor.getCurrentPageShapeIds())).toEqual(
new Set([ids.box1, ids.box2, ids.box3])
)
})
})

View file

@ -23,7 +23,7 @@ function asPlainObject(styles: ReadonlySharedStyleMap | null) {
beforeEach(() => {
editor = new TestEditor()
editor.createShapes(createDefaultShapes())
editor.reparentShapes([defaultShapesIds.ellipse1], editor.currentPageId)
editor.reparentShapes([defaultShapesIds.ellipse1], editor.getCurrentPageId())
})
describe('Editor.styles', () => {

View file

@ -173,15 +173,15 @@ describe('When cloning...', () => {
})
it('clones a single shape and restores when stopping cloning', () => {
expect(editor.currentPageShapeIds.size).toBe(3)
expect(editor.currentPageShapeIds.size).toBe(3)
expect(editor.getCurrentPageShapeIds().size).toBe(3)
expect(editor.getCurrentPageShapeIds().size).toBe(3)
editor.select(ids.box1).pointerDown(50, 50, ids.box1).pointerMove(50, 40) // [0, -10]
expect(editor.currentPageShapeIds.size).toBe(3)
expect(editor.getCurrentPageShapeIds().size).toBe(3)
editor.expectShapeToMatch({ id: ids.box1, x: 10, y: 0 }) // Translated A...
// Start cloning!
editor.keyDown('Alt')
expect(editor.currentPageShapeIds.size).toBe(4)
expect(editor.getCurrentPageShapeIds().size).toBe(4)
const newShape = editor.getSelectedShapes()[0]
expect(newShape.id).not.toBe(ids.box1)
@ -202,13 +202,13 @@ describe('When cloning...', () => {
it('clones multiple single shape and restores when stopping cloning', () => {
editor.select(ids.box1, ids.box2).pointerDown(50, 50, ids.box1).pointerMove(50, 40) // [0, -10]
expect(editor.currentPageShapeIds.size).toBe(3)
expect(editor.getCurrentPageShapeIds().size).toBe(3)
editor.expectShapeToMatch({ id: ids.box1, x: 10, y: 0 }) // Translated A...
editor.expectShapeToMatch({ id: ids.box2, x: 200, y: 190 }) // Translated B...
// Start cloning!
editor.keyDown('Alt')
expect(editor.currentPageShapeIds.size).toBe(5) // Two new shapes!
expect(editor.getCurrentPageShapeIds().size).toBe(5) // Two new shapes!
const newShapeA = editor.getShape(editor.getSelectedShapeIds()[0])!
const newShapeB = editor.getShape(editor.getSelectedShapeIds()[1])!
expect(newShapeA).toBeDefined()
@ -242,9 +242,9 @@ describe('When cloning...', () => {
expect(editor.getShape(ids.line1)!.parentId).toBe(ids.box2)
editor.select(ids.box2).pointerDown(250, 250, ids.box2).pointerMove(250, 240) // [0, -10]
expect(editor.currentPageShapeIds.size).toBe(3)
expect(editor.getCurrentPageShapeIds().size).toBe(3)
editor.keyDown('Alt', { altKey: true })
expect(editor.currentPageShapeIds.size).toBe(5) // Creates a clone of B and C (its descendant)
expect(editor.getCurrentPageShapeIds().size).toBe(5) // Creates a clone of B and C (its descendant)
const newShapeA = editor.getShape(editor.getSelectedShapeIds()[0])!
const newShapeB = editor.getShape(editor.getSortedChildIdsForParent(newShapeA.id)[0])!
@ -1730,7 +1730,7 @@ describe('When dragging a shape onto a parent', () => {
editor.pointerDown(550, 550, ids.box1).pointerMove(350, 350).pointerUp()
// It should not become the child of frame2 because it is clipped
expect(editor.getShape(ids.box1)?.parentId).toBe(editor.currentPageId)
expect(editor.getShape(ids.box1)?.parentId).toBe(editor.getCurrentPageId())
})
})

View file

@ -248,6 +248,9 @@ export function throttle<T extends (...args: any) => any>(func: T, limit: number
// @internal
export function throttledRaf(fn: () => void): void;
// @internal (undocumented)
export function warnDeprecatedGetter(name: string): void;
// (No @packageDocumentation comment for this package)
```

View file

@ -34,3 +34,4 @@ export { sortById } from './lib/sort'
export type { Expand, RecursivePartial, Required } from './lib/types'
export { isValidUrl } from './lib/url'
export { isDefined, isNonNull, isNonNullish, structuredClone } from './lib/value'
export { warnDeprecatedGetter } from './lib/warnDeprecatedGetter'

View file

@ -0,0 +1,15 @@
const warnedNames = new Set<string>()
/**
* @internal
*/
export function warnDeprecatedGetter(name: string) {
if (warnedNames.has(name)) return
warnedNames.add(name)
console.warn(
`Using '${name}' is deprecated and will be removed in the near future. Please refactor to use 'get${name[0].toLocaleUpperCase()}${name.slice(
1
)}' instead.`
)
}

View file

@ -2298,7 +2298,7 @@ __metadata:
languageName: node
linkType: hard
"@eslint-community/eslint-utils@npm:^4.2.0":
"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0":
version: 4.4.0
resolution: "@eslint-community/eslint-utils@npm:4.4.0"
dependencies:
@ -4514,6 +4514,7 @@ __metadata:
auto: ^10.46.0
eslint: ^8.37.0
eslint-config-prettier: ^8.8.0
eslint-plugin-deprecation: ^2.0.0
eslint-plugin-import: ^2.27.5
eslint-plugin-local: ^1.0.0
eslint-plugin-no-only-tests: ^3.1.0
@ -5047,6 +5048,13 @@ __metadata:
languageName: node
linkType: hard
"@types/json-schema@npm:^7.0.12":
version: 7.0.15
resolution: "@types/json-schema@npm:7.0.15"
checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98
languageName: node
linkType: hard
"@types/json-schema@npm:^7.0.6, @types/json-schema@npm:^7.0.9":
version: 7.0.11
resolution: "@types/json-schema@npm:7.0.11"
@ -5296,6 +5304,13 @@ __metadata:
languageName: node
linkType: hard
"@types/semver@npm:^7.5.0":
version: 7.5.5
resolution: "@types/semver@npm:7.5.5"
checksum: 533e6c93d1262d65f449423d94a445f7f3db0672e7429f21b6a1636d6051dbab3a2989ddcda9b79c69bb37830931d09fc958a65305a891357f5cea3257c297f5
languageName: node
linkType: hard
"@types/stack-utils@npm:^2.0.0":
version: 2.0.1
resolution: "@types/stack-utils@npm:2.0.1"
@ -5430,6 +5445,16 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/scope-manager@npm:6.11.0":
version: 6.11.0
resolution: "@typescript-eslint/scope-manager@npm:6.11.0"
dependencies:
"@typescript-eslint/types": 6.11.0
"@typescript-eslint/visitor-keys": 6.11.0
checksum: d219a96fd80fb14176cdcc47b070e870c73ccc0dfb32a8657f6ceaefb613dc0ea240a77250dcfc437d9c9360ca165c2765d4cf8fe689dae7e9eee2c0d6a98a50
languageName: node
linkType: hard
"@typescript-eslint/type-utils@npm:5.59.0":
version: 5.59.0
resolution: "@typescript-eslint/type-utils@npm:5.59.0"
@ -5454,6 +5479,13 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/types@npm:6.11.0":
version: 6.11.0
resolution: "@typescript-eslint/types@npm:6.11.0"
checksum: ca8a11320286c9b0759a70ec83b9fd99937c9686fafdd41d8ea09ed7b2fa12e6b342bf65547efe5495926cd04cfc6488315920e3caffd27f12d42cb9a8cf88c8
languageName: node
linkType: hard
"@typescript-eslint/typescript-estree@npm:5.59.0":
version: 5.59.0
resolution: "@typescript-eslint/typescript-estree@npm:5.59.0"
@ -5472,6 +5504,24 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/typescript-estree@npm:6.11.0":
version: 6.11.0
resolution: "@typescript-eslint/typescript-estree@npm:6.11.0"
dependencies:
"@typescript-eslint/types": 6.11.0
"@typescript-eslint/visitor-keys": 6.11.0
debug: ^4.3.4
globby: ^11.1.0
is-glob: ^4.0.3
semver: ^7.5.4
ts-api-utils: ^1.0.1
peerDependenciesMeta:
typescript:
optional: true
checksum: e137ba7c4cad08853a44d9c40072496ca5f2d440828be9fd2d207a59db56b05a6dcb4756f3ba341ee2ae714de45df80114477946d30801c5a46eed67314fd9c6
languageName: node
linkType: hard
"@typescript-eslint/utils@npm:5.59.0, @typescript-eslint/utils@npm:^5.59.0":
version: 5.59.0
resolution: "@typescript-eslint/utils@npm:5.59.0"
@ -5490,6 +5540,23 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/utils@npm:^6.0.0":
version: 6.11.0
resolution: "@typescript-eslint/utils@npm:6.11.0"
dependencies:
"@eslint-community/eslint-utils": ^4.4.0
"@types/json-schema": ^7.0.12
"@types/semver": ^7.5.0
"@typescript-eslint/scope-manager": 6.11.0
"@typescript-eslint/types": 6.11.0
"@typescript-eslint/typescript-estree": 6.11.0
semver: ^7.5.4
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
checksum: e90aa2c8c56038a48de65a5303f9e4a4a70bb0d4d0a05cfcd28157fc0f06b2fc186c2e76a495f4540a903ea37577daa1403bab923d940114ec27a6326153d60f
languageName: node
linkType: hard
"@typescript-eslint/visitor-keys@npm:5.59.0":
version: 5.59.0
resolution: "@typescript-eslint/visitor-keys@npm:5.59.0"
@ -5500,6 +5567,16 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/visitor-keys@npm:6.11.0":
version: 6.11.0
resolution: "@typescript-eslint/visitor-keys@npm:6.11.0"
dependencies:
"@typescript-eslint/types": 6.11.0
eslint-visitor-keys: ^3.4.1
checksum: 6aae9dd79963bbefbf2e310015b909627da541a13ab4d8359eea3c86c34fdbb91e583f65b5a99dee1959f7c5d67b21b45e5a05c63ddb4b82dacd60c890ce8b25
languageName: node
linkType: hard
"@ungap/promise-all-settled@npm:1.1.2":
version: 1.1.2
resolution: "@ungap/promise-all-settled@npm:1.1.2"
@ -8872,6 +8949,20 @@ __metadata:
languageName: node
linkType: hard
"eslint-plugin-deprecation@npm:^2.0.0":
version: 2.0.0
resolution: "eslint-plugin-deprecation@npm:2.0.0"
dependencies:
"@typescript-eslint/utils": ^6.0.0
tslib: ^2.3.1
tsutils: ^3.21.0
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
typescript: ^4.2.4 || ^5.0.0
checksum: d79611e902ac419a21e51eab582fcdbcf8170aff820c5e5197e7d242e7ca6bda59c0077d88404970c25993017398dd65c96df7d31a833e332d45dd330935324b
languageName: node
linkType: hard
"eslint-plugin-import@npm:^2.27.5":
version: 2.27.5
resolution: "eslint-plugin-import@npm:2.27.5"
@ -8996,6 +9087,13 @@ __metadata:
languageName: node
linkType: hard
"eslint-visitor-keys@npm:^3.4.1":
version: 3.4.3
resolution: "eslint-visitor-keys@npm:3.4.3"
checksum: 36e9ef87fca698b6fd7ca5ca35d7b2b6eeaaf106572e2f7fd31c12d3bfdaccdb587bba6d3621067e5aece31c8c3a348b93922ab8f7b2cbc6aaab5e1d89040c60
languageName: node
linkType: hard
"eslint@npm:^8.37.0":
version: 8.38.0
resolution: "eslint@npm:8.38.0"
@ -15667,6 +15765,17 @@ __metadata:
languageName: node
linkType: hard
"semver@npm:^7.5.4":
version: 7.5.4
resolution: "semver@npm:7.5.4"
dependencies:
lru-cache: ^6.0.0
bin:
semver: bin/semver.js
checksum: 12d8ad952fa353b0995bf180cdac205a4068b759a140e5d3c608317098b3575ac2f1e09182206bf2eb26120e1c0ed8fb92c48c592f6099680de56bb071423ca3
languageName: node
linkType: hard
"send@npm:0.18.0":
version: 0.18.0
resolution: "send@npm:0.18.0"
@ -16599,6 +16708,15 @@ __metadata:
languageName: node
linkType: hard
"ts-api-utils@npm:^1.0.1":
version: 1.0.3
resolution: "ts-api-utils@npm:1.0.3"
peerDependencies:
typescript: ">=4.2.0"
checksum: 441cc4489d65fd515ae6b0f4eb8690057add6f3b6a63a36073753547fb6ce0c9ea0e0530220a0b282b0eec535f52c4dfc315d35f8a4c9a91c0def0707a714ca6
languageName: node
linkType: hard
"ts-dedent@npm:^2.2.0":
version: 2.2.0
resolution: "ts-dedent@npm:2.2.0"
@ -16787,6 +16905,13 @@ __metadata:
languageName: node
linkType: hard
"tslib@npm:^2.3.1":
version: 2.6.2
resolution: "tslib@npm:2.6.2"
checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad
languageName: node
linkType: hard
"tsutils@npm:^3.21.0":
version: 3.21.0
resolution: "tsutils@npm:3.21.0"