* fix: support collaboration in bounded text
* align implementation irrespective of collab/submit
* don't wrap when submitted
* fix
* tests: exit editor via ESCAPE instead to remove async hacks
* simplify and remove dead comment
* remove mutating coords in submit since its taken care in updateWysiwygStyle
Co-authored-by: dwelle <luzar.david@gmail.com>
* fix: don't mutate the bounded text if not updated when submitted
* dont update text for bounded text unless submitted
* add specs
* use node 16
* fix
* Update text when editing and cache prev text
* update prev text when props updated
* remove only
* type properly and remove unnecessary type checks
* cache original text and compare with editor value to fix alignement issue after editing and add specs
* naming tweak
Co-authored-by: dwelle <luzar.david@gmail.com>
* fix: support moving binded text when container selected via group
* update coords of bounded text only when element doesn't belong to any group or element in group is selected
* dnt drag binded text when nested group selected
* Update src/element/dragElements.ts
Co-authored-by: David Luzar <luzar.david@gmail.com>
Co-authored-by: David Luzar <luzar.david@gmail.com>
* feat: Word wrap inside rect and increase height when size exceeded
* fixes for auto increase in height
* fix height
* respect newlines when wrapping text
* shift text area when height increases beyond mid rect height until it reaches to the top
* select bound text if present when rect selected
* mutate y coord after text submit
* Add padding of 30px and update dimensions acordingly
* Don't allow selecting bound text element directly
* support deletion of bound text element when rect deleted
* trim text
* Support autoshrink and improve algo
* calculate approx line height instead of hardcoding
* use textContainerId instead of storing textContainer element itself
* rename boundTextElement -> boundTextElementId
* fix text properties not getting reflected after edit inside rect
* Support resizing
* remove ts ignore
* increase height of container when text height increases while resizing
* use original text when editing/resizing so it adjusts based on original text
* fix tests
* add util isRectangleElement
* use isTextElement util everywhere
* disable selecting text inside rect when selectAll
* Bind text to circle and diamond as well
* fix tests
* vertically center align the text always
* better vertical align
* Disable binding arrows for text inside shapes
* set min width for text container when text is binded to container
* update dimensions of container if its less than min width/ min height
* Allow selecting of text container for transparent containers when clicked inside
* fix test
* preserve whitespaces between long word exceeding width and next word
Use word break instead of whitespace no wrap for better readability and support safari
* Perf improvements for measuring text width and resizing
* Use canvas measureText instead of our algo. This has reduced the perf ~ 10 times
* Rewrite wrapText algo to break in words appropriately and for longer words
calculate the char width in order unless max width reached. This makes the
the number of runs linear (max text length times) which was earlier
textLength * textLength-1/2 as I was slicing the chars from end until max width reached for each run
* Add a util to calculate getApproxCharsToFitInWidth to calculate min chars to fit in a line
* use console.info so eslint doesnt warn :p
* cache char width and don't call resize unless min width exceeded
* update line height and height correctly when text properties inside container updated
* improve vertical centering when text properties updated, not yet perfect though
* when double clicked inside a conatiner take the cursor to end of text same as what happens when enter is pressed
* Add hint when container selected
* Select container when escape key is pressed after submitting text
* fix copy/paste when using copy/paste action
* fix copy when dragged with alt pressed
* fix export to svg/png
* fix add to library
* Fix copy as png/svg
* Don't allow selecting text when using selection tool and support resizing when multiple elements include ones with binded text selectec
* fix rotation jump
* moove all text utils to textElement.ts
* resize text element only after container resized so that width doesnt change when editing
* insert the remaining chars for long words once it goes beyond line
* fix typo, use string for character type
* renaming
* fix bugs in word wrap algo
* make grouping work
* set boundTextElementId only when text present else unset it
* rename textContainerId to containerId
* fix
* fix snap
* use originalText in redrawTextBoundingBox so height is calculated properly and center align works after props updated
* use boundElementIds and also support binding text in images 🎉
* fix the sw/se ends when resizing from ne/nw
* fix y coord when resizing from north
* bind when enter is pressed, double click/text tool willl edit the binded text if present else create a new text
* bind when clicked on center of container
* use pre-wrap instead of normal so it works in ff
* use container boundTextElement when container present and trying to edit text
* review fixes
* make getBoundTextElementId type safe and check for existence when using this function
* fix
* don't duplicate boundElementIds when text submitted
* only remove last trailing space if present which we have added when joining words
* set width correctly when resizing to fix alignment issues
* make duplication work using cmd/ctrl+d
* set X coord correctly during resize
* don't allow resize to negative dimensions when text is bounded to container
* fix, check last char is space
* remove logs
* make sure text editor doesn't go beyond viewport and set container dimensions in case it overflows
* add a util isTextBindableContainer to check if the container could bind text
* feat: Allow publishing libraries from UI
* Add status for each library item and show publish only for unpublished libs
* Add publish library dialog
* Pass the data to publish the library
* pass lib blob
* Handle old and new libraries when importing
* Better error handling
* Show publish success when library submitted for review
* don't close library when publish success dialog open
* Support multiple libs deletion and publish
* Set status to published once library submitted for review
* Save to LS after library published
* unique key for publish and delete
* fix layout shift when hover and also highlight selected library items
* design improvements
* migrate old library to the new one
* fix
* fix tests
* use i18n
* Support submit type in toolbutton
* Use html5 form validation, add asteriks for required fields, add twitter handle, mark github handle optional
* Add twitter handle in form state
* revert html5 validation as fetch is giving some issues :/
* clarify types around LibraryItems
* Add website optional field
* event.preventDefault to make htm5 form validationw work
* improve png generation by drawing a bounding box rect and aligining pngs to support multiple libs png
* remove ts-ignore
* add placeholders for fields
* decrease clickable area for checkbox by 0.5em
* add checkbox background color
* rename `items` to `elements`
* improve checkbox hit area
* show selected library items in publish dialog
* decrease dimensions by 3px to improve jerky experience when opening/closing library menu
* Don't close publish dialog when clicked outside
* Show selected library actions only when any library item selected and use icons instead of button
* rename library to libraryItems in excalidrawLib and added migration
* change icon and swap bg/color
* use blue brand color for hover/selected states
* prompt for confirmation when deleting library items
* separate unpublished items from published
* factor `LibraryMenu` into own file
* i18n and minor fixes for unpublished items
* fix not rendering empty cells when library empty
* don't render published section if empty and unpublished is not
* Add edit name functionality for library items
* fix
* edit lib name with onchange/blur
* bump library version
* prefer response error message
* add library urls to ENV vars
* mark lib item name as required
* Use input only for lib item name
* better error validation for lib items
* fix label styling for lib items
* design and i18n fixes
* Save publish dialog data to local storage and clear once published
* Add a note about MIT License
* Add note for guidelines
* Add tooltip for publish button
* Show spinner in submit button when submission is in progress
* assign id for older lib items when installed and set status as published for all lib when installed
* update export icon and support export library for selected items
* move LibraryMenuItems into its own component as its best to keep one comp per file
* fix spec
* Refactoring the library actions for reusablility
* show only load when items not present
* close on click outside in publish dialog
* ad dialog description and tweak copy
* vertically center input labels
* align input styles
* move author name input to other usernames
* rename param
* inline to simplify
* fix to not inline `undefined` class names
* fix version & include only latest lib schema in library export type
* await response callback
* refactor types
* refactor
* i18n
* align casing & tweaks
* move ls logic to publishLibrary
* support removal of item inside publish dialog
* fix labels for trash icon when items selected
* replace window.confirm for removal libs with confirm dialog
* fix input/textarea styling
* move library item menu scss to its own file
* use blue for load and cyan for publish
* reduce margin for submit and make submit => Submit
* Make library items header sticky
* move publish icon to left so there is no jerkiness when unpublish items selected
* update url
* fix grid gap between lib items
* Mark older items imported from initial data as unpublished
* add text to publish button on non-mobile
* add items counter
* fix test
* show personal and excal libs sections and personal goes first
* show toast on adding to library via contextMenu
* Animate plus icon and not the pending item
* fix snap
* use i18n when no item in publish dialog
* tweak style of new lib item
* show empty cells for both sections and set status as published for installed libs
* fix
* push selected item first in unpublished section
* set status as published for imported from webiste but unpublished for json
* Add items to the begining of library
* add `created` library item attr
* fix test
* use `defaultValue` instead of `value`
* fix dark theme styles
* fix toggle button not closing library
* close library menu on Escape
* tweak publish dialog item remove style
* fix remove icon in publish dialog
Co-authored-by: dwelle <luzar.david@gmail.com>
* fix: image not initialized correctly due to not renewing `state.pendingImageElement`
* ensure we replace elements on update
* set file as errored on >= 400 status respones
* flush queues on portal close
* fix mouse broadcast race condition
* stop mutating image elements when updating status
to fix race condition when closing/opening collab room
* check `files` when resolving `LayerUI`
* fix displaying AbortError
* Use Theme type everywhere
* Rename Appearance type to Theme for consistency
* Reorder headers in readme
The host don't need to pass hardcoded strings any more and instead can use the exported constant
* feat: Add shortcuts for opening stroke and background color picker
* Use App.tsx keydown handler
* only get selectedElements if applicable (perf)
* fix tests and snaps
* reuse `appState.openMenu`
Co-authored-by: dwelle <luzar.david@gmail.com>
* feat: allow inner-drag-selecting with cmd/ctrl
* don't use cursor when pressing cmd/ctrl
* ensure we reset deselected groups
* add tests
* add docs
* couple fixes around group selection
* feat: support updating appState in updateScene API
* make `updateScene.data.appState` more type-safe
* restore `appState` when passing to `updateScene`
* fix
Co-authored-by: dwelle <luzar.david@gmail.com>
* fix: only hand cut/paste events inside excalidraw
* changelog
* check if excalidraw is active for copy event
* check if active element is part of excalidraw
* feat: dnt share library & attach to the excalidraw instance
* fix
* Add addToLibrary, resetLibrary and libraryItems in initialData
* remove comment
* handle errors & improve types
* remove resetLibrary and addToLibrary and add onLibraryChange prop
* set library cache to empty arrary on reset
* Add i18n for remove/add library
* Update src/locales/en.json
Co-authored-by: David Luzar <luzar.david@gmail.com>
* update docs
* Assign unique ID to
each excalidraw component and remove csrfToken from library as its not needed
* tweaks
Co-authored-by: David Luzar <luzar.david@gmail.com>
* update
* tweak
Co-authored-by: dwelle <luzar.david@gmail.com>
* fix: Bind keyboard events to excalidraw container
* fix cases around blurring
* fix modal rendering so keyboard shortcuts work on modal as well
* Revert "fix modal rendering so keyboard shortcuts work on modal as well"
This reverts commit 2c8ec6be8e.
* Attach keyboard event in react way so we need not handle portals separately (modals)
* dnt propagate esc event when modal shown
* focus the container when help dialog closed with shift+?
* focus the help icon when help dialog on close triggered
* move focusNearestTabbableParent to util
* rename util to focusNearestParent and remove outline from excal and modal
* Add prop bindKeyGlobally to decide if keyboard events should be binded to document and allow it in excal app, revert tests
* fix
* focus container after installing library, reset library and closing error dialog
* fix tests and create util to focus container
* Add excalidraw-container class to focus on the container
* pass focus container to library to focus current instance of excal
* update docs
* remove util as it wont be used anywhere
* fix propagation not being stopped for React keyboard handling
* tweak reamde
Co-authored-by: David Luzar <luzar.david@gmail.com>
* tweak changelog
* rename prop to handleKeyboardGlobally
Co-authored-by: dwelle <luzar.david@gmail.com>
* feat: Support hiding save, save as, clear & export
* Remove canvasActions from state & minor changes
* Rename prop to UIOptions & pass default value
* Make requested changes
* better type checking so that optional check not needed at every point
* remove optional checks
* Add few tests
* Add describe block for canvasActions & use snapshot tests
* Add support for hiding canvas background picker
* Take snapshot of canvasActions instead of the whole app
* Add support for hiding dark mode toggle
* Update README.md
* Rename table heading
* Update changelog
* Make requested changes
* Update test name
* tweaks
Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
* Remove width/height from the ".excalidraw" container so it will sized automatically.
* updated all ref calculation to ".excalidraw" instead of parent since now ".excalidraw" will get resized
* Remove props width/height as its not needed anymore.
* Resize handler is also not needed anymore.
* Position absolute canvas due to #3379 (comment)
* move css to style and remove one extra rerendering
* factor out mock logic for test
* set height, width so as to avoid unnecessary updates of regression snap
* better mock
* better type checking and omit width,height from getDefaultAppState and also restore
* revert
* default to window dimensions in constructor
* update docs
* update
* update
* tweaks
* feat: Add renderCustomStats prop to render extra stats & move storage and version to renderCustomStats
* expose Api to update toast message so single instance of toast is used
* rename to setToastMessage
* update docs
* feat: Add label for name field and use input when editable in export dialog
* fix
* review fix
* dnt allow to edit file name when view mode
* Update src/components/ProjectName.tsx
Co-authored-by: David Luzar <luzar.david@gmail.com>
Co-authored-by: David Luzar <luzar.david@gmail.com>
* Allow updating name on updateScene
* Revert "Allow updating name on updateScene"
This reverts commit 4e07a608d3.
* Make requested changes
* Make requested changes
* Remove customName from state
* Remove redundant if statement
* Add tests, update changelog and minor fixes
* remove eempty lines
* minor fixes
* no border and on hover no background change
* Give preference to name prop when initialData.appState.name is present and update specs
* minor fix
* Fix name input style in dark mode
Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
* feat: Expose the API to calculate offsets and remove offsetTop and offsetLeft props
* update
* fix tests
* fix
* update readme and changelog
* fix
* better
* support appearance when updating scene data
* works!
* whoops, missed a prop
* hide appearance button when prop is not set
* cleanup
* fix export + rename prop to theme
* rename to showThemeBtn, hide via react instead of css
* adapt to new state name
* add tests and css selector to target the dark mode toggle
* updated changelog and readme
* fix markdown rendering in readme
* pr feedback
* Use the web share target API
* Make requested changes
* Remove line
* Add application/json back
* Add application/vnd.excalidraw+json
* Add 'POST' check back
* Make requested changes
* Update src/appState.ts
Co-authored-by: Thomas Steiner <tomac@google.com>
* Update test
* Override initializeScene
* Use Excalidraw MIME type
* Minor fixes
* More MIME type tweaks
* More permissive file open
* Be overpermissive in file open
Co-authored-by: Thomas Steiner <tomac@google.com>
Co-authored-by: tomayac <steiner.thomas@gmail.com>
* fix: Position text editor absolute and fix the offsets so it doesn't remain fixed when container is scrolled
* update changelog
* Update src/packages/excalidraw/CHANGELOG.md
* fix: wrap excalidraw in position relative so that host need not add it explicitly to fix positioning when non zero offsets
* patch version
* Hide scrollbars on excalidraw container
* remove overflow hidden from index.html since its handled in excalidraw container
* review fix
* update changelog
* fix: Reduce the scroll debounce timeout to 100ms so offsets get updated faster when the container scrolled
fixes https://github.com/excalidraw/excalidraw/issues/3175
* update changelog
* update offsets only when if it changes
* up
* Update src/components/App.tsx
Co-authored-by: David Luzar <luzar.david@gmail.com>
* feat: Add support for scrollToCenter in initialData so host can control whether to scroll to center on mount
* fix
* update changelog and readme
* fix
* Scroll to center only for collab and shareable links in excalidraw app
* fix test
* update readme
* Update src/packages/excalidraw/README.md
* refactor: remove position fixed from excalidraw container, modal and stats
* remove unused css
* remove position fixed from toast and scroll to content
* Make excal interactable by fixing offsets and set popover as fixed since position needs to be calculate from viewport top
* Assign 200px less than height of Excalidraw to the selected shapes actions o UI doesn't overflow
* update changelog, readme and package.json
* fix: pass default value for grid mode / zen mode so it sets the value from initialData appState
fixes#2870
* change checked from boolean to be a function which recieves appState and returns boolean
* fix
* use clsx
Co-authored-by: dwelle <luzar.david@gmail.com>
* Remove copy & paste from context menu on desktop
* fix build
* Make requested changes
* More changes
* make into function
* update changelog
* fix tests
Co-authored-by: dwelle <luzar.david@gmail.com>
My last attempt removed the gesture handler altogether but broke macbooks. This one keeps it working on macbook but makes sure it zooms properly on iPhone and iPad.
If you start the gesture on the chrome, gesture is not defined and the zoom will be set to NaN and you will have to refresh.
Typescript was actually right and we shouldn't have overridden the bang ;)
Repro:
- On iPhone touch down on a shape, touch down on the chrome, start moving around
- See that the selection is off, but the zoom is not being modified like crazy.
https://user-images.githubusercontent.com/197597/102722206-6c182400-42b4-11eb-9865-6ae1cd0af9be.MP4
We were processing both the touch move and gesture on iOS which was first firing twice as many set state, but also caused issues:
- The gesture implementation didn't support zooming on the center
- Touching down on a circle and then on the bottom chrome would freak out because initialScale was null
Touching down on the menu still isn't perfect as it shifts the shape around but doesn't completly break the zoom
This was very annoying when you would zoom on mobile and the context menu would appear.
The problem was the following:
- You put a finger in, it creates a timeout
- You put a second finger in, it creates another timeout
- 300ms elapsed, which is not that much
- The context menu opens
- Now you move your fingers, which works, but the context menu is still open
The fix is to invalidate the context menu if a second finger is added even if the first one hasn't moved.
* Refactor: simplify linear element type
* Refactor: dedupe scrollbar handling
* First step towards binding - establish relationship and basic test for dragged lines
* Refactor: use zoom from appstate
* Refactor: generalize getElementAtPosition
* Only consider bindable elements in hit test
* Refactor: pull out pieces of hit test for reuse later
* Refactor: pull out diamond from hit test for reuse later
* Refactor: pull out text from hit test for reuse later
* Suggest binding when hovering
* Give shapes in regression test real size
* Give shapes in undo/redo test real size
* Keep bound element highlighted
* Show binding suggestion for multi-point elements
* Move binding to its on module with functions so that I can use it from actions, add support for binding end of multi-point elements
* Use Id instead of ID
* Improve boundary offset for non-squarish elements
* Fix localStorage for binding on linear elements
* Simplify dragging code and fix elements bound twice to the same shape
* Fix binding for rectangles
* Bind both ends at the end of the linear element creation, needed for focus points
* wip
* Refactor: Renames and reshapes for next commit
* Calculate and store focus points and gaps, but dont use them yet
* Focus points for rectangles
* Dont blow up when canceling linear element
* Stop suggesting binding when a non-compatible tool is selected
* Clean up collision code
* Using Geometric Algebra for hit tests
* Correct binding for all shapes
* Constant gap around polygon corners
* Fix rotation handling
* Generalize update and fix hit test for rotated elements
* Handle rotation realtime
* Handle scaling
* Remove vibration when moving bound and binding element together
* Handle simultenous scaling
* Allow binding and unbinding when editing linear elements
* Dont delete binding when the end point wasnt touched
* Bind on enter/escape when editing
* Support multiple suggested bindable elements in preparation for supporting linear elements dragging
* Update binding when moving linear elements
* Update binding when resizing linear elements
* Dont re-render UI on binding hints
* Update both ends when one is moved
* Use distance instead of focus point for binding
* Complicated approach for posterity, ignore this commit
* Revert the complicated approach
* Better focus point strategy, working for all shapes
* Update snapshots
* Dont break binding gap when mirroring shape
* Dont break binding gap when grid mode pushes it inside
* Dont bind draw elements
* Support alt duplication
* Fix alt duplication to
* Support cmd+D duplication
* All copy mechanisms are supported
* Allow binding shapes to arrows, having arrows created first
* Prevent arrows from disappearing for ellipses
* Better binding suggestion highlight for shapes
* Dont suggest second binding for simple elements when editing or moving them
* Dont steal already bound linear elements when moving shapes
* Fix highlighting diamonds and more precisely highlight other shapes
* Highlight linear element edges for binding
* Highlight text binding too
* Handle deletion
* Dont suggest second binding for simple linear elements when creating them
* Dont highlight bound element during creation
* Fix binding for rotated linear elements
* Fix collision check for ellipses
* Dont show suggested bindings for selected pairs
* Bind multi-point linear elements when the tool is switched - important for mobile
* Handle unbinding one of two bound edges correctly
* Rename boundElement in state to startBoundElement
* Dont double account for zoom when rendering binding highlight
* Fix rendering of edited linear element point handles
* Suggest binding when adding new point to a linear element
* Bind when adding a new point to a linear element and dont unbind when moving middle elements
* Handle deleting points
* Add cmd modifier key to disable binding
* Use state for enabling binding, fix not binding for linear elements during creation
* Drop support for binding lines, only arrows are bindable
* Reset binding mode on blur
* Fix not binding lines
* update simplifier distance to reflect zoom
The distance used in the iterative end-point fit algorithm to
determine if points can be removed no longer ignores the
zoom. As the zoom gets larger this distance will get smaller
and fewer points will be removed, thus making for finer grain
control over the drawing. As the zoom gets smaller the drawing
will get more coarse as more points are removed.
* remove the comment
Co-authored-by: John Dupuis <wasp7@Johns-MacBook-Pro.local>
Co-authored-by: Michal Srb <xixixao@seznam.cz>
This was an oversight to enable it for all the shapes. I don't believe that we want to be able to insert text on double click when drawing a rectangle for example. And it's definitely a broken experience when doing so for free draw.
Fixes part of #1935
* feat: calculate coords based on parent left and top so it renders correctly in host App
* fix text
* move offsets to state & fix bugs
* fix text jumping
* account for zoom in textWysiwyg & undo incorrect offsetting
Co-authored-by: dwelle <luzar.david@gmail.com>
* Refactor: use pointer down state for alt duplication flag
* Refactor: use pointer down state for drag state
* Refactor: simplify over scrollbars check
* Refactor: move pointer move handler out of pointer down handler
* Refactor: move pointer up handler out of pointer down handler
* Refactor: further simplify scrollbar check state in pointer down event
* Refactor: pull out initial pointer down state creation
* Refactor: introduce pointer down state to replace implicit closure state with an explicit object
* Refactor: use pointer down state for resize handle
* Refactor: use pointer down state for isResizing
* Refactor: use pointer down state for resizing offset
* Refactor: use pointer down state for hit element
* Refactor: move selection handling out of pointer down event handler
* Refactor: move text handling out of pointer down event handler
* Refactor: move linear tools handling out of pointer down event handler
* Refactor: move element creation out of pointer down handler
* Refactor: Move context menu touch device handling
* Refactor: Move more stuff out of pointer down
* Refactor: Move last coords into an object
* Refactor: Move scrollbar handling out of pointer down
* Refactor: simplify resizing in pointer down
* Refactor: further simplify resizing in pointer down
* Refactor: clarify clearing selection code
* Refactor: move out clearing selection from pointer down
* Refactor: further simplify deselection in pointer down
* Initial support for touch context menu
* Only deal with touch if it's available
* Fix touch checking
* Remove touch checking
* Added comments
* Combine onTouch with onPointer for mobile context menu support