Skip to content

Commit

Permalink
Review Lukas + JSDoc for useParsedFormat
Browse files Browse the repository at this point in the history
  • Loading branch information
flaviendelangle committed Oct 7, 2024
1 parent 2365f69 commit 1772912
Show file tree
Hide file tree
Showing 18 changed files with 94 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { useValidation, validateDate } from '@mui/x-date-pickers/validation';
import {
useSplitFieldProps,
useFieldPlaceholder,
useParsedFormat,
usePickersContext,
} from '@mui/x-date-pickers/hooks';

Expand All @@ -18,7 +18,7 @@ function ReadOnlyDateField(props) {

const pickersContext = usePickersContext();

const placeholder = useFieldPlaceholder(internalProps);
const parsedFormat = useParsedFormat(internalProps);
const { hasValidationError } = useValidation({
validator: validateDate,
value,
Expand All @@ -30,7 +30,7 @@ function ReadOnlyDateField(props) {
<TextField
{...other}
value={value == null ? '' : value.format(format)}
placeholder={placeholder}
placeholder={parsedFormat}
InputProps={{ ...InputProps, readOnly: true }}
error={hasValidationError}
onClick={pickersContext.onToggleView}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import { useValidation, validateDate } from '@mui/x-date-pickers/validation';
import {
useSplitFieldProps,
useFieldPlaceholder,
useParsedFormat,
usePickersContext,
} from '@mui/x-date-pickers/hooks';

Expand All @@ -22,7 +22,7 @@ function ReadOnlyDateField(props: DatePickerFieldProps<Dayjs, false>) {

const pickersContext = usePickersContext();

const placeholder = useFieldPlaceholder(internalProps);
const parsedFormat = useParsedFormat(internalProps);
const { hasValidationError } = useValidation({
validator: validateDate,
value,
Expand All @@ -34,7 +34,7 @@ function ReadOnlyDateField(props: DatePickerFieldProps<Dayjs, false>) {
<TextField
{...other}
value={value == null ? '' : value.format(format)}
placeholder={placeholder}
placeholder={parsedFormat}
InputProps={{ ...InputProps, readOnly: true }}
error={hasValidationError}
onClick={pickersContext.onToggleView}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export const useDesktopRangePicker = <
renderCurrentView,
shouldRestoreFocus,
fieldProps: pickerFieldProps,
fieldContextValue,
contextValue,
} = usePicker<
DateRange<TDate>,
TDate,
Expand Down Expand Up @@ -210,7 +210,7 @@ export const useDesktopRangePicker = <
const Layout = slots?.layout ?? PickersLayout;

const renderPicker = () => (
<PickersProvider fieldContextValue={fieldContextValue} localeText={localeText}>
<PickersProvider contextValue={contextValue} localeText={localeText}>
<Field {...enrichedFieldProps} />
<PickersPopper
role="tooltip"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export const useMobileRangePicker = <
layoutProps,
renderCurrentView,
fieldProps: pickerFieldProps,
fieldContextValue,
contextValue,
} = usePicker<
DateRange<TDate>,
TDate,
Expand Down Expand Up @@ -215,7 +215,7 @@ export const useMobileRangePicker = <
};

const renderPicker = () => (
<PickersProvider fieldContextValue={fieldContextValue} localeText={localeText}>
<PickersProvider contextValue={contextValue} localeText={localeText}>
<Field {...enrichedFieldProps} />
<PickersModalDialog {...actions} open={open} slots={slots} slotProps={slotProps}>
<Layout
Expand Down
2 changes: 1 addition & 1 deletion packages/x-date-pickers/src/hooks/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export { usePickersTranslations } from './usePickersTranslations';

export { useSplitFieldProps } from './useSplitFieldProps';

export { useFieldPlaceholder } from './useFieldPlaceholder';
export { useParsedFormat } from './useParsedFormat';

export { usePickersContext } from './usePickersContext';
56 changes: 0 additions & 56 deletions packages/x-date-pickers/src/hooks/useFieldPlaceholder.ts

This file was deleted.

61 changes: 61 additions & 0 deletions packages/x-date-pickers/src/hooks/useParsedFormat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
'use client';
import * as React from 'react';
import { useRtl } from '@mui/system/RtlProvider';
import { useUtils } from '../internals/hooks/useUtils';
import { buildSectionsFromFormat } from '../internals/hooks/useField/buildSectionsFromFormat';
import { getLocalizedDigits } from '../internals/hooks/useField/useField.utils';
import { PickerValidDate } from '../models';
import { usePickersTranslations } from './usePickersTranslations';
import type { UseFieldInternalProps } from '../internals/hooks/useField';

interface UseParsedFormatParameters
extends Pick<
UseFieldInternalProps<any, any, any, any, any>,
'format' | 'formatDensity' | 'shouldRespectLeadingZeros'
> {}

/**
* Returns the parsed format to be rendered in the field when their is no value or in other parts of the picker.
* This format is localized (e.g: `AAAA` for the year with the French locale) and cannot be parsed by your date library.
* @param {object} The parameters needed to build the placeholder.
* @param {string} params.format Format of the date to use.
* @param {'dense' | 'spacious'} params.formatDensity Density of the format (setting `formatDensity` to `"spacious"` will add a space before and after each `/`, `-` and `.` character).
* @param {boolean} params.shouldRespectLeadingZeros If `true`, the format will respect the leading zeroes, if `false`, the format will always add leading zeroes.
* @returns
*/
export const useParsedFormat = <TDate extends PickerValidDate>(
parameters: UseParsedFormatParameters,
) => {
const { format, formatDensity = 'dense', shouldRespectLeadingZeros = false } = parameters;
const utils = useUtils<TDate>();
const isRtl = useRtl();
const translations = usePickersTranslations<TDate>();
const localizedDigits = React.useMemo(() => getLocalizedDigits(utils), [utils]);

return React.useMemo(() => {
const sections = buildSectionsFromFormat({
utils,
format,
formatDensity,
isRtl,
shouldRespectLeadingZeros,
localeText: translations,
localizedDigits,
date: null,
// TODO v9: Make sure we still don't reverse in `buildSectionsFromFormat` when using `useParsedFormat`.
enableAccessibleFieldDOMStructure: false,
});

return sections
.map((section) => `${section.startSeparator}${section.placeholder}${section.endSeparator}`)
.join('');
}, [
utils,
isRtl,
translations,
localizedDigits,
format,
formatDensity,
shouldRespectLeadingZeros,
]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,25 @@ export const PickersContext = React.createContext<PickersContextValue | null>(nu

/**
* Provides the context for the various parts of a picker component:
* - fieldContextValue: the context for the field
* - contextValue: the context for the picker sub-components.
* - localizationProvider: the translations passed through the props and through a parent LocalizationProvider.
*
* @ignore - do not document.
*/
export function PickersProvider<TDate extends PickerValidDate>(
props: PickersFieldProviderProps<TDate>,
) {
const { fieldContextValue, localeText, children } = props;
const { contextValue, localeText, children } = props;

return (
<PickersContext.Provider value={fieldContextValue}>
<PickersContext.Provider value={contextValue}>
<LocalizationProvider localeText={localeText}>{children}</LocalizationProvider>
</PickersContext.Provider>
);
}

interface PickersFieldProviderProps<TDate extends PickerValidDate> {
fieldContextValue: PickersContextValue;
contextValue: PickersContextValue;
localeText: PickersInputLocaleText<TDate> | undefined;
children: React.ReactNode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export const useDesktopPicker = <
renderCurrentView,
shouldRestoreFocus,
fieldProps: pickerFieldProps,
fieldContextValue,
contextValue,
} = usePicker<TDate | null, TDate, TView, FieldSection, TExternalProps, {}>({
...pickerParams,
props,
Expand Down Expand Up @@ -213,7 +213,7 @@ export const useDesktopPicker = <
const handleFieldRef = useForkRef(fieldRef, fieldProps.unstableFieldRef);

const renderPicker = () => (
<PickersProvider fieldContextValue={fieldContextValue} localeText={localeText}>
<PickersProvider contextValue={contextValue} localeText={localeText}>
<Field
{...fieldProps}
slots={slotsForField}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FieldSection, MuiPickersAdapter, PickersTimezone, PickerValidDate } from '../../../models';
import { FieldSection, MuiPickersAdapter, PickerValidDate } from '../../../models';
import { PickersLocaleText } from '../../../locales';
import {
applyLocalizedDigits,
Expand All @@ -13,7 +13,6 @@ interface BuildSectionsFromFormatParams<TDate extends PickerValidDate> {
format: string;
formatDensity: 'dense' | 'spacious';
isRtl: boolean;
timezone: PickersTimezone;
shouldRespectLeadingZeros: boolean;
localeText: PickersLocaleText<TDate>;
localizedDigits: string[];
Expand Down Expand Up @@ -64,15 +63,14 @@ const getEscapedPartsFromFormat = <TDate extends PickerValidDate>({

const getSectionPlaceholder = <TDate extends PickerValidDate>(
utils: MuiPickersAdapter<TDate>,
timezone: PickersTimezone,
localeText: PickersLocaleText<TDate>,
sectionConfig: Pick<FieldSection, 'type' | 'contentType'>,
sectionFormat: string,
) => {
switch (sectionConfig.type) {
case 'year': {
return localeText.fieldYearPlaceholder({
digitAmount: utils.formatByString(utils.date(undefined, timezone), sectionFormat).length,
digitAmount: utils.formatByString(utils.date(undefined, 'default'), sectionFormat).length,
format: sectionFormat,
});
}
Expand Down Expand Up @@ -119,7 +117,6 @@ const getSectionPlaceholder = <TDate extends PickerValidDate>(

const createSection = <TDate extends PickerValidDate>({
utils,
timezone,
date,
shouldRespectLeadingZeros,
localeText,
Expand All @@ -140,7 +137,6 @@ const createSection = <TDate extends PickerValidDate>({

const hasLeadingZerosInFormat = doesSectionFormatHaveLeadingZeros(
utils,
timezone,
sectionConfig.contentType,
sectionConfig.type,
token,
Expand Down Expand Up @@ -181,7 +177,7 @@ const createSection = <TDate extends PickerValidDate>({
format: token,
maxLength,
value: sectionValue,
placeholder: getSectionPlaceholder(utils, timezone, localeText, sectionConfig, token),
placeholder: getSectionPlaceholder(utils, localeText, sectionConfig, token),
hasLeadingZerosInFormat,
hasLeadingZerosInInput,
startSeparator,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export interface UseFieldInternalProps<
*/
onChange?: FieldChangeHandler<TValue, TError>;
/**
* Format of the date when rendered in the input(s).
* Format of the date when rendered in the field.
*/
format: string;
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,13 +393,11 @@ export const changeSectionValueFormat = <TDate extends PickerValidDate>(

const isFourDigitYearFormat = <TDate extends PickerValidDate>(
utils: MuiPickersAdapter<TDate>,
timezone: PickersTimezone,
format: string,
) => utils.formatByString(utils.date(undefined, timezone), format).length === 4;
) => utils.formatByString(utils.date(undefined, 'system'), format).length === 4;

export const doesSectionFormatHaveLeadingZeros = <TDate extends PickerValidDate>(
utils: MuiPickersAdapter<TDate>,
timezone: PickersTimezone,
contentType: FieldSectionContentType,
sectionType: FieldSectionType,
format: string,
Expand All @@ -408,12 +406,12 @@ export const doesSectionFormatHaveLeadingZeros = <TDate extends PickerValidDate>
return false;
}

const now = utils.date(undefined, timezone);
const now = utils.date(undefined, 'default');

switch (sectionType) {
// We can't use `changeSectionValueFormat`, because `utils.parse('1', 'YYYY')` returns `1971` instead of `1`.
case 'year': {
if (isFourDigitYearFormat(utils, timezone, format)) {
if (isFourDigitYearFormat(utils, format)) {
const formatted0001 = utils.formatByString(utils.setYear(now, 1), format);
return formatted0001 === '0001';
}
Expand Down Expand Up @@ -547,7 +545,7 @@ export const getSectionsBoundaries = <TDate extends PickerValidDate>(
return {
year: ({ format }) => ({
minimum: 0,
maximum: isFourDigitYearFormat(utils, timezone, format) ? 9999 : 99,
maximum: isFourDigitYearFormat(utils, format) ? 9999 : 99,
}),
month: () => ({
minimum: 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const useMobilePicker = <
layoutProps,
renderCurrentView,
fieldProps: pickerFieldProps,
fieldContextValue,
contextValue,
} = usePicker<TDate | null, TDate, TView, FieldSection, TExternalProps, {}>({
...pickerParams,
props,
Expand Down Expand Up @@ -160,7 +160,7 @@ export const useMobilePicker = <
const handleFieldRef = useForkRef(fieldRef, fieldProps.unstableFieldRef);

const renderPicker = () => (
<PickersProvider fieldContextValue={fieldContextValue} localeText={localeText}>
<PickersProvider contextValue={contextValue} localeText={localeText}>
<Field
{...fieldProps}
slots={slotsForField}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,6 @@ export const usePicker = <
layoutProps: pickerLayoutResponse.layoutProps,

// Picker field
fieldContextValue: pickerValueResponse.fieldContextValue,
contextValue: pickerValueResponse.contextValue,
};
};
Loading

0 comments on commit 1772912

Please sign in to comment.