Skip to content

Commit

Permalink
feat(extension-events): add contextmenu and hover
Browse files Browse the repository at this point in the history
  • Loading branch information
ifiokjr committed Mar 14, 2021
1 parent ac37ea7 commit 0adccf9
Show file tree
Hide file tree
Showing 21 changed files with 164 additions and 56 deletions.
5 changes: 5 additions & 0 deletions .changeset/cold-melons-call.md
@@ -0,0 +1,5 @@
---
'@remirror/extension-events': patch
---

Prevent `hover` and `contextmenu` events from automatically calling `preventDefault()` when intercepted.
2 changes: 1 addition & 1 deletion .changeset/funny-bees-complain.md
Expand Up @@ -168,7 +168,7 @@ const Editor = () => {
stringHandler: '',
});

return <Remirror manager={manager} onChange={onChange} state={state}></Remirror>;
return <Remirror manager={manager} onChange={onChange} state={state} />;
};
```

Expand Down
5 changes: 5 additions & 0 deletions .changeset/large-dodos-watch.md
@@ -0,0 +1,5 @@
---
'@remirror/extension-code-block': minor
---

Add support for `wrap` option. This determines whether text in the code block will wrap at the end of the line.
5 changes: 5 additions & 0 deletions .changeset/loud-feet-arrive.md
@@ -0,0 +1,5 @@
---
'@remirror/extension-events': minor
---

Add type signatures for each of the `EventHandler` events to `EventsExtension`.
5 changes: 5 additions & 0 deletions .changeset/orange-ways-fix.md
@@ -0,0 +1,5 @@
---
'@remirror/react-hooks': major
---

Rename `useEvents` to `useEvent` which is a more accurate depiction of what the hook does.
5 changes: 5 additions & 0 deletions .changeset/strange-guests-visit.md
@@ -0,0 +1,5 @@
---
'@remirror/react-hooks': minor
---

Add `useContextMenu` and `useHover` hooks.
58 changes: 32 additions & 26 deletions packages/remirror__extension-events/src/events-extension.ts
Expand Up @@ -33,49 +33,49 @@ export interface EventsOptions {
*
* Return `true` to prevent any other prosemirror listeners from firing.
*/
blur?: Handler<(event: FocusEvent) => boolean | undefined | void>;
blur?: Handler<BlurEventHandler>;

/**
* Listens for focus events on the editor.
*
* Return `true` to prevent any other prosemirror listeners from firing.
*/
focus?: Handler<(event: FocusEvent) => boolean | undefined | void>;
focus?: Handler<FocusEventHandler>;

/**
* Listens to scroll events on the editor.
*
* Return `true` to prevent any other prosemirror listeners from firing.
*/
scroll?: Handler<(event: Event) => boolean | undefined | void>;
scroll?: Handler<ScrollEventHandler>;

/**
* Listens for mousedown events on the editor.
*
* Return `true` to prevent any other prosemirror listeners from firing.
*/
mousedown?: Handler<(event: MouseEvent) => boolean | undefined | void>;
mousedown?: Handler<MousedownEventHandler>;

/**
* Listens for mouseup events on the editor.
*
* Return `true` to prevent any other prosemirror listeners from firing.
*/
mouseup?: Handler<(event: MouseEvent) => boolean | undefined | void>;
mouseup?: Handler<MouseupEventHandler>;

/**
* Listens for mouseenter events on the editor.
*
* Return `true` to prevent any other prosemirror listeners from firing.
*/
mouseenter?: Handler<(event: MouseEvent) => boolean | undefined | void>;
mouseenter?: Handler<MouseenterEventHandler>;

/**
* Listens for mouseleave events on the editor.
*
* Return `true` to prevent any other prosemirror listeners from firing.
*/
mouseleave?: Handler<(event: MouseEvent) => boolean | undefined | void>;
mouseleave?: Handler<MouseleaveEventHandler>;

/**
* Listens for click events and provides information which may be useful in
Expand All @@ -101,15 +101,33 @@ export interface EventsOptions {
* Listen for contextmenu events and pass through props which detail the
* direct node and parent nodes which were activated.
*/
contextmenu?: Handler<(props: MouseEventHandlerProps) => boolean | undefined | void>;
contextmenu?: Handler<ContextMenuEventHandler>;

/**
* Listen for hover events and pass through details of every node and mark
* which was hovered at the current position.
*/
hover?: Handler<(props: HoverEventHandlerProps) => boolean | undefined | void>;
hover?: Handler<HoverEventHandler>;
}

export type BlurEventHandler = (event: FocusEvent) => boolean | undefined | void;
export type FocusEventHandler = (event: FocusEvent) => boolean | undefined | void;
export type ScrollEventHandler = (event: Event) => boolean | undefined | void;
export type MousedownEventHandler = (event: MouseEvent) => boolean | undefined | void;
export type MouseupEventHandler = (event: MouseEvent) => boolean | undefined | void;
export type MouseenterEventHandler = (event: MouseEvent) => boolean | undefined | void;
export type MouseleaveEventHandler = (event: MouseEvent) => boolean | undefined | void;
export type ClickEventHandler = (
event: MouseEvent,
state: ClickHandlerState,
) => boolean | undefined | void;
export type ClickMarkEventHandler = (
event: MouseEvent,
state: ClickMarkHandlerState,
) => boolean | undefined | void;
export type ContextMenuEventHandler = (props: MouseEventHandlerProps) => boolean | undefined | void;
export type HoverEventHandler = (props: HoverEventHandlerProps) => boolean | undefined | void;

/**
* The events extension which listens to events which occur within the
* remirror editor.
Expand Down Expand Up @@ -382,7 +400,7 @@ export class EventsExtension extends PlainExtension<EventsOptions> {
}
}

const isCaptured = fn({
return fn({
event,
view,
nodes,
Expand Down Expand Up @@ -414,12 +432,6 @@ export class EventsExtension extends PlainExtension<EventsOptions> {
return { ...nodeWithPos, isRoot: !!nodes[0]?.node.eq(nodeWithPos.node) };
},
});

if (isCaptured) {
event.preventDefault();
}

return isCaptured;
};
};
}
Expand Down Expand Up @@ -472,12 +484,9 @@ function createClickMarkState(props: CreateClickMarkStateProps): ClickMarkHandle
}

/**
* The click handler for events.
* @deprecated use [[`ClickEventHandler`]] instead.
*/
export type ClickHandler = (
event: MouseEvent,
clickState: ClickHandlerState,
) => boolean | undefined | void;
export type ClickHandler = ClickEventHandler;

export interface ClickMarkHandlerState extends BaseEventState {
/**
Expand All @@ -493,12 +502,9 @@ export interface ClickMarkHandlerState extends BaseEventState {
}

/**
* An event solely focused on clicks on marks.
* @deprecated use [[`ClickMarkEventHandler`]] instead.
*/
export type ClickMarkHandler = (
event: MouseEvent,
clickState: ClickMarkHandlerState,
) => boolean | undefined | void;
export type ClickMarkHandler = ClickMarkEventHandler;

/**
* The helpers passed into the `ClickHandler`.
Expand Down
11 changes: 11 additions & 0 deletions packages/remirror__extension-events/src/index.ts
@@ -1,11 +1,22 @@
export type {
BlurEventHandler,
ClickEventHandler,
ClickHandler,
ClickHandlerState,
ClickMarkEventHandler,
ClickMarkHandler,
ClickMarkHandlerState,
ContextMenuEventHandler,
CreateEventHandlers,
EventsOptions,
FocusEventHandler,
HoverEventHandler,
HoverEventHandlerProps,
MousedownEventHandler,
MouseenterEventHandler,
MouseEventHandlerProps,
MouseleaveEventHandler,
MouseupEventHandler,
ScrollEventHandler,
} from './events-extension';
export { EventsExtension } from './events-extension';
39 changes: 27 additions & 12 deletions packages/remirror__react-hooks/package.json
Expand Up @@ -19,6 +19,12 @@
},
"./package.json": "./package.json",
"./types/*": "./dist/declarations/src/*.d.ts",
"./use-context-menu": {
"import": "./use-context-menu/dist/remirror-react-hooks-use-context-menu.esm.js",
"require": "./use-context-menu/dist/remirror-react-hooks-use-context-menu.cjs.js",
"browser": "./use-context-menu/dist/remirror-react-hooks.browser.esm.js",
"default": "./use-context-menu/dist/remirror-react-hooks-use-context-menu.esm.js"
},
"./use-editor-focus": {
"import": "./use-editor-focus/dist/remirror-react-hooks-use-editor-focus.esm.js",
"require": "./use-editor-focus/dist/remirror-react-hooks-use-editor-focus.cjs.js",
Expand All @@ -33,12 +39,11 @@
"types": "./use-emoji/dist/remirror-react-hooks-use-emoji.cjs.d.ts",
"default": "./use-emoji/dist/remirror-react-hooks-use-emoji.esm.js"
},
"./use-events": {
"import": "./use-events/dist/remirror-react-hooks-use-events.esm.js",
"require": "./use-events/dist/remirror-react-hooks-use-events.cjs.js",
"browser": "./use-events/dist/remirror-react-hooks.browser.esm.js",
"types": "./use-events/dist/remirror-react-hooks-use-events.cjs.d.ts",
"default": "./use-events/dist/remirror-react-hooks-use-events.esm.js"
"./use-event": {
"import": "./use-event/dist/remirror-react-hooks-use-event.esm.js",
"require": "./use-event/dist/remirror-react-hooks-use-event.cjs.js",
"browser": "./use-event/dist/remirror-react-hooks.browser.esm.js",
"default": "./use-event/dist/remirror-react-hooks-use-event.esm.js"
},
"./use-history": {
"import": "./use-history/dist/remirror-react-hooks-use-history.esm.js",
Expand All @@ -47,6 +52,12 @@
"types": "./use-history/dist/remirror-react-hooks-use-history.cjs.d.ts",
"default": "./use-history/dist/remirror-react-hooks-use-history.esm.js"
},
"./use-hover": {
"import": "./use-hover/dist/remirror-react-hooks-use-hover.esm.js",
"require": "./use-hover/dist/remirror-react-hooks-use-hover.cjs.js",
"browser": "./use-hover/dist/remirror-react-hooks.browser.esm.js",
"default": "./use-hover/dist/remirror-react-hooks-use-hover.esm.js"
},
"./use-keymap": {
"import": "./use-keymap/dist/remirror-react-hooks-use-keymap.esm.js",
"require": "./use-keymap/dist/remirror-react-hooks-use-keymap.cjs.js",
Expand Down Expand Up @@ -111,10 +122,12 @@
"types": "dist/remirror-react-hooks.cjs.d.ts",
"files": [
"dist",
"use-context-menu",
"use-editor-focus",
"use-emoji",
"use-events",
"use-event",
"use-history",
"use-hover",
"use-keymap",
"use-keymaps",
"use-mention-atom",
Expand All @@ -137,18 +150,18 @@
"@remirror/react-core": "0.0.0",
"@remirror/react-utils": "1.0.0-next.60",
"multishift": "1.0.0-next.60",
"type-fest": "^0.21.2",
"type-fest": "^0.21.3",
"use-isomorphic-layout-effect": "^1.1.1",
"use-previous": "^1.1.0"
},
"devDependencies": {
"@remirror/pm": "1.0.0-next.60",
"@remirror/react": "1.0.0-next.60",
"@types/react": "^17.0.1",
"@types/react-dom": "^17.0.0",
"@types/react": "^17.0.2",
"@types/react-dom": "^17.0.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"svgmoji": "^3.0.0"
"svgmoji": "^3.1.0"
},
"peerDependencies": {
"@remirror/pm": "1.0.0-next.60",
Expand Down Expand Up @@ -180,10 +193,12 @@
"preconstruct": {
"entrypoints": [
"index.ts",
"use-context-menu.ts",
"use-editor-focus.ts",
"use-emoji.ts",
"use-events.ts",
"use-event.ts",
"use-history.ts",
"use-hover.ts",
"use-keymap.ts",
"use-keymaps.ts",
"use-mention-atom.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/remirror__react-hooks/src/index.ts
@@ -1,7 +1,7 @@
export * from './react-hook-utils';
export * from './use-editor-focus';
export * from './use-emoji';
export * from './use-events';
export * from './use-event';
export * from './use-history';
export * from './use-keymap';
export * from './use-keymaps';
Expand Down
14 changes: 14 additions & 0 deletions packages/remirror__react-hooks/src/use-context-menu.ts
@@ -0,0 +1,14 @@
import { ContextMenuEventHandler } from '@remirror/extension-events';

import { useEvent } from './use-event';

/**
* A hook which listens to context menu events.
*
* In order to fully override the context menu events when they occur in the
* editor make sure to call `event.preventDefault()` this will allow you to
* replace the default context menu with your own version.
*/
export function useContextMenu(handler: ContextMenuEventHandler): void {
useEvent('contextmenu', handler);
}
6 changes: 3 additions & 3 deletions packages/remirror__react-hooks/src/use-editor-focus.ts
Expand Up @@ -2,7 +2,7 @@ import { useCallback, useState } from 'react';
import type { FocusType } from '@remirror/core';
import { useRemirrorContext } from '@remirror/react-core';

import { useEvents } from './use-events';
import { useEvent } from './use-event';

export interface UseEditorFocusProps {
/**
Expand Down Expand Up @@ -38,7 +38,7 @@ export function useEditorFocus(
const [isFocused, setIsFocused] = useState(() => view.hasFocus());

// Listen to blur events and set focused to false in those instances.
useEvents(
useEvent(
'blur',
useCallback(
(_: FocusEvent) => {
Expand All @@ -64,7 +64,7 @@ export function useEditorFocus(
);

// Listen to focus events and set focused to true in those instances.
useEvents(
useEvent(
'focus',
useCallback(
(_: FocusEvent) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/remirror__react-hooks/src/use-emoji.ts
@@ -1,5 +1,5 @@
import { useCallback, useMemo, useState } from 'react';
import { isEmptyArray } from '@remirror/core';
import { isEmptyArray, take } from '@remirror/core';
import {
EmojiExtension,
EmojiSuggestHandler,
Expand Down Expand Up @@ -107,7 +107,7 @@ export function useEmoji(props: UseEmojiProps = {}): UseEmojiReturn {
if (change) {
setIndex(0);
setState({
list: moji.search(query).map((emoji) => ({ ...emoji, url: moji.url(emoji) })),
list: take(moji.search(query), 20).map((emoji) => ({ ...emoji, url: moji.url(emoji) })),
apply: (code) => {
setState(null);
return apply(code);
Expand Down
Expand Up @@ -5,9 +5,14 @@ import { useExtension } from '@remirror/react-core';
/**
* A hook for subscribing to events from the editor.
*/
export function useEvents<Key extends StringKey<GetHandler<EventsOptions>>>(
export function useEvent<Key extends StringKey<GetHandler<EventsOptions>>>(
event: Key,
handler: GetHandler<EventsOptions>[Key],
): void {
useExtension(EventsExtension, ({ addHandler }) => addHandler(event, handler), [event, handler]);
}

/**
* @deprecated prefer `useEvent`
*/
export const useEvents = useEvent;
3 changes: 2 additions & 1 deletion packages/remirror__react-hooks/src/use-history.ts
Expand Up @@ -3,7 +3,8 @@ import { HistoryExtension, HistoryOptions } from '@remirror/extension-history';
import { useExtension } from '@remirror/react-core';

/**
* A hook for to the undo and redo events from the ProseMirror history extension.
* A hook which is called every time an undo or redo event is triggered from
* within the ProseMirror history extension.
*/
export function useHistory<Key extends StringKey<GetHandler<HistoryOptions>>>(
event: Key,
Expand Down

0 comments on commit 0adccf9

Please sign in to comment.