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 (
{props.children}
);
}
return (
);
}
/** @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 (
{children}
);
}
/**
* 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;
}