jbpenrath
2025-01-07 23:28:47 +01:00
committed by Jean-Baptiste PENRATH
parent 0f6a8dfa72
commit 56d9ed88f0
27 changed files with 1497 additions and 1546 deletions

View File

@@ -1,9 +1,8 @@
import React, {
forwardRef,
PropsWithChildren,
Ref,
useMemo,
useRef,
RefAttributes,
} from "react";
import {
DateRangePickerState,
@@ -36,7 +35,8 @@ export type DatePickerAuxSubProps = FieldProps & {
};
export type DatePickerAuxProps = PropsWithChildren &
DatePickerAuxSubProps & {
DatePickerAuxSubProps &
RefAttributes<HTMLDivElement> & {
pickerState: DateRangePickerState | DatePickerState;
pickerProps: Pick<
DateRangePickerAria | DatePickerAria,
@@ -54,154 +54,147 @@ export type DatePickerAuxProps = PropsWithChildren &
* This component is used by date and date range picker components.
* It contains the common logic between the two.
*/
const DatePickerAux = forwardRef(
(
{
className,
pickerState,
pickerProps,
onClear,
isFocused,
labelAsPlaceholder,
calendar,
children,
name,
locale,
disabled = false,
optionalClassName,
isRange,
...props
}: DatePickerAuxProps,
ref: Ref<HTMLDivElement>,
) => {
const { t, currentLocale } = useCunningham();
const pickerRef = useRef<HTMLDivElement>(null);
const DatePickerAux = ({
className,
pickerState,
pickerProps,
onClear,
isFocused,
labelAsPlaceholder,
calendar,
children,
name,
locale,
disabled = false,
optionalClassName,
isRange,
ref,
...props
}: DatePickerAuxProps) => {
const { t, currentLocale } = useCunningham();
const pickerRef = useRef<HTMLDivElement>(null);
const isDateInvalid = useMemo(
() =>
pickerState.validationState === "invalid" || props.state === "error",
[pickerState.validationState, props.state],
);
const isDateInvalid = useMemo(
() => pickerState.validationState === "invalid" || props.state === "error",
[pickerState.validationState, props.state],
);
return (
<I18nProvider locale={locale || currentLocale}>
<Field
{...props}
className={classNames(className, {
"c__date-picker__range__container": isRange,
return (
<I18nProvider locale={locale || currentLocale}>
<Field
{...props}
className={classNames(className, {
"c__date-picker__range__container": isRange,
})}
>
<div
ref={pickerRef}
className={classNames(["c__date-picker", optionalClassName], {
"c__date-picker--disabled": disabled,
"c__date-picker--invalid": isDateInvalid,
"c__date-picker--success": props.state === "success",
"c__date-picker--focused":
!isDateInvalid && !disabled && (pickerState.isOpen || isFocused),
})}
>
<div
ref={pickerRef}
className={classNames(["c__date-picker", optionalClassName], {
"c__date-picker--disabled": disabled,
"c__date-picker--invalid": isDateInvalid,
"c__date-picker--success": props.state === "success",
"c__date-picker--focused":
!isDateInvalid &&
!disabled &&
(pickerState.isOpen || isFocused),
className={classNames("c__date-picker__wrapper", {
"c__date-picker__wrapper--clickable": labelAsPlaceholder,
})}
ref={ref}
{...pickerProps.groupProps}
role="button"
tabIndex={0}
onClick={() => !pickerState.isOpen && pickerState.open()}
>
<div
className={classNames("c__date-picker__wrapper", {
"c__date-picker__wrapper--clickable": labelAsPlaceholder,
})}
ref={ref}
{...pickerProps.groupProps}
role="button"
tabIndex={0}
onClick={() => !pickerState.isOpen && pickerState.open()}
>
{"dateRange" in pickerState ? (
<>
<input
type="hidden"
name={name && `${name}_start`}
value={convertDateValueToString(
pickerState.value?.start ?? null,
props.timezone,
)}
/>
<input
type="hidden"
name={name && `${name}_end`}
value={convertDateValueToString(
pickerState.value?.end ?? null,
props.timezone,
)}
/>
</>
) : (
{"dateRange" in pickerState ? (
<>
<input
type="hidden"
name={name}
name={name && `${name}_start`}
value={convertDateValueToString(
pickerState.value,
pickerState.value?.start ?? null,
props.timezone,
)}
/>
)}
<div className="c__date-picker__wrapper__icon">
<Button
type="button"
onKeyDown={(e) => {
if (e.key === "Enter") {
pickerState.toggle();
}
}}
onClick={pickerState.toggle}
aria-label={t(
pickerState.isOpen
? "components.forms.date_picker.toggle_button_aria_label_close"
: "components.forms.date_picker.toggle_button_aria_label_open",
<input
type="hidden"
name={name && `${name}_end`}
value={convertDateValueToString(
pickerState.value?.end ?? null,
props.timezone,
)}
color="tertiary-text"
size="small"
className="c__date-picker__wrapper__toggle"
icon={
<span className="material-icons icon">calendar_today</span>
}
disabled={disabled}
/>
</div>
{children}
</>
) : (
<input
type="hidden"
name={name}
value={convertDateValueToString(
pickerState.value,
props.timezone,
)}
/>
)}
<div className="c__date-picker__wrapper__icon">
<Button
className={classNames("c__date-picker__inner__action", {
"c__date-picker__inner__action--empty": !pickerState.value,
"c__date-picker__inner__action--hidden":
labelAsPlaceholder || disabled,
})}
color="tertiary-text"
size="nano"
icon={<span className="material-icons">close</span>}
onClick={onClear}
type="button"
onKeyDown={(e) => {
if (e.key === "Enter") {
onClear();
pickerState.toggle();
}
}}
onClick={pickerState.toggle}
aria-label={t(
"components.forms.date_picker.clear_button_aria_label",
pickerState.isOpen
? "components.forms.date_picker.toggle_button_aria_label_close"
: "components.forms.date_picker.toggle_button_aria_label_open",
)}
color="tertiary-text"
size="small"
className="c__date-picker__wrapper__toggle"
icon={
<span className="material-icons icon">calendar_today</span>
}
disabled={disabled}
type="button"
/>
</div>
{pickerState.isOpen && (
<Popover
parentRef={pickerRef}
onClickOutside={pickerState.close}
borderless
>
{calendar}
</Popover>
)}
{children}
<Button
className={classNames("c__date-picker__inner__action", {
"c__date-picker__inner__action--empty": !pickerState.value,
"c__date-picker__inner__action--hidden":
labelAsPlaceholder || disabled,
})}
color="tertiary-text"
size="nano"
icon={<span className="material-icons">close</span>}
onClick={onClear}
onKeyDown={(e) => {
if (e.key === "Enter") {
onClear();
}
}}
aria-label={t(
"components.forms.date_picker.clear_button_aria_label",
)}
disabled={disabled}
type="button"
/>
</div>
</Field>
</I18nProvider>
);
},
);
{pickerState.isOpen && (
<Popover
parentRef={pickerRef}
onClickOutside={pickerState.close}
borderless
>
{calendar}
</Popover>
)}
</div>
</Field>
</I18nProvider>
);
};
export default DatePickerAux;