Skip to content

Instantly share code, notes, and snippets.

@zwhitchcox
Created October 22, 2025 21:14
Show Gist options
  • Select an option

  • Save zwhitchcox/76bfe746a17fbccaa4909df5923f7388 to your computer and use it in GitHub Desktop.

Select an option

Save zwhitchcox/76bfe746a17fbccaa4909df5923f7388 to your computer and use it in GitHub Desktop.
responsive shadcn calendar
import * as React from 'react'
import { DayPicker } from 'react-day-picker'
import { cn } from '#app/utils/misc.js'
import { buttonVariants } from './button'
import { Icon } from './icon'
export type CalendarProps = React.ComponentProps<typeof DayPicker>
function Calendar({
className,
classNames,
showOutsideDays = true,
...props
}: CalendarProps) {
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn('w-full rounded-md border p-3', className)}
classNames={{
months: 'flex w-full flex-wrap relative',
month: 'w-full px-3',
month_caption: 'flex justify-start items-center py-2 px-3',
caption_label: 'text-md font-medium',
nav: 'flex items-center justify-end w-full absolute px-3 h-10',
button_previous: cn(
buttonVariants({ variant: 'outline' }),
'h-7 w-7 border-0 bg-transparent p-0 opacity-50 hover:opacity-100',
),
button_next: cn(
buttonVariants({ variant: 'outline' }),
'h-7 w-7 border-0 bg-transparent p-0 opacity-50 hover:opacity-100',
),
month_grid: 'w-full border-collapse',
weekdays: 'flex w-full',
weekday:
'text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] text-center',
week: 'flex w-full',
day: 'flex-1 text-center text-sm p-1 relative aspect-square',
day_button: cn(
buttonVariants({ variant: 'ghost' }),
'h-full w-full min-w-0 items-center justify-center p-0 font-normal aria-selected:opacity-100',
),
range_end: 'day-range-end',
selected:
'bg-secondary text-secondary-foreground hover:bg-secondary hover:text-secondary-foreground focus:bg-secondary focus:text-secondary-foreground rounded-md',
outside:
'day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30',
disabled: 'text-muted-foreground opacity-50',
range_middle:
'aria-selected:bg-accent aria-selected:text-accent-foreground',
hidden: 'invisible',
...classNames,
}}
components={{
Chevron: (props) => {
if (props.orientation === 'left') {
return <Icon name="chevron-left" className="h-4 w-4" />
}
return <Icon name="chevron-right" className="h-4 w-4" />
},
}}
{...props}
/>
)
}
Calendar.displayName = 'Calendar'
export { Calendar }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment