[WEB-4841] chore: calendar component migration UI to propel (#7730)

* chore: move calendar components and dependencies

* chore: update package configurations

* chore: calendar import updated

* chore: propel config updated

* chore: propel calendar code refactor

* chore: code refactor

* fix: build error
This commit is contained in:
Anmol Singh Bhatia 2025-09-09 23:50:51 +05:30 committed by GitHub
parent 9ab3143a73
commit 498613284e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 156 additions and 164 deletions

View file

@ -1,5 +1,6 @@
import type { Preview } from "@storybook/react-vite";
import "@plane/tailwind-config/global.css";
import "../src/styles/react-day-picker.css";
const parameters: Preview["parameters"] = {
controls: {

View file

@ -18,6 +18,7 @@
"exports": {
"./accordion": "./dist/accordion/index.js",
"./avatar": "./dist/avatar/index.js",
"./calendar": "./dist/calendar/index.js",
"./card": "./dist/card/index.js",
"./charts/*": "./dist/charts/*/index.js",
"./collapsible": "./dist/collapsible/index.js",
@ -31,6 +32,7 @@
"./scrollarea": "./dist/scrollarea/index.js",
"./skeleton": "./dist/skeleton/index.js",
"./styles/fonts": "./dist/styles/fonts/index.css",
"./styles/react-day-picker": "./dist/styles/react-day-picker.css",
"./switch": "./dist/switch/index.js",
"./table": "./dist/table/index.js",
"./tabs": "./dist/tabs/index.js",
@ -50,6 +52,7 @@
"frimousse": "^0.3.0",
"lucide-react": "catalog:",
"react": "catalog:",
"react-day-picker": "9.5.0",
"react-dom": "catalog:",
"recharts": "^2.15.1",
"tailwind-merge": "^3.3.1",

View file

@ -0,0 +1,32 @@
import { ComponentProps, useState } from "react";
import type { Meta, StoryObj } from "@storybook/react-vite";
import { Calendar } from "./root";
type CalendarProps = ComponentProps<typeof Calendar>;
const meta: Meta<CalendarProps> = {
title: "Components/Calendar",
component: Calendar,
parameters: {
layout: "centered",
},
args: {
showOutsideDays: true,
},
};
export default meta;
type Story = StoryObj<CalendarProps>;
export const Default: Story = {
args: {},
render: (args: CalendarProps) => {
const [date, setDate] = useState<Date | undefined>(new Date());
return (
<div className="p-4">
<Calendar {...args} mode="single" selected={date} onSelect={setDate} className="rounded-md border" />
</div>
);
},
};

View file

@ -0,0 +1,2 @@
export * from "./root";
export type { Matcher, DateRange } from "react-day-picker";

View file

@ -0,0 +1,38 @@
"use client";
import * as React from "react";
import { ChevronLeft } from "lucide-react";
import { DayPicker } from "react-day-picker";
import { cn } from "../utils";
export type CalendarProps = React.ComponentProps<typeof DayPicker>;
export const Calendar = ({ className, showOutsideDays = true, ...props }: CalendarProps) => {
const currentYear = new Date().getFullYear();
const thirtyYearsAgoFirstDay = new Date(currentYear - 30, 0, 1);
const thirtyYearsFromNowFirstDay = new Date(currentYear + 30, 11, 31);
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn("p-3", className)}
weekStartsOn={props.weekStartsOn}
components={{
Chevron: ({ className, ...props }) => (
<ChevronLeft
className={cn(
"size-4",
{ "rotate-180": props.orientation === "right", "-rotate-90": props.orientation === "down" },
className
)}
{...props}
/>
),
}}
startMonth={thirtyYearsAgoFirstDay}
endMonth={thirtyYearsFromNowFirstDay}
{...props}
/>
);
};

View file

@ -0,0 +1,311 @@
.rdp-root {
font-size: 12px;
--rdp-cell-size: 40px;
/* Size of the day cells. */
--rdp-caption-font-size: 1rem;
/* Font size for the caption labels. */
--rdp-caption-navigation-size: 1.25rem;
/* Font size for the caption labels. */
--rdp-accent-color: rgba(var(--color-primary-100));
/* Accent color for the background of selected days. */
--rdp-background-color: rgba(var(--color-primary-100), 0.5);
/* Background color for the hovered/focused elements. */
--rdp-dark-background-color: rgba(var(--color-primary-300));
/* Background color for the hovered/focused, already selected elements. */
--rdp-outline: 2px solid var(--rdp-accent-color);
/* Outline border for focused elements */
--rdp-selected-color: #ffffff;
/* Color of selected day text */
background: transparent;
}
.rdp-root {
position: relative; /* Required to position the nav. */
box-sizing: border-box;
}
/* ---------- */
/* Day Buttons */
/* ----------- */
.rdp-day_button {
display: flex;
overflow: hidden;
align-items: center;
justify-content: center;
box-sizing: border-box;
width: var(--rdp-cell-size);
max-width: var(--rdp-cell-size);
height: var(--rdp-cell-size);
margin: 0;
border: 2px solid transparent;
border-radius: 50%;
}
.rdp-day.rdp-outside:not(.rdp-selected) .rdp-day_button {
opacity: 0.5;
}
.rdp-day.rdp-disabled:not(.rdp-selected) .rdp-day_button {
opacity: 0.25;
}
.rdp-day:not(.rdp-disabled) .rdp-day_button {
cursor: pointer;
}
.rdp-day:not(.rdp-selected, .rdp-disabled) .rdp-day_button:focus-visible {
color: inherit;
background-color: var(--rdp-background-color);
}
.rdp-selected:not(.rdp-range_middle, .rdp-disabled) .rdp-day_button:focus-visible {
outline: var(--rdp-outline);
outline-offset: 2px;
background-color: var(--rdp-dark-background-color);
outline-width: thin;
}
.rdp-day:not(.rdp-disabled) .rdp-day_button:hover {
background-color: var(--rdp-background-color);
}
.rdp-selected .rdp-day_button {
background-color: var(--rdp-accent-color);
border-radius: 50%;
color: var(--rdp-selected-color);
z-index: 1;
}
.rdp-selected .rdp-day_button:hover:not(.rdp-disabled) {
background-color: var(--rdp-dark-background-color);
}
.rdp-week {
margin: 0;
padding: 0;
}
.rdp-today:not(.rdp-outside) {
position: relative;
}
.rdp-today:not(.rdp-outside)::after {
content: "";
position: absolute;
left: 50%;
bottom: 2px;
width: 0.5em;
height: 0.5em;
background-color: var(--rdp-background-color);
border-radius: 100%;
transform: translate(-50%, 0);
}
.rdp-selected .rdp-day_button:focus-visible,
.rdp-selected .rdp-day_button:hover {
color: var(--rdp-selected-color);
opacity: 1;
background-color: var(--rdp-accent-color);
}
.rdp-weekday {
vertical-align: middle;
font-weight: 700;
text-align: center;
font-size: 0.75em;
height: var(--rdp-cell-size);
padding: 0;
text-transform: uppercase;
}
/* ---------- */
/* Top Nav */
/* ---------- */
.rdp-nav {
box-sizing: border-box;
position: absolute;
padding: inherit;
top: 1.2em;
right: 1em;
display: flex;
align-items: center;
}
.rdp-button_next,
.rdp-button_previous {
border: none;
background: none;
padding: 0;
margin: 0;
cursor: pointer;
font: inherit;
-moz-appearance: none;
-webkit-appearance: none;
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
appearance: none;
width: var(--rdp-caption-navigation-size);
height: var(--rdp-caption-navigation-size);
padding: 0.25em;
border-radius: 2px;
}
.rdp-chevron {
fill: rgba(var(--color-text-200));
height: 0.75rem;
width: 0.75rem;
}
.rdp-button_next:hover,
.rdp-button_previous:hover,
.rdp-button_next:focus-visible,
.rdp-button_previous:focus-visible {
background-color: rgba(var(--color-background-80)) !important;
}
/* ---------- */
/* Dropdowns */
/* ---------- */
.rdp-dropdowns {
position: relative;
/* width: 100%; */
display: inline-flex;
align-items: center;
}
.rdp-dropdown {
appearance: none;
--webkit-appearance: none;
--moz-appearance: none;
position: absolute;
z-index: 2;
top: 0;
bottom: 0;
left: 0;
width: 100%;
margin: 0;
padding: 0;
opacity: 0;
border: none;
font-family: inherit;
font-size: 1rem;
line-height: inherit;
cursor: pointer;
background: transparent;
&:hover {
background-color: rgba(var(--color-background-80)) !important;
}
}
.rdp-dropdown_root {
margin: 0;
position: relative;
display: inline-flex;
align-items: center;
}
.rdp-months_dropdown {
text-transform: capitalize;
}
.rdp-dropdown[data-disabled="true"] {
opacity: unset;
color: unset;
}
.rdp-caption_label {
z-index: 1;
display: inline-flex;
align-items: center;
gap: 0.25rem;
margin: 0;
padding: 0 0.25em;
white-space: nowrap;
color: currentColor;
border: 0;
border: 2px solid transparent;
font-family: inherit;
font-size: var(--rdp-caption-font-size);
font-weight: 600;
background: transparent;
border-radius: 4px;
}
.rdp-dropdown:not([data-disabled="true"]) {
&:focus-visible + .rdp-caption_label {
border: var(--rdp-outline);
border-radius: 6px;
}
&:hover {
& + .rdp-caption_label {
background-color: rgba(var(--color-background-80)) !important;
}
}
}
.rdp-dropdown_icon {
margin: 0 0 0 5px;
}
/* --------------- */
/* Range selection */
/* --------------- */
.rdp-range_start,
.rdp-range_middle,
.rdp-range_end {
position: relative;
}
.rdp-range_start::before,
.rdp-range_middle::before,
.rdp-range_end::before {
content: "";
position: absolute;
background-color: var(--rdp-background-color);
top: 50%;
height: 100%;
width: 50%;
transform: translate(0, -50%);
z-index: -1;
}
.rdp-range_start::before {
left: 50%;
}
.rdp-range_middle::before {
left: 50%;
width: 100%;
transform: translate(-50%, -50%);
}
.rdp-range_end::before {
right: 50%;
}
.rdp-range_start.rdp-range_end::before {
display: none;
}
.rdp-range_middle .rdp-day_button {
background-color: transparent;
color: inherit;
}
.rdp-day.rdp-range_middle .rdp-day_button:hover,
.rdp-day.rdp-range_middle .rdp-day_button:focus-visible {
background-color: var(--rdp-background-color);
color: inherit;
}

View file

@ -4,6 +4,7 @@ export default defineConfig({
entry: [
"src/accordion/index.ts",
"src/avatar/index.ts",
"src/calendar/index.ts",
"src/card/index.ts",
"src/charts/*/index.ts",
"src/collapsible/index.ts",