mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-01 04:50:27 +02:00
Allow control of Slate's event handler execution in custom event handler API (#4299)
Co-authored-by: Georg Berecz <gberecz@palantir.com> Co-authored-by: Claudéric Demers <clauderic.d@gmail.com>
This commit is contained in:
49
.changeset/override-event-handlers.md
Normal file
49
.changeset/override-event-handlers.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
---
|
||||||
|
'slate-react': minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Allow custom event handlers on Editable component to return boolean flag to specify whether the event can be treated as being handled.
|
||||||
|
|
||||||
|
By default, the `Editable` component comes with a set of event handlers that handle typical rich-text editing behaviors (for example, it implements its own `onCopy`, `onPaste`, `onDrop`, and `onKeyDown` handlers).
|
||||||
|
|
||||||
|
In some cases you may want to extend or override Slate's default behavior, which can be done by passing your own event handler(s) to the `Editable` component.
|
||||||
|
|
||||||
|
Your custom event handler can control whether or not Slate should execute its own event handling for a given event after your handler runs depending on the return value of your event handler as described below.
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import {Editable} from 'slate-react';
|
||||||
|
|
||||||
|
function MyEditor() {
|
||||||
|
const onClick = event => {
|
||||||
|
// Implement custom event logic...
|
||||||
|
|
||||||
|
// When no value is returned, Slate will execute its own event handler when
|
||||||
|
// neither isDefaultPrevented nor isPropagationStopped was set on the event
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDrop = event => {
|
||||||
|
// Implement custom event logic...
|
||||||
|
|
||||||
|
// No matter the state of the event, treat it as being handled by returning
|
||||||
|
// true here, Slate will skip its own event handler
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDragStart = event => {
|
||||||
|
// Implement custom event logic...
|
||||||
|
|
||||||
|
// No matter the status of the event, treat event as *not* being handled by
|
||||||
|
// returning false, Slate will exectue its own event handler afterward
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Editable
|
||||||
|
onClick={onClick}
|
||||||
|
onDrop={onDrop}
|
||||||
|
onDragStart={onDragStart}
|
||||||
|
{/*...*/}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
@@ -18,6 +18,52 @@ React components for rendering Slate editors
|
|||||||
|
|
||||||
The main Slate editor.
|
The main Slate editor.
|
||||||
|
|
||||||
|
#### Event Handling
|
||||||
|
|
||||||
|
By default, the `Editable` component comes with a set of event handlers that handle typical rich-text editing behaviors (for example, it implements its own `onCopy`, `onPaste`, `onDrop`, and `onKeyDown` handlers).
|
||||||
|
|
||||||
|
In some cases you may want to extend or override Slate's default behavior, which can be done by passing your own event handler(s) to the `Editable` component.
|
||||||
|
|
||||||
|
Your custom event handler can control whether or not Slate should execute its own event handling for a given event after your handler runs depending on the return value of your event handler as described below.
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import {Editable} from 'slate-react';
|
||||||
|
|
||||||
|
function MyEditor() {
|
||||||
|
const onClick = event => {
|
||||||
|
// Implement custom event logic...
|
||||||
|
|
||||||
|
// When no value is returned, Slate will execute its own event handler when
|
||||||
|
// neither isDefaultPrevented nor isPropagationStopped was set on the event
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDrop = event => {
|
||||||
|
// Implement custom event logic...
|
||||||
|
|
||||||
|
// No matter the state of the event, treat it as being handled by returning
|
||||||
|
// true here, Slate will skip its own event handler
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDragStart = event => {
|
||||||
|
// Implement custom event logic...
|
||||||
|
|
||||||
|
// No matter the status of the event, treat event as *not* being handled by
|
||||||
|
// returning false, Slate will exectue its own event handler afterward
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Editable
|
||||||
|
onClick={onClick}
|
||||||
|
onDrop={onDrop}
|
||||||
|
onDragStart={onDragStart}
|
||||||
|
{/*...*/}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### `DefaultElement(props: RenderElementProps)`
|
### `DefaultElement(props: RenderElementProps)`
|
||||||
|
|
||||||
The default element renderer.
|
The default element renderer.
|
||||||
|
@@ -1191,13 +1191,19 @@ export const isEventHandled = <
|
|||||||
EventType extends React.SyntheticEvent<unknown, unknown>
|
EventType extends React.SyntheticEvent<unknown, unknown>
|
||||||
>(
|
>(
|
||||||
event: EventType,
|
event: EventType,
|
||||||
handler?: (event: EventType) => void
|
handler?: (event: EventType) => void | boolean
|
||||||
) => {
|
) => {
|
||||||
if (!handler) {
|
if (!handler) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
// The custom event handler may return a boolean to specify whether the event
|
||||||
|
// shall be treated as being handled or not.
|
||||||
|
const shouldTreatEventAsHandled = handler(event)
|
||||||
|
|
||||||
|
if (shouldTreatEventAsHandled != null) {
|
||||||
|
return shouldTreatEventAsHandled
|
||||||
|
}
|
||||||
|
|
||||||
handler(event)
|
|
||||||
return event.isDefaultPrevented() || event.isPropagationStopped()
|
return event.isDefaultPrevented() || event.isPropagationStopped()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1207,12 +1213,19 @@ export const isEventHandled = <
|
|||||||
|
|
||||||
export const isDOMEventHandled = <E extends Event>(
|
export const isDOMEventHandled = <E extends Event>(
|
||||||
event: E,
|
event: E,
|
||||||
handler?: (event: E) => void
|
handler?: (event: E) => void | boolean
|
||||||
) => {
|
) => {
|
||||||
if (!handler) {
|
if (!handler) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
handler(event)
|
// The custom event handler may return a boolean to specify whether the event
|
||||||
|
// shall be treated as being handled or not.
|
||||||
|
const shouldTreatEventAsHandled = handler(event)
|
||||||
|
|
||||||
|
if (shouldTreatEventAsHandled != null) {
|
||||||
|
return shouldTreatEventAsHandled
|
||||||
|
}
|
||||||
|
|
||||||
return event.defaultPrevented
|
return event.defaultPrevented
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user