From dc85636f8738fa976b9e87401a613909ef48bb1a Mon Sep 17 00:00:00 2001 From: Rohan Chakraborty Date: Wed, 24 Sep 2025 14:12:11 +0530 Subject: [PATCH 1/2] feat: support popover props in datepicker and rangepicker --- .../raystack/components/calendar/calendar.tsx | 2 +- .../components/calendar/date-picker.tsx | 32 +++++++++++-------- .../components/calendar/range-picker.tsx | 14 +++++--- .../raystack/components/popover/popover.tsx | 2 +- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/packages/raystack/components/calendar/calendar.tsx b/packages/raystack/components/calendar/calendar.tsx index 811d73ae..fcba549a 100644 --- a/packages/raystack/components/calendar/calendar.tsx +++ b/packages/raystack/components/calendar/calendar.tsx @@ -54,7 +54,7 @@ function DropDown({ useEffect(() => { if (open && onDropdownOpen) onDropdownOpen(); - }, [open]); + }, [open, onDropdownOpen]); function handleChange(value: string) { if (onChange) { diff --git a/packages/raystack/components/calendar/date-picker.tsx b/packages/raystack/components/calendar/date-picker.tsx index 8f657316..640301e2 100644 --- a/packages/raystack/components/calendar/date-picker.tsx +++ b/packages/raystack/components/calendar/date-picker.tsx @@ -1,21 +1,21 @@ 'use client'; import { CalendarIcon } from '@radix-ui/react-icons'; +import { cx } from 'class-variance-authority'; import dayjs from 'dayjs'; import customParseFormat from 'dayjs/plugin/customParseFormat'; import { useCallback, useEffect, useRef, useState } from 'react'; import { PropsBase, PropsSingleRequired } from 'react-day-picker'; - import { InputField } from '../input-field'; import { InputFieldProps } from '../input-field/input-field'; import { Popover } from '../popover'; +import { PopoverContentProps } from '../popover/popover'; import { Calendar } from './calendar'; import styles from './calendar.module.css'; dayjs.extend(customParseFormat); interface DatePickerProps { - side?: 'top' | 'right' | 'bottom' | 'left'; dateFormat?: string; inputFieldProps?: InputFieldProps; calendarProps?: PropsSingleRequired & PropsBase; @@ -26,10 +26,10 @@ interface DatePickerProps { | ((props: { selectedDate: string }) => React.ReactNode); showCalendarIcon?: boolean; timeZone?: string; + popoverProps?: PopoverContentProps; } export function DatePicker({ - side = 'top', dateFormat = 'DD/MM/YYYY', inputFieldProps, calendarProps, @@ -37,7 +37,8 @@ export function DatePicker({ onSelect = () => {}, children, showCalendarIcon = true, - timeZone + timeZone, + popoverProps }: DatePickerProps) { const [showCalendar, setShowCalendar] = useState(false); const [selectedDate, setSelectedDate] = useState(value); @@ -55,19 +56,22 @@ export function DatePicker({ selectedDateRef.current = selectedDate; }, [selectedDate]); - function isElementOutside(el: HTMLElement) { + const isElementOutside = useCallback((el: HTMLElement) => { return ( !isDropdownOpenRef.current && // Month and Year dropdown from Date picker !inputFieldRef.current?.contains(el) && // InputField !contentRef.current?.contains(el) ); - } - - const handleMouseDown = useCallback((event: MouseEvent) => { - const el = event.target as HTMLElement | null; - if (el && isElementOutside(el)) removeEventListeners(); }, []); + const handleMouseDown = useCallback( + (event: MouseEvent) => { + const el = event.target as HTMLElement | null; + if (el && isElementOutside(el)) removeEventListeners(); + }, + [isElementOutside] + ); + function registerEventListeners() { isInputFieldFocused.current = true; document.addEventListener('mouseup', handleMouseDown); @@ -184,17 +188,17 @@ export function DatePicker({ ) : children ? (
{children}
) : ( - defaultTrigger +
{defaultTrigger}
); return ( {trigger} - {trigger} - + { ariaLabel?: string; } From 6f617361eaf55cfce0f75f5174c8349541ba9b44 Mon Sep 17 00:00:00 2001 From: Rohan Chakraborty Date: Wed, 24 Sep 2025 14:27:19 +0530 Subject: [PATCH 2/2] feat: update calendar doc --- apps/www/src/content/docs/components/calendar/index.mdx | 4 ++++ apps/www/src/content/docs/components/calendar/props.ts | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/apps/www/src/content/docs/components/calendar/index.mdx b/apps/www/src/content/docs/components/calendar/index.mdx index 7a5e65d8..b47d7a9c 100644 --- a/apps/www/src/content/docs/components/calendar/index.mdx +++ b/apps/www/src/content/docs/components/calendar/index.mdx @@ -24,10 +24,14 @@ import { Calendar, RangePicker, DatePicker } from '@raystack/apsara' ## RangePicker Props +The RangePicker supports customizing the popover behavior using the `popoverProps` prop. + ## DatePicker Props +The DatePicker supports customizing the popover behavior using the `popoverProps` prop. + ## Examples diff --git a/apps/www/src/content/docs/components/calendar/props.ts b/apps/www/src/content/docs/components/calendar/props.ts index 0c9f4d63..342b8dba 100644 --- a/apps/www/src/content/docs/components/calendar/props.ts +++ b/apps/www/src/content/docs/components/calendar/props.ts @@ -1,4 +1,5 @@ import { InputFieldProps } from '../input-field/props'; +import { PopoverContentProps } from '../popover/props'; export interface CalendarProps { /** Number of months to display */ @@ -74,6 +75,9 @@ export interface RangePickerProps { * If not provided, uses the local timezone. */ timeZone?: string; + + /** Props for customizing the popover */ + popoverProps?: PopoverContentProps; } export interface DatePickerProps { @@ -114,4 +118,7 @@ export interface DatePickerProps { * If not provided, uses the local timezone. */ timeZone?: string; + + /** Props for customizing the popover */ + popoverProps?: PopoverContentProps; }