
Я пытаюсь использовать DatePicker Ant Design внутри формы, которая отображается внутри модального окна.
DatePicker работает, но панель календаря ведет себя очень странно: числа в сетке календаря выглядят беспорядочно и меняются каждый раз, когда пользователь наводит на него указатель мыши. компонент, почти как если бы они менялись случайным образом.
Ошибок консоли нет, и выбранное значение не меняется — меняется только визуальное расположение календаря при наведении (это похоже на состояние гонки, цикл или нарушенное состояние).
Вот мой компонент DatePicker:
import useTranslation from '@qulture/core/services/hooks/use-translation';
import {
onlyIconDatepickerFormat,
smallYearDateFormat,
} from '@qulture/core/services/locale/locale';
import { moment, Moment } from '@qulture/core/utils/qr-time-utils';
import { DatePicker as AntDatePicker } from 'antd';
import type { DatePickerProps } from 'antd/es/date-picker';
import React, { Fragment, useMemo, useState } from 'react';
import styled from 'styled-components';
import withSpaceProps from '../../../hocs/with-space';
import useDynamicOpenDirection from '../../../hooks/use-dynamic-open-direction';
import ButtonDanger from '../../button/button-danger/button-danger.component';
import Layout from '../../layout/layout.component';
import { INPUT_STYLE } from '../input-style-mapper';
import { IBaseInput } from '../input.interface';
import {
CalendarInfoDivider,
IDatePickerStyledProps,
} from './date-picker.styles';
/*
const DatePickerTypographyFix = styled.div`
.ant-picker-dropdown {
font-family: ${props => props.theme.fontFamily.default};
* {
font-family: ${props => props.theme.fontFamily.default};
font-variant-numeric: tabular-nums;
font-feature-settings: 'tnum';
box-sizing: border-box;
}
.ant-picker-cell-inner {
line-height: 24px;
}
}
`;
export interface IDatePickerProps
extends IBaseInput void, () => void>,
IDatePickerStyledProps {
showInputIcon?: boolean;
placeholder?: string;
startFocused?: boolean;
className?: string;
customButtonContent?: React.ReactElement;
smallYearFormat?: boolean;
showClearButton?: boolean;
onClose?: (date: string | null) => void;
isOutsideRange?: (day: Moment) => boolean;
appendToBody?: boolean;
showClearDate?: boolean;
openDirection?: 'up' | 'down';
anchorDirection?: 'left' | 'right';
block?: boolean;
noBorder?: boolean;
}
const StyledDatePicker = styled(AntDatePicker)`
&&& {
${props => props.$block && 'width: 100%;'}
${props => props.$width && `width: ${props.$width};`}
${props =>
props.$noBorder &&
`
border: none !important;
&:hover, &:focus {
border: none !important;
}
`}
${props =>
props.$error &&
`
border-color: ${props.theme.colors.important} !important;
&:hover, &:focus, &:focus-within {
border-color: ${props.theme.colors.important} !important;
}
`}
${props =>
props.$onlyIcon &&
`
.ant-picker-input > input {
display: none;
}
`}
font-family: ${props => props.theme.fontFamily.default};
.ant-picker-input > input {
font-family: ${props => props.theme.fontFamily.default};
}
}
`;
const BaseDatePicker: React.FC = ({
width,
id,
showInputIcon = true,
placeholder,
value,
onChange,
startFocused,
onBlur,
isOutsideRange,
appendToBody,
disabled,
className,
onlyIcon,
showClearDate,
openDirection,
anchorDirection,
block,
noBorder,
customButtonContent,
smallYearFormat,
openFromText,
textColor,
inputStyle = INPUT_STYLE.base,
showClearButton,
onClose,
error,
}) => {
const [focused, setFocus] = useState(startFocused);
const { verticalDirection: dynamicOpenDirection, containerRef } =
useDynamicOpenDirection();
const { t } = useTranslation();
const memoizedValue = useMemo(() => (value ? moment(value) : null), [value]);
const calculatedOpenDirection = openDirection || dynamicOpenDirection;
const handleDateChange: DatePickerProps['onChange'] = date => {
const newDate = date ? moment(date).utc().toISOString() : null;
onChange(newDate);
};
const handleOpenChange = (open: boolean): void => {
setFocus(open);
if (!open) {
onBlur?.();
onClose?.(value);
}
};
const handleRemove = (): void => {
onChange(null);
onClose?.(null);
};
const disabledDate: DatePickerProps['disabledDate'] = current => {
if (isOutsideRange && current) {
return isOutsideRange(moment(current));
}
return false;
};
const onlyIconDateFormat = smallYearFormat
? moment(value).format(smallYearDateFormat())
: moment(value).format(onlyIconDatepickerFormat());
const renderExtraFooter = (): React.ReactElement => {
return showClearButton ? (
{t('shared:remove')}
) : null;
};
console.log('memoizedValue', memoizedValue);
return (
trigger.parentElement || document.body
}
placement={
calculatedOpenDirection === 'up' ? 'topLeft' : 'bottomLeft'
}
$block={block}
$noBorder={noBorder}
$error={error}
$onlyIcon={onlyIcon}
$width={width}
format="DD/MM/YYYY"
allowClear={showClearDate}
autoFocus={startFocused}
renderExtraFooter={renderExtraFooter}
/>
);
};
const DatePicker = withSpaceProps(BaseDatePicker);
DatePicker.displayName = 'DatePicker';
export default DatePicker;
Моя компонента поля формы:
import React from 'react';
import withField from '../../../hocs/field/with-field';
import DatePicker, {
IDatePickerProps,
} from '../../input/datepicker/date-picker.component';
export interface IFieldDatePickerProps extends IDatePickerProps {}
const BaseFieldDatePickerProps: React.FC = ({
...props
}) => ;
const FieldDatePicker = withField(BaseFieldDatePickerProps);
export default FieldDatePicker;
Подробнее здесь: https://stackoverflow.com/questions/798 ... ker-formik
Мобильная версия