From 077b251ff77781ccc3283ba1c8b7cad20419fd9f Mon Sep 17 00:00:00 2001 From: Ou Date: Thu, 10 Oct 2024 21:32:13 +0800 Subject: [PATCH] pref: overlay scrollbar --- package.json | 1 + pnpm-lock.yaml | 3 + shared/data.ts | 4 +- src/components/common/overlay-scrollbar.tsx | 43 ++++++++++++ src/components/header.tsx | 2 +- src/components/section/card.tsx | 74 +++++++++------------ src/components/section/dnd.tsx | 6 +- src/components/section/index.tsx | 36 +++++----- src/routes/__root.tsx | 20 ++---- src/styles/globals.css | 4 +- uno.config.ts | 58 +--------------- 11 files changed, 113 insertions(+), 138 deletions(-) create mode 100644 src/components/common/overlay-scrollbar.tsx diff --git a/package.json b/package.json index ba6a8ca..2925222 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "consola": "^3.2.3", "dayjs": "1.11.13", "db0": "npm:@ourongxing/db0@latest", + "defu": "^6.1.4", "fast-xml-parser": "^4.5.0", "favicons-scraper": "^1.3.2", "framer-motion": "^11.11.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 561b4e4..dc70fd8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -56,6 +56,9 @@ importers: db0: specifier: npm:@ourongxing/db0@latest version: '@ourongxing/db0@0.1.5(libsql@0.4.5)' + defu: + specifier: ^6.1.4 + version: 6.1.4 fast-xml-parser: specifier: ^4.5.0 version: 4.5.0 diff --git a/shared/data.ts b/shared/data.ts index 29d0fca..b115db6 100644 --- a/shared/data.ts +++ b/shared/data.ts @@ -13,11 +13,11 @@ export const metadata: Metadata = { }, china: { name: "国内", - sources: ["toutiao", "zhihu", "cankaoxiaoxi"], + sources: ["toutiao", "zhihu"], }, world: { name: "国际", - sources: ["sputniknewscn", "zaobao"], + sources: ["sputniknewscn", "zaobao", "cankaoxiaoxi"], }, code: { name: "代码", diff --git a/src/components/common/overlay-scrollbar.tsx b/src/components/common/overlay-scrollbar.tsx new file mode 100644 index 0000000..838cfe5 --- /dev/null +++ b/src/components/common/overlay-scrollbar.tsx @@ -0,0 +1,43 @@ +import type { UseOverlayScrollbarsParams } from "overlayscrollbars-react" +import { useOverlayScrollbars } from "overlayscrollbars-react" +import type { HTMLProps, PropsWithChildren } from "react" +import { useEffect, useMemo, useRef } from "react" +import { defu } from "defu" + +type Props = HTMLProps & UseOverlayScrollbarsParams +const defaultScrollbarParams: UseOverlayScrollbarsParams = { + options: { + scrollbars: { + autoHide: "scroll", + }, + }, + defer: true, +} + +export function OverlayScrollbar({ children, options, events, defer, ...props }: PropsWithChildren) { + const ref = useRef(null) + const scrollbarParams = useMemo(() => defu >({ + options, + events, + defer, + }, defaultScrollbarParams), [options, events, defer]) + + const [initialize] = useOverlayScrollbars(scrollbarParams) + + useEffect(() => { + initialize({ + target: ref.current!, + cancel: { + // 如果浏览器原生滚动条是覆盖在元素上的,则取消初始化 + nativeScrollbarsOverlaid: true, + }, + }) + }, [initialize]) + + return ( +
+ {/* 只能有一个 element */} +
{children}
+
+ ) +} diff --git a/src/components/header.tsx b/src/components/header.tsx index 8c63534..a0c30d5 100644 --- a/src/components/header.tsx +++ b/src/components/header.tsx @@ -44,7 +44,7 @@ function RefreshButton() { export function Header() { return ( -
+
logo NewsNow diff --git a/src/components/section/card.tsx b/src/components/section/card.tsx index 137dc41..3d5b2d2 100644 --- a/src/components/section/card.tsx +++ b/src/components/section/card.tsx @@ -1,5 +1,4 @@ import type { NewsItem, SourceID, SourceInfo, SourceResponse } from "@shared/types" -import { OverlayScrollbarsComponent } from "overlayscrollbars-react" import type { UseQueryResult } from "@tanstack/react-query" import { useQuery } from "@tanstack/react-query" import clsx from "clsx" @@ -9,6 +8,7 @@ import { forwardRef, useCallback, useImperativeHandle, useRef } from "react" import { sources } from "@shared/sources" import type { SyntheticListenerMap } from "@dnd-kit/core/dist/hooks/utilities" import { ofetch } from "ofetch" +import { OverlayScrollbar } from "../common/overlay-scrollbar" import { focusSourcesAtom, refetchSourcesAtom } from "~/atoms" import { useRelativeTime } from "~/hooks/useRelativeTime" @@ -46,7 +46,8 @@ export const CardWrapper = forwardRef(({ id, isDragg
{id} e.currentTarget.hidden = true} /> @@ -111,16 +107,16 @@ export function NewsCard({ id, inView, isOverlay, handleListeners }: NewsCardPro {sources[id].name}
- {sources[id]?.title} +
+ {sources[id]?.title} +
- - - +
@@ -140,7 +136,6 @@ function UpdateTime({ query }: Query) { const updatedTime = useRelativeTime(query.data?.updatedTime ?? "") if (updatedTime) return {`${updatedTime}更新`} if (query.isError) return 获取失败 - return } function Num({ num }: { num: number }) { @@ -159,7 +154,7 @@ function ExtraInfo({ item }: { item: NewsItem }) { } if (item?.extra?.icon) { - return + return e.currentTarget.hidden = true} /> } if (relativeTime) { @@ -169,33 +164,26 @@ function ExtraInfo({ item }: { item: NewsItem }) { function NewsList({ query }: Query) { const items = query.data?.items - if (items?.length) { - return ( - <> - {items.slice(0, 20).map((item, i) => ( - - ))} - - ) - } return ( - <> - {Array.from({ length: 20 }).map((_, i) => i).map(i => ( -
+ + {items?.slice(0, 20).map((item, i) => ( + ))} - + ) } diff --git a/src/components/section/dnd.tsx b/src/components/section/dnd.tsx index 4f28040..4e77377 100644 --- a/src/components/section/dnd.tsx +++ b/src/components/section/dnd.tsx @@ -24,9 +24,9 @@ export function Dnd() { return ( -
- {sectionIds.map(section => ( - - {metadata[section].name} - - ))} -
+ <> +
+
+ {sectionIds.map(section => ( + + {metadata[section].name} + + ))} +
+
{ currentSectionID === id && } -
+ ) } diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index 26e1dce..20448aa 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -4,9 +4,9 @@ import { ReactQueryDevtools } from "@tanstack/react-query-devtools" import "~/styles/globals.css" import "virtual:uno.css" import type { QueryClient } from "@tanstack/react-query" -import { OverlayScrollbarsComponent } from "overlayscrollbars-react" import { Header } from "~/components/header" import { useOnReload } from "~/hooks/useOnReload" +import { OverlayScrollbar } from "~/components/common/overlay-scrollbar" export const Route = createRootRouteWithContext<{ queryClient: QueryClient @@ -25,23 +25,17 @@ function NotFoundComponent() { function RootComponent() { useOnReload() return ( - -
- + <> + +
+ + { import.meta.env.DEV && ( <> )} - + ) } diff --git a/src/styles/globals.css b/src/styles/globals.css index 2993dbf..0aa34d3 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -27,8 +27,8 @@ button:disabled { pointer-events: all !important; } -::-webkit-scrollbar { - width: 0px; +::-webkit-scrollbar-thumb { + border-radius: 8px; } /* https://github.com/KingSora/OverlayScrollbars/blob/master/packages/overlayscrollbars/src/styles/themes.scss */ diff --git a/uno.config.ts b/uno.config.ts index 6da12ab..ec8df68 100644 --- a/uno.config.ts +++ b/uno.config.ts @@ -31,36 +31,8 @@ export default defineConfig({ }, theme: { colors: { - neutral: { - 50: "#FCFCFD", - 100: "#F9FAFB", - 200: "#F2F4F7", - 300: "#E4E7EC", - 400: "#D0D5DD", - 500: "#98A2B3", - 600: "#667085", - 700: "#475467", - 800: "#344054", - 900: "#1D2939", - 950: "#101828", - }, - primary: { - DEFAULT: "#34B49B", - 50: "#EFFAF8", - 100: "#DBF5F0", - 200: "#B8EAE0", - 300: "#88DDCC", - 400: "#51CDB4", - 500: "#34B49B", - 600: "#2FA28B", - 700: "#298E7A", - 800: "#227766", - 900: "#185347", - 950: "#123F36", - }, - - warning: { + DEFAULT: "#FDB022", 50: "#FFFCF5", 100: "#FFFAEB", 200: "#FEF0C7", @@ -73,34 +45,6 @@ export default defineConfig({ 900: "#93370D", 950: "#7A2E0E", }, - - success: { - 50: "#F6FEF9", - 100: "#ECFDF3", - 200: "#D1FADF", - 300: "#A6F4C5", - 400: "#6CE9A6", - 500: "#32D583", - 600: "#12B76A", - 700: "#039855", - 800: "#027A48", - 900: "#05603A", - 950: "#054F31", - }, - - rose: { - 50: "#FFF5F6", - 100: "#FFF1F3", - 200: "#FFE4E8", - 300: "#FECDD6", - 400: "#FEA3B4", - 500: "#FD6F8E", - 600: "#F63D68", - 700: "#E31B54", - 800: "#C01048", - 900: "#A11043", - 950: "#89123E", - }, }, }, })