import { scrollFog, type ScrollFogVariantProps } from "@seed-design/css/recipes/scroll-fog"; import clsx from "clsx"; import { forwardRef, useMemo } from "react"; import { scrollFog as vars } from "@seed-design/css/vars/component"; type ScrollPlacement = "top" | "bottom" | "left" | "right"; type SizesConfig = { top?: number; bottom?: number; left?: number; right?: number; }; export interface ScrollFogProps extends ScrollFogVariantProps, React.HTMLAttributes { /** * Placement of fog effect * @default ["top", "bottom"] */ placement?: ScrollPlacement[]; /** * Size of the fog effect in pixels * @default 20 */ size?: number; /** * Size of the fog effect for each direction in pixels */ sizes?: SizesConfig; } export const ScrollFog = forwardRef( ( { className, hideScrollBar, placement = ["top", "bottom"], size = vars.base.enabled.root.size, sizes, style, ...props }, ref, ) => { const [variantProps, restProps] = scrollFog.splitVariantProps({ hideScrollBar, ...props, }); const scrollFogClassName = scrollFog(variantProps); const sizePx = typeof size === "number" ? `${size}px` : size; const sizeStyle = useMemo(() => { const finalSizes = { top: sizes?.top ? `${sizes.top}px` : sizePx, bottom: sizes?.bottom ? `${sizes.bottom}px` : sizePx, left: sizes?.left ? `${sizes.left}px` : sizePx, right: sizes?.right ? `${sizes.right}px` : sizePx, }; return { "--scroll-fog-size-top": finalSizes.top, "--scroll-fog-size-bottom": finalSizes.bottom, "--scroll-fog-size-left": finalSizes.left, "--scroll-fog-size-right": finalSizes.right, // placement에 포함된 방향만 1, 나머지는 0 "--scrollable-top": placement.includes("top") ? "1" : "0", "--scrollable-bottom": placement.includes("bottom") ? "1" : "0", "--scrollable-left": placement.includes("left") ? "1" : "0", "--scrollable-right": placement.includes("right") ? "1" : "0", } as React.CSSProperties; }, [sizePx, sizes, placement]); return (
); }, ); ScrollFog.displayName = "ScrollFog";