Skip to content

Conversation

anmolsinghbhatia
Copy link
Collaborator

@anmolsinghbhatia anmolsinghbhatia commented Sep 5, 2025

Description

This PR includes the following changes:

  • Migrated the Calendar component from @plane/ui to @plane/propel
  • Removed the react-day-picker dependency from the web app
  • Updated related imports and code refactoring
  • Stories added for calendar component

Type of Change

  • Improvement
  • Code refactoring

Media

Media
media

Summary by CodeRabbit

  • New Features
    • Added Calendar component stories to Storybook for browsing and examples.
  • Refactor
    • Moved calendar/date-picker into the design system package and updated app imports.
    • Centralized date-picker styling to load from the design system.
  • Chores
    • Removed direct date-picker dependency from the web app; managed via the design system.
  • Documentation
    • Expanded Storybook usage scenarios.
  • Notes
    • No user-facing behavior changes expected for date pickers.

Copy link

makeplane bot commented Sep 5, 2025

Pull Request Linked with Plane Work Items

Comment Automatically Generated by Plane

Copy link
Contributor

coderabbitai bot commented Sep 5, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Calendar UI and DayPicker styles are moved from the UI package into a new Propel calendar module; web app imports updated to @plane/propel/calendar and Propel exposes new exports/styles and Storybook stories. react-day-picker dep moved from apps/web into packages/propel. UI package calendar file and its re-export removed.

Changes

Cohort / File(s) Summary of changes
Web: Calendar import migration
apps/web/core/components/core/filters/date-filter-modal.tsx, apps/web/core/components/dropdowns/date-range.tsx, apps/web/core/components/dropdowns/date.tsx, apps/web/core/components/inbox/modals/snooze-issue-modal.tsx
Switched Calendar (and related types) imports to @plane/propel/calendar; split some combined imports (Button, ComboDropDown) into separate statements; no runtime logic changes.
Web: Global DayPicker styles import
apps/web/app/(all)/layout.tsx
Replaced local CSS import with @plane/propel/styles/react-day-picker.
Web: Dependency cleanup
apps/web/package.json
Removed react-day-picker dependency from web app.
Propel: New Calendar module and exports
packages/propel/src/calendar/root.tsx, packages/propel/src/calendar/index.ts, packages/propel/package.json, packages/propel/tsdown.config.ts
Added Calendar wrapper component (root) re-exported via a new calendar barrel; re-exported types Matcher and DateRange; added ./calendar and ./styles/react-day-picker exports and react-day-picker dependency; added calendar entry to tsdown build config.
Propel: Storybook and styles
packages/propel/.storybook/preview.ts, packages/propel/src/calendar/calendar.stories.tsx
Imported DayPicker CSS into Storybook preview and added Calendar stories (Basic, DateRange, Multiple, WithDisabledDates, WeekStartsOnMonday, WithoutOutsideDays).
UI: Remove Calendar from UI package
packages/ui/src/calendar.tsx, packages/ui/src/index.ts
Deleted the UI package Calendar implementation and removed its re-export from UI index.

Sequence Diagram(s)

sequenceDiagram
  participant Web as apps/web components
  participant Propel as @plane/propel/calendar
  participant RDP as react-day-picker

  Note over Web,Propel: Import-time routing after change
  Web->>Propel: import { Calendar, Matcher, DateRange } from "@plane/propel/calendar"
  Propel->>RDP: wraps and forwards props to DayPicker
  Propel->>Propel: apply startMonth/endMonth, chevrons, classNames
  Propel->>Web: rendered Calendar component (DayPicker output)

  Note over UI,Web: Old flow (removed)
  UI--xWeb: previously exported Calendar (deleted)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

🌟improvement

Suggested reviewers

  • sriramveeraghanta
  • vamsikrishnamathala

Poem

I hopped from UI fields to Propel’s glen,
Calendars bloomed where stories begin.
Dates now dance with tidy grace,
Styles in tow, a cleaner place.
Farewell old paths, new trails ahead—🐇📅


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 953991e and 8f51b2b.

📒 Files selected for processing (1)
  • apps/web/core/components/dropdowns/date.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/core/components/dropdowns/date.tsx
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore-calendar-migration-ui-to-propel

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR migrates the Calendar component from @plane/ui to @plane/propel package, consolidating dependencies and improving component organization.

  • Moved Calendar component from @plane/ui to @plane/propel with react-day-picker dependency
  • Updated all import statements across the web app to use the new calendar location
  • Added comprehensive Storybook stories for the calendar component

Reviewed Changes

Copilot reviewed 14 out of 16 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/ui/src/index.ts Removed calendar export from UI package
packages/ui/src/calendar.tsx Deleted old calendar component implementation
packages/propel/tsdown.config.ts Added calendar to build configuration
packages/propel/src/calendar/root.tsx New calendar component implementation in propel
packages/propel/src/calendar/index.ts Calendar component exports and type re-exports
packages/propel/src/calendar/calendar.stories.tsx Comprehensive Storybook stories for calendar
packages/propel/package.json Added calendar export and react-day-picker dependency
packages/propel/.storybook/preview.ts Added calendar styles to Storybook
apps/web/package.json Removed react-day-picker dependency from web app
apps/web/core/components/inbox/modals/snooze-issue-modal.tsx Updated calendar import
apps/web/core/components/dropdowns/date.tsx Updated calendar and types import
apps/web/core/components/dropdowns/date-range.tsx Updated calendar and types import
apps/web/core/components/core/filters/date-filter-modal.tsx Updated calendar import
apps/web/app/(all)/layout.tsx Updated calendar styles import
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/web/core/components/core/filters/date-filter-modal.tsx (1)

47-50: Bug: date2 watches date1, breaking range validation

date2 is incorrectly derived from watch("date1"), so isInvalid can’t detect inverted ranges.

Apply this diff:

-  const date1 = getDate(watch("date1"));
-  const date2 = getDate(watch("date1"));
+  const date1 = getDate(watch("date1"));
+  const date2 = getDate(watch("date2"));
apps/web/core/components/inbox/modals/snooze-issue-modal.tsx (1)

67-73: Fix undefined close() call in onClick.

close() is not defined in scope; call the provided handleClose() to dismiss the modal before confirming.

-                  <Button
+                  <Button
                     variant="primary"
                     onClick={() => {
-                      close();
+                      handleClose();
                       onConfirm(date);
                     }}
                   >
🧹 Nitpick comments (10)
packages/propel/package.json (1)

52-52: Version ownership: pin vs. catalog

Having Propel own [email protected] is fine. If you prefer centralized versioning like other deps (catalog:), consider moving this to the repo catalog for consistency. Optional.

apps/web/core/components/core/filters/date-filter-modal.tsx (1)

97-110: Minor: dedupe repeated Calendar classNames

The classNames.root string is duplicated. Consider extracting to a constant to keep it DRY.

+ const calendarRootClass = "border border-custom-border-200 p-3 rounded-md";
...
   <Calendar
-    classNames={{ root: ` border border-custom-border-200 p-3 rounded-md` }}
+    classNames={{ root: calendarRootClass }}
     ...
   />
...
   <Calendar
-    classNames={{ root: ` border border-custom-border-200 p-3 rounded-md` }}
+    classNames={{ root: calendarRootClass }}
     ...
   />

Also applies to: 122-135

apps/web/core/components/inbox/modals/snooze-issue-modal.tsx (1)

51-66: Optional: avoid shadowing and redundant cloning.

The onSelect parameter date shadows the state variable date, and selected/defaultMonth re-wrap date with new Date(..) unnecessarily. Not a bug, but minor cleanup possible.

-                    onSelect={(date) => {
-                      if (!date) return;
-                      setDate(date);
+                    onSelect={(d) => {
+                      if (!d) return;
+                      setDate(d);
                     }}
-                    selected={date ? new Date(date) : undefined}
-                    defaultMonth={date ? new Date(date) : undefined}
+                    selected={date ?? undefined}
+                    defaultMonth={date ?? undefined}
packages/propel/src/calendar/root.tsx (2)

21-33: Tighten Chevron override (destructure orientation, clearer props).

Readability: destructure orientation directly and pass the rest explicitly.

-      components={{
-        Chevron: ({ className, ...props }) => (
-          <ChevronLeft
-            className={cn(
-              "size-4",
-              { "rotate-180": props.orientation === "right", "-rotate-90": props.orientation === "down" },
-              className
-            )}
-            {...props}
-          />
-        ),
-      }}
+      components={{
+        Chevron: ({ className, orientation, ...rest }) => (
+          <ChevronLeft
+            className={cn(
+              "size-4",
+              { "rotate-180": orientation === "right", "-rotate-90": orientation === "down" },
+              className
+            )}
+            {...rest}
+          />
+        ),
+      }}

19-35: Remove redundant prop and clarify end-of-window var name.

  • weekStartsOn is already included via {...props}; the explicit prop is redundant.
  • Rename thirtyYearsFromNowFirstDay to thirtyYearsFromNowLastDay to reflect Dec 31.
 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);
+  const thirtyYearsFromNowLastDay = 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}
+      endMonth={thirtyYearsFromNowLastDay}
       {...props}
     />
   );
 }
packages/propel/src/calendar/calendar.stories.tsx (5)

1-4: Import from the public barrel and pull in reusable types

Stories should exercise the public API and reuse exported types.

-import { Calendar } from "./root";
+import { Calendar, type DateRange, type Matcher } from ".";

41-44: Use the DateRange type for stronger typing

Aligns with the Calendar/DayPicker API and simplifies future refactors.

-    const [dateRange, setDateRange] = useState<{ from?: Date; to?: Date }>({
+    const [dateRange, setDateRange] = useState<DateRange | undefined>({
       from: new Date(),
       to: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days from now
     });

73-75: Guard onSelect against undefined in multiple mode

DayPicker may call onSelect with undefined; keep state consistent.

-          onSelect={setDates}
+          onSelect={(v) => setDates(v ?? [])}

86-90: Type disabledDays for better safety and editor help

Annotate as Matcher[] to match DayPicker’s matcher API.

-    const disabledDays = [
+    const disabledDays: Matcher[] = [
       { dayOfWeek: [0, 6] }, // Sunday and Saturday
       new Date(2024, 4, 10), // May 10, 2024
     ];

21-143: Optional: make stories time-stable

Direct new Date() calls can cause flaky visuals over time. Consider a fixed “today” (e.g., via a const or Storybook global/arg) to stabilize snapshots.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 20d139c and 953991e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • apps/web/app/(all)/layout.tsx (1 hunks)
  • apps/web/core/components/core/filters/date-filter-modal.tsx (1 hunks)
  • apps/web/core/components/dropdowns/date-range.tsx (1 hunks)
  • apps/web/core/components/dropdowns/date.tsx (1 hunks)
  • apps/web/core/components/inbox/modals/snooze-issue-modal.tsx (1 hunks)
  • apps/web/package.json (0 hunks)
  • packages/propel/.storybook/preview.ts (1 hunks)
  • packages/propel/package.json (3 hunks)
  • packages/propel/src/calendar/calendar.stories.tsx (1 hunks)
  • packages/propel/src/calendar/index.ts (1 hunks)
  • packages/propel/src/calendar/root.tsx (1 hunks)
  • packages/propel/tsdown.config.ts (1 hunks)
  • packages/ui/src/calendar.tsx (0 hunks)
  • packages/ui/src/index.ts (0 hunks)
💤 Files with no reviewable changes (3)
  • packages/ui/src/index.ts
  • apps/web/package.json
  • packages/ui/src/calendar.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-04T16:22:44.344Z
Learnt from: lifeiscontent
PR: makeplane/plane#7164
File: packages/ui/.storybook/main.ts:24-47
Timestamp: 2025-06-04T16:22:44.344Z
Learning: In packages/ui/.storybook/main.ts, the webpackFinal function intentionally overrides the CSS loader strategy by finding and replacing existing CSS rules. This is a temporary workaround for a known upstream issue in Storybook's CSS handling that has been communicated to the Storybook maintainers. The current implementation should not be changed until the upstream issue is resolved.

Applied to files:

  • packages/propel/.storybook/preview.ts
🧬 Code graph analysis (1)
packages/propel/src/calendar/calendar.stories.tsx (1)
packages/propel/src/calendar/root.tsx (1)
  • Calendar (11-38)
🪛 GitHub Check: Build and lint web apps
packages/propel/src/calendar/calendar.stories.tsx

[failure] 5-5:
An interface declaring no members is equivalent to its supertype

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (12)
apps/web/app/(all)/layout.tsx (1)

8-8: No lingering old stylesheet references; migration complete
Verified there are no imports or files for the old react-day-picker.css and all consumers now import from @plane/propel/styles/react-day-picker.

packages/propel/.storybook/preview.ts (1)

3-3: Storybook CSS import is appropriate for local dev

Importing from src keeps HMR tight for Storybook. No change requested.

packages/propel/package.json (2)

21-34: Exports and copy step verified
Calendar and react-day-picker CSS subpath exports match their dist paths and tsdown copies src/styles as configured, so importing the CSS subpath will work.


41-57: Confirm no react-day-picker usage in apps/web
No references found in apps/web/package.json or code imports/requires; safe to merge.

packages/propel/tsdown.config.ts (2)

7-8: Calendar entry added to build surface—LGTM

Including src/calendar/index.ts ensures types and JS ship properly.


27-28: Verify CSS export path Ensure that after running the build, react-day-picker.css is located at packages/propel/dist/styles/react-day-picker.css.

apps/web/core/components/core/filters/date-filter-modal.tsx (1)

8-9: Import migration to Propel calendar looks correct

Decouples the app from UI’s calendar. Button import separation is fine.

apps/web/core/components/inbox/modals/snooze-issue-modal.tsx (2)

7-8: Calendar import migration looks good.

Importing Calendar from @plane/propel/calendar and keeping Button from @plane/ui aligns with the package split.


1-85: Resolve DayPicker style and dependency checks: CSS import from @plane/propel/styles/react-day-picker is present, no direct react-day-picker imports or Calendar from @plane/ui remain, and the react-day-picker dependency has been moved to packages/propel.

packages/propel/src/calendar/index.ts (1)

1-2: Barrel and type re-exports look correct.

Re-exporting Calendar and the Matcher/DateRange types from one place simplifies app imports.

apps/web/core/components/dropdowns/date-range.tsx (1)

12-13: Good consolidation of imports via Propel.

Pulling Calendar, DateRange, and Matcher from @plane/propel/calendar removes the app’s direct coupling to react-day-picker.

apps/web/core/components/dropdowns/date.tsx (1)

8-9: Import migration looks good.

Using Calendar and Matcher from @plane/propel/calendar with ComboDropDown from @plane/ui matches the new split.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant