@@ -11,7 +11,7 @@ import {
1111 subWeeks ,
1212} from "date-fns" ;
1313import parse from "parse-duration" ;
14- import { startTransition , useCallback , useEffect , useState , type ReactNode } from "react" ;
14+ import { startTransition , useCallback , useEffect , useRef , useState , type ReactNode } from "react" ;
1515import simplur from "simplur" ;
1616import { AppliedFilter } from "~/components/primitives/AppliedFilter" ;
1717import { Callout } from "~/components/primitives/Callout" ;
@@ -23,7 +23,8 @@ import { RadioButtonCircle } from "~/components/primitives/RadioButton";
2323import { ComboboxProvider , SelectPopover , SelectProvider } from "~/components/primitives/Select" ;
2424import { useOptionalOrganization } from "~/hooks/useOrganizations" ;
2525import { useSearchParams } from "~/hooks/useSearchParam" ;
26- import { type ShortcutDefinition } from "~/hooks/useShortcutKeys" ;
26+ import { type ShortcutDefinition , useShortcutKeys } from "~/hooks/useShortcutKeys" ;
27+ import { ShortcutKey } from "~/components/primitives/ShortcutKey" ;
2728import { cn } from "~/utils/cn" ;
2829import { organizationBillingPath } from "~/utils/pathBuilder" ;
2930import { Button , LinkButton } from "../../primitives/Buttons" ;
@@ -347,6 +348,8 @@ export interface TimeFilterProps {
347348 /** Label name used in the filter display, defaults to "Created" */
348349 labelName ?: string ;
349350 hideLabel ?: boolean ;
351+ /** Keyboard shortcut to open the dropdown */
352+ shortcut ?: ShortcutDefinition ;
350353 applyShortcut ?: ShortcutDefinition | undefined ;
351354 /** Callback when the user applies a time filter selection, receives the applied values */
352355 onValueChange ?: ( values : TimeFilterApplyValues ) => void ;
@@ -363,6 +366,7 @@ export function TimeFilter({
363366 to,
364367 labelName = "Created" ,
365368 hideLabel = false ,
369+ shortcut,
366370 applyShortcut,
367371 onValueChange,
368372 maxPeriodDays,
@@ -372,6 +376,16 @@ export function TimeFilter({
372376 const periodValue = period ?? value ( "period" ) ;
373377 const fromValue = from ?? value ( "from" ) ;
374378 const toValue = to ?? value ( "to" ) ;
379+ const triggerRef = useRef < HTMLDivElement > ( null ) ;
380+
381+ useShortcutKeys ( {
382+ shortcut,
383+ action : ( e ) => {
384+ e . preventDefault ( ) ;
385+ e . stopPropagation ( ) ;
386+ triggerRef . current ?. click ( ) ;
387+ } ,
388+ } ) ;
375389
376390 const constrained = timeFilters ( {
377391 period : periodValue ,
@@ -386,16 +400,37 @@ export function TimeFilter({
386400 { ( ) => (
387401 < TimeDropdown
388402 trigger = {
389- < Ariakit . Select render = { < div className = "group cursor-pointer focus-custom" /> } >
390- < AppliedFilter
391- label = { hideLabel ? undefined : constrained . label }
392- icon = { filterIcon ( "period" ) }
393- value = { constrained . valueLabel }
394- removable = { false }
395- variant = "secondary/small"
396- valueClassName = { valueClassName }
397- />
398- </ Ariakit . Select >
403+ < Ariakit . TooltipProvider timeout = { 200 } >
404+ < Ariakit . TooltipAnchor
405+ render = {
406+ < Ariakit . Select
407+ ref = { triggerRef }
408+ render = { < div className = "group cursor-pointer focus-custom" /> }
409+ />
410+ }
411+ >
412+ < AppliedFilter
413+ label = { hideLabel ? undefined : constrained . label }
414+ icon = { filterIcon ( "period" ) }
415+ value = { constrained . valueLabel }
416+ removable = { false }
417+ variant = "secondary/small"
418+ valueClassName = { valueClassName }
419+ />
420+ </ Ariakit . TooltipAnchor >
421+ { shortcut && (
422+ < Ariakit . Tooltip className = "z-40 cursor-default rounded border border-charcoal-700 bg-background-bright px-2 py-1.5 text-xs" >
423+ < div className = "flex items-center gap-2" >
424+ < span > Filter by time period</ span >
425+ < ShortcutKey
426+ className = "size-4 flex-none"
427+ shortcut = { shortcut }
428+ variant = "small"
429+ />
430+ </ div >
431+ </ Ariakit . Tooltip >
432+ ) }
433+ </ Ariakit . TooltipProvider >
399434 }
400435 period = { constrained . period }
401436 from = { constrained . from }
0 commit comments