bc518174
王天杨
提交两个项目文件
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
import { RefObject, useEffect } from 'react';
import { isSameDay } from 'date-fns';
import { ButtonProps } from 'components/Button';
import { DayContent } from 'components/DayContent';
import { useDayPicker } from 'contexts/DayPicker';
import { useFocusContext } from 'contexts/Focus';
import { useActiveModifiers } from 'hooks/useActiveModifiers';
import {
DayEventHandlers,
useDayEventHandlers
} from 'hooks/useDayEventHandlers';
import { SelectedDays, useSelectedDays } from 'hooks/useSelectedDays';
import { ActiveModifiers } from 'types/Modifiers';
import { StyledComponent } from 'types/Styles';
import { getDayClassNames } from './utils/getDayClassNames';
import { getDayStyle } from './utils/getDayStyle';
export type DayRender = {
/** Whether the day should be rendered a `button` instead of a `div` */
isButton: boolean;
/** Whether the day should be hidden. */
isHidden: boolean;
/** The modifiers active for the given day. */
activeModifiers: ActiveModifiers;
/** The props to apply to the button element (when `isButton` is true). */
buttonProps: StyledComponent &
Pick<ButtonProps, 'disabled' | 'aria-selected' | 'tabIndex'> &
DayEventHandlers;
/** The props to apply to the div element (when `isButton` is false). */
divProps: StyledComponent;
selectedDays: SelectedDays;
};
/**
* Return props and data used to render the {@link Day} component.
*
* Use this hook when creating a component to replace the built-in `Day`
* component.
*/
export function useDayRender(
/** The date to render. */
day: Date,
/** The month where the date is displayed (if not the same as `date`, it means it is an "outside" day). */
displayMonth: Date,
/** A ref to the button element that will be target of focus when rendered (if required). */
buttonRef: RefObject<HTMLButtonElement>
): DayRender {
const dayPicker = useDayPicker();
const focusContext = useFocusContext();
const activeModifiers = useActiveModifiers(day, displayMonth);
const eventHandlers = useDayEventHandlers(day, activeModifiers);
const selectedDays = useSelectedDays();
const isButton = Boolean(
dayPicker.onDayClick || dayPicker.mode !== 'default'
);
// Focus the button if the day is focused according to the focus context
useEffect(() => {
if (activeModifiers.outside) return;
if (!focusContext.focusedDay) return;
if (!isButton) return;
if (isSameDay(focusContext.focusedDay, day)) {
buttonRef.current?.focus();
}
}, [
focusContext.focusedDay,
day,
buttonRef,
isButton,
activeModifiers.outside
]);
const className = getDayClassNames(dayPicker, activeModifiers).join(' ');
const style = getDayStyle(dayPicker, activeModifiers);
const isHidden = Boolean(
(activeModifiers.outside && !dayPicker.showOutsideDays) ||
activeModifiers.hidden
);
const DayContentComponent = dayPicker.components?.DayContent ?? DayContent;
const children = (
<DayContentComponent
date={day}
displayMonth={displayMonth}
activeModifiers={activeModifiers}
/>
);
const divProps = {
style,
className,
children,
role: 'gridcell'
};
const isFocusTarget =
focusContext.focusTarget &&
isSameDay(focusContext.focusTarget, day) &&
!activeModifiers.outside;
const isFocused =
focusContext.focusedDay && isSameDay(focusContext.focusedDay, day);
const buttonProps = {
...divProps,
disabled: activeModifiers.disabled,
role: 'gridcell',
['aria-selected']: activeModifiers.selected,
tabIndex: isFocused || isFocusTarget ? 0 : -1,
...eventHandlers
};
const dayRender: DayRender = {
isButton,
isHidden,
activeModifiers: activeModifiers,
selectedDays,
buttonProps,
divProps
};
return dayRender;
}
|