excalidraw/src/types.ts
zsviczian 1d5e865da1
update to latest master (#6286)
* fix: fonts not rendered on init if `loadingdone` not fired (#5923)

* fix: fonts not rendered on init if `loadingdone` not fired

* remove unnecessary check

* fix: Always bind to container selected by user (#5880)

* fix: Always bind to container selected by user

* Don't bind to container when using text tool

* adjust z-index for bound text

* fix

* Add spec

* Add test

* Allow double click on transparent container and add spec

* fix spec

* adjust z-index only when binding

* update index

* fix

* add index check

* Update src/scene/Scene.ts

Co-authored-by: dwelle <luzar.david@gmail.com>

* feat: changed text copy/paste behaviour (#5786)

Co-authored-by: dwelle <luzar.david@gmail.com>
Co-authored-by: Antonio Della Fortuna <a.dellafortuna00@gmail.com>

* feat: Don't add midpoint until dragged beyond a threshold (#5927)

* Don't add midpoint until dragged beyond a threshold

* remove unnecessary code

* fix tests

* fix

* add spec

* remove isMidpoint

* cleanup

* fix threshold for zoom

* split into shouldAddMidpoint and addMidpoint

* wrap in flushSync for synchronous updates

* remove threshold for line editor and add spec

* [unrelated] fix stack overflow state update

* fix tests

* don't drag arrow when dragging to add mid point

* add specs

Co-authored-by: dwelle <luzar.david@gmail.com>

* refactor: remove unnecessary code (#5933)

* fix: scale font correctly when using shift (#5935)

* fix: scale font correctly when using shift

* fix

* Empty-Commit

* Add spec

* fix

* fix: Dedupe boundElement ids when container duplicated with alt+drag  (#5938)

* Dedupe boundElement ids when container duplicated with alt+drag and add spec

* set to null by default

* fix: bindings do not survive history serialization (#5942)

* fix: don't allow whitespaces for bound text (#5939)

* fix: don't allow whitespaces for bound text

* fix

* remove

* remove empty else

* fix

* fix

* fix

* feat: Support labels for arrow 🔥 (#5723)

* feat: support arrow with text

* render arrow -> clear rect-> render text

* move bound text when linear elements move

* fix centering cursor when linear element rotated

* fix y coord when new line added and container has 3 points

* update text position when 2nd point moved

* support adding label on top of 2nd point when 3 points are present

* change linear element editor shortcut to cmd+enter and fix tests

* scale bound text points when resizing via bounding box

* ohh yeah rotation works :)

* fix coords when updating text properties

* calculate new position after rotation always from original position

* rotate the bound text by same angle as parent

* don't rotate text and make sure dimensions and coords are always calculated from original point

* hardcoding the text width for now

* Move the linear element when bound text hit

* Rotation working yaay

* consider text element angle when editing

* refactor

* update x2 coords if needed when text updated

* simplify

* consider bound text to be part of bounding box when hit

* show bounding box correctly when multiple element selected

* fix typo

* support rotating multiple elements

* support multiple element resizing

* shift bound text to mid point when odd points

* Always render linear element handles inside editor after element rendered so point is visible for bound text

* Delete bound text when point attached to it deleted

* move bound to mid segement mid point when points are even

* shift bound text when points nearby deleted and handle segment deletion

* Resize working :)

* more resize fixes

* don't update cache-its breaking delete points, look for better soln

* update mid point cache for bound elements when updated

* introduce wrapping when resizing

* wrap when resize for 2 pointer linear elements

* support adding text for linear elements with more than 3 points

* export to svg  working :)

* clip from nearest enclosing element with non transparent color if present when exporting and fill with correct color in canvas

* fix snap

* use visible elements

* Make export to svg work with Mask :)

* remove id

* mask canvas linear element area where label is added

* decide the position of bound text during render

* fix coords when editing

* fix multiple resize

* update cache when bound text version changes

* fix masking when rotated

* render text in correct position in preview

* remove unnecessary code

* fix masking when rotating linear element

* fix masking with zoom

* fix mask in preview for export

* fix offsets in export view

* fix coords on svg export

* fix mask when element rotated in svg

* enable double-click to enter text

* fix hint

* Position cursor correctly and text dimensiosn when height of element is negative

* don't allow 2 pointer linear element with bound text width to go beyond min width

* code cleanup

* fix freedraw

* Add padding

* don't show vertical align action for linear element containers

* Add specs for getBoundTextElementPosition

* more specs

* move some utils to linearElementEditor.ts

* remove only :p

* check absoulte coods in test

* Add test to hide vertical align for linear eleemnt with bound text

* improve export preview

* support labels only for arrows

* spec

* fix large texts

* fix tests

* fix zooming

* enter line editor with cmd+double click

* Allow points to move beyond min width/height for 2 pointer arrow with bound text

* fix hint for line editing

* attempt to fix arrow getting deselected

* fix hint and shortcut

* Add padding of 5px when creating bound text and add spec

* Wrap bound text when arrow binding containers moved

* Add spec

* remove

* set boundTextElementVersion to null if not present

* dont use cache when version mismatch

* Add a padding of 5px vertically when creating text

* Add box sizing content box

* Set bound elements when text element created to fix the padding

* fix zooming in editor

* fix zoom in export

* remove globalCompositeOperation and use clearRect instead of fillRect

* fix: repair element bindings on restore (#5956)

* fix: repair element bindings on restore

* fix dropping non-text bound elements

* be more conservative

* build: move release scripts to use release branch (#5958)

* fix: renderFooter styling (#5962)

* fix: `ExcalidrawArrowElement` rather than `ExcalidrawArrowEleement` (#5955)

* fix: Galego and Kurdî missing in languages plus two locale typos (#5954)

* fix: remove blank space (#5950)

* fix: remove editor onpaste handler (#5971)

* feat: better default radius sizes for rectangles (#5553)

Co-authored-by: Ryan <diweihao@bytedance.com>
Co-authored-by: dwelle <luzar.david@gmail.com>

* chore: add display name to context providers (#5974)

* chore: add display name to context providers

* fix typo

* fix: apply the right type of roundness when pasting styles (#5979)

* fix: only paste roundness when target and source elements are of the same type

* apply roundness when pasting across different types

* simplify

Co-authored-by: dwelle <luzar.david@gmail.com>

* feat: allow readonly actions to be used in viewMode (#5982)

* fix: chart pasting not working due to removing tab characters (#5987)

* fix: Avatar outline on safari & center (#5997)

* fix: not properly restoring element stroke and bg colors (#6002)

* fix: PWA not working after CRA@5 update (#6012)

* fix: PWA not working after CRA@5 update

* fix: fallback to default locale when fetch fails

* fix: resize sometimes throwing on missing null-checks (#6013)

* fix: showing `grabbing` cursor when holding `spacebar` (#6015)

* fix: don't push whitespace to next line when exceeding max width during wrapping and make sure to use same width of text editor on DOM when measuring dimensions (#5996)

* fix: don't push whitespace to next line when exceeding max width during wrapping

* add a helper function and never push empty line

* use width same as in text area so dimensions are same

* add tests

* make sure dom element has exact same width as text editor

* feat: render footer as a component instead of render prop (#5970)

* feat: render footer as a component instead of render prop

* Export FooterCenter as footer

* remove useDevice export

* revert some changes

* remove

* add spec

* update specs

* parse children into a dictionary

* factor app footer components into a single file

* Add docs

* split app footer components

Co-authored-by: dwelle <luzar.david@gmail.com>

* feat: move contextMenu into the component tree and control via appState (#6021)

* fix: ColorPicker getColor (#5949)

Co-authored-by: dwelle <luzar.david@gmail.com>

* chore: bump typescript @ 4.9.4 (#6024)

* feat: support shrinking text containers to original height when text removed (#6025)

* fix:cache bind text containers height so that it could autoshrink to original height when text deleted

* revert

* rename

* reset cache when resized

* safe check

* restore original containr height when text is unbind

* update cache when redrawing bounding box

* reset cache when unbind

* make type-safe

* add specs

* skip one test

* remoe mock

* fix

Co-authored-by: dwelle <luzar.david@gmail.com>

* fix: restoring deleted bindings (#6029)

* fix: restoring deleted bindings

* add tests

* add one more test

* merge restore tests files

* fix: use canvas measureText to calculate width in measureText (#6030)

* fix: use canvas measureText to calculate width in measureText

* calculate multiline width correctly using canvas measure text and rename functions

* set correct width when pasting in bound container

* take existing value + new pasted

* remove debugger :p

* fix snaps

* fix: remove background from wysiwyg when editing arrow label (#6033)

Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>

* fix: use displayName since name gets stripped off when uglifying/minifiyng in production (#6036)

fix: use displayName since name gets stripped off when uglifying/minifiy in production

* feat: Scroll using PageUp and PageDown (#6038)

* feat: Scroll using PageUp and PageDown

* support x-axis via `shift` & enable in viewMode

* tweak test

Co-authored-by: dwelle <luzar.david@gmail.com>

* chore: Update translations from Crowdin (#5807)

Co-authored-by: David Luzar <luzar.david@gmail.com>

* fix: remove ga from docker build (#6059)

* fix: remove ga from docker build

* lint

* fix debug

* fix: show error message on collab save failure (#6063)

* fix: show error message on collab save failure

* comment

* feat: new Menu Component API (#6034)

* feat: new Menu Component API

* allow valid children types

* introduce menu group to group items

* Add lang footer

* use display name

* displayName

* define types inside

* fix default menu

* add json export to menu

* fix

* simplify expression

* put open menu into own compo to optimize perf

So that we don't rerun `useOutsideClickHook` (and rebind event listeners
all the time)

* naming tweaks

* rename MenuComponents->MenuDefaultItems and export default items from Menu.Items

* import Menu.scss in Menu.tsx

* move menu scss to excal app

* Don't filter children inside menu group

* move E+ out of socials

* support style prop for MenuItem and MenuGroup

* Support header in menu group and add Excalidraw links header for default items in social section

* rename header to title

* fix padding for lang

* render menu in mobile

* review fixes

* tweaks

* Export collaborators and show in mobile menu

* revert .env

* lint :p

* again lint

* show correct actions in view mode for mobile

* Whitelist Collaborators Comp

* mobile styling

* padding

* don't show nerds when menu open in mobile

* lint :(

* hide shortcuts

* refactor userlist to support mobile and keep a wrapper comp for excal app

* use only UserList

* render only on mobile for default items

* remove unused hooks

* Show collab button in menu when onCollabButtonClick present and hide export when UIOptions.canvasActions.export is false

* fix tests

* lint

* inject userlist inside menu on mobile

* revert userlist

* move menu socials to default menu

* fix collab

* use meny in library

* Make Menu generic and create hamburgemenu for public excal menu and use menu in library as well

* use appState.openMenu for mobile

* fix tests

* styling fixes and support style and class name in menu content

* fix test

* rename MenuDefaultItems->DefaultItems

* move footer css to its own comp

* rename HamburgerMenu -> MainMenu

* rename menu -> dropdownMenu and update classes, onClick->onToggle

* close main menu when dialog closes

* by bye filtering

* update docs

* fix lint

* update example, docs for useDevice and footer in mobile, rename menu ->DropDownMenu everywhere

* spec

* remove isMenuOpenAtom and set openMenu as canvas for main menu, render decreases in specs :)

* [temp] remove cyclic depenedency to fix build

* hack- update appstate to sync lang change

* Add more specs

* wip: rewrite MainMenu footer

* fix margin

* fix snaps

* not needed as lang list no more imported

* simplify custom footer rendering

* Add DropdownMenuItemLink and DropdownMenuItemCustom and update API, docs

* fix `MainMenu.ItemCustom`

* naming

* use onSelect and base class for custom items

* fix lint

* fix snap

* use custom item for lang

* update docs

* fix

* properly use `MainMenu.ItemCustom` for `LanguageList`

* add margin top to custom items

* flex

Co-authored-by: dwelle <luzar.david@gmail.com>

* fix: HelpDialog (#6072)

* chore: Update translations from Crowdin (#6052)

* New translations en.json (German)

* Auto commit: Calculate translation coverage

* New translations en.json (Hindi)

* New translations en.json (Marathi)

* New translations en.json (Hindi)

* Auto commit: Calculate translation coverage

* New translations en.json (Galician)

* Auto commit: Calculate translation coverage

* New translations en.json (Romanian)

* New translations en.json (French)

* New translations en.json (Spanish)

* New translations en.json (Arabic)

* New translations en.json (Bulgarian)

* New translations en.json (Catalan)

* New translations en.json (Czech)

* New translations en.json (Danish)

* New translations en.json (German)

* New translations en.json (Greek)

* New translations en.json (Basque)

* New translations en.json (Finnish)

* New translations en.json (Hebrew)

* New translations en.json (Hungarian)

* New translations en.json (Italian)

* New translations en.json (Japanese)

* New translations en.json (Korean)

* New translations en.json (Kurdish)

* New translations en.json (Lithuanian)

* New translations en.json (Dutch)

* New translations en.json (Punjabi)

* New translations en.json (Polish)

* New translations en.json (Portuguese)

* New translations en.json (Russian)

* New translations en.json (Slovak)

* New translations en.json (Slovenian)

* New translations en.json (Swedish)

* New translations en.json (Turkish)

* New translations en.json (Ukrainian)

* New translations en.json (Chinese Simplified)

* New translations en.json (Chinese Traditional)

* New translations en.json (Vietnamese)

* New translations en.json (Galician)

* New translations en.json (Portuguese, Brazilian)

* New translations en.json (Indonesian)

* New translations en.json (Persian)

* New translations en.json (Tamil)

* New translations en.json (Bengali)

* New translations en.json (Marathi)

* New translations en.json (Norwegian Nynorsk)

* New translations en.json (Kazakh)

* New translations en.json (Latvian)

* New translations en.json (Hindi)

* New translations en.json (Burmese)

* New translations en.json (Chinese Traditional, Hong Kong)

* New translations en.json (Sinhala)

* New translations en.json (Norwegian Bokmal)

* New translations en.json (Occitan)

* New translations en.json (Kabyle)

* Auto commit: Calculate translation coverage

* New translations en.json (Chinese Simplified)

* Auto commit: Calculate translation coverage

* New translations en.json (Chinese Traditional)

* New translations en.json (Chinese Traditional)

* New translations en.json (Norwegian Bokmal)

* Auto commit: Calculate translation coverage

* New translations en.json (Latvian)

* Auto commit: Calculate translation coverage

* New translations en.json (Romanian)

* Auto commit: Calculate translation coverage

* New translations en.json (Slovenian)

* Auto commit: Calculate translation coverage

* New translations en.json (Spanish)

* New translations en.json (Russian)

* Auto commit: Calculate translation coverage

* New translations en.json (German)

* Auto commit: Calculate translation coverage

* New translations en.json (Vietnamese)

* Auto commit: Calculate translation coverage

* New translations en.json (Hindi)

* Auto commit: Calculate translation coverage

* New translations en.json (Dutch)

* Auto commit: Calculate translation coverage

* New translations en.json (Marathi)

* Auto commit: Calculate translation coverage

* New translations en.json (Latvian)

* New translations en.json (French)

* Auto commit: Calculate translation coverage

* New translations en.json (French)

* Auto commit: Calculate translation coverage

* New translations en.json (Portuguese, Brazilian)

* Auto commit: Calculate translation coverage

* New translations en.json (Japanese)

* Auto commit: Calculate translation coverage

* build(deps): bump json5 from 2.2.1 to 2.2.3 in /src/packages/excalidraw (#6062)

Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump json5 from 2.2.1 to 2.2.3 in /src/packages/utils (#6061)

Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump json5 from 2.2.1 to 2.2.3 in /dev-docs (#6060)

Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump decode-uri-component from 0.2.0 to 0.2.2 (#5963)

Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump json5 from 1.0.1 to 1.0.2 (#6076)

Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump loader-utils from 2.0.3 to 2.0.4 (#5905)

Bumps [loader-utils](https://github.com/webpack/loader-utils) from 2.0.3 to 2.0.4.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v2.0.4/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v2.0.3...v2.0.4)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump loader-utils from 2.0.3 to 2.0.4 in /src/packages/excalidraw (#5892)

build(deps): bump loader-utils in /src/packages/excalidraw

Bumps [loader-utils](https://github.com/webpack/loader-utils) from 2.0.3 to 2.0.4.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v2.0.4/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v2.0.3...v2.0.4)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix: stale appState of MainMenu defaultItems rendered from Actions (#6074)

* fix: png-exporting does not preserve angles correctly for flipped images (#6085)

* fix: png-exporting does not preserve angles correctly for flipped images

* refactor related code

* simplify further and comment

* fix: image horizontal flip fix + improved tests (#5799)

Co-authored-by: Antonio Della Fortuna <a.dellafortuna00@gmail.com>
Co-authored-by: dwelle <luzar.david@gmail.com>
fixes https://github.com/excalidraw/excalidraw/issues/5784

* fix: React.memo resolvers not accounting for all props (#6042)

* fix: use position absolute for mobile misc tools (#6099)

* feat: generic button export (#6092)

Co-authored-by: dwelle <luzar.david@gmail.com>

* feat: render unknown supplied children to UI (#6096)

* feat: support WelcomeScreen customization API (#6048)

* fix: renamed folder MainMenu->main-menu and support rest props (#6103)

* renamed folder MainMenu -> main-menu

* rename ariaLabel -> aria-label and dataTestId -> data-testid

* allow rest props

* fix

* lint

* add ts check

* ts for div

* fix

* fix

* fix

* feat: new Live Collaboration Component API (#6104)

* feat: new Live Collaboration Component API

* namespace export icons into `icons` dictionary and lowercase

* update readme and changelog

* review fixes

* fix

* fix

* update docs

* remove

* allow button rest props

* update docs

* docs

* add `WelcomeScreen.Center.MenuItemLiveCollaborationTrigger`

* fix lint

* update changelog

Co-authored-by: dwelle <luzar.david@gmail.com>

* fix: mobile tools positioning (#6107)

* fix: mobile tools positioning

* add var for padding

* use css var

* new line

* stupid mistake

* lint

* fix: remove overflow hidden from button (#6110)

remove overflow hidden from button

* docs: release @excalidraw/excalidraw@0.14.0  🎉 (#6109)

* docs: release @excalidraw/excalidraw@0.14.1 🎉 (#6112)

* build: temporarily disable pre-commit (#6132)

* chore: Update translations from Crowdin (#6077)

* feat: show copy-as-png export button on firefox and show steps how to enable it (#6125)

* feat: hide copy-as-png shortcut from help dialog if not supported

* fix: support firefox if clipboard.write supported

* show shrotcut in firefox and instead show error message how to enable the flag support

* widen to TypeError because minification

* show copy-as-png on firefox even if it will throw

* style: change in ExportButton style (#6147) (#6148)

Co-authored-by: David Luzar <luzar.david@gmail.com>

* fix: button background and svg sizes (#6155)

* fix: button background color fallback

* fix svg width/height

* feat: add hand/panning tool (#6141)

* feat: add hand/panning tool

* move hand tool right of tool lock separator

* tweak i18n

* rename `panning` -> `hand`

* toggle between last tool and hand on `H` shortcut

* hide properties sidebar when `hand` active

* revert to rendering HandButton manually due to mobile toolbar

* feat: close MainMenu and Library dropdown on item select (#6152)

* fix: declare css variable for font in excalidraw so its available in host (#6160)

declar css variable for font in excalidraw so its available in host

* fix: 🐛 broken emojis when wrap text (#6153)

* fix: 🐛 broken emojis when wrap text

* refactor: Delete unnecessary "else" (reduce indentation)

* fix: remove code block that causes the emojis to disappear

* Apply suggestions from code review

Co-authored-by: David Luzar <luzar.david@gmail.com>

* fix: 🚑 possibly undefined value

* Add spec

Co-authored-by: David Luzar <luzar.david@gmail.com>
Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>

* fix: set the width correctly using measureText in editor (#6162)

* fix: quick typo fix (#6167)

* fix: add 1px width to the container to calculate more accurately (#6174)

* fix: add 1px width to the container to calculate accurately

* fix tests

* feat: rewrite public UI component rendering using tunnels (#6117)

* feat: rewrite public UI component rendering using tunnels

* factor out into components

* comments

* fix variable naming

* fix not hiding welcomeScreen

* factor out AppFooter and memoize components

* remove `UIOptions.welcomeScreen` and render only from host app

* factor out tunnels into own file

* update changelog. Keep `UIOptions.welcomeScreen` as deprecated

* update changelog

* lint

---------

Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>

* fix: make tunnels work in multi-instance scenarios (#6178)

* fix: make tunnels work in multi-instance scenarios

* factor tunnels out

* use tunnel-rat fork until upsteam updated

* fix: horizontal padding when aligning bound text containers (#6180)

* fix: horizontal padding when aligning bound text containers

* Add specs

* fix

* docs: release @excalidraw/excalidraw@0.14.2  🎉 (#6181)

* docs: migrating dev docs to docusaurus :) (#6073)

* docs: migrating existing docs to docosaraus :)

* log broken links

* lint :p

* fix

* divide the doc into diff categories

* fix

* order sidebars and more

* fix lint

* point to installation

* making docs better :)

* fix

* renaming git

* renaming git

* fix links

* fix

* update readme

* fix

* resolve duplicate url and make /docs as base url

* fix

* move main docs as well

* making docs better

* support mdx

* update og

* fix title

* upgrade docusarus to stable version

* use draculla theme

* fix

* make entire sidebar collapsable

* live editor for footer wohoo

* render excalidraw only on client to fix the prod build

* migrate MainMenu to live editor too :)

* lint :p

* cleanup integration and use live editor and tabs

* fix

* Add welcome screen doc

* Live Collaboration comp docs

* Add collaborator example

* Add example

* add more

* remove isCollaborating

* Rewrite ref and move to sidebar

* change color of links inside pre

* add initial data

* fix lint

* Add styling

* fix lint

* Add example for customizing styles

* fix lint

* fix

* fix lint

* Add link to livecollabtrigger

* fix

* rewrite UIOptions to sidebar

* move initialdata to sidebar

* move render props to sidebar and rewrite renderTopRightUI and renderCustomStats

* rewrite renderSidebar

* update og

* update url for testing

* fix url

* update readme

* fix style

* tweaks

* Add highlight comp to highlight text

* Add bash syntax highlight

* fix

* tweaks

* fix

* rewrite export utilities

* fix restore

* rewrite utils

* move constants to sidebar

* update readme

* add copyright

* fix links style

* Add linkedin

* tweaks

* rename package to @excalidraw/excalidraw

* enable algolia with dummy creds

* tweaks to integration doc

* tweak WelcomeScreen docs to reflect upcoming API changes

* tweak components intro

* tweak nomenclature

* fix admonition

* rename `components` sidebar item and change order of components list

* uncollapse package section in sidebar

* show level 4 haeadings in TOC

* remove algolia

* remove unused assets

* capitalize C

* tweak

* rename components to App

* rename components -> children-components in the routes

* move notable used tools to intro

* update MainMenu docs with `onSelect` preventDefault behavior

* change sidebar label for children components

* use code

* tweak README & docs intro

* tweak package development doc

* make scrollbar gutter stable

* tweak api intro

* add admonition for export utils

* use next

* wip

* wip

* make excalidraw examples use current color theme & prefer system

* fix welcomescreen docs

* use latest temp release

* fix component order

* revert wip changes

* use next

* tweak

* increase height to fix welcome screen hint

* tweak editor height

* update excal version

* wrap Excal with forwardRef to fix refs

* migrate contributing.md

* fix broken links

---------

Co-authored-by: dwelle <luzar.david@gmail.com>

* fix: edit link in docs (#6182)

* docs: show last updated time and author (#6183)

docs:show last updated time and author

* fix: hide welcome screen on mobile once user interacts (#6185)

* fix: hide welcome screen on mobile once started drawing

* Add specs

* fix: sort bound text elements to fix text duplication z-index error (#5130)

* fix: sort bound text elements to fix text duplication z-index error

* improve & sort groups & add tests

* fix backtracking and discontiguous groups

---------

Co-authored-by: dwelle <luzar.david@gmail.com>

* feat: disable canvas smoothing (antialiasing) for right-angled elements (#6186)Co-authored-by: Ignacio Cuadra <67276174+ignacio-cuadra@users.noreply.github.com>

* feat: disable canvas smoothing for text and other types

* disable smoothing for all right-angled elements

* Update src/renderer/renderElement.ts

Co-authored-by: Ignacio Cuadra <67276174+ignacio-cuadra@users.noreply.github.com>

* Update src/renderer/renderElement.ts

Co-authored-by: Ignacio Cuadra <67276174+ignacio-cuadra@users.noreply.github.com>

* fix lint

* always enable smoothing while zooming

---------

Co-authored-by: Ignacio Cuadra <67276174+ignacio-cuadra@users.noreply.github.com>

* chore: Update translations from Crowdin (#6150)

* feat: shortcut for clearCanvas confirmDialog (#6114)

Co-authored-by: dwelle <luzar.david@gmail.com>
resolve https://github.com/excalidraw/excalidraw/issues/5818

* feat: show error message when not connected to internet while collabo… (#6165)

Co-authored-by: dwelle <luzar.david@gmail.com>
Resolves https://github.com/excalidraw/excalidraw/issues/5994

* fix: docker build architecture:linux/amd64 error occur on linux/arm64 instance (#6197)

fix docker build
when in linux/arm64 use docker buildx plugin to build linux/amd64 image, a build error will occur causing the build to break

* refactor: Make the example React app reusable without duplication (#6188)

* fix: don't allow blank space in collab name (#6211)

* don't allow blank space in collab name

* add spec

* prevent blank

* docs: enable Algolia for search (#6230)

* feat: Make repair and refreshDimensions configurable in restoreElements (#6238)

* fix: don't repair during reconcilation

* Add opts to restoreElement and enable refreshDimensions and repair via config

* remove

* update changelog

* fix tests

* rename to repairBindings

* docs: Fixed broken codesandbox link in the dev-docs (#6229)

fixed broken link

* docs: new readme (#6240)

Co-authored-by: David Luzar <luzar.david@gmail.com>

* docs: fix next.js example (#6241)

* docs: fix typo (#6252)

* feat: Bind text to container if double clicked on filled shape or stroke (#6250)

* feat: bind text to container when clicked on filled shape or element stroke

* Bind if double clicked on stroke as well

* remove

* specs

* remove

* shuffle

* fix

* back to normal

* docs: Fix outdated link in README.md (#6263)

* fix: improve text wrapping in ellipse and alignment (#6172)

* fix: improve text wrapping in ellipse

* compute height when font properties updated

* fix alignment

* fix alignment when resizing

* fix

* ad padding

* always compute height when redrawing bounding box and refactor

* lint

* fix specs

* fix

* redraw text bounding box when pasted or refreshed

* fix

* Add specs

* fix

* restore on font load

* add comments

* fix: improve text wrapping inside rhombus and more fixes (#6265)

* fix: improve text wrapping inside rhombus

* Add comments

* specs

* fix: shift resize and multiple element regression for ellipse and rhombus

* use container width for scaling font size

* fix

* fix multiple resize

* lint

* redraw on submit

* redraw only newly pasted elements

* no padding when center

* fix tests

* fix

* dont add padding in rhombus when aligning

* refactor

* fix

* move getMaxContainerHeight and getMaxContainerWidth to textElement.ts

* Add specs

* fix: indenting via `tab` clashing with IME compositor (#6258)

* chore: Update translations from Crowdin (#6191)

* fix: rerender i18n in host components on lang change (#6224)

* fix: fit mobile toolbar and make scrollable (#6270)

Co-authored-by: dwelle <luzar.david@gmail.com>

* feat: improve text measurements in bound containers (#6187)

* feat: move to canvas measureText

* calcualte height with better heuristic

* improve heuristic more

* remove vertical offset as its not needed

* lint

* calculate width of individual char and ceil to calculate width and remove adjustment factor

* push the word if equal to max width

* update height when text overflows for vertical alignment top/bottom

* remove the hack of updating height when line mismatch as its not needed

* remove scroll height and calculate the height instead

* remove unused code

* fix

* remove

* use math.ceil for whole width instead of individual chars

* fix tests

* fix

* fix

* redraw text bounding box instead when font loaded to fix alignment as well

* fix

* fix

* fix

* Add a 0.05px extra only for firefox

* Add spec

* stop taking ceil and increase firefox editor width by 0.05px

* Ad 0.05px in safari too

* lint

* lint

* remove baseline from measureFontSizeFromWH

* don't redraw on font load

* lint

* refactor name and signature

* fix: compute container height from bound text correctly (#6273)

* fix: compute container height from bound text correctly

* fix specs

* Add tests

* fix: svg text baseline (#6285

* fix: svg text baseline

* fix for multiline

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: David Luzar <luzar.david@gmail.com>
Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
Co-authored-by: Antonio Della Fortuna <50418432+adarkforce@users.noreply.github.com>
Co-authored-by: Antonio Della Fortuna <a.dellafortuna00@gmail.com>
Co-authored-by: DanielJGeiger <1852529+DanielJGeiger@users.noreply.github.com>
Co-authored-by: Fer <63980689+1fbr@users.noreply.github.com>
Co-authored-by: fennghuang <89014758+fennghuang@users.noreply.github.com>
Co-authored-by: Ryan Di <ryan.weihao.di@gmail.com>
Co-authored-by: Ryan <diweihao@bytedance.com>
Co-authored-by: Excalidraw Bot <77840495+excalibot@users.noreply.github.com>
Co-authored-by: EternalWill43 <70084418+EternalWill43@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Barnabás Molnár <38168628+barnabasmolnar@users.noreply.github.com>
Co-authored-by: Nishant-l <61119157+Nishant-l@users.noreply.github.com>
Co-authored-by: Ignacio Cuadra <67276174+ignacio-cuadra@users.noreply.github.com>
Co-authored-by: JUNYI OU <49964599+Irvingouj@users.noreply.github.com>
Co-authored-by: Jang Min <jangmin.dev@gmail.com>
Co-authored-by: Matthieu Rossignon <51274353+Mattross45@users.noreply.github.com>
Co-authored-by: Dejavu Moe <jialong.vip@gmail.com>
Co-authored-by: Luka Hietala <95122845+LukaHietala@users.noreply.github.com>
Co-authored-by: Milos Vetesnik <maielo.mv@gmail.com>
Co-authored-by: Jan Klass <kissaki@posteo.de>
Co-authored-by: Hikaru Yoshino <57059705+osushicrusher@users.noreply.github.com>
Co-authored-by: Tengku Farhan <109069184+tfarhan00@users.noreply.github.com>
2023-02-26 20:48:47 +01:00

526 lines
16 KiB
TypeScript

import {
PointerType,
ExcalidrawLinearElement,
NonDeletedExcalidrawElement,
NonDeleted,
TextAlign,
ExcalidrawElement,
GroupId,
ExcalidrawBindableElement,
Arrowhead,
ChartType,
FontFamilyValues,
FileId,
ExcalidrawImageElement,
Theme,
StrokeRoundness,
} from "./element/types";
import { SHAPES } from "./shapes";
import { Point as RoughPoint } from "roughjs/bin/geometry";
import { LinearElementEditor } from "./element/linearElementEditor";
import { SuggestedBinding } from "./element/binding";
import { ImportedDataState } from "./data/types";
import type App from "./components/App";
import type { ResolvablePromise, throttleRAF } from "./utils";
import { Spreadsheet } from "./charts";
import { Language } from "./i18n";
import { ClipboardData } from "./clipboard";
import { isOverScrollBars } from "./scene";
import { MaybeTransformHandleType } from "./element/transformHandles";
import Library from "./data/library";
import type { FileSystemHandle } from "./data/filesystem";
import type { ALLOWED_IMAGE_MIME_TYPES, MIME_TYPES } from "./constants";
import { ContextMenuItems } from "./components/ContextMenu";
export type Point = Readonly<RoughPoint>;
export type Collaborator = {
pointer?: {
x: number;
y: number;
};
button?: "up" | "down";
selectedElementIds?: AppState["selectedElementIds"];
username?: string | null;
userState?: UserIdleState;
color?: {
background: string;
stroke: string;
};
// The url of the collaborator's avatar, defaults to username intials
// if not present
avatarUrl?: string;
// user id. If supplied, we'll filter out duplicates when rendering user avatars.
id?: string;
};
export type DataURL = string & { _brand: "DataURL" };
export type BinaryFileData = {
mimeType:
| typeof ALLOWED_IMAGE_MIME_TYPES[number]
// future user or unknown file type
| typeof MIME_TYPES.binary;
id: FileId;
dataURL: DataURL;
/**
* Epoch timestamp in milliseconds
*/
created: number;
/**
* Indicates when the file was last retrieved from storage to be loaded
* onto the scene. We use this flag to determine whether to delete unused
* files from storage.
*
* Epoch timestamp in milliseconds.
*/
lastRetrieved?: number;
};
export type BinaryFileMetadata = Omit<BinaryFileData, "dataURL">;
export type BinaryFiles = Record<ExcalidrawElement["id"], BinaryFileData>;
export type LastActiveTool =
| {
type: typeof SHAPES[number]["value"] | "eraser" | "hand";
customType: null;
}
| {
type: "custom";
customType: string;
}
| null;
export type AppState = {
contextMenu: {
items: ContextMenuItems;
top: number;
left: number;
} | null;
showWelcomeScreen: boolean;
isLoading: boolean;
errorMessage: string | null;
draggingElement: NonDeletedExcalidrawElement | null;
resizingElement: NonDeletedExcalidrawElement | null;
multiElement: NonDeleted<ExcalidrawLinearElement> | null;
selectionElement: NonDeletedExcalidrawElement | null;
isBindingEnabled: boolean;
startBoundElement: NonDeleted<ExcalidrawBindableElement> | null;
suggestedBindings: SuggestedBinding[];
// element being edited, but not necessarily added to elements array yet
// (e.g. text element when typing into the input)
editingElement: NonDeletedExcalidrawElement | null;
editingLinearElement: LinearElementEditor | null;
activeTool: {
/**
* indicates a previous tool we should revert back to if we deselect the
* currently active tool. At the moment applies to `eraser` and `hand` tool.
*/
lastActiveTool: LastActiveTool;
locked: boolean;
} & (
| {
type: typeof SHAPES[number]["value"] | "eraser" | "hand";
customType: null;
}
| {
type: "custom";
customType: string;
}
);
penMode: boolean;
penDetected: boolean;
exportBackground: boolean;
exportEmbedScene: boolean;
exportWithDarkMode: boolean;
exportScale: number;
currentItemStrokeColor: string;
currentItemBackgroundColor: string;
currentItemFillStyle: ExcalidrawElement["fillStyle"];
currentItemStrokeWidth: number;
currentItemStrokeStyle: ExcalidrawElement["strokeStyle"];
currentItemRoughness: number;
currentItemOpacity: number;
currentItemFontFamily: FontFamilyValues;
currentItemFontSize: number;
currentItemTextAlign: TextAlign;
currentItemStartArrowhead: Arrowhead | null;
currentItemEndArrowhead: Arrowhead | null;
currentItemRoundness: StrokeRoundness;
viewBackgroundColor: string;
scrollX: number;
scrollY: number;
cursorButton: "up" | "down";
scrolledOutside: boolean;
name: string;
isResizing: boolean;
isRotating: boolean;
zoom: Zoom;
// mobile-only
openMenu: "canvas" | "shape" | null;
openPopup:
| "canvasColorPicker"
| "backgroundColorPicker"
| "strokeColorPicker"
| null;
openSidebar: "library" | "customSidebar" | null;
openDialog: "imageExport" | "help" | "jsonExport" | null;
isSidebarDocked: boolean;
lastPointerDownWith: PointerType;
selectedElementIds: { [id: string]: boolean };
previousSelectedElementIds: { [id: string]: boolean };
shouldCacheIgnoreZoom: boolean;
toast: { message: string; closable?: boolean; duration?: number } | null;
zenModeEnabled: boolean;
theme: Theme;
gridSize: number | null;
viewModeEnabled: boolean;
/** top-most selected groups (i.e. does not include nested groups) */
selectedGroupIds: { [groupId: string]: boolean };
/** group being edited when you drill down to its constituent element
(e.g. when you double-click on a group's element) */
editingGroupId: GroupId | null;
width: number;
height: number;
offsetTop: number;
offsetLeft: number;
fileHandle: FileSystemHandle | null;
collaborators: Map<string, Collaborator>;
showStats: boolean;
currentChartType: ChartType;
pasteDialog:
| {
shown: false;
data: null;
}
| {
shown: true;
data: Spreadsheet;
};
/** imageElement waiting to be placed on canvas */
pendingImageElementId: ExcalidrawImageElement["id"] | null;
showHyperlinkPopup: false | "info" | "editor";
selectedLinearElement: LinearElementEditor | null;
};
export type NormalizedZoomValue = number & { _brand: "normalizedZoom" };
export type Zoom = Readonly<{
value: NormalizedZoomValue;
}>;
export type PointerCoords = Readonly<{
x: number;
y: number;
}>;
export type Gesture = {
pointers: Map<number, PointerCoords>;
lastCenter: { x: number; y: number } | null;
initialDistance: number | null;
initialScale: number | null;
};
export declare class GestureEvent extends UIEvent {
readonly rotation: number;
readonly scale: number;
}
// libraries
// -----------------------------------------------------------------------------
/** @deprecated legacy: do not use outside of migration paths */
export type LibraryItem_v1 = readonly NonDeleted<ExcalidrawElement>[];
/** @deprecated legacy: do not use outside of migration paths */
type LibraryItems_v1 = readonly LibraryItem_v1[];
/** v2 library item */
export type LibraryItem = {
id: string;
status: "published" | "unpublished";
elements: readonly NonDeleted<ExcalidrawElement>[];
/** timestamp in epoch (ms) */
created: number;
name?: string;
error?: string;
};
export type LibraryItems = readonly LibraryItem[];
export type LibraryItems_anyVersion = LibraryItems | LibraryItems_v1;
export type LibraryItemsSource =
| ((
currentLibraryItems: LibraryItems,
) =>
| Blob
| LibraryItems_anyVersion
| Promise<LibraryItems_anyVersion | Blob>)
| Blob
| LibraryItems_anyVersion
| Promise<LibraryItems_anyVersion | Blob>;
// -----------------------------------------------------------------------------
// NOTE ready/readyPromise props are optional for host apps' sake (our own
// implem guarantees existence)
export type ExcalidrawAPIRefValue =
| ExcalidrawImperativeAPI
| {
readyPromise?: ResolvablePromise<ExcalidrawImperativeAPI>;
ready?: false;
};
export type ExcalidrawInitialDataState = Merge<
ImportedDataState,
{
libraryItems?:
| Required<ImportedDataState>["libraryItems"]
| Promise<Required<ImportedDataState>["libraryItems"]>;
}
>;
export interface ExcalidrawProps {
onChange?: (
elements: readonly ExcalidrawElement[],
appState: AppState,
files: BinaryFiles,
) => void;
initialData?:
| ExcalidrawInitialDataState
| null
| Promise<ExcalidrawInitialDataState | null>;
excalidrawRef?: ForwardRef<ExcalidrawAPIRefValue>;
isCollaborating?: boolean;
onPointerUpdate?: (payload: {
pointer: { x: number; y: number };
button: "down" | "up";
pointersMap: Gesture["pointers"];
}) => void;
onPaste?: (
data: ClipboardData,
event: ClipboardEvent | null,
) => Promise<boolean> | boolean;
renderTopRightUI?: (
isMobile: boolean,
appState: AppState,
) => JSX.Element | null;
langCode?: Language["code"];
viewModeEnabled?: boolean;
zenModeEnabled?: boolean;
gridModeEnabled?: boolean;
libraryReturnUrl?: string;
theme?: Theme;
name?: string;
renderCustomStats?: (
elements: readonly NonDeletedExcalidrawElement[],
appState: AppState,
) => JSX.Element;
UIOptions?: Partial<UIOptions>;
detectScroll?: boolean;
handleKeyboardGlobally?: boolean;
onLibraryChange?: (libraryItems: LibraryItems) => void | Promise<any>;
autoFocus?: boolean;
generateIdForFile?: (file: File) => string | Promise<string>;
onLinkOpen?: (
element: NonDeletedExcalidrawElement,
event: CustomEvent<{
nativeEvent: MouseEvent | React.PointerEvent<HTMLCanvasElement>;
}>,
) => void;
onPointerDown?: (
activeTool: AppState["activeTool"],
pointerDownState: PointerDownState,
) => void;
onScrollChange?: (scrollX: number, scrollY: number) => void;
/**
* Render function that renders custom <Sidebar /> component.
*/
renderSidebar?: () => JSX.Element | null;
children?: React.ReactNode;
}
export type SceneData = {
elements?: ImportedDataState["elements"];
appState?: ImportedDataState["appState"];
collaborators?: Map<string, Collaborator>;
commitToHistory?: boolean;
};
export enum UserIdleState {
ACTIVE = "active",
AWAY = "away",
IDLE = "idle",
}
export type ExportOpts = {
saveFileToDisk?: boolean;
onExportToBackend?: (
exportedElements: readonly NonDeletedExcalidrawElement[],
appState: AppState,
files: BinaryFiles,
canvas: HTMLCanvasElement | null,
) => void;
renderCustomUI?: (
exportedElements: readonly NonDeletedExcalidrawElement[],
appState: AppState,
files: BinaryFiles,
canvas: HTMLCanvasElement | null,
) => JSX.Element;
};
// NOTE at the moment, if action name coressponds to canvasAction prop, its
// truthiness value will determine whether the action is rendered or not
// (see manager renderAction). We also override canvasAction values in
// excalidraw package index.tsx.
type CanvasActions = Partial<{
changeViewBackgroundColor: boolean;
clearCanvas: boolean;
export: false | ExportOpts;
loadScene: boolean;
saveToActiveFile: boolean;
toggleTheme: boolean | null;
saveAsImage: boolean;
}>;
type UIOptions = Partial<{
dockedSidebarBreakpoint: number;
canvasActions: CanvasActions;
/** @deprecated does nothing. Will be removed in 0.15 */
welcomeScreen?: boolean;
}>;
export type AppProps = Merge<
ExcalidrawProps,
{
UIOptions: Merge<
UIOptions,
{
canvasActions: Required<CanvasActions> & { export: ExportOpts };
}
>;
detectScroll: boolean;
handleKeyboardGlobally: boolean;
isCollaborating: boolean;
children?: React.ReactNode;
}
>;
/** A subset of App class properties that we need to use elsewhere
* in the app, eg Manager. Factored out into a separate type to keep DRY. */
export type AppClassProperties = {
props: AppProps;
canvas: HTMLCanvasElement | null;
focusContainer(): void;
library: Library;
imageCache: Map<
FileId,
{
image: HTMLImageElement | Promise<HTMLImageElement>;
mimeType: typeof ALLOWED_IMAGE_MIME_TYPES[number];
}
>;
files: BinaryFiles;
device: App["device"];
scene: App["scene"];
pasteFromClipboard: App["pasteFromClipboard"];
};
export type PointerDownState = Readonly<{
// The first position at which pointerDown happened
origin: Readonly<{ x: number; y: number }>;
// Same as "origin" but snapped to the grid, if grid is on
originInGrid: Readonly<{ x: number; y: number }>;
// Scrollbar checks
scrollbars: ReturnType<typeof isOverScrollBars>;
// The previous pointer position
lastCoords: { x: number; y: number };
// map of original elements data
originalElements: Map<string, NonDeleted<ExcalidrawElement>>;
resize: {
// Handle when resizing, might change during the pointer interaction
handleType: MaybeTransformHandleType;
// This is determined on the initial pointer down event
isResizing: boolean;
// This is determined on the initial pointer down event
offset: { x: number; y: number };
// This is determined on the initial pointer down event
arrowDirection: "origin" | "end";
// This is a center point of selected elements determined on the initial pointer down event (for rotation only)
center: { x: number; y: number };
};
hit: {
// The element the pointer is "hitting", is determined on the initial
// pointer down event
element: NonDeleted<ExcalidrawElement> | null;
// The elements the pointer is "hitting", is determined on the initial
// pointer down event
allHitElements: NonDeleted<ExcalidrawElement>[];
// This is determined on the initial pointer down event
wasAddedToSelection: boolean;
// Whether selected element(s) were duplicated, might change during the
// pointer interaction
hasBeenDuplicated: boolean;
hasHitCommonBoundingBoxOfSelectedElements: boolean;
};
withCmdOrCtrl: boolean;
drag: {
// Might change during the pointer interaction
hasOccurred: boolean;
// Might change during the pointer interaction
offset: { x: number; y: number } | null;
};
// We need to have these in the state so that we can unsubscribe them
eventListeners: {
// It's defined on the initial pointer down event
onMove: null | ReturnType<typeof throttleRAF>;
// It's defined on the initial pointer down event
onUp: null | ((event: PointerEvent) => void);
// It's defined on the initial pointer down event
onKeyDown: null | ((event: KeyboardEvent) => void);
// It's defined on the initial pointer down event
onKeyUp: null | ((event: KeyboardEvent) => void);
};
boxSelection: {
hasOccurred: boolean;
};
elementIdsToErase: {
[key: ExcalidrawElement["id"]]: {
opacity: ExcalidrawElement["opacity"];
erase: boolean;
};
};
}>;
export type ExcalidrawImperativeAPI = {
updateScene: InstanceType<typeof App>["updateScene"];
updateLibrary: InstanceType<typeof Library>["updateLibrary"];
resetScene: InstanceType<typeof App>["resetScene"];
getSceneElementsIncludingDeleted: InstanceType<
typeof App
>["getSceneElementsIncludingDeleted"];
history: {
clear: InstanceType<typeof App>["resetHistory"];
};
scrollToContent: InstanceType<typeof App>["scrollToContent"];
getSceneElements: InstanceType<typeof App>["getSceneElements"];
getAppState: () => InstanceType<typeof App>["state"];
getFiles: () => InstanceType<typeof App>["files"];
refresh: InstanceType<typeof App>["refresh"];
setToast: InstanceType<typeof App>["setToast"];
addFiles: (data: BinaryFileData[]) => void;
readyPromise: ResolvablePromise<ExcalidrawImperativeAPI>;
ready: true;
id: string;
setActiveTool: InstanceType<typeof App>["setActiveTool"];
setCursor: InstanceType<typeof App>["setCursor"];
resetCursor: InstanceType<typeof App>["resetCursor"];
toggleMenu: InstanceType<typeof App>["toggleMenu"];
};
export type Device = Readonly<{
isSmScreen: boolean;
isMobile: boolean;
isTouchScreen: boolean;
canDeviceFitSidebar: boolean;
}>;