adobe / adobe/react-spectrum

Allow providing generic FocusableProps type in DateRangePicker

Open
#5,766 2 comments 0 reactions 0 assignees View on GitHub
help wanted typescript
Dominant language
TypeScript
Stars
15.9k
Forks
1.6k
Avg merge
3d 9m
Merged PRs (30d)
59

Description

### Provide a general summary of the feature here

Currently DateRangePicker has props of type DateRangePickerProps which extends AriaDateRangePickerProps -> AriaDatePickerBaseProps -> DatePickerBase -> DateFieldBase which finally extends FocusableProps

DateFieldBase is not allowing FocusableProps to set custom Target element type (it's always Element)

```
interface DateFieldBase extends InputBase, Validation>, FocusableProps, LabelableProps, HelpTextProps, OverlayTriggerProps {
// ommited for brewity
}
```

This prevents using use of DateRangePicker with libraries like react-final-form, which has onBlur, onFocus event target set as HTMLElement.

Result in type error during compilation:

```
Type 'FocusEvent' is not assignable to type 'FocusEvent'.
```

### 🤔 Expected Behavior?

DateRangePicker, down to DateFieldBase should allow override default Target for FocusableProps.

https://github.com/adobe/react-spectrum/blob/87dbb748cbfd9bd6f53183221b8e2ef96defbfc3/packages/react-aria-components/src/DatePicker.tsx#L156C10-L156C25

### 😯 Current Behavior

DateFieldBase doesn't allow to specify target element element type (it's always typeof Element)

### 💁 Possible Solution

```
interface DateFieldBase extends InputBase, Validation>, FocusableProps, LabelableProps, HelpTextProps, OverlayTriggerProps {
// ommited for brewity
}
```

### 🔦 Context

Creating form wrapper for DateRangePicker using react-final-form is not possible because react-final-form expects onBlur, onFocus event's target to extend HTMLElement:

### 💻 Examples

```
import type { DateRange } from 'react-aria';
import { Field } from 'react-final-form';
import { useTranslation } from 'next-i18next';
import { useCountry } from '@colonnade/api';
import { DateRangePicker } from '@colonnade/react-components';
import { GregorianCalendar, parseDate, toCalendar } from '@internationalized/date';
import { OverlayTriggerProps } from '@react-types/overlays';
import { FocusableProps, HelpTextProps, InputBase, LabelableProps, Validation } from '@react-types/shared';

interface TripValues {
departureDate: string;
returnDate: string;
}

export const InternationalSingleTrip = () => {
const { t } = useTranslation('travel');
const country = useCountry();

const parseDateRange = (value: DateRange | null): TripValues | null => {
if (!value) return null;
return { departureDate: value.start.toString(), returnDate: value.end.toString() };
};

const formatDateRange = (value: TripValues | null): DateRange | null => {
if (!value) return null;

const start = toCalendar(parseDate(value.departureDate), new GregorianCalendar());
const end = toCalendar(parseDate(value.returnDate), new GregorianCalendar());

return { start, end };
};

return (



name="tripDate"
startName="departureDate"
endName="returnDate"
locale={country}
parse={parseDateRange}
format={formatDateRange}
label={t('pages.tripDetails.basicTripInformation.tripDateRange.label')}
>
{({ input, ...otherProps }) => }


);
};

```

### 🧢 Your Company/Team

_No response_

### 🕷 Tracking Issue

_No response_

Contributor guide

Open the contributing guide

Research direction

Start at packages/react-aria-components/src/DatePicker.tsx near the DateRangePicker type definition, then trace the DateRangePickerProps, AriaDateRangePickerProps, DateFieldBase, and FocusableProps types named in the issue. The change is done when a target element type can be supplied through this chain and the react-final-form example no longer produces the FocusEvent type error.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.