/* * Copyright 2025 Commonwealth Scientific and Industrial Research * Organisation (CSIRO) ABN 41 687 119 230. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import type { ChangeEvent, Dispatch, SetStateAction } from 'react'; import { useRef } from 'react'; import type { Dayjs } from 'dayjs'; import InputAdornment from '@mui/material/InputAdornment'; import type { PropsWithIsTabledAttribute } from '../../../../interfaces/renderProps.interface'; import { StandardTextField } from '../../Textfield.styles'; import DatePicker from './DatePicker'; import { useRendererConfigStore } from '../../../../stores'; import useDateFormat from '../../../../hooks/useDateFormat'; import { interpolate } from '../../../../i18n'; import ExpressionUpdateFadingIcon from '../../ItemParts/ExpressionUpdateFadingIcon'; interface CustomDateFieldProps extends PropsWithIsTabledAttribute { linkId: string; itemType: string; itemText: string | undefined; valueDate: string; input: string; feedback: string; feedbackSeverity?: 'error' | 'warning'; isFocused: boolean; displayPrompt: string; entryFormat: string; readOnly: boolean; calcExpUpdated: boolean; isPartOfDateTime: boolean; instructionsId: string | undefined; setFocused: Dispatch>; onInputChange: (newInput: string) => void; onSelectDate: (newDateValue: string) => void; } function CustomDateField(props: CustomDateFieldProps) { const { linkId, itemType, itemText, valueDate, input, feedback, feedbackSeverity, isFocused, displayPrompt, entryFormat, readOnly, calcExpUpdated, isPartOfDateTime, isTabled, instructionsId, setFocused, onInputChange, onSelectDate } = props; const readOnlyVisualStyle = useRendererConfigStore.use.readOnlyVisualStyle(); const textFieldWidth = useRendererConfigStore.use.textFieldWidth(); const dateFormat = useDateFormat(); const rendererStrings = useRendererConfigStore.use.rendererStrings(); const anchorRef = useRef(null); // If this reusable date field is part of a DateTime component, the id should be appended with '-date' const id = isPartOfDateTime ? itemType + '-' + linkId + '-date' : itemType + '-' + linkId; let placeholderText = dateFormat; if (displayPrompt !== '') { placeholderText = displayPrompt; } if (entryFormat !== '') { placeholderText = entryFormat; } return ( ) => onInputChange(e.target.value)} placeholder={placeholderText} disabled={readOnly && readOnlyVisualStyle === 'disabled'} size="small" focused={isFocused} onFocus={() => setFocused(true)} onBlur={() => setFocused(false)} slotProps={{ input: { readOnly: readOnly && readOnlyVisualStyle === 'readonly', endAdornment: ( { onSelectDate(valueDayjs.format(dateFormat)); }} onFocus={(focus) => setFocused(focus)} /> ) }, htmlInput: { ...(isTabled ? {} : { 'aria-label': itemText ?? interpolate(rendererStrings.unnamedItem, { type: itemType }) }), ...(instructionsId && { 'aria-describedby': instructionsId }) }, formHelperText: { sx: feedbackSeverity === 'warning' && !!feedback ? { color: 'warning.main' } : undefined } }} helperText={feedback} /> ); } export default CustomDateField;