Skip to content

Commit f6fcf3f

Browse files
authored
RAC: Support hover event props (#5351)
1 parent 6bc8bc7 commit f6fcf3f

25 files changed

+154
-51
lines changed

packages/react-aria-components/src/Button.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* OF ANY KIND, either express or implied. See the License for the specific language
1010
* governing permissions and limitations under the License.
1111
*/
12-
import {AriaButtonProps, mergeProps, useButton, useFocusRing, useHover} from 'react-aria';
12+
import {AriaButtonProps, HoverEvents, mergeProps, useButton, useFocusRing, useHover} from 'react-aria';
1313
import {ContextValue, createHideableComponent, RenderProps, SlotProps, useContextProps, useRenderProps} from './utils';
1414
import {filterDOMProps} from '@react-aria/utils';
1515
import React, {createContext, ForwardedRef} from 'react';
@@ -42,7 +42,7 @@ export interface ButtonRenderProps {
4242
isDisabled: boolean
4343
}
4444

45-
export interface ButtonProps extends Omit<AriaButtonProps, 'children' | 'href' | 'target' | 'rel' | 'elementType'>, SlotProps, RenderProps<ButtonRenderProps> {
45+
export interface ButtonProps extends Omit<AriaButtonProps, 'children' | 'href' | 'target' | 'rel' | 'elementType'>, HoverEvents, SlotProps, RenderProps<ButtonRenderProps> {
4646
/**
4747
* The <form> element to associate the button with.
4848
* The value of this attribute must be the id of a <form> in the same document.

packages/react-aria-components/src/Calendar.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {ButtonContext} from './Button';
1414
import {CalendarDate, createCalendar, DateDuration, endOfMonth, getWeeksInMonth, isSameDay, isSameMonth} from '@internationalized/date';
1515
import {CalendarState, RangeCalendarState, useCalendarState, useRangeCalendarState} from 'react-stately';
1616
import {ContextValue, DOMProps, forwardRefType, Provider, RenderProps, SlotProps, StyleProps, useContextProps, useRenderProps} from './utils';
17-
import {DOMAttributes, FocusableElement} from '@react-types/shared';
17+
import {DOMAttributes, FocusableElement, HoverEvents} from '@react-types/shared';
1818
import {filterDOMProps, useObjectRef} from '@react-aria/utils';
1919
import {HeadingContext} from './Heading';
2020
import React, {createContext, ForwardedRef, forwardRef, ReactElement, useContext} from 'react';
@@ -459,7 +459,7 @@ function CalendarGridBody(props: CalendarGridBodyProps, ref: ForwardedRef<HTMLTa
459459
const CalendarGridBodyForwardRef = /*#__PURE__*/ (forwardRef as forwardRefType)(CalendarGridBody);
460460
export {CalendarGridBodyForwardRef as CalendarGridBody};
461461

462-
export interface CalendarCellProps extends RenderProps<CalendarCellRenderProps> {
462+
export interface CalendarCellProps extends RenderProps<CalendarCellRenderProps>, HoverEvents {
463463
/** The date to render in the cell. */
464464
date: CalendarDate
465465
}
@@ -476,7 +476,7 @@ function CalendarCell({date, ...otherProps}: CalendarCellProps, ref: ForwardedRe
476476
objectRef
477477
);
478478

479-
let {hoverProps, isHovered} = useHover({isDisabled: states.isDisabled});
479+
let {hoverProps, isHovered} = useHover({...otherProps, isDisabled: states.isDisabled});
480480
let {focusProps, isFocusVisible} = useFocusRing();
481481
let isOutsideMonth = !isSameMonth(currentMonth, date);
482482
let isSelectionStart = false;

packages/react-aria-components/src/Checkbox.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* OF ANY KIND, either express or implied. See the License for the specific language
1010
* governing permissions and limitations under the License.
1111
*/
12-
import {AriaCheckboxGroupProps, AriaCheckboxProps, mergeProps, useCheckbox, useCheckboxGroup, useCheckboxGroupItem, useFocusRing, useHover, usePress, VisuallyHidden} from 'react-aria';
12+
import {AriaCheckboxGroupProps, AriaCheckboxProps, HoverEvents, mergeProps, useCheckbox, useCheckboxGroup, useCheckboxGroupItem, useFocusRing, useHover, usePress, VisuallyHidden} from 'react-aria';
1313
import {CheckboxGroupState, useCheckboxGroupState, useToggleState} from 'react-stately';
1414
import {ContextValue, forwardRefType, Provider, RACValidation, RenderProps, SlotProps, useContextProps, useRenderProps, useSlot} from './utils';
1515
import {FieldErrorContext} from './FieldError';
@@ -19,7 +19,7 @@ import React, {createContext, ForwardedRef, forwardRef, useContext, useState} fr
1919
import {TextContext} from './Text';
2020

2121
export interface CheckboxGroupProps extends Omit<AriaCheckboxGroupProps, 'children' | 'label' | 'description' | 'errorMessage' | 'validationState' | 'validationBehavior'>, RACValidation, RenderProps<CheckboxGroupRenderProps>, SlotProps {}
22-
export interface CheckboxProps extends Omit<AriaCheckboxProps, 'children' | 'validationState'>, RACValidation, RenderProps<CheckboxRenderProps>, SlotProps {}
22+
export interface CheckboxProps extends Omit<AriaCheckboxProps, 'children' | 'validationState'>, HoverEvents, RACValidation, RenderProps<CheckboxRenderProps>, SlotProps {}
2323

2424
export interface CheckboxGroupRenderProps {
2525
/**
@@ -201,6 +201,7 @@ function Checkbox(props: CheckboxProps, ref: ForwardedRef<HTMLInputElement>) {
201201
});
202202

203203
let {hoverProps, isHovered} = useHover({
204+
...props,
204205
isDisabled: isInteractionDisabled
205206
});
206207

packages/react-aria-components/src/DateField.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* OF ANY KIND, either express or implied. See the License for the specific language
1010
* governing permissions and limitations under the License.
1111
*/
12-
import {AriaDateFieldProps, AriaTimeFieldProps, DateValue, mergeProps, TimeValue, useDateField, useDateSegment, useFocusRing, useHover, useLocale, useTimeField} from 'react-aria';
12+
import {AriaDateFieldProps, AriaTimeFieldProps, DateValue, HoverEvents, mergeProps, TimeValue, useDateField, useDateSegment, useFocusRing, useHover, useLocale, useTimeField} from 'react-aria';
1313
import {ContextValue, forwardRefType, Provider, RACValidation, removeDataAttributes, RenderProps, SlotProps, StyleRenderProps, useContextProps, useRenderProps, useSlot} from './utils';
1414
import {createCalendar} from '@internationalized/date';
1515
import {DateFieldState, DateSegmentType, DateSegment as IDateSegment, TimeFieldState, useDateFieldState, useTimeFieldState} from 'react-stately';
@@ -300,7 +300,7 @@ export interface DateSegmentRenderProps extends Omit<IDateSegment, 'isEditable'>
300300
type: DateSegmentType
301301
}
302302

303-
export interface DateSegmentProps extends RenderProps<DateSegmentRenderProps> {
303+
export interface DateSegmentProps extends RenderProps<DateSegmentRenderProps>, HoverEvents {
304304
segment: IDateSegment
305305
}
306306

@@ -311,7 +311,7 @@ function DateSegment({segment, ...otherProps}: DateSegmentProps, ref: ForwardedR
311311
let domRef = useObjectRef(ref);
312312
let {segmentProps} = useDateSegment(segment, state, domRef);
313313
let {focusProps, isFocused, isFocusVisible} = useFocusRing();
314-
let {hoverProps, isHovered} = useHover({isDisabled: state.isDisabled || segment.type === 'literal'});
314+
let {hoverProps, isHovered} = useHover({...otherProps, isDisabled: state.isDisabled || segment.type === 'literal'});
315315
let renderProps = useRenderProps({
316316
...otherProps,
317317
values: {

packages/react-aria-components/src/DatePicker.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export interface DatePickerRenderProps {
4242
isDisabled: boolean,
4343
/**
4444
* Whether the date picker is invalid.
45-
* @selector [data-disabled]
45+
* @selector [data-invalid]
4646
*/
4747
isInvalid: boolean,
4848
/**

packages/react-aria-components/src/DropZone.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import {AriaLabelingProps} from '@react-types/shared';
13+
import {AriaLabelingProps, HoverEvents} from '@react-types/shared';
1414
import {ContextValue, Provider, RenderProps, SlotProps, useContextProps, useRenderProps} from './utils';
1515
import {DropOptions, mergeProps, useClipboard, useDrop, useFocusRing, useHover, useLocalizedStringFormatter, VisuallyHidden} from 'react-aria';
1616
import {filterDOMProps, useLabels, useSlotId} from '@react-aria/utils';
@@ -42,15 +42,15 @@ export interface DropZoneRenderProps {
4242
isDropTarget: boolean
4343
}
4444

45-
export interface DropZoneProps extends Omit<DropOptions, 'getDropOperationForPoint' | 'ref' | 'hasDropButton'>, RenderProps<DropZoneRenderProps>, SlotProps, AriaLabelingProps {}
45+
export interface DropZoneProps extends Omit<DropOptions, 'getDropOperationForPoint' | 'ref' | 'hasDropButton'>, HoverEvents, RenderProps<DropZoneRenderProps>, SlotProps, AriaLabelingProps {}
4646

4747
export const DropZoneContext = createContext<ContextValue<DropZoneProps, HTMLDivElement>>(null);
4848

4949
function DropZone(props: DropZoneProps, ref: ForwardedRef<HTMLDivElement>) {
5050
[props, ref] = useContextProps(props, ref, DropZoneContext);
5151
let buttonRef = useRef<HTMLButtonElement>(null);
5252
let {dropProps, dropButtonProps, isDropTarget} = useDrop({...props, ref: buttonRef, hasDropButton: true});
53-
let {hoverProps, isHovered} = useHover({});
53+
let {hoverProps, isHovered} = useHover(props);
5454
let {focusProps, isFocused, isFocusVisible} = useFocusRing();
5555
let stringFormatter = useLocalizedStringFormatter(intlMessages);
5656

packages/react-aria-components/src/Group.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import {AriaLabelingProps} from '@react-types/shared';
13+
import {AriaLabelingProps, HoverEvents} from '@react-types/shared';
1414
import {ContextValue, StyleRenderProps, useContextProps, useRenderProps} from './utils';
1515
import {mergeProps, useFocusRing, useHover} from 'react-aria';
1616
import React, {createContext, ForwardedRef, forwardRef, HTMLAttributes} from 'react';
@@ -43,7 +43,7 @@ export interface GroupRenderProps {
4343
isInvalid: boolean
4444
}
4545

46-
export interface GroupProps extends AriaLabelingProps, Omit<HTMLAttributes<HTMLElement>, 'className' | 'style' | 'role'>, StyleRenderProps<GroupRenderProps> {
46+
export interface GroupProps extends AriaLabelingProps, Omit<HTMLAttributes<HTMLElement>, 'className' | 'style' | 'role'>, HoverEvents, StyleRenderProps<GroupRenderProps> {
4747
/** Whether the group is disabled. */
4848
isDisabled?: boolean,
4949
/** Whether the group is invalid. */
@@ -63,7 +63,7 @@ export const GroupContext = createContext<ContextValue<GroupProps, HTMLDivElemen
6363
function Group(props: GroupProps, ref: ForwardedRef<HTMLDivElement>) {
6464
[props, ref] = useContextProps(props, ref, GroupContext);
6565

66-
let {hoverProps, isHovered} = useHover({});
66+
let {hoverProps, isHovered} = useHover(props);
6767
let {isFocused, isFocusVisible, focusProps} = useFocusRing({
6868
within: true
6969
});

packages/react-aria-components/src/Input.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*/
1212

1313
import {ContextValue, createHideableComponent, StyleRenderProps, useContextProps, useRenderProps} from './utils';
14-
import {mergeProps, useFocusRing, useHover} from 'react-aria';
14+
import {HoverEvents, mergeProps, useFocusRing, useHover} from 'react-aria';
1515
import React, {createContext, ForwardedRef, InputHTMLAttributes} from 'react';
1616

1717
export interface InputRenderProps {
@@ -42,14 +42,20 @@ export interface InputRenderProps {
4242
isInvalid: boolean
4343
}
4444

45-
export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'className' | 'style'>, StyleRenderProps<InputRenderProps> {}
45+
export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'className' | 'style'>, HoverEvents, StyleRenderProps<InputRenderProps> {}
4646

4747
export const InputContext = createContext<ContextValue<InputProps, HTMLInputElement>>({});
4848

49+
let filterHoverProps = (props: InputProps) => {
50+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
51+
let {onHoverStart, onHoverChange, onHoverEnd, ...otherProps} = props;
52+
return otherProps;
53+
};
54+
4955
function Input(props: InputProps, ref: ForwardedRef<HTMLInputElement>) {
5056
[props, ref] = useContextProps(props, ref, InputContext);
5157

52-
let {hoverProps, isHovered} = useHover({});
58+
let {hoverProps, isHovered} = useHover(props);
5359
let {isFocused, isFocusVisible, focusProps} = useFocusRing({
5460
isTextInput: true,
5561
autoFocus: props.autoFocus
@@ -70,7 +76,7 @@ function Input(props: InputProps, ref: ForwardedRef<HTMLInputElement>) {
7076

7177
return (
7278
<input
73-
{...mergeProps(props, focusProps, hoverProps)}
79+
{...mergeProps(filterHoverProps(props), focusProps, hoverProps)}
7480
{...renderProps}
7581
ref={ref}
7682
data-focused={isFocused || undefined}

packages/react-aria-components/src/Link.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import {AriaLinkOptions, mergeProps, useFocusRing, useHover, useLink} from 'react-aria';
13+
import {AriaLinkOptions, HoverEvents, mergeProps, useFocusRing, useHover, useLink} from 'react-aria';
1414
import {ContextValue, forwardRefType, RenderProps, SlotProps, useContextProps, useRenderProps} from './utils';
1515
import React, {createContext, ElementType, ForwardedRef, forwardRef} from 'react';
1616

17-
export interface LinkProps extends Omit<AriaLinkOptions, 'elementType'>, RenderProps<LinkRenderProps>, SlotProps {}
17+
export interface LinkProps extends Omit<AriaLinkOptions, 'elementType'>, HoverEvents, RenderProps<LinkRenderProps>, SlotProps {}
1818

1919
export interface LinkRenderProps {
2020
/**

packages/react-aria-components/src/RadioGroup.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import {AriaRadioGroupProps, AriaRadioProps, Orientation, useFocusRing, useHover, usePress, useRadio, useRadioGroup, VisuallyHidden} from 'react-aria';
13+
import {AriaRadioGroupProps, AriaRadioProps, HoverEvents, Orientation, useFocusRing, useHover, usePress, useRadio, useRadioGroup, VisuallyHidden} from 'react-aria';
1414
import {ContextValue, forwardRefType, Provider, RACValidation, removeDataAttributes, RenderProps, SlotProps, useContextProps, useRenderProps, useSlot} from './utils';
1515
import {FieldErrorContext} from './FieldError';
1616
import {filterDOMProps, mergeProps, useObjectRef} from '@react-aria/utils';
@@ -20,7 +20,7 @@ import React, {createContext, ForwardedRef, forwardRef, useState} from 'react';
2020
import {TextContext} from './Text';
2121

2222
export interface RadioGroupProps extends Omit<AriaRadioGroupProps, 'children' | 'label' | 'description' | 'errorMessage' | 'validationState' | 'validationBehavior'>, RACValidation, RenderProps<RadioGroupRenderProps>, SlotProps {}
23-
export interface RadioProps extends Omit<AriaRadioProps, 'children'>, RenderProps<RadioRenderProps>, SlotProps {}
23+
export interface RadioProps extends Omit<AriaRadioProps, 'children'>, HoverEvents, RenderProps<RadioRenderProps>, SlotProps {}
2424

2525
export interface RadioGroupRenderProps {
2626
/**
@@ -192,6 +192,7 @@ function Radio(props: RadioProps, ref: ForwardedRef<HTMLInputElement>) {
192192
});
193193

194194
let {hoverProps, isHovered} = useHover({
195+
...props,
195196
isDisabled: interactionDisabled
196197
});
197198

0 commit comments

Comments
 (0)