Feat/v2 daterangepicker (#4002)
* fixes minimum notice label * adds story for daterange picker * imports styles from global * adds daterangepicker type inside packages types folder * wraps tooltip with tooltip provider * improvements * further fixes * fixes NIT * match design specs * adds space between input and calendar * NITs Co-authored-by: Peer Richelsen <peeroke@gmail.com>pull/4081/head
parent
d5b7195d67
commit
c455639ff4
|
@ -11,7 +11,7 @@ export const Default = () => {
|
|||
const [selected, setSelected] = useState<Date>(new Date());
|
||||
return (
|
||||
<div style={{ width: "455px" }}>
|
||||
{/* <DatePicker selected={selected} onChange={setSelected} locale="en" /> */}
|
||||
<DatePicker selected={selected} onChange={setSelected} locale="en" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import { ComponentMeta, ComponentStory } from "@storybook/react";
|
||||
import "@wojtekmaj/react-daterange-picker/dist/DateRangePicker.css";
|
||||
import { useState } from "react";
|
||||
|
||||
import DateRangePicker from "@calcom/ui/v2/core/form/date-range-picker/DateRangePicker";
|
||||
import "@calcom/ui/v2/core/form/date-range-picker/styles.css";
|
||||
|
||||
function getISOLocalDate(date) {
|
||||
const year = padStart(date.getFullYear(), 4);
|
||||
const month = padStart(date.getMonth() + 1);
|
||||
const day = padStart(date.getDate());
|
||||
|
||||
return [`${year}-${month}-${day}`];
|
||||
}
|
||||
|
||||
function padStart(num, val = 2) {
|
||||
const numStr = `${num}`;
|
||||
if (numStr.length >= val) {
|
||||
return num;
|
||||
}
|
||||
|
||||
return `0000${numStr}`.slice(-val);
|
||||
}
|
||||
|
||||
export default {
|
||||
title: "Date Range Picker",
|
||||
component: DateRangePicker,
|
||||
} as ComponentMeta<typeof DateRangePicker>;
|
||||
|
||||
export const Default: ComponentStory<typeof DateRangePicker> = () => {
|
||||
const [startDate, setStartDate] = useState<Date>(new Date());
|
||||
const [endDate, setEndDate] = useState<Date>(new Date());
|
||||
return (
|
||||
<div>
|
||||
<DateRangePicker
|
||||
startDate={getISOLocalDate(startDate) as unknown as Date}
|
||||
endDate={getISOLocalDate(endDate) as unknown as Date}
|
||||
onDatesChange={({ startDate, endDate }) => {
|
||||
setStartDate(startDate);
|
||||
setEndDate(endDate);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
|
@ -2,6 +2,9 @@
|
|||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@import "../../../packages/ui/v2/core/form/date-range-picker/styles.css";
|
||||
@import "../../../node_modules/@wojtekmaj/react-daterange-picker/dist/DateRangePicker.css";
|
||||
|
||||
:root {
|
||||
--brand-color: #292929;
|
||||
--brand-text-color: #ffffff;
|
||||
|
|
|
@ -7,8 +7,7 @@ import { classNames } from "@calcom/lib";
|
|||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { PeriodType } from "@calcom/prisma/client";
|
||||
import { Select, Switch, Label } from "@calcom/ui/v2";
|
||||
|
||||
import { DateRangePicker } from "@components/ui/form/DateRangePicker";
|
||||
import DateRangePicker from "@calcom/ui/v2/core/form/date-range-picker/DateRangePicker";
|
||||
|
||||
export const EventLimitsTab = (props: Pick<EventTypeSetupInfered, "eventType">) => {
|
||||
const { t } = useLocale();
|
||||
|
@ -112,7 +111,7 @@ export const EventLimitsTab = (props: Pick<EventTypeSetupInfered, "eventType">)
|
|||
/>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<Label htmlFor="minimumBookingNotice">{t("after_event")} </Label>
|
||||
<Label htmlFor="minimumBookingNotice">{t("minimum_booking_notice")} </Label>
|
||||
<Controller
|
||||
name="minimumBookingNotice"
|
||||
control={formMethods.control}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
declare module "@wojtekmaj/react-daterange-picker/dist/entry.nostyle" {
|
||||
import { CalendarProps } from "react-calendar";
|
||||
export type DateRangePickerCalendarProps = Omit<
|
||||
CalendarProps,
|
||||
"calendarClassName" | "onChange" | "value"
|
||||
> & {
|
||||
calendarClassName?: string;
|
||||
onChange: (value: [Date, Date]) => void;
|
||||
value: [Date, Date];
|
||||
clearIcon: JSX.Element | null;
|
||||
calendarIcon: JSX.Element | null;
|
||||
rangeDivider: JSX.Element | null;
|
||||
disabled?: boolean | null;
|
||||
nextLabel?: JSX.Element | null;
|
||||
prevLabel?: JSX.Element | null;
|
||||
};
|
||||
export default function DateRangePicker(props: DateRangePickerCalendarProps): JSX.Element;
|
||||
}
|
|
@ -54,13 +54,15 @@ export default function Avatar(props: AvatarProps) {
|
|||
);
|
||||
|
||||
return title ? (
|
||||
<Tooltip.Tooltip delayDuration={300}>
|
||||
<Tooltip.TooltipTrigger className="cursor-default">{avatar}</Tooltip.TooltipTrigger>
|
||||
<Tooltip.Content className="rounded-sm bg-black p-2 text-sm text-white shadow-sm">
|
||||
<Tooltip.Arrow />
|
||||
{title}
|
||||
</Tooltip.Content>
|
||||
</Tooltip.Tooltip>
|
||||
<Tooltip.Provider>
|
||||
<Tooltip.Tooltip delayDuration={300}>
|
||||
<Tooltip.TooltipTrigger className="cursor-default">{avatar}</Tooltip.TooltipTrigger>
|
||||
<Tooltip.Content className="rounded-sm bg-black p-2 text-sm text-white shadow-sm">
|
||||
<Tooltip.Arrow />
|
||||
{title}
|
||||
</Tooltip.Content>
|
||||
</Tooltip.Tooltip>
|
||||
</Tooltip.Provider>
|
||||
) : (
|
||||
<>{avatar}</>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
// @see: https://github.com/wojtekmaj/react-daterange-picker/issues/91
|
||||
import "@wojtekmaj/react-daterange-picker/dist/DateRangePicker.css";
|
||||
import PrimitiveDateRangePicker from "@wojtekmaj/react-daterange-picker/dist/entry.nostyle";
|
||||
import React from "react";
|
||||
|
||||
import { Icon } from "@calcom/ui/Icon";
|
||||
import "@calcom/ui/v2/core/form/date-range-picker/styles.css";
|
||||
|
||||
type Props = {
|
||||
disabled?: boolean | undefined;
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
onDatesChange?: ((arg: { startDate: Date; endDate: Date }) => void) | undefined;
|
||||
};
|
||||
|
||||
const DateRangePicker = ({ disabled, startDate, endDate, onDatesChange }: Props) => {
|
||||
return (
|
||||
<>
|
||||
<PrimitiveDateRangePicker
|
||||
disabled={disabled || false}
|
||||
className="rounded-sm border-gray-300 text-sm"
|
||||
clearIcon={null}
|
||||
calendarIcon={<Icon.FiCalendar className="h-4 w-4 text-gray-500" />}
|
||||
rangeDivider={<Icon.FiArrowRight className="h-4 w-4 text-gray-400 ltr:mr-2 rtl:ml-2" />}
|
||||
value={[startDate, endDate]}
|
||||
onChange={([startDate, endDate]: [Date, Date]) => {
|
||||
if (typeof onDatesChange === "function") onDatesChange({ startDate, endDate });
|
||||
}}
|
||||
nextLabel={<Icon.FiChevronRight className="h-4 w-4 text-gray-500" />}
|
||||
prevLabel={<Icon.FiChevronLeft className="h-4 w-4 text-gray-500" />}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DateRangePicker;
|
|
@ -0,0 +1,158 @@
|
|||
.react-daterange-picker > .react-daterange-picker__wrapper {
|
||||
padding: .625rem .75rem;
|
||||
font-size: .875rem;
|
||||
line-height: 1.25rem;
|
||||
border-radius: .375rem;
|
||||
border-color: #E5E7EB;
|
||||
width: 360px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.react-daterange-picker__wrapper > .react-daterange-picker__calendar-button.react-daterange-picker__button {
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.react-daterange-picker > .react-daterange-picker__wrapper > .react-daterange-picker__inputGroup {
|
||||
height: auto;
|
||||
}
|
||||
.react-daterange-picker.react-daterange-picker--disabled {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.react-daterange-picker.react-daterange-picker--disabled > .react-daterange-picker__wrapper {
|
||||
background-color: #F3F4F6;
|
||||
}
|
||||
|
||||
.react-daterange-picker > .react-daterange-picker__wrapper:focus-within,
|
||||
.react-daterange-picker > .react-daterange-picker__wrapper:focus-within:hover {
|
||||
border-color: #111827;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
|
||||
.react-daterange-picker > .react-daterange-picker__wrapper input {
|
||||
margin: 0;
|
||||
height: auto;
|
||||
border-radius: .125rem;
|
||||
}
|
||||
|
||||
.react-daterange-picker__calendar.react-daterange-picker__calendar--open {
|
||||
width: 360px;
|
||||
}
|
||||
|
||||
.react-daterange-picker__calendar > .react-calendar{
|
||||
padding: 0.5rem;
|
||||
border-radius: 0.375rem;
|
||||
border-width: 1px;
|
||||
border-color: #E5E7EB;
|
||||
width: 360px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.react-calendar__navigation > .react-calendar__navigation__arrow {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.react-calendar__navigation > .react-calendar__navigation__arrow.react-calendar__navigation__prev2-button,
|
||||
.react-calendar__navigation > .react-calendar__navigation__arrow.react-calendar__navigation__next2-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.react-calendar__navigation > .react-calendar__navigation__label {
|
||||
display: flex;
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
color: #111827;
|
||||
order: -9999;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.react-calendar__navigation > .react-calendar__navigation__arrow {
|
||||
text-align: center;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.react-calendar__month-view__weekdays__weekday > abbr {
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.react-calendar__month-view__days {
|
||||
padding: 0.25rem;
|
||||
gap: 0.25rem;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
button.react-calendar__tile.react-calendar__month-view__days__day {
|
||||
flex : 0 0 13.25% !important;
|
||||
border-radius: 0.375rem;
|
||||
padding-top: 13px;
|
||||
padding-bottom: 13px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.react-calendar__tile--now,
|
||||
.react-calendar__tile.react-calendar__tile--hover:not(.react-calendar__tile--active) {
|
||||
background-color: #E5E7EB !important;
|
||||
}
|
||||
|
||||
.react-calendar__month-view__days > .react-calendar__tile.react-calendar__tile--hasActive,
|
||||
.react-calendar__month-view__days > .react-calendar__tile.react-calendar__tile--active,
|
||||
.react-calendar__month-view__days > button.react-calendar__tile.react-calendar__tile--active:hover {
|
||||
background-color: #111827;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.react-calendar__tile.react-calendar__tile--active.react-calendar__month-view__days__day--weekend {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.react-calendar__tile.react-calendar__month-view__days__day--weekend {
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.react-calendar__tile.react-calendar__month-view__days__day--neighboringMonth {
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
|
||||
.react-calendar__tile--now::before {
|
||||
content:"\A";
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
background-color: #111827;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
bottom: 0;
|
||||
z-index: inherit;
|
||||
}
|
||||
|
||||
button.react-calendar__tile.react-calendar__month-view__days__day:hover,
|
||||
.react-calendar__tile.react-calendar__year-view__months__month:hover {
|
||||
background-color: #D1D5DB;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.react-daterange-picker > .react-daterange-picker__wrapper:hover {
|
||||
border-color: #9CA3AF;
|
||||
}
|
||||
|
||||
.react-daterange-picker.react-daterange-picker--disabled > .react-daterange-picker__wrapper:hover {
|
||||
border-color: #E5E7EB;
|
||||
}
|
||||
|
||||
.react-calendar__navigation button.react-calendar__navigation__label:enabled:hover,
|
||||
.react-calendar__navigation button.react-calendar__navigation__label:enabled:focus {
|
||||
background-color: transparent;
|
||||
}
|
Loading…
Reference in New Issue