diff --git a/apps/renderer/src/modules/editor/css-editor.tsx b/apps/renderer/src/modules/editor/css-editor.tsx index 395dbce9c..a12f9e484 100644 --- a/apps/renderer/src/modules/editor/css-editor.tsx +++ b/apps/renderer/src/modules/editor/css-editor.tsx @@ -1,4 +1,4 @@ -import { useIsDark } from "@follow/hooks" +import { useInputComposition, useIsDark } from "@follow/hooks" import { nextFrame } from "@follow/utils/dom" import { cn } from "@follow/utils/utils" import { createPlainShiki } from "plain-shiki" @@ -44,30 +44,45 @@ export const CSSEditor: Component<{ } return () => dispose?.() }, [isDark]) + const props = useInputComposition({ + onKeyDown: (e) => { + if (e.key === "Escape") { + e.preventDefault() + } + if (e.key === "Tab") { + e.preventDefault() + const selection = window.getSelection() + if (selection && selection.rangeCount > 0) { + const range = selection.getRangeAt(0) + const tabNode = document.createTextNode("\u00A0\u00A0\u00A0\u00A0") // Using four non-breaking spaces as a tab + range.insertNode(tabNode) + range.setStartAfter(tabNode) + range.setEndAfter(tabNode) + selection.removeAllRanges() + selection.addRange(range) + } + } + nextFrame(() => { + onChange(ref.current?.textContent ?? "") + }) + }, + }) return (
{ - if (e.key === "Tab") { - e.preventDefault() - const selection = window.getSelection() - if (selection && selection.rangeCount > 0) { - const range = selection.getRangeAt(0) - const tabNode = document.createTextNode("\u00A0\u00A0\u00A0\u00A0") // Using four non-breaking spaces as a tab - range.insertNode(tabNode) - range.setStartAfter(tabNode) - range.setEndAfter(tabNode) - selection.removeAllRanges() - selection.addRange(range) - } - } - nextFrame(() => { - onChange(ref.current?.textContent ?? "") - }) - }} + {...props} /> ) } diff --git a/apps/renderer/src/modules/settings/tabs/apperance.tsx b/apps/renderer/src/modules/settings/tabs/apperance.tsx index 53d29c8da..cfd923c8f 100644 --- a/apps/renderer/src/modules/settings/tabs/apperance.tsx +++ b/apps/renderer/src/modules/settings/tabs/apperance.tsx @@ -1,4 +1,5 @@ import { Button } from "@follow/components/ui/button/index.js" +import { LoadingCircle } from "@follow/components/ui/loading/index.js" import { Select, SelectContent, @@ -10,7 +11,7 @@ import { useIsDark, useThemeAtomValue } from "@follow/hooks" import { IN_ELECTRON } from "@follow/shared/constants" import { getOS } from "@follow/utils/utils" import { useForceUpdate } from "framer-motion" -import { useEffect, useRef } from "react" +import { lazy, Suspense, useEffect, useRef } from "react" import { useTranslation } from "react-i18next" import { bundledThemesInfo } from "shiki/themes" @@ -26,7 +27,6 @@ import { useCurrentModal, useModalStack } from "~/components/ui/modal/stacked/ho import { isElectronBuild } from "~/constants" import { useSetTheme } from "~/hooks/common" -import { CSSEditor } from "../../editor/css-editor" import { SETTING_MODAL_ID } from "../constants" import { SettingActionItem, @@ -330,6 +330,9 @@ const CustomCSS = () => { ) } +const LazyCSSEditor = lazy(() => + import("../../editor/css-editor").then((m) => ({ default: m.CSSEditor })), +) const CustomCSSModal = () => { const initialCSS = useRef(getUISettings().customCSS) @@ -350,7 +353,7 @@ const CustomCSSModal = () => { return () => { setUISetting("modalOverlay", prevOverlay) - modal.style.display = "block" + modal.style.display = "" } }, []) const [forceUpdate, key] = useForceUpdate() @@ -365,14 +368,22 @@ const CustomCSSModal = () => { dismiss() }} > - { - setUISetting("customCSS", value) - }} - /> + + +
+ } + > + { + setUISetting("customCSS", value) + }} + /> +