Skip to content

useRangeCalendarState should allow controlling selectionAlignment #4721

@longzheng

Description

@longzheng

🙋 Feature Request

The useRangeCalendarState should allow controlling the selectionAlignment prop of useCalendarState

/** Determines how to align the initial selection relative to the visible date range. */
selectionAlignment?: 'start' | 'center' | 'end'

🤔 Expected Behavior

Allow setting selectionAlignment

😯 Current Behavior

Does not allow setting selectionAlignment, it is automatically calculated from value

let alignment: 'center' | 'start' = 'center';
if (value && value.start && value.end) {
let start = alignCenter(toCalendarDate(value.start), visibleDuration, locale, minValue, maxValue);
let end = start.add(visibleDuration).subtract({days: 1});
if (value.end.compare(end) > 0) {
alignment = 'start';
}
}

💁 Possible Solution

There should be a selectionAlignment prop and use the prop value if it is set and fallback to the existing value logic if there is no prop value.

Maybe something like these changes to useRangeCalendarState.ts

export interface RangeCalendarStateOptions<T extends DateValue = DateValue> extends RangeCalendarProps<T> {
    /** The locale to display and edit the value according to. */
    locale: string;
    /**
     * A function that creates a [Calendar](../internationalized/date/Calendar.html)
     * object for a given calendar identifier. Such a function may be imported from the
     * `@internationalized/date` package, or manually implemented to include support for
     * only certain calendars.
     */
    createCalendar: (name: string) => Calendar;
    /**
     * The amount of days that will be displayed at once. This affects how pagination works.
     * @default {months: 1}
     */
    visibleDuration?: DateDuration;
+   /** Determines how to align the initial selection relative to the visible date range. */
+   selectionAlignment?: 'start' | 'center' | 'end';
}
  let calendar = useCalendarState({
    ...calendarProps,
    value: value && value.start,
    createCalendar,
    locale,
    visibleDuration,
    minValue: min,
    maxValue: max,
-   selectionAlignment: alignment
+   selectionAlignment: props.selectionAlignment ?? alignment
  });

🔦 Context

I want to show a range calendar with 2 months but the selection should always be aligned at the start, so it should always start on the left/first month.

💻 Examples

Without this fix, sometimes my range selection start is shown on the right month.

image

I want it always be shown on the left month.

image

🧢 Your Company/Team

🎁 Tracking Ticket (optional)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    ✅ Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions