diff --git a/package-lock.json b/package-lock.json
index 38a2fb88..c01c94a7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -86,7 +86,6 @@
"react-icons": "4.7.1",
"react-markdown": "8.0.5",
"react-syntax-highlighter": "15.5.0",
- "react-use-event-hook": "0.9.3",
"rehype-raw": "6.1.1",
"remark-gfm": "3.0.1",
"rimraf": "3.0.2",
@@ -30399,15 +30398,6 @@
"url": "https://github.com/sponsors/wooorm"
}
},
- "node_modules/react-use-event-hook": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/react-use-event-hook/-/react-use-event-hook-0.9.3.tgz",
- "integrity": "sha512-8edWglTZ9Z5kfl31EuRjr4MDkTcEczHvrbo2EG1WVrX/a1B2sP3S9RCXjtSwrEnYRw29ldErlvDQNbTOxHNcmQ==",
- "dev": true,
- "peerDependencies": {
- "react": ">=16.8.0"
- }
- },
"node_modules/read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -59889,13 +59879,6 @@
}
}
},
- "react-use-event-hook": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/react-use-event-hook/-/react-use-event-hook-0.9.3.tgz",
- "integrity": "sha512-8edWglTZ9Z5kfl31EuRjr4MDkTcEczHvrbo2EG1WVrX/a1B2sP3S9RCXjtSwrEnYRw29ldErlvDQNbTOxHNcmQ==",
- "dev": true,
- "requires": {}
- },
"read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
diff --git a/package.json b/package.json
index ea09850c..b105ce8d 100644
--- a/package.json
+++ b/package.json
@@ -123,7 +123,6 @@
"react-icons": "4.7.1",
"react-markdown": "8.0.5",
"react-syntax-highlighter": "15.5.0",
- "react-use-event-hook": "0.9.3",
"rehype-raw": "6.1.1",
"remark-gfm": "3.0.1",
"rimraf": "3.0.2",
diff --git a/stories/documentation/tips-and-tricks/performance.md b/stories/documentation/tips-and-tricks/performance.md
index 0abb4893..3d0bbb6f 100644
--- a/stories/documentation/tips-and-tricks/performance.md
+++ b/stories/documentation/tips-and-tricks/performance.md
@@ -35,5 +35,3 @@ function PlainTextEditorContainer({ content }) {
return
}
```
-
-The same is true for event handler properties, such as the `onUpdate`, `onTransaction`, and all others. For these, you may consider wrapping them with `useEvent` from the third-party [`react-use-event-hook`](https://github.com/scottrippey/react-use-event-hook) package, which keeps the callback reference more stable than `useCallback` while invoking the callback with always up-to-date properties and state. Please refer to [Usage → Helpers](/?path=/docs/documentation-usage-helpers--page) for a `useEvent` example.
diff --git a/stories/documentation/usage/helpers.md b/stories/documentation/usage/helpers.md
index b3f0247d..0b83a99e 100644
--- a/stories/documentation/usage/helpers.md
+++ b/stories/documentation/usage/helpers.md
@@ -7,8 +7,7 @@ Passing down a `ref` to the `TypistEditor` component gives us access to some hel
- `getAllNodesAttributesByType(nodeType)`: Returns the attributes of a given node type for all the nodes in the editor document.
```tsx
-import { useRef } from 'react'
-import { useEvent } from 'react-use-event-hook'
+import { useCallback, useRef } from 'react'
import { TypistEditor, RichTextKit } from '@doist/typist'
@@ -17,9 +16,9 @@ import type { TypistEditorRef } from '@doist/typist'
function TypistEditorContainer({ content }) {
const typistEditorRef = useRef(null)
- const handleUpdate = useEvent(function handleUpdate() {
+ const handleUpdate = useCallback(function handleUpdate() {
console.log(typistEditorRef.current?.getMarkdown() || '')
- })
+ }, [])
return (
{
+ const handleUpdate = useCallback((props: UpdateProps) => {
setMarkdownOutput(props.getMarkdown())
- })
+ }, [])
useEffect(
function updateMarkdownOutputOnContentControlChange() {
diff --git a/stories/typist-editor/decorators/typist-editor-decorator/typist-editor-toolbar.tsx b/stories/typist-editor/decorators/typist-editor-decorator/typist-editor-toolbar.tsx
index eddba9a4..80400fae 100644
--- a/stories/typist-editor/decorators/typist-editor-decorator/typist-editor-toolbar.tsx
+++ b/stories/typist-editor/decorators/typist-editor-decorator/typist-editor-toolbar.tsx
@@ -1,4 +1,4 @@
-import { useEffect } from 'react'
+import { useCallback, useEffect } from 'react'
import {
RiArrowGoBackLine,
RiArrowGoForwardLine,
@@ -25,7 +25,6 @@ import {
RiStrikethrough,
RiTextWrap,
} from 'react-icons/ri'
-import { useEvent } from 'react-use-event-hook'
import { Box, Button } from '@doist/reactist'
@@ -61,7 +60,7 @@ function TypistEditorToolbar({ editor }: TypistEditorToolbarProps) {
[editor, forceRerender],
)
- const handleLinkButtonClick = useEvent(() => {
+ const handleLinkButtonClick = useCallback(() => {
const previousUrl = String(editor.getAttributes('link').href || '')
const newUrl = window.prompt('Link URL', previousUrl)
@@ -71,9 +70,9 @@ function TypistEditorToolbar({ editor }: TypistEditorToolbarProps) {
}
editor.chain().focus().extendMarkRange('link').setLink({ href: newUrl }).run()
- })
+ }, [editor])
- const handleImageButtonClick = useEvent(() => {
+ const handleImageButtonClick = useCallback(() => {
const newUrl = window.prompt('Image URL')
if (newUrl === null) {
@@ -82,7 +81,7 @@ function TypistEditorToolbar({ editor }: TypistEditorToolbarProps) {
}
editor.chain().focus().insertImage({ src: newUrl }).run()
- })
+ }, [editor])
return (
({
const areSuggestionsLoading = items.length === 1 && 'isLoading' in items[0]
const areSuggestionsEmpty = items.length === 0
- const handleItemSelect = useEvent((index: number) => {
- const item = items[index]
+ const handleItemSelect = useCallback(
+ (index: number) => {
+ const item = items[index]
- if (item) {
- onItemSelect(item)
- }
- })
+ if (item) {
+ onItemSelect(item)
+ }
+ },
+ [items, onItemSelect],
+ )
useEffect(
function scrollSelectedItemIntoView() {
diff --git a/stories/typist-editor/plain-text-functions.stories.tsx b/stories/typist-editor/plain-text-functions.stories.tsx
index 0448634b..11f5ce32 100644
--- a/stories/typist-editor/plain-text-functions.stories.tsx
+++ b/stories/typist-editor/plain-text-functions.stories.tsx
@@ -1,5 +1,4 @@
-import { useRef } from 'react'
-import { useEvent } from 'react-use-event-hook'
+import { useCallback, useRef } from 'react'
import { Button } from '@doist/reactist'
@@ -29,18 +28,18 @@ export const Commands: ComponentStoryObj = {
(Story, context) => {
const typistEditorRef = useRef(null)
- const handleExtendWordRangeClick = useEvent(() => {
+ const handleExtendWordRangeClick = useCallback(() => {
typistEditorRef.current?.getEditor().chain().focus().extendWordRange().run()
- })
+ }, [])
- const handleInsertMarkdownContentClick = useEvent(() => {
+ const handleInsertMarkdownContentClick = useCallback(() => {
typistEditorRef.current
?.getEditor()
.chain()
.focus()
.insertMarkdownContent(MARKDOWN_PLACEHOLDER)
.run()
- })
+ }, [])
return (
= {
(Story, context) => {
const typistEditorRef = useRef(null)
- const handleGetEditorClick = useEvent(() => {
+ const handleGetEditorClick = useCallback(() => {
action('getEditor')(typistEditorRef.current?.getEditor())
- })
+ }, [])
- const handleGetMarkdownClick = useEvent(() => {
+ const handleGetMarkdownClick = useCallback(() => {
action('getMarkdown')(typistEditorRef.current?.getMarkdown() || '')
- })
+ }, [])
- const handleGetAllNodesAttributesByTypeClick = useEvent(() => {
+ const handleGetAllNodesAttributesByTypeClick = useCallback(() => {
action('getAllNodesAttributesByType')(
typistEditorRef.current?.getAllNodesAttributesByType('mentionSuggestion'),
)
- })
+ }, [])
return (
= {
},
decorators: [
(Story, context) => {
- const handleKeyDown = useEvent((event: KeyboardEvent, view: EditorView) => {
+ const handleKeyDown = useCallback((event: KeyboardEvent, view: EditorView) => {
if (event.key === 'Enter') {
action('onEnterPressed')({
event,
@@ -65,7 +65,7 @@ export const Singleline: ComponentStoryObj = {
})
return true
}
- })
+ }, [])
return (
= {
(Story, context) => {
const typistEditorRef = useRef(null)
- const handleExtendWordRangeClick = useEvent(() => {
+ const handleExtendWordRangeClick = useCallback(() => {
typistEditorRef.current?.getEditor().chain().focus().extendWordRange().run()
- })
+ }, [])
- const handleInsertMarkdownContentClick = useEvent(() => {
+ const handleInsertMarkdownContentClick = useCallback(() => {
typistEditorRef.current
?.getEditor()
.chain()
.focus()
.insertMarkdownContent(MARKDOWN_PLACEHOLDER)
.run()
- })
+ }, [])
return (
= {
(Story, context) => {
const typistEditorRef = useRef(null)
- const handleGetEditorClick = useEvent(() => {
+ const handleGetEditorClick = useCallback(() => {
action('getEditor')(typistEditorRef.current?.getEditor())
- })
+ }, [])
- const handleGetMarkdownClick = useEvent(() => {
+ const handleGetMarkdownClick = useCallback(() => {
action('getMarkdown')(typistEditorRef.current?.getMarkdown() || '')
- })
+ }, [])
- const handleGetAllNodesAttributesByTypeClick = useEvent(() => {
+ const handleGetAllNodesAttributesByTypeClick = useCallback(() => {
action('getAllNodesAttributesByType')(
typistEditorRef.current?.getAllNodesAttributesByType('mentionSuggestion'),
)
- })
+ }, [])
return (
= {
[imageAttachmentsProgress],
)
- const handleImageFilePaste = useEvent((file: File) => {
+ const handleImageFilePaste = useCallback((file: File) => {
const attachmentId = Math.random().toString(16).slice(2, 10)
setImageAttachmentsProgress((prevState) => ({ ...prevState, [attachmentId]: 0 }))
@@ -107,7 +106,7 @@ export const Default: ComponentStoryObj = {
}
fileReader.readAsDataURL(file)
- })
+ }, [])
const extensions = useMemo(
function configureExtensions() {
@@ -162,7 +161,7 @@ export const Singleline: ComponentStoryObj = {
},
decorators: [
(Story, context) => {
- const handleKeyDown = useEvent((event: KeyboardEvent, view: EditorView) => {
+ const handleKeyDown = useCallback((event: KeyboardEvent, view: EditorView) => {
if (event.key === 'Enter') {
action('onEnterPressed')({
event,
@@ -170,7 +169,7 @@ export const Singleline: ComponentStoryObj = {
})
return true
}
- })
+ }, [])
return (