Skip to content

Instantly share code, notes, and snippets.

@bicho19
Forked from mjbalcueva/calendar.tsx
Created December 7, 2023 16:48
Show Gist options
  • Select an option

  • Save bicho19/c56d6002bd46b3d17d1d9afc1fe5f992 to your computer and use it in GitHub Desktop.

Select an option

Save bicho19/c56d6002bd46b3d17d1d9afc1fe5f992 to your computer and use it in GitHub Desktop.

Revisions

  1. @mjbalcueva mjbalcueva revised this gist Jul 12, 2023. 1 changed file with 37 additions and 0 deletions.
    37 changes: 37 additions & 0 deletions sample-date-picker.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,37 @@
    "use client"

    import * as React from "react"
    import { Button } from "@/components/ui/button"
    import { Calendar } from "@/components/ui/calendar"
    import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
    import { cn } from "@/lib/utils"
    import { format } from "date-fns"
    import { CalendarIcon } from "lucide-react"

    export function SampleDatePicker() {
    const [date, setDate] = React.useState<Date>()

    return (
    <Popover>
    <PopoverTrigger asChild>
    <Button
    variant={"outline"}
    className={cn("w-[240px] justify-start text-left font-normal", !date && "text-muted-foreground")}
    >
    <CalendarIcon className="mr-2 h-4 w-4" />
    {date ? format(date, "PPP") : <span>Pick a date</span>}
    </Button>
    </PopoverTrigger>
    <PopoverContent align="start" className=" w-auto p-0">
    <Calendar
    mode="single"
    captionLayout="dropdown-buttons"
    selected={date}
    onSelect={setDate}
    fromYear={1960}
    toYear={2030}
    />
    </PopoverContent>
    </Popover>
    )
    }
  2. @mjbalcueva mjbalcueva revised this gist Jul 12, 2023. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions globals.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,5 @@
    /* add this snippet in your globals.css file */

    .rdp-vhidden {
    @apply hidden;
    }
  3. @mjbalcueva mjbalcueva created this gist Jul 12, 2023.
    87 changes: 87 additions & 0 deletions calendar.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,87 @@
    "use client"

    import * as React from "react"
    import { buttonVariants } from "@/components/ui/button"
    import { ScrollArea } from "@/components/ui/scroll-area"
    import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
    import { cn } from "@/lib/utils"
    import { ChevronLeft, ChevronRight } from "lucide-react"
    import { DayPicker, DropdownProps } from "react-day-picker"

    export type CalendarProps = React.ComponentProps<typeof DayPicker>

    function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) {
    return (
    <DayPicker
    showOutsideDays={showOutsideDays}
    className={cn("p-3", className)}
    classNames={{
    months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
    month: "space-y-4",
    caption: "flex justify-center pt-1 relative items-center",
    caption_label: "text-sm font-medium",
    caption_dropdowns: "flex justify-center gap-1",
    nav: "space-x-1 flex items-center",
    nav_button: cn(
    buttonVariants({ variant: "outline" }),
    "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
    ),
    nav_button_previous: "absolute left-1",
    nav_button_next: "absolute right-1",
    table: "w-full border-collapse space-y-1",
    head_row: "flex",
    head_cell: "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
    row: "flex w-full mt-2",
    cell: "text-center text-sm p-0 relative [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
    day: cn(buttonVariants({ variant: "ghost" }), "h-9 w-9 p-0 font-normal aria-selected:opacity-100"),
    day_selected:
    "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
    day_today: "bg-accent text-accent-foreground",
    day_outside: "text-muted-foreground opacity-50",
    day_disabled: "text-muted-foreground opacity-50",
    day_range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
    day_hidden: "invisible",
    ...classNames,
    }}
    components={{
    Dropdown: ({ value, onChange, children, ...props }: DropdownProps) => {
    const options = React.Children.toArray(children) as React.ReactElement<React.HTMLProps<HTMLOptionElement>>[]
    const selected = options.find((child) => child.props.value === value)
    const handleChange = (value: string) => {
    const changeEvent = {
    target: { value },
    } as React.ChangeEvent<HTMLSelectElement>
    onChange?.(changeEvent)
    }
    return (
    <Select
    value={value?.toString()}
    onValueChange={(value) => {
    handleChange(value)
    }}
    >
    <SelectTrigger className="pr-1.5 focus:ring-0">
    <SelectValue>{selected?.props?.children}</SelectValue>
    </SelectTrigger>
    <SelectContent position="popper">
    <ScrollArea className="h-80">
    {options.map((option, id: number) => (
    <SelectItem key={`${option.props.value}-${id}`} value={option.props.value?.toString() ?? ""}>
    {option.props.children}
    </SelectItem>
    ))}
    </ScrollArea>
    </SelectContent>
    </Select>
    )
    },
    IconLeft: ({ ...props }) => <ChevronLeft className="h-4 w-4" />,
    IconRight: ({ ...props }) => <ChevronRight className="h-4 w-4" />,
    }}
    {...props}
    />
    )
    }
    Calendar.displayName = "Calendar"

    export { Calendar }