EN · DE · RU · FR · ES

#2654: DateInput.jsx

projectforge-webapp/src/components/design/input/calendar/DateInput.jsx Tipo: JavaScript/React · Rol: Calendario · Fuente: projectforge-webapp/src/components/design/input/calendar/DateInput.jsx 184 líneas · 159 código · 1 comentario · 24 en blanco
Componente de entrada de fecha/hora en React que proporciona selector de calendario, rango de fechas y visualización formateada para la aplicación web ProjectForge.

Estructura del código

Hooks utilizados: Selector, Selector, Selector, State, State, State, Ref, Effect

Importaciones de: ../../../../utilities/propTypes, ../../popper/AdvancedPopper, ../AdditionalLabel, ../InputContainer, ./CalendarInput.module.scss, moment, prop-types, react, react-day-picker, react-day-picker/locale, react-redux

Tiene PropTypes para: DateInput

Utiliza Módulos CSS para el estilo.

Código fuente (resumido)

import moment from 'moment';
import 'moment/min/locales';
import PropTypes from 'prop-types';
import React from 'react';
import { DayPicker } from 'react-day-picker';
import { de } from 'react-day-picker/locale';
import { useSelector } from 'react-redux';
import { colorPropType } from '../../../../utilities/propTypes';
import AdvancedPopper from '../../popper/AdvancedPopper';
import AdditionalLabel from '../AdditionalLabel';
import InputContainer from '../InputContainer';
import styles from './CalendarInput.module.scss';

function DateInput(
    {
        additionalLabel,
        color,
        hideDayPicker = false,
        label,
        noInputContainer = false,
        setDate,
        todayButton,
        value,
    },
) {
    const jsDateFormat = useSelector((state) => state.authentication.user.jsDateFormat);
    const locale = useSelector((state) => state.authentication.user.locale) || 'en';
    const weekStartsOn = useSelector((state) => state.authentication.user.firstDayOfWeekSunday0);
    const [inputValue, setInputValue] = React.useState('');
    const [isActive, setIsActive] = React.useState(false);
    const [isOpen, setIsOpen] = React.useState(false);
    const inputRef = React.useRef(null);
    const Tag = noInputContainer ? React.Fragment : InputContainer;

    React.useEffect(() => {
        if (value) {
            setInputValue(moment(value)
                .format(jsDateFormat));
        } else {
            setInputValue('');
        }
    }, [value]);

    const handleBlur = () => {
        setIsActive(false);

        if (inputValue.trim() === '') {
            setDate(undefined);
            return;
        }

        const momentDate = moment(inputValue, jsDateFormat);

        if (momentDate.isValid()) {
            setDate(momentDate.toDate());
        } else {
            setInputValue(moment(value)
                .format(jsDateFormat));
        }
    };

    const handleChange = ({ target }) => {
        setInputValue(target.value);

        // Tiene que ser estricto, para que moment no corrija tu entrada cada vez
        const momentDate = moment(target.value, jsDateFormat, true);

        if (momentDate.isValid()) {
            setDate(momentDate.toDate());
        }
    };

    const handleFocus = () => setIsActive(true);

    const handleKeyDown = (event) => {
        const momentDate = moment(inputValue, jsDateFormat, true);

        if (momentDate.isValid()) {
            let newDate;
            if (event.key === 'ArrowUp') {
                newDate = momentDate.add(1, 'd');
            } else if (event.key === 'ArrowDown') {
                newDate = momentDate.subtract(1, 'd');
            }

            if (newDate) {
                event.preventDefault();
                setDate(newDate.toDate());
            }
        }
    };

    const handleTagClick = () => {
        if (inputRef.current) {
            inputRef.current.focus();
        }
    };

    const tagProps = {};

    if (Tag !== React.Fragment) {
        tagProps.color = color;
        tagProps.isActive = isActive || inputValue !== '';
        tagProps.label = label;
        tagProps.onClick = handleTagClick;
        tagProps.withMargin = true;
    }

    const placeholder = jsDateFormat
        .split('')
        .filter((char, index) => index >= inputValue.length)
        .join('');

    const input = (
        <>
            <Tag {...tagProps}>
                <div className={styles.dateInput}>
                    {isActive && (
                        <span
                            className={styles.placeholder}
// ... (truncado, total 184 líneas)

Historial de Git

bf988bc6d Elimina 43 vulnerabilidades npm: react-scripts→Vite, ESLint 9, limpieza de dependencias, corrección de errores
ae4653957 corrige el mes predeterminado de entrada de fecha
95b5d879a DayPicker también en alemán.
f586d54a5 corrige el primer día de la semana en DayPicker
284e5d90f corrige la navegación mensual del DayPicker