feat: add overlay scrollbar

This commit is contained in:
Ou 2024-10-02 11:01:02 +08:00
parent 5c94fa2a19
commit 9859049a22
6 changed files with 69 additions and 17 deletions

View File

@ -27,6 +27,8 @@
"h3": "^1.12.0",
"jotai": "^2.10.0",
"node-fetch": "^3.3.2",
"overlayscrollbars": "^2.10.0",
"overlayscrollbars-react": "^0.5.6",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-intersection-observer": "^9.13.1",

22
pnpm-lock.yaml generated
View File

@ -47,6 +47,12 @@ importers:
node-fetch:
specifier: ^3.3.2
version: 3.3.2
overlayscrollbars:
specifier: ^2.10.0
version: 2.10.0
overlayscrollbars-react:
specifier: ^0.5.6
version: 0.5.6(overlayscrollbars@2.10.0)(react@18.3.1)
react:
specifier: ^18.3.1
version: 18.3.1
@ -3291,6 +3297,15 @@ packages:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
engines: {node: '>= 0.8.0'}
overlayscrollbars-react@0.5.6:
resolution: {integrity: sha512-E5To04bL5brn9GVCZ36SnfGanxa2I2MDkWoa4Cjo5wol7l+diAgi4DBc983V7l2nOk/OLJ6Feg4kySspQEGDBw==}
peerDependencies:
overlayscrollbars: ^2.0.0
react: '>=16.8.0'
overlayscrollbars@2.10.0:
resolution: {integrity: sha512-diNMeEafWTE0A4GJfwRpdBp2rE/BEvrhptBdBcDu8/UeytWcdCy9Td8tZWnztJeJ26f8/uHCWfPnPUC/dtgJdw==}
p-limit@2.3.0:
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
engines: {node: '>=6'}
@ -7595,6 +7610,13 @@ snapshots:
type-check: 0.4.0
word-wrap: 1.2.5
overlayscrollbars-react@0.5.6(overlayscrollbars@2.10.0)(react@18.3.1):
dependencies:
overlayscrollbars: 2.10.0
react: 18.3.1
overlayscrollbars@2.10.0: {}
p-limit@2.3.0:
dependencies:
p-try: 2.2.0

View File

@ -1,4 +1,5 @@
import type { SourceID, SourceInfo } from "@shared/types"
import { OverlayScrollbarsComponent } from "overlayscrollbars-react"
import type { UseQueryResult } from "@tanstack/react-query"
import { useQuery } from "@tanstack/react-query"
import { relativeTime } from "@shared/utils"
@ -44,7 +45,7 @@ export const CardWrapper = forwardRef<HTMLDivElement, ItemsProps>(({ id, isDragg
<div
ref={ref}
className={clsx(
"flex flex-col bg-base border rounded-md px-2 h-500px",
"flex flex-col bg-base border rounded-md h-500px",
isDragged && "op-50",
isOverlay ? "bg-glass" : "",
)}
@ -92,7 +93,14 @@ export function NewsCard({ id, inView, isOverlay, handleListeners }: NewsCardPro
return (
<>
<div {...handleListeners} className={clsx("flex justify-between py-2 items-center", handleListeners && "cursor-grab", isOverlay && "cursor-grabbing")}>
<div
{...handleListeners}
className={clsx([
"flex justify-between p-2 items-center",
handleListeners && "cursor-grab",
isOverlay && "cursor-grabbing",
])}
>
<div className="flex items-center gap-2">
<img src={`/icons/${id}.png`} className="w-4 h-4 rounded" alt={id} onError={e => e.currentTarget.hidden = true} />
<span className="text-md font-bold">
@ -101,10 +109,15 @@ export function NewsCard({ id, inView, isOverlay, handleListeners }: NewsCardPro
</div>
<SubTitle query={query} />
</div>
<div className="overflow-auto h-full">
<OverlayScrollbarsComponent
defer
className="h-full pl-2 pr-3 mr-1"
element="div"
options={{ scrollbars: { autoHide: "scroll" } }}
>
<NewsList query={query} />
</div>
<div className="py-2 flex items-center justify-between">
</OverlayScrollbarsComponent>
<div className="p-2 flex items-center justify-between">
<UpdateTime query={query} />
<div className="flex gap-1">
<button

View File

@ -1,4 +1,4 @@
import { useEffect } from "react"
import { useEffect, useMemo } from "react"
import { useLocalStorage, useMedia } from "react-use"
export declare type ColorScheme = "dark" | "light" | "auto"
@ -6,7 +6,7 @@ export declare type ColorScheme = "dark" | "light" | "auto"
export function useDark(key = "color-scheme", defaultColorScheme: ColorScheme = "auto") {
const [colorScheme, setColorScheme] = useLocalStorage(key, defaultColorScheme)
const prefersDarkMode = useMedia("(prefers-color-scheme: dark)")
const isDark = colorScheme === "auto" ? prefersDarkMode : colorScheme === "dark"
const isDark = useMemo(() => colorScheme === "auto" ? prefersDarkMode : colorScheme === "dark", [colorScheme, prefersDarkMode])
useEffect(() => {
document.documentElement.classList.toggle("dark", isDark)

View File

@ -2,9 +2,9 @@ import { Outlet, createRootRouteWithContext } from "@tanstack/react-router"
import { TanStackRouterDevtools } from "@tanstack/router-devtools"
import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
import "~/styles/globals.css"
import "@unocss/reset/tailwind.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"
@ -12,23 +12,24 @@ export const Route = createRootRouteWithContext<{
queryClient: QueryClient
}>()({
component: RootComponent,
notFoundComponent: () => {
return (
<div>
<p>This is the notFoundComponent configured on root route</p>
</div>
)
},
})
export function RootComponent() {
useOnReload()
return (
<div className="md:p-10 p-4">
<OverlayScrollbarsComponent
defer
className="md:p-10 p-4 h-full"
element="div"
options={{
showNativeOverlaidScrollbars: true,
scrollbars: { autoHide: "scroll" },
}}
>
<Header />
<Outlet />
<ReactQueryDevtools buttonPosition="bottom-left" />
<TanStackRouterDevtools position="bottom-right" />
</div>
</OverlayScrollbarsComponent>
)
}

View File

@ -1,3 +1,6 @@
@import url(@unocss/reset/tailwind.css);
@import url(overlayscrollbars/overlayscrollbars.css);
html,
body,
#app {
@ -23,3 +26,14 @@ button:disabled {
cursor: not-allowed;
pointer-events: all !important;
}
::-webkit-scrollbar {
width: 0px;
}
/* https://github.com/KingSora/OverlayScrollbars/blob/master/packages/overlayscrollbars/src/styles/themes.scss */
.dark .os-theme-dark {
--os-handle-bg: rgba(255, 255, 255, 0.44);
--os-handle-bg-hover: rgba(255, 255, 255, 0.55);
--os-handle-bg-active: rgba(255, 255, 255, 0.66);
}