Skip to content

I've made a change to use this component with useForm. Here's the code — I hope it helps some developers working with useForm. #19

@im4nu

Description

@im4nu

First, this time-picker with date is awesome. The UX can be very improved using this component. Thank u Maximilian Kaske, Aaron Green, eliassebastian, Nicolas Cuellar Ochoa, Thibault Le Ouay, Ishan.

Now let me explain my usage.

// Using on main component

{...}
              <Controller
                control={control}
                name="endDate"
                render={({ field }) => (
                  <DateTimePicker
                    value={getElectionByIdQuery?.endDate ?? undefined}
                    onChange={field.onChange}
                  />
                )}
              />
{...}

// The modified component

"use client";

import { format, set } from "date-fns";
import { ptBR } from "date-fns/locale";
import { Calendar as CalendarIcon } from "lucide-react";
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 { TimePickerDemo } from "./time-picker-demo";

interface DateTimePickerProps {
  onChange: (date: Date) => void;
  value?: Date;
}

export function DateTimePicker({ onChange, value }: DateTimePickerProps) {
  const [date, setDate] = React.useState<Date>();

  function toggleSelect() {
    if (!date) return;
    onChange(date);
  }

  React.useEffect(() => {
    if (value) {
      setDate(value);
    }
  }, [value]);
  return (
    <Popover
      onOpenChange={(current) => {
        if (!current) {
          toggleSelect();
        }
      }}
    >
      <PopoverTrigger asChild>
        <Button
          variant={"outline"}
          className={cn(
            "w-[280px] justify-start text-left font-normal",
            !date && "text-muted-foreground",
          )}
        >
          <CalendarIcon className="mr-2 h-4 w-4" />
          {date ? (
            format(date, "dd/MM/yyyy | HH:mm")
          ) : (
            <span>Selecione uma data</span>
          )}
        </Button>
      </PopoverTrigger>
      <PopoverContent className="w-auto p-0">
        <Calendar
          mode="single"
          selected={date}
          onSelect={(d) => {
            setDate(d);
          }}
          initialFocus
          locale={ptBR}
        />
        <div className="flex justify-between border-t border-border p-3">
          <TimePickerDemo
            setDate={(d) => {
              setDate((currentDate) => {
                if (!currentDate) return;
                if (!d) return;

                // console.log({ d, currentDate });

                return set(currentDate, {
                  hours: d.getHours(),
                  minutes: d.getMinutes(),
                });
              });
            }}
            date={date}
          />
        </div>
      </PopoverContent>
    </Popover>
  );
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions