fix: scroll container mask

Signed-off-by: Innei <i@innei.in>
This commit is contained in:
Innei 2024-07-16 11:34:52 +08:00
parent 249a6b174d
commit 356f3c76e6
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
5 changed files with 41 additions and 8 deletions

View File

@ -17,6 +17,7 @@
"build": "npm run typecheck && electron-vite build --outDir=dist && electron-forge make",
"build:web": "vite build",
"dev": "electron-vite dev --outDir=dist",
"dev:web": "vite",
"lint": "eslint",
"lint:fix": "eslint --fix",
"prepare": "pnpm exec simple-git-hooks && test -f .env || cp .env.example .env",

View File

@ -3,7 +3,7 @@ import { stopPropagation } from "@renderer/lib/dom"
import { cn } from "@renderer/lib/utils"
import * as React from "react"
import { useMaskScrollArea } from "./useMaskScrollArea"
import styles from "./index.module.css"
const Corner = React.forwardRef<
React.ElementRef<typeof ScrollAreaBase.Corner>,
@ -66,16 +66,13 @@ export const Viewport = React.forwardRef<
React.ComponentPropsWithoutRef<typeof ScrollAreaBase.Viewport>
>(({ className, ...rest }, forwardedRef) => {
const ref = React.useRef<HTMLDivElement>(null)
const [, maskClassName] = useMaskScrollArea({
ref,
size: "lg",
})
React.useImperativeHandle(forwardedRef, () => ref.current as HTMLDivElement)
return (
<ScrollAreaBase.Viewport
{...rest}
ref={ref}
className={cn("block size-full", maskClassName, className)}
className={cn("block size-full", styles["scroller"], className)}
/>
)
})

View File

@ -0,0 +1,33 @@
.scroller {
--mask-size: 48px;
padding: 0;
background: transparent;
mask: linear-gradient(white, transparent) 50% 0 / 100% 0 no-repeat,
linear-gradient(white, white) 50% 50% / 100% 100% no-repeat,
linear-gradient(transparent, white) 50% 100% / 100% 100px no-repeat;
mask-composite: exclude;
mask-size: 100% calc((var(--scroll-progress-top) / 100) * 100px), 100% 100%,
100% calc((100 - (100 * (var(--scroll-progress-bottom) / 100))) * 1px);
}
@supports (animation-timeline: scroll()) {
.scroller {
mask: linear-gradient(white, transparent) 50% 0 / 100% 0 no-repeat,
linear-gradient(white, white) 50% 50% / 100% 100% no-repeat,
linear-gradient(transparent, white) 50% 100% / 100% 100px no-repeat;
mask-composite: exclude;
animation: mask-up both linear, mask-down both linear;
animation-timeline: scroll(self);
animation-range: 0 2rem, calc(100% - 2rem) 100%;
}
}
@keyframes mask-up {
100% {
mask-size: 100% 100px, 100% 100%, 100% 100px;
}
}
@keyframes mask-down {
100% {
mask-size: 100% 100px, 100% 100%, 100% 0;
}
}

View File

@ -149,8 +149,9 @@ export const SearchCmdK: React.FC = () => {
<ScrollArea.ScrollArea
ref={scrollViewRef}
viewportClassName="max-h-[50vh] px-5 [&>div]:!flex"
rootClassName="h-full"
viewportClassName="max-h-[50vh] [&>div]:!flex"
rootClassName="h-full px-5"
scrollbarClassName="mb-6"
>
<Command.List className="flex w-full min-w-0 flex-col">
<SearchPlaceholder />

View File

@ -15,6 +15,7 @@ export default defineConfig({
sourcemap: true,
},
root: "./src/renderer",
envDir: resolve(__dirname, "."),
resolve: {
alias: {
"@renderer": resolve("src/renderer/src"),