|
1 | 1 | import { cn } from "@dub/utils"; |
2 | 2 | import { enUS } from "date-fns/locale"; |
3 | | -import { useEffect, useMemo, useState } from "react"; |
| 3 | +import { PropsWithChildren, useEffect, useMemo, useRef, useState } from "react"; |
4 | 4 | import { SelectRangeEventHandler } from "react-day-picker"; |
5 | | -import { useKeyboardShortcut, useMediaQuery } from "../hooks"; |
| 5 | +import { |
| 6 | + useKeyboardShortcut, |
| 7 | + useMediaQuery, |
| 8 | + useScrollProgress, |
| 9 | +} from "../hooks"; |
6 | 10 | import { Popover } from "../popover"; |
7 | 11 | import { Calendar as CalendarPrimitive } from "./calendar"; |
8 | 12 | import { Presets } from "./presets"; |
@@ -132,24 +136,20 @@ const DateRangePickerInner = ({ |
132 | 136 | popoverContentClassName="rounded-xl" |
133 | 137 | content={ |
134 | 138 | <div className="flex w-full"> |
135 | | - <div className="scrollbar-hide flex w-full flex-col overflow-x-scroll sm:flex-row-reverse sm:items-start"> |
| 139 | + <div className="scrollbar-hide relative flex w-full flex-col overflow-x-scroll sm:flex-row-reverse sm:items-start"> |
136 | 140 | {presets && presets.length > 0 && ( |
137 | | - <div |
138 | | - className={cn( |
139 | | - "relative flex h-16 w-full items-center sm:h-full sm:w-48", |
140 | | - "border-b border-neutral-200 sm:border-b-0 sm:border-l", |
141 | | - "scrollbar-hide overflow-auto", |
142 | | - )} |
143 | | - > |
144 | | - <div className="absolute px-3 sm:inset-0 sm:left-0 sm:p-3"> |
145 | | - <Presets |
146 | | - currentPresetId={presetId} |
147 | | - currentValue={range} |
148 | | - presets={presets} |
149 | | - onSelect={onPresetSelected} |
150 | | - /> |
| 141 | + <PresetScrollContainer> |
| 142 | + <div className="absolute px-3 sm:inset-0 sm:left-0"> |
| 143 | + <div className="sm:py-3"> |
| 144 | + <Presets |
| 145 | + currentPresetId={presetId} |
| 146 | + currentValue={range} |
| 147 | + presets={presets} |
| 148 | + onSelect={onPresetSelected} |
| 149 | + /> |
| 150 | + </div> |
151 | 151 | </div> |
152 | | - </div> |
| 152 | + </PresetScrollContainer> |
153 | 153 | )} |
154 | 154 | <div className="scrollbar-hide overflow-x-scroll"> |
155 | 155 | <CalendarPrimitive |
@@ -197,3 +197,28 @@ export function DateRangePicker({ presets, ...props }: RangeDatePickerProps) { |
197 | 197 |
|
198 | 198 | return <DateRangePickerInner presets={presets} {...props} />; |
199 | 199 | } |
| 200 | + |
| 201 | +function PresetScrollContainer({ children }: PropsWithChildren) { |
| 202 | + const ref = useRef<HTMLDivElement>(null); |
| 203 | + const { scrollProgress, updateScrollProgress } = useScrollProgress(ref); |
| 204 | + return ( |
| 205 | + <div className="relative sm:h-full"> |
| 206 | + <div |
| 207 | + ref={ref} |
| 208 | + onScroll={updateScrollProgress} |
| 209 | + className={cn( |
| 210 | + "relative flex h-16 w-full items-center sm:h-full sm:w-48", |
| 211 | + "border-b border-neutral-200 sm:border-b-0 sm:border-l", |
| 212 | + "scrollbar-hide overflow-auto", |
| 213 | + )} |
| 214 | + > |
| 215 | + {children} |
| 216 | + </div> |
| 217 | + {/* Bottom scroll fade */} |
| 218 | + <div |
| 219 | + className="pointer-events-none absolute bottom-0 left-0 hidden h-16 w-full rounded-b-lg bg-gradient-to-t from-white sm:block" |
| 220 | + style={{ opacity: 1 - Math.pow(scrollProgress, 2) }} |
| 221 | + /> |
| 222 | + </div> |
| 223 | + ); |
| 224 | +} |
0 commit comments