SelectSingleContext.tsx
2.67 KB
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
import { createContext, ReactNode, useContext } from 'react';
import { DayPickerBase } from 'types/DayPickerBase';
import { DayPickerSingleProps, isDayPickerSingle } from 'types/DayPickerSingle';
import { DayClickEventHandler } from 'types/EventHandlers';
/** Represents the value of a {@link SelectSingleContext}. */
export interface SelectSingleContextValue {
/** The day that has been selected. */
selected: Date | undefined;
/** Event handler to attach to the day button to enable the single select. */
onDayClick?: DayClickEventHandler;
}
/**
* The SelectSingle context shares details about the selected days when in
* single selection mode.
*
* Access this context from the {@link useSelectSingle} hook.
*/
export const SelectSingleContext = createContext<
SelectSingleContextValue | undefined
>(undefined);
export interface SelectSingleProviderProps {
initialProps: DayPickerBase;
children?: ReactNode;
}
/** Provides the values for the {@link SelectSingleProvider}. */
export function SelectSingleProvider(
props: SelectSingleProviderProps
): JSX.Element {
if (!isDayPickerSingle(props.initialProps)) {
const emptyContextValue: SelectSingleContextValue = {
selected: undefined
};
return (
<SelectSingleContext.Provider value={emptyContextValue}>
{props.children}
</SelectSingleContext.Provider>
);
}
return (
<SelectSingleProviderInternal
initialProps={props.initialProps}
children={props.children}
/>
);
}
/** @private */
export interface SelectSingleProviderInternal {
initialProps: DayPickerSingleProps;
children?: ReactNode;
}
export function SelectSingleProviderInternal({
initialProps,
children
}: SelectSingleProviderInternal): JSX.Element {
const onDayClick: DayClickEventHandler = (day, activeModifiers, e) => {
initialProps.onDayClick?.(day, activeModifiers, e);
if (activeModifiers.selected && !initialProps.required) {
initialProps.onSelect?.(undefined, day, activeModifiers, e);
return;
}
initialProps.onSelect?.(day, day, activeModifiers, e);
};
const contextValue: SelectSingleContextValue = {
selected: initialProps.selected,
onDayClick
};
return (
<SelectSingleContext.Provider value={contextValue}>
{children}
</SelectSingleContext.Provider>
);
}
/**
* Hook to access the {@link SelectSingleContextValue}.
*
* This hook is meant to be used inside internal or custom components.
*/
export function useSelectSingle(): SelectSingleContextValue {
const context = useContext(SelectSingleContext);
if (!context) {
throw new Error(
'useSelectSingle must be used within a SelectSingleProvider'
);
}
return context;
}