feat: Bind keyboard events to the current excalidraw container and add handleKeyboardGlobally prop to allow host to bind to document (#3430)

* 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>
This commit is contained in:
Aakansha Doshi 2021-04-13 01:29:25 +05:30 committed by GitHub
parent 153ca6a7c6
commit d126d04d17
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 537 additions and 409 deletions

View file

@ -15,6 +15,14 @@ Please add the latest change on the top under the correct section.
## Excalidraw API
### Features
- Bind the keyboard events to component and added a prop [`handleKeyboardGlobally`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#handleKeyboardGlobally) which if set to true will bind the keyboard events to document [#3430](https://github.com/excalidraw/excalidraw/pull/3430).
#### BREAKING CHNAGE
- Earlier keyboard events were bind to document but now its bind to Excalidraw component by default. So you will need to set [`handleKeyboardGlobally`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#handleKeyboardGlobally) to true if you want the previous behaviour (bind the keyboard events to document).
- Recompute offsets on `scroll` of the nearest scrollable container [#3408](https://github.com/excalidraw/excalidraw/pull/3408). This can be disabled by setting [`detectScroll`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#detectScroll) to `false`.
- Add `onPaste` prop to handle custom clipboard behaviours [#3420](https://github.com/excalidraw/excalidraw/pull/3420).

View file

@ -366,6 +366,7 @@ To view the full example visit :point_down:
| [`UIOptions`](#UIOptions) | <pre>{ canvasActions: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L208"> CanvasActions<a/> }</pre> | [DEFAULT UI OPTIONS](https://github.com/excalidraw/excalidraw/blob/master/src/constants.ts#L129) | To customise UI options. Currently we support customising [`canvas actions`](#canvasActions) |
| [`onPaste`](#onPaste) | <pre>(data: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/clipboard.ts#L17">ClipboardData</a>, event: ClipboardEvent &#124; null) => boolean</pre> | | Callback to be triggered if passed when the something is pasted in to the scene |
| [`detectScroll`](#detectScroll) | boolean | true | Indicates whether to update the offsets when nearest ancestor is scrolled. |
| [`handleKeyboardGlobally`](#handleKeyboardGlobally) | boolean | false | Indicates whether to bind the keyboard events to document. |
### Dimensions of Excalidraw
@ -592,6 +593,12 @@ Try out the [Demo](#Demo) to see it in action.
Indicates whether Excalidraw should listen for `scroll` event on the nearest scrollable container in the DOM tree and recompute the coordinates (e.g. to correctly handle the cursor) when the component's position changes. You can disable this when you either know this doesn't affect your app or you want to take care of it yourself (calling the [`refresh()`](#ref) method).
### handleKeyboardGlobally
Indicates whether to bind keyboard events to `document`. Disabled by default, meaning the keyboard events are bound to the Excalidraw component. This allows for multiple Excalidraw components to live on the same page, and ensures that Excalidraw keyboard handling doesn't collide with your app's (or the browser) when the component isn't focused.
Enable this if you want Excalidraw to handle keyboard even if the component isn't focused (e.g. a user is interacting with the navbar, sidebar, or similar).
### Extra API's
#### `getSceneVersion`

View file

@ -31,6 +31,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
renderCustomStats,
onPaste,
detectScroll = true,
handleKeyboardGlobally = false,
} = props;
const canvasActions = props.UIOptions?.canvasActions;
@ -82,6 +83,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
UIOptions={UIOptions}
onPaste={onPaste}
detectScroll={detectScroll}
handleKeyboardGlobally={handleKeyboardGlobally}
/>
</InitializeApp>
);