From eda8eaa8d0c69177b9286b444e5448560ee70508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dudak?= Date: Mon, 7 Oct 2024 11:28:37 +0200 Subject: [PATCH] [Field] Move types to namespaces (#710) --- .../src/Checkbox/Root/CheckboxRoot.tsx | 4 +- .../CheckboxGroup/Root/CheckboxGroupRoot.tsx | 4 +- .../src/Field/Control/FieldControl.tsx | 20 ++++- .../src/Field/Control/FieldControl.types.ts | 13 ---- .../src/Field/Control/useFieldControl.ts | 22 +++--- .../Field/Description/FieldDescription.tsx | 11 ++- .../Description/FieldDescription.types.tsx | 7 -- .../Field/Description/useFieldDescription.ts | 12 +-- .../mui-base/src/Field/Error/FieldError.tsx | 21 +++++- .../src/Field/Error/FieldError.types.tsx | 16 ---- .../mui-base/src/Field/Error/useFieldError.ts | 16 ++-- .../mui-base/src/Field/Label/FieldLabel.tsx | 11 ++- .../src/Field/Label/FieldLabel.types.ts | 6 -- .../mui-base/src/Field/Label/useFieldLabel.ts | 12 +-- .../mui-base/src/Field/Root/FieldRoot.tsx | 73 +++++++++++++++++-- .../src/Field/Root/FieldRoot.types.ts | 62 ---------------- .../src/Field/Root/FieldRootContext.ts | 8 +- .../src/Field/Validity/FieldValidity.tsx | 16 +++- .../src/Field/Validity/FieldValidity.types.ts | 12 --- packages/mui-base/src/Field/index.barrel.ts | 7 +- packages/mui-base/src/Field/index.ts | 23 +----- .../utils/getCombinedFieldValidityData.ts | 2 +- .../mui-base/src/Form/Root/FormRootContext.ts | 2 +- .../src/NumberField/Root/NumberFieldRoot.tsx | 4 +- .../src/Slider/Root/SliderRoot.types.ts | 4 +- .../mui-base/src/Switch/Root/SwitchRoot.tsx | 4 +- 26 files changed, 189 insertions(+), 203 deletions(-) delete mode 100644 packages/mui-base/src/Field/Control/FieldControl.types.ts delete mode 100644 packages/mui-base/src/Field/Description/FieldDescription.types.tsx delete mode 100644 packages/mui-base/src/Field/Error/FieldError.types.tsx delete mode 100644 packages/mui-base/src/Field/Label/FieldLabel.types.ts delete mode 100644 packages/mui-base/src/Field/Root/FieldRoot.types.ts delete mode 100644 packages/mui-base/src/Field/Validity/FieldValidity.types.ts diff --git a/packages/mui-base/src/Checkbox/Root/CheckboxRoot.tsx b/packages/mui-base/src/Checkbox/Root/CheckboxRoot.tsx index b6974305d0..4e3dcf87b6 100644 --- a/packages/mui-base/src/Checkbox/Root/CheckboxRoot.tsx +++ b/packages/mui-base/src/Checkbox/Root/CheckboxRoot.tsx @@ -5,7 +5,7 @@ import { useCheckboxGroupRootContext } from '../../CheckboxGroup/Root/CheckboxGr import { useFieldRootContext } from '../../Field/Root/FieldRootContext'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; import { useCustomStyleHookMapping } from '../utils/useCustomStyleHookMapping'; -import type { FieldRootOwnerState } from '../../Field/Root/FieldRoot.types'; +import type { FieldRoot } from '../../Field/Root/FieldRoot'; import type { BaseUIComponentProps } from '../../utils/types'; import { type UseCheckboxRoot, useCheckboxRoot } from './useCheckboxRoot'; import { CheckboxRootContext } from './CheckboxRootContext'; @@ -111,7 +111,7 @@ const CheckboxRoot = React.forwardRef(function CheckboxRoot( }); namespace CheckboxRoot { - export interface OwnerState extends FieldRootOwnerState { + export interface OwnerState extends FieldRoot.OwnerState { checked: boolean; disabled: boolean; readOnly: boolean; diff --git a/packages/mui-base/src/CheckboxGroup/Root/CheckboxGroupRoot.tsx b/packages/mui-base/src/CheckboxGroup/Root/CheckboxGroupRoot.tsx index 14b3388730..37a8e0c550 100644 --- a/packages/mui-base/src/CheckboxGroup/Root/CheckboxGroupRoot.tsx +++ b/packages/mui-base/src/CheckboxGroup/Root/CheckboxGroupRoot.tsx @@ -4,9 +4,9 @@ import PropTypes from 'prop-types'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; import { useCheckboxGroupRoot } from './useCheckboxGroupRoot'; import { CheckboxGroupRootContext } from './CheckboxGroupRootContext'; +import type { FieldRoot } from '../../Field/Root/FieldRoot'; import { useFieldRootContext } from '../../Field/Root/FieldRootContext'; import type { BaseUIComponentProps } from '../../utils/types'; -import type { FieldRootOwnerState } from '../../Field/Root/FieldRoot.types'; /** * The foundation for building custom-styled checkbox groups. @@ -82,7 +82,7 @@ const CheckboxGroupRoot = React.forwardRef(function CheckboxGroupRoot( }); namespace CheckboxGroupRoot { - export interface OwnerState extends FieldRootOwnerState { + export interface OwnerState extends FieldRoot.OwnerState { disabled: boolean; } export interface Props extends BaseUIComponentProps<'div', OwnerState> { diff --git a/packages/mui-base/src/Field/Control/FieldControl.tsx b/packages/mui-base/src/Field/Control/FieldControl.tsx index 6370d56078..73339b9baa 100644 --- a/packages/mui-base/src/Field/Control/FieldControl.tsx +++ b/packages/mui-base/src/Field/Control/FieldControl.tsx @@ -2,10 +2,13 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; -import type { FieldControlElement, FieldControlProps } from './FieldControl.types'; import { useFieldControl } from './useFieldControl'; +import { FieldRoot } from '../Root/FieldRoot'; import { useFieldRootContext } from '../Root/FieldRootContext'; import { STYLE_HOOK_MAPPING } from '../utils/constants'; +import { BaseUIComponentProps } from '../../utils/types'; + +export type FieldControlElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement; /** * The field's control element. This is not necessary to use when using a native Base UI input @@ -20,7 +23,7 @@ import { STYLE_HOOK_MAPPING } from '../utils/constants'; * - [FieldControl API](https://base-ui.netlify.app/components/react-field/#api-reference-FieldControl) */ const FieldControl = React.forwardRef(function FieldControl( - props: FieldControlProps, + props: FieldControl.Props, forwardedRef: React.ForwardedRef, ) { const { @@ -44,7 +47,7 @@ const FieldControl = React.forwardRef(function FieldControl( const disabled = fieldDisabled || disabledProp; const name = fieldName ?? nameProp; - const ownerState = React.useMemo( + const ownerState: FieldControl.OwnerState = React.useMemo( () => ({ ...fieldOwnerState, disabled }), [fieldOwnerState, disabled], ); @@ -71,6 +74,17 @@ const FieldControl = React.forwardRef(function FieldControl( return renderElement(); }); +namespace FieldControl { + export type OwnerState = FieldRoot.OwnerState; + + export interface Props extends BaseUIComponentProps<'input', OwnerState> { + /** + * Callback fired when the `value` changes. Use when controlled. + */ + onValueChange?: (value: string | number | readonly string[] | undefined, event: Event) => void; + } +} + FieldControl.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ diff --git a/packages/mui-base/src/Field/Control/FieldControl.types.ts b/packages/mui-base/src/Field/Control/FieldControl.types.ts deleted file mode 100644 index 7817308c0c..0000000000 --- a/packages/mui-base/src/Field/Control/FieldControl.types.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { BaseUIComponentProps } from '../../utils/types'; -import type { FieldRootOwnerState } from '../Root/FieldRoot.types'; - -export type FieldControlElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement; - -export type FieldControlOwnerState = FieldRootOwnerState; - -export interface FieldControlProps extends BaseUIComponentProps<'input', FieldControlOwnerState> { - /** - * Callback fired when the `value` changes. Use when controlled. - */ - onValueChange?: (value: string | number | readonly string[] | undefined, event: Event) => void; -} diff --git a/packages/mui-base/src/Field/Control/useFieldControl.ts b/packages/mui-base/src/Field/Control/useFieldControl.ts index 93f4a788c2..9208ac5737 100644 --- a/packages/mui-base/src/Field/Control/useFieldControl.ts +++ b/packages/mui-base/src/Field/Control/useFieldControl.ts @@ -10,16 +10,7 @@ import { useField } from '../useField'; import { useControlled } from '../../utils/useControlled'; import { useEventCallback } from '../../utils/useEventCallback'; -interface UseFieldControlParameters { - id?: string; - name?: string; - value?: string | number | readonly string[]; - defaultValue?: string | number | readonly string[]; - onValueChange?: (value: string | number | readonly string[], event: Event) => void; - disabled?: boolean; -} - -export function useFieldControl(params: UseFieldControlParameters) { +export function useFieldControl(params: useFieldControl.Parameters) { const { id: idProp, name, value: valueProp, defaultValue, onValueChange, disabled } = params; const { setControlId, labelId, setTouched, setDirty, validityData } = useFieldRootContext(); @@ -117,3 +108,14 @@ export function useFieldControl(params: UseFieldControlParameters) { [getControlProps], ); } + +export namespace useFieldControl { + export interface Parameters { + id?: string; + name?: string; + value?: string | number | readonly string[]; + defaultValue?: string | number | readonly string[]; + onValueChange?: (value: string | number | readonly string[], event: Event) => void; + disabled?: boolean; + } +} diff --git a/packages/mui-base/src/Field/Description/FieldDescription.tsx b/packages/mui-base/src/Field/Description/FieldDescription.tsx index e7c91c84d5..20eb153a24 100644 --- a/packages/mui-base/src/Field/Description/FieldDescription.tsx +++ b/packages/mui-base/src/Field/Description/FieldDescription.tsx @@ -2,10 +2,11 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; -import type { FieldDescriptionProps } from './FieldDescription.types'; +import { FieldRoot } from '../Root/FieldRoot'; import { useFieldRootContext } from '../Root/FieldRootContext'; import { useFieldDescription } from './useFieldDescription'; import { STYLE_HOOK_MAPPING } from '../utils/constants'; +import type { BaseUIComponentProps } from '../../utils/types'; /** * A description message for the field's control. @@ -19,7 +20,7 @@ import { STYLE_HOOK_MAPPING } from '../utils/constants'; * - [FieldDescription API](https://base-ui.netlify.app/components/react-field/#api-reference-FieldDescription) */ const FieldDescription = React.forwardRef(function FieldDescription( - props: FieldDescriptionProps, + props: FieldDescription.Props, forwardedRef: React.ForwardedRef, ) { const { render, id, className, ...otherProps } = props; @@ -41,6 +42,12 @@ const FieldDescription = React.forwardRef(function FieldDescription( return renderElement(); }); +namespace FieldDescription { + export type OwnerState = FieldRoot.OwnerState; + + export interface Props extends BaseUIComponentProps<'p', OwnerState> {} +} + FieldDescription.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ diff --git a/packages/mui-base/src/Field/Description/FieldDescription.types.tsx b/packages/mui-base/src/Field/Description/FieldDescription.types.tsx deleted file mode 100644 index eb3b50576d..0000000000 --- a/packages/mui-base/src/Field/Description/FieldDescription.types.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import type { BaseUIComponentProps } from '../../utils/types'; -import type { FieldRootOwnerState } from '../Root/FieldRoot.types'; - -export type FieldDescriptionOwnerState = FieldRootOwnerState; - -export interface FieldDescriptionProps - extends BaseUIComponentProps<'p', FieldDescriptionOwnerState> {} diff --git a/packages/mui-base/src/Field/Description/useFieldDescription.ts b/packages/mui-base/src/Field/Description/useFieldDescription.ts index 8a0705d7ec..49898908f9 100644 --- a/packages/mui-base/src/Field/Description/useFieldDescription.ts +++ b/packages/mui-base/src/Field/Description/useFieldDescription.ts @@ -5,11 +5,7 @@ import { useId } from '../../utils/useId'; import { useEnhancedEffect } from '../../utils/useEnhancedEffect'; import { useFieldRootContext } from '../Root/FieldRootContext'; -interface UseFieldDescriptionParameters { - id: string | undefined; -} - -export function useFieldDescription(params: UseFieldDescriptionParameters) { +export function useFieldDescription(params: useFieldDescription.Parameters) { const { id: idProp } = params; const { setMessageIds } = useFieldRootContext(); @@ -43,3 +39,9 @@ export function useFieldDescription(params: UseFieldDescriptionParameters) { [getDescriptionProps], ); } + +export namespace useFieldDescription { + export interface Parameters { + id: string | undefined; + } +} diff --git a/packages/mui-base/src/Field/Error/FieldError.tsx b/packages/mui-base/src/Field/Error/FieldError.tsx index d1f56339bd..cd4362a8de 100644 --- a/packages/mui-base/src/Field/Error/FieldError.tsx +++ b/packages/mui-base/src/Field/Error/FieldError.tsx @@ -2,11 +2,12 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; -import type { FieldErrorProps } from './FieldError.types'; +import { FieldRoot } from '../Root/FieldRoot'; import { useFieldRootContext } from '../Root/FieldRootContext'; import { useFieldError } from './useFieldError'; import { STYLE_HOOK_MAPPING } from '../utils/constants'; import { useFormRootContext } from '../../Form/Root/FormRootContext'; +import type { BaseUIComponentProps } from '../../utils/types'; /** * Displays error messages for the field's control. @@ -20,7 +21,7 @@ import { useFormRootContext } from '../../Form/Root/FormRootContext'; * - [FieldError API](https://base-ui.netlify.app/components/react-field/#api-reference-FieldError) */ const FieldError = React.forwardRef(function FieldError( - props: FieldErrorProps, + props: FieldError.Props, forwardedRef: React.ForwardedRef, ) { const { render, id, className, show, forceShow, ...otherProps } = props; @@ -59,6 +60,22 @@ const FieldError = React.forwardRef(function FieldError( return renderElement(); }); +namespace FieldError { + export type OwnerState = FieldRoot.OwnerState; + + export interface Props extends BaseUIComponentProps<'div', OwnerState> { + /** + * Determines whether the error message should be shown when it matches a given property of the + * field's `ValidityState`. + */ + show?: keyof ValidityState; + /** + * Determines whether the error message should be shown regardless of the field's client validity. + */ + forceShow?: boolean; + } +} + FieldError.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ diff --git a/packages/mui-base/src/Field/Error/FieldError.types.tsx b/packages/mui-base/src/Field/Error/FieldError.types.tsx deleted file mode 100644 index a65ec06bd2..0000000000 --- a/packages/mui-base/src/Field/Error/FieldError.types.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import type { BaseUIComponentProps } from '../../utils/types'; -import type { FieldRootOwnerState } from '../Root/FieldRoot.types'; - -export type FieldErrorOwnerState = FieldRootOwnerState; - -export interface FieldErrorProps extends BaseUIComponentProps<'div', FieldErrorOwnerState> { - /** - * Determines whether the error message should be shown when it matches a given property of the - * field's `ValidityState`. - */ - show?: keyof ValidityState; - /** - * Determines whether the error message should be shown regardless of the field's client validity. - */ - forceShow?: boolean; -} diff --git a/packages/mui-base/src/Field/Error/useFieldError.ts b/packages/mui-base/src/Field/Error/useFieldError.ts index dc2a1c1d04..ad3afe60f5 100644 --- a/packages/mui-base/src/Field/Error/useFieldError.ts +++ b/packages/mui-base/src/Field/Error/useFieldError.ts @@ -5,13 +5,7 @@ import { useId } from '../../utils/useId'; import { useEnhancedEffect } from '../../utils/useEnhancedEffect'; import { useFieldRootContext } from '../Root/FieldRootContext'; -interface UseFieldErrorParameters { - id: string | undefined; - rendered: boolean; - formError: string | string[] | null; -} - -export function useFieldError(params: UseFieldErrorParameters) { +export function useFieldError(params: useFieldError.Parameters) { const { id: idProp, rendered, formError } = params; const { setMessageIds, validityData } = useFieldRootContext(); @@ -56,3 +50,11 @@ export function useFieldError(params: UseFieldErrorParameters) { [getErrorProps], ); } + +export namespace useFieldError { + export interface Parameters { + id: string | undefined; + rendered: boolean; + formError: string | string[] | null; + } +} diff --git a/packages/mui-base/src/Field/Label/FieldLabel.tsx b/packages/mui-base/src/Field/Label/FieldLabel.tsx index e721a74f97..5b7c88606a 100644 --- a/packages/mui-base/src/Field/Label/FieldLabel.tsx +++ b/packages/mui-base/src/Field/Label/FieldLabel.tsx @@ -2,12 +2,13 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; -import type { FieldLabelProps } from './FieldLabel.types'; +import { FieldRoot } from '../Root/FieldRoot'; import { useFieldRootContext } from '../Root/FieldRootContext'; import { useFieldLabel } from './useFieldLabel'; import { STYLE_HOOK_MAPPING } from '../utils/constants'; import { useId } from '../../utils/useId'; import { useEnhancedEffect } from '../../utils/useEnhancedEffect'; +import type { BaseUIComponentProps } from '../../utils/types'; /** * A label for the field's control. @@ -21,7 +22,7 @@ import { useEnhancedEffect } from '../../utils/useEnhancedEffect'; * - [FieldLabel API](https://base-ui.netlify.app/components/react-field/#api-reference-FieldLabel) */ const FieldLabel = React.forwardRef(function FieldLabel( - props: FieldLabelProps, + props: FieldLabel.Props, forwardedRef: React.ForwardedRef, ) { const { render, className, id: idProp, ...otherProps } = props; @@ -52,6 +53,12 @@ const FieldLabel = React.forwardRef(function FieldLabel( return renderElement(); }); +namespace FieldLabel { + export type OwnerState = FieldRoot.OwnerState; + + export interface Props extends BaseUIComponentProps<'div', OwnerState> {} +} + FieldLabel.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ diff --git a/packages/mui-base/src/Field/Label/FieldLabel.types.ts b/packages/mui-base/src/Field/Label/FieldLabel.types.ts deleted file mode 100644 index afa6dd7b71..0000000000 --- a/packages/mui-base/src/Field/Label/FieldLabel.types.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { BaseUIComponentProps } from '../../utils/types'; -import type { FieldRootOwnerState } from '../Root/FieldRoot.types'; - -export type FieldLabelOwnerState = FieldRootOwnerState; - -export interface FieldLabelProps extends BaseUIComponentProps<'div', FieldLabelOwnerState> {} diff --git a/packages/mui-base/src/Field/Label/useFieldLabel.ts b/packages/mui-base/src/Field/Label/useFieldLabel.ts index e0d44c4464..12cc28cdeb 100644 --- a/packages/mui-base/src/Field/Label/useFieldLabel.ts +++ b/packages/mui-base/src/Field/Label/useFieldLabel.ts @@ -3,11 +3,7 @@ import * as React from 'react'; import { mergeReactProps } from '../../utils/mergeReactProps'; import { useFieldRootContext } from '../Root/FieldRootContext'; -interface UseFieldLabelParameters { - customTag: boolean; -} - -export function useFieldLabel(params: UseFieldLabelParameters) { +export function useFieldLabel(params: useFieldLabel.Parameters) { const { customTag } = params; const { controlId, labelId } = useFieldRootContext(); @@ -39,3 +35,9 @@ export function useFieldLabel(params: UseFieldLabelParameters) { [getLabelProps], ); } + +export namespace useFieldLabel { + export interface Parameters { + customTag: boolean; + } +} diff --git a/packages/mui-base/src/Field/Root/FieldRoot.tsx b/packages/mui-base/src/Field/Root/FieldRoot.tsx index f156763c0c..0a7a57643d 100644 --- a/packages/mui-base/src/Field/Root/FieldRoot.tsx +++ b/packages/mui-base/src/Field/Root/FieldRoot.tsx @@ -2,12 +2,12 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; -import type { FieldRootOwnerState, FieldValidityData, FieldRootProps } from './FieldRoot.types'; -import { FieldRootContext, type FieldRootContextValue } from './FieldRootContext'; +import { FieldRootContext } from './FieldRootContext'; import { DEFAULT_VALIDITY_STATE, STYLE_HOOK_MAPPING } from '../utils/constants'; import { useFieldsetRootContext } from '../../Fieldset/Root/FieldsetRootContext'; import { useEventCallback } from '../../utils/useEventCallback'; import { useFormRootContext } from '../../Form/Root/FormRootContext'; +import { BaseUIComponentProps } from '../../utils/types'; /** * The foundation for building custom-styled fields. @@ -21,7 +21,7 @@ import { useFormRootContext } from '../../Form/Root/FormRootContext'; * - [FieldRoot API](https://base-ui.netlify.app/components/react-field/#api-reference-FieldRoot) */ const FieldRoot = React.forwardRef(function FieldRoot( - props: FieldRootProps, + props: FieldRoot.Props, forwardedRef: React.ForwardedRef, ) { const { @@ -72,7 +72,7 @@ const FieldRoot = React.forwardRef(function FieldRoot( const valid = !invalid && validityData.state.valid; - const ownerState: FieldRootOwnerState = React.useMemo( + const ownerState: FieldRoot.OwnerState = React.useMemo( () => ({ disabled, touched, @@ -82,7 +82,7 @@ const FieldRoot = React.forwardRef(function FieldRoot( [disabled, touched, dirty, valid], ); - const contextValue: FieldRootContextValue = React.useMemo( + const contextValue: FieldRootContext = React.useMemo( () => ({ invalid, controlId, @@ -137,6 +137,69 @@ const FieldRoot = React.forwardRef(function FieldRoot( ); }); +export interface FieldValidityData { + state: { + badInput: boolean; + customError: boolean; + patternMismatch: boolean; + rangeOverflow: boolean; + rangeUnderflow: boolean; + stepMismatch: boolean; + tooLong: boolean; + tooShort: boolean; + typeMismatch: boolean; + valueMissing: boolean; + valid: boolean | null; + }; + error: string; + errors: string[]; + value: unknown; + initialValue: unknown; +} + +namespace FieldRoot { + export interface OwnerState { + disabled: boolean; + touched: boolean; + dirty: boolean; + valid: boolean | null; + } + + export interface Props extends BaseUIComponentProps<'div', OwnerState> { + /** + * Whether the field is disabled. Takes precedence over the `disabled` prop of the `Field.Control` + * component. + * @default false + */ + disabled?: boolean; + /** + * The field's name. Takes precedence over the `name` prop of the `Field.Control` component. + */ + name?: string; + /** + * Function to custom-validate the field's value. Return a string or array of strings with error + * messages if the value is invalid, or `null` if the value is valid. The function can also return + * a promise that resolves to a string, array of strings, or `null`. + */ + validate?: (value: unknown) => string | string[] | null | Promise; + /** + * Determines if validation should be triggered on the `change` event, rather than only on commit + * (blur). + * @default false + */ + validateOnChange?: boolean; + /** + * The debounce time in milliseconds for the `validate` function in the `change` phase. + * @default 0 + */ + validateDebounceTime?: number; + /** + * Determines if the field is forcefully marked as invalid. + */ + invalid?: boolean; + } +} + FieldRoot.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ diff --git a/packages/mui-base/src/Field/Root/FieldRoot.types.ts b/packages/mui-base/src/Field/Root/FieldRoot.types.ts deleted file mode 100644 index 659257f49b..0000000000 --- a/packages/mui-base/src/Field/Root/FieldRoot.types.ts +++ /dev/null @@ -1,62 +0,0 @@ -import type { BaseUIComponentProps } from '../../utils/types'; - -export interface FieldValidityData { - state: { - badInput: boolean; - customError: boolean; - patternMismatch: boolean; - rangeOverflow: boolean; - rangeUnderflow: boolean; - stepMismatch: boolean; - tooLong: boolean; - tooShort: boolean; - typeMismatch: boolean; - valueMissing: boolean; - valid: boolean | null; - }; - error: string; - errors: string[]; - value: unknown; - initialValue: unknown; -} - -export interface FieldRootOwnerState { - disabled: boolean; - touched: boolean; - dirty: boolean; - valid: boolean | null; -} - -export interface FieldRootProps extends BaseUIComponentProps<'div', FieldRootOwnerState> { - /** - * Whether the field is disabled. Takes precedence over the `disabled` prop of the `Field.Control` - * component. - * @default false - */ - disabled?: boolean; - /** - * The field's name. Takes precedence over the `name` prop of the `Field.Control` component. - */ - name?: string; - /** - * Function to custom-validate the field's value. Return a string or array of strings with error - * messages if the value is invalid, or `null` if the value is valid. The function can also return - * a promise that resolves to a string, array of strings, or `null`. - */ - validate?: (value: unknown) => string | string[] | null | Promise; - /** - * Determines if validation should be triggered on the `change` event, rather than only on commit - * (blur). - * @default false - */ - validateOnChange?: boolean; - /** - * The debounce time in milliseconds for the `validate` function in the `change` phase. - * @default 0 - */ - validateDebounceTime?: number; - /** - * Determines if the field is forcefully marked as invalid. - */ - invalid?: boolean; -} diff --git a/packages/mui-base/src/Field/Root/FieldRootContext.ts b/packages/mui-base/src/Field/Root/FieldRootContext.ts index 248009f59a..833c761be6 100644 --- a/packages/mui-base/src/Field/Root/FieldRootContext.ts +++ b/packages/mui-base/src/Field/Root/FieldRootContext.ts @@ -1,11 +1,11 @@ 'use client'; import * as React from 'react'; import { DEFAULT_VALIDITY_STATE } from '../utils/constants'; -import type { FieldRootOwnerState, FieldValidityData } from './FieldRoot.types'; +import type { FieldRoot, FieldValidityData } from './FieldRoot'; const NOOP = () => {}; -export interface FieldRootContextValue { +export interface FieldRootContext { invalid: boolean | undefined; controlId: string | undefined; setControlId: React.Dispatch>; @@ -24,11 +24,11 @@ export interface FieldRootContextValue { validate: (value: unknown) => string | string[] | null | Promise; validateOnChange: boolean; validateDebounceTime: number; - ownerState: FieldRootOwnerState; + ownerState: FieldRoot.OwnerState; markedDirtyRef: React.MutableRefObject; } -export const FieldRootContext = React.createContext({ +export const FieldRootContext = React.createContext({ invalid: undefined, controlId: undefined, setControlId: NOOP, diff --git a/packages/mui-base/src/Field/Validity/FieldValidity.tsx b/packages/mui-base/src/Field/Validity/FieldValidity.tsx index f20c8c1793..ebe70f797e 100644 --- a/packages/mui-base/src/Field/Validity/FieldValidity.tsx +++ b/packages/mui-base/src/Field/Validity/FieldValidity.tsx @@ -2,8 +2,8 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useFieldRootContext } from '../Root/FieldRootContext'; -import type { FieldValidityProps, FieldValidityState } from './FieldValidity.types'; import { getCombinedFieldValidityData } from '../utils/getCombinedFieldValidityData'; +import { FieldValidityData } from '../Root/FieldRoot'; /** * Render prop component that provides the field's validity state and value to its children. @@ -16,7 +16,7 @@ import { getCombinedFieldValidityData } from '../utils/getCombinedFieldValidityD * * - [FieldValidity API](https://base-ui.netlify.app/components/react-field/#api-reference-FieldValidity) */ -function FieldValidity(props: FieldValidityProps) { +function FieldValidity(props: FieldValidity.Props) { const { validityData, invalid } = useFieldRootContext(false); const fieldValidityState: FieldValidityState = React.useMemo(() => { @@ -30,6 +30,18 @@ function FieldValidity(props: FieldValidityProps) { return {props.children(fieldValidityState)}; } +export interface FieldValidityState extends Omit { + validity: FieldValidityData['state']; +} + +namespace FieldValidity { + export interface OwnerState {} + + export interface Props { + children: (state: FieldValidityState) => React.ReactNode; + } +} + FieldValidity.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ diff --git a/packages/mui-base/src/Field/Validity/FieldValidity.types.ts b/packages/mui-base/src/Field/Validity/FieldValidity.types.ts deleted file mode 100644 index 7e0975c6cf..0000000000 --- a/packages/mui-base/src/Field/Validity/FieldValidity.types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type * as React from 'react'; -import type { FieldValidityData } from '../Root/FieldRoot.types'; - -export interface FieldValidityState extends Omit { - validity: FieldValidityData['state']; -} - -export interface FieldValidityOwnerState {} - -export interface FieldValidityProps { - children: (state: FieldValidityState) => React.ReactNode; -} diff --git a/packages/mui-base/src/Field/index.barrel.ts b/packages/mui-base/src/Field/index.barrel.ts index 44e3c5cee7..e9604532cf 100644 --- a/packages/mui-base/src/Field/index.barrel.ts +++ b/packages/mui-base/src/Field/index.barrel.ts @@ -5,9 +5,4 @@ export * from './Description/FieldDescription'; export * from './Control/FieldControl'; export * from './Validity/FieldValidity'; -export type * from './Root/FieldRoot.types'; -export type * from './Label/FieldLabel.types'; -export type * from './Error/FieldError.types'; -export type * from './Description/FieldDescription.types'; -export type * from './Control/FieldControl.types'; -export type * from './Validity/FieldValidity.types'; +export type { FieldValidityData } from './Root/FieldRoot'; diff --git a/packages/mui-base/src/Field/index.ts b/packages/mui-base/src/Field/index.ts index 51e9f3afb3..caded13966 100644 --- a/packages/mui-base/src/Field/index.ts +++ b/packages/mui-base/src/Field/index.ts @@ -5,25 +5,4 @@ export { FieldDescription as Description } from './Description/FieldDescription' export { FieldControl as Control } from './Control/FieldControl'; export { FieldValidity as Validity } from './Validity/FieldValidity'; -export type { - FieldRootProps as RootProps, - FieldRootOwnerState as RootOwnerState, - FieldValidityData as ValidityData, -} from './Root/FieldRoot.types'; -export type { - FieldLabelProps as LabelProps, - FieldLabelOwnerState as LabelOwnerState, -} from './Label/FieldLabel.types'; -export type { - FieldErrorProps as ErrorProps, - FieldErrorOwnerState as ErrorOwnerState, -} from './Error/FieldError.types'; -export type { - FieldDescriptionProps as DescriptionProps, - FieldDescriptionOwnerState as DescriptionOwnerState, -} from './Description/FieldDescription.types'; -export type { - FieldControlProps as ControlProps, - FieldControlOwnerState as ControlOwnerState, -} from './Control/FieldControl.types'; -export type { FieldValidityProps as ValidityProps } from './Validity/FieldValidity.types'; +export type { FieldValidityData as ValidityData } from './Root/FieldRoot'; diff --git a/packages/mui-base/src/Field/utils/getCombinedFieldValidityData.ts b/packages/mui-base/src/Field/utils/getCombinedFieldValidityData.ts index a4f9adc041..fdf7bb43ab 100644 --- a/packages/mui-base/src/Field/utils/getCombinedFieldValidityData.ts +++ b/packages/mui-base/src/Field/utils/getCombinedFieldValidityData.ts @@ -1,4 +1,4 @@ -import type { FieldValidityData } from '../Root/FieldRoot.types'; +import { FieldValidityData } from '../Root/FieldRoot'; /** * Combines the field's client-side, stateful validity data with the external invalid state to diff --git a/packages/mui-base/src/Form/Root/FormRootContext.ts b/packages/mui-base/src/Form/Root/FormRootContext.ts index 842fbdba2a..8eb9bf6da4 100644 --- a/packages/mui-base/src/Form/Root/FormRootContext.ts +++ b/packages/mui-base/src/Form/Root/FormRootContext.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import type { FieldValidityData } from '../../Field/Root/FieldRoot.types'; +import type { FieldValidityData } from '../../Field/Root/FieldRoot'; type Errors = Record; diff --git a/packages/mui-base/src/NumberField/Root/NumberFieldRoot.tsx b/packages/mui-base/src/NumberField/Root/NumberFieldRoot.tsx index 201004938b..fb5bce021a 100644 --- a/packages/mui-base/src/NumberField/Root/NumberFieldRoot.tsx +++ b/packages/mui-base/src/NumberField/Root/NumberFieldRoot.tsx @@ -6,7 +6,7 @@ import { UseNumberFieldRoot, useNumberFieldRoot } from './useNumberFieldRoot'; import { useFieldRootContext } from '../../Field/Root/FieldRootContext'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; import type { BaseUIComponentProps } from '../../utils/types'; -import type { FieldRootOwnerState } from '../../Field/Root/FieldRoot.types'; +import type { FieldRoot } from '../../Field/Root/FieldRoot'; /** * The foundation for building custom-styled number fields. @@ -102,7 +102,7 @@ export namespace NumberFieldRoot { extends UseNumberFieldRoot.Parameters, Omit, 'onChange' | 'defaultValue'> {} - export interface OwnerState extends FieldRootOwnerState { + export interface OwnerState extends FieldRoot.OwnerState { /** * The raw number value of the input element. */ diff --git a/packages/mui-base/src/Slider/Root/SliderRoot.types.ts b/packages/mui-base/src/Slider/Root/SliderRoot.types.ts index 4eefca63ee..1cb4b53fa5 100644 --- a/packages/mui-base/src/Slider/Root/SliderRoot.types.ts +++ b/packages/mui-base/src/Slider/Root/SliderRoot.types.ts @@ -1,6 +1,6 @@ import type { BaseUIComponentProps } from '../../utils/types'; import type { CompoundComponentContextValue } from '../../useCompound'; -import type { FieldRootOwnerState } from '../../Field/Root/FieldRoot.types'; +import type { FieldRoot } from '../../Field/Root/FieldRoot'; export interface SliderThumbMetadata { inputId: string; @@ -23,7 +23,7 @@ export type SliderDirection = 'ltr' | 'rtl'; export type SliderOrientation = 'horizontal' | 'vertical'; -export interface SliderRootOwnerState extends FieldRootOwnerState { +export interface SliderRootOwnerState extends FieldRoot.OwnerState { /** * The index of the active thumb. */ diff --git a/packages/mui-base/src/Switch/Root/SwitchRoot.tsx b/packages/mui-base/src/Switch/Root/SwitchRoot.tsx index 0c72e0152d..40831d0b5d 100644 --- a/packages/mui-base/src/Switch/Root/SwitchRoot.tsx +++ b/packages/mui-base/src/Switch/Root/SwitchRoot.tsx @@ -6,9 +6,9 @@ import { useSwitchRoot } from './useSwitchRoot'; import { SwitchRootContext } from './SwitchRootContext'; import { styleHookMapping } from '../styleHooks'; import { useComponentRenderer } from '../../utils/useComponentRenderer'; +import type { FieldRoot } from '../../Field/Root/FieldRoot'; import { useFieldRootContext } from '../../Field/Root/FieldRootContext'; import type { BaseUIComponentProps } from '../../utils/types'; -import type { FieldRootOwnerState } from '../../Field/Root/FieldRoot.types'; /** * The foundation for building custom-styled switches. @@ -78,7 +78,7 @@ namespace SwitchRoot { extends useSwitchRoot.Parameters, Omit, 'onChange'> {} - export interface OwnerState extends FieldRootOwnerState { + export interface OwnerState extends FieldRoot.OwnerState { checked: boolean; disabled: boolean; readOnly: boolean;