@rjsf/utils
Version:
Utility functions for @rjsf/core
72 lines • 3.67 kB
JavaScript
'use client';
import { jsx as _jsx } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useState } from 'react';
import dateRangeOptions from './dateRangeOptions.js';
import getDateElementProps from './getDateElementProps.js';
import { ariaDescribedByIds } from './idGenerators.js';
import parseDateString from './parseDateString.js';
import toDateString from './toDateString.js';
/** Function that checks to see if a `DateObject` is ready for the onChange callback to be triggered
*
* @param state - The current `DateObject`
* @returns - True if the `state` is ready to trigger an onChange
*/
function readyForChange(state) {
return Object.values(state).every((value) => value !== -1);
}
/** The `DateElement` component renders one of the 6 date element selectors for an `AltDateWidget`, using the `select`
* widget from the registry.
*
* @param props - The `DateElementProps` for the date element
*/
export function DateElement(props) {
const { className = 'form-control', type, range, value, select, rootId, name, disabled, readonly, autofocus, registry, onBlur, onFocus, } = props;
const id = `${rootId}_${type}`;
const { SelectWidget } = registry.widgets;
const onChange = useCallback((value) => select(type, value), [select, type]);
return (_jsx(SelectWidget, { schema: { type: 'integer' }, id: id, name: name, className: className, options: { enumOptions: dateRangeOptions(range[0], range[1]) }, placeholder: type, value: value, disabled: disabled, readonly: readonly, autofocus: autofocus, onChange: onChange, onBlur: onBlur, onFocus: onFocus, registry: registry, label: '', "aria-describedby": ariaDescribedByIds(rootId) }));
}
/** Hook which encapsulates the logic needed to render an `AltDateWidget` with optional `time` elements. It contains
* the `state` of the current date(/time) selections in the widget. It returns a `UseAltDateWidgetResult` object
* that contains the `elements: DateElementProp[]` and three callbacks needed to change one of the rendered `elements`,
* and to handle the clicking of the `clear` and `setNow` buttons.
*
* @param props - The `WidgetProps` for the `AltDateWidget`
*/
export default function useAltDateWidgetProps(props) {
const { time = false, disabled = false, readonly = false, options, onChange, value } = props;
const [state, setState] = useState(parseDateString(value, time));
useEffect(() => {
setState(parseDateString(value, time));
}, [time, value]);
const handleChange = useCallback((property, value) => {
const nextState = {
...state,
[property]: typeof value === 'undefined' ? -1 : value,
};
if (readyForChange(nextState)) {
onChange(toDateString(nextState, time));
}
else {
setState(nextState);
}
}, [state, onChange, time]);
const handleClear = useCallback((event) => {
event.preventDefault();
if (disabled || readonly) {
return;
}
onChange(undefined);
}, [disabled, readonly, onChange]);
const handleSetNow = useCallback((event) => {
event.preventDefault();
if (disabled || readonly) {
return;
}
const nextState = parseDateString(new Date().toJSON(), time);
onChange(toDateString(nextState, time));
}, [disabled, readonly, time, onChange]);
const elements = useMemo(() => getDateElementProps(state, time, options.yearsRange, options.format), [state, time, options.yearsRange, options.format]);
return { elements, handleChange, handleClear, handleSetNow };
}
//# sourceMappingURL=useAltDateWidgetProps.js.map