diff --git a/package-lock.json b/package-lock.json index adb6448abe..d82ab7bf9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25712,18 +25712,6 @@ } } }, - "node_modules/use-prefers-color-scheme": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/use-prefers-color-scheme/-/use-prefers-color-scheme-1.1.3.tgz", - "integrity": "sha512-ZRgDfb5BFLum/Sud4SpZ+d1YcV+lRbsupw0qQ/rGy5kGrpE3KMUQgEQOKiQQSa4Wslex46n5fKFO+9FGMTosUQ==", - "engines": { - "node": ">=8", - "npm": ">=5" - }, - "peerDependencies": { - "react": ">= 16.8.0" - } - }, "node_modules/use-sidecar": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", @@ -27195,8 +27183,7 @@ "@mantine/utils": "^6.0.21", "react": "^18", "react-dom": "^18", - "react-icons": "^5.2.1", - "use-prefers-color-scheme": "^1.1.3" + "react-icons": "^5.2.1" }, "devDependencies": { "@types/react": "^18.0.25", @@ -27246,8 +27233,7 @@ "lodash.merge": "^4.6.2", "react": "^18", "react-dom": "^18", - "react-icons": "^5.2.1", - "use-prefers-color-scheme": "^1.1.3" + "react-icons": "^5.2.1" }, "devDependencies": { "@types/lodash.foreach": "^4.5.9", diff --git a/packages/mantine/package.json b/packages/mantine/package.json index c50e66891b..5f6b667699 100644 --- a/packages/mantine/package.json +++ b/packages/mantine/package.json @@ -58,8 +58,7 @@ "@mantine/utils": "^6.0.21", "react": "^18", "react-dom": "^18", - "react-icons": "^5.2.1", - "use-prefers-color-scheme": "^1.1.3" + "react-icons": "^5.2.1" }, "devDependencies": { "@types/react": "^18.0.25", diff --git a/packages/mantine/src/index.tsx b/packages/mantine/src/index.tsx index 2fc1bcb612..142a2db836 100644 --- a/packages/mantine/src/index.tsx +++ b/packages/mantine/src/index.tsx @@ -9,10 +9,10 @@ import { Components, ComponentsContext, useBlockNoteContext, + usePrefersColorScheme, } from "@blocknote/react"; import { MantineProvider } from "@mantine/core"; import { ComponentProps, useCallback } from "react"; -import { usePrefersColorScheme } from "use-prefers-color-scheme"; import { Theme, diff --git a/packages/react/package.json b/packages/react/package.json index 9a90d8b7bc..02f8630fbd 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -58,8 +58,7 @@ "lodash.merge": "^4.6.2", "react": "^18", "react-dom": "^18", - "react-icons": "^5.2.1", - "use-prefers-color-scheme": "^1.1.3" + "react-icons": "^5.2.1" }, "devDependencies": { "@types/lodash.foreach": "^4.5.9", diff --git a/packages/react/src/editor/BlockNoteView.tsx b/packages/react/src/editor/BlockNoteView.tsx index 215ba6fba6..d76d37240f 100644 --- a/packages/react/src/editor/BlockNoteView.tsx +++ b/packages/react/src/editor/BlockNoteView.tsx @@ -15,9 +15,9 @@ import React, { useMemo, useState, } from "react"; -import { usePrefersColorScheme } from "use-prefers-color-scheme"; import { useEditorChange } from "../hooks/useEditorChange"; import { useEditorSelectionChange } from "../hooks/useEditorSelectionChange"; +import { usePrefersColorScheme } from "../hooks/usePrefersColorScheme"; import { BlockNoteContext, useBlockNoteContext } from "./BlockNoteContext"; import { BlockNoteDefaultUI, diff --git a/packages/react/src/hooks/usePrefersColorScheme.ts b/packages/react/src/hooks/usePrefersColorScheme.ts new file mode 100644 index 0000000000..543231e262 --- /dev/null +++ b/packages/react/src/hooks/usePrefersColorScheme.ts @@ -0,0 +1,79 @@ +// This code is taken from the `use-prefers-color-scheme` repo: +// https://github.com/rfoel/use-prefers-color-scheme/blob/v1.0.0/src/index.ts +// The code is copied instead of being imported as the package seems to cause +// issues when used in a NextJS project. +import { useEffect, useState } from "react"; + +const darkQuery = window.matchMedia?.("(prefers-color-scheme: dark)"); + +const lightQuery = window.matchMedia?.("(prefers-color-scheme: light)"); + +export const usePrefersColorScheme = () => { + const isDark = darkQuery?.matches; + const isLight = lightQuery?.matches; + + const [preferredColorSchema, setPreferredColorSchema] = useState< + "dark" | "light" | "no-preference" + >(isDark ? "dark" : isLight ? "light" : "no-preference"); + + useEffect(() => { + if (isDark) { + setPreferredColorSchema("dark"); + } else if (isLight) { + setPreferredColorSchema("light"); + } else { + setPreferredColorSchema("no-preference"); + } + }, [isDark, isLight]); + + useEffect(() => { + if (typeof darkQuery?.addEventListener === "function") { + // In modern browsers MediaQueryList should subclass EventTarget + // https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList + + const darkListener = ({ matches }: MediaQueryListEvent) => + matches && setPreferredColorSchema("dark"); + const lightListener = ({ matches }: MediaQueryListEvent) => + matches && setPreferredColorSchema("light"); + + darkQuery?.addEventListener("change", darkListener); + lightQuery?.addEventListener("change", lightListener); + + return () => { + darkQuery?.removeEventListener("change", darkListener); + lightQuery?.removeEventListener("change", lightListener); + }; + } else { + // In some early implementations MediaQueryList existed, but did not + // subclass EventTarget + + // Closing over isDark here would cause it to not update when + // `darkQuery.matches` changes + const listener = () => + setPreferredColorSchema( + darkQuery.matches + ? "dark" + : lightQuery.matches + ? "light" + : "no-preference" + ); + + // This is two state updates if a user changes from dark to light, but + // both state updates will be consistent and should be batched by React, + // resulting in only one re-render + darkQuery?.addEventListener("change", listener); + lightQuery?.addEventListener("change", listener); + + return () => { + darkQuery?.removeEventListener("change", listener); + lightQuery?.removeEventListener("change", listener); + }; + } + }, []); + + if (typeof window.matchMedia !== "function") { + return preferredColorSchema; + } + + return preferredColorSchema; +}; diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 82372ce357..8f50414f25 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -74,6 +74,7 @@ export * from "./hooks/useEditorChange"; export * from "./hooks/useEditorContentOrSelectionChange"; export * from "./hooks/useEditorForceUpdate"; export * from "./hooks/useEditorSelectionChange"; +export * from "./hooks/usePrefersColorScheme"; export * from "./hooks/useSelectedBlocks"; export * from "./schema/ReactBlockSpec";