Skip to content

Commit

Permalink
[FormControl][base] Drop component prop
Browse files Browse the repository at this point in the history
  • Loading branch information
hbjORbj committed Apr 26, 2023
1 parent 95f93e7 commit 3a29767
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 17 deletions.
14 changes: 14 additions & 0 deletions docs/data/base/components/form-control/form-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ Note that it also uses the `useFormControlContext` hook in order to pass props t

{{"demo": "BasicFormControl.js"}}

#### Usage with TypeScript

In TypeScript, you can specify the custom component type used in the `slots.root` as a generic to the unstyled component. This way, you can safely provide the custom compoenent's props directly on the compnent:

```tsx
<FormControl<typeof CustomComponent> slots={{ root: CustomComponent }} customProp />
```

The same applies for props specific to custom primitive elements:

```tsx
<FormControl<'button'> slots={{ root: 'button' }} onClick={() => {}} />
```

## Hook

```jsx
Expand Down
1 change: 0 additions & 1 deletion docs/pages/base/api/form-control.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"props": {
"children": { "type": { "name": "union", "description": "node<br>&#124;&nbsp;func" } },
"component": { "type": { "name": "elementType" } },
"disabled": { "type": { "name": "bool" }, "default": "false" },
"error": { "type": { "name": "bool" }, "default": "false" },
"onChange": { "type": { "name": "func" } },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"componentDescription": "Provides context such as filled/focused/error/required for form inputs.\nRelying on the context provides high flexibility and ensures that the state always stays\nconsistent across the children of the `FormControl`.\nThis context is used by the following components:\n\n* FormLabel\n* FormHelperText\n* Input\n* InputLabel\n\nYou can find one composition example below and more going to [the demos](https://mui.com/material-ui/react-text-field/#components).\n\n```jsx\n<FormControl>\n <InputLabel htmlFor=\"my-input\">Email address</InputLabel>\n <Input id=\"my-input\" aria-describedby=\"my-helper-text\" />\n <FormHelperText id=\"my-helper-text\">We'll never share your email.</FormHelperText>\n</FormControl>\n```\n\n⚠️ Only one `Input` can be used within a FormControl because it create visual inconsistencies.\nFor instance, only one input can be focused at the same time, the state shouldn't be shared.",
"propDescriptions": {
"children": "The content of the component.",
"component": "The component used for the root node. Either a string to use a HTML element or a component.",
"disabled": "If <code>true</code>, the label, input and helper text should be displayed in a disabled state.",
"error": "If <code>true</code>, the label is displayed in an error state.",
"onChange": "Callback fired when the form element&#39;s value is modified.",
Expand Down
32 changes: 26 additions & 6 deletions packages/mui-base/src/FormControl/FormControl.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,39 @@ function FormControlTest() {
{/* @ts-expect-error */}
<FormControl invalidProp={0} />

<FormControl component="a" href="#" />
<FormControl<'a'>
slots={{
root: 'a',
}}
href="#"
/>

<FormControl<typeof CustomComponent>
slots={{
root: CustomComponent,
}}
stringProp="test"
numberProp={0}
/>

<FormControl component={CustomComponent} stringProp="test" numberProp={0} />
{/* @ts-expect-error */}
<FormControl component={CustomComponent} />
<FormControl<typeof CustomComponent>
slots={{
root: CustomComponent,
}}
/>

<FormControl
component="button"
<FormControl<'button'>
slots={{
root: 'button',
}}
onClick={(e: React.MouseEvent<HTMLButtonElement>) => e.currentTarget.checkValidity()}
/>

<FormControl<'button'>
component="button"
slots={{
root: 'button',
}}
ref={(elem) => {
expectType<HTMLButtonElement | null, typeof elem>(elem);
}}
Expand Down
1 change: 1 addition & 0 deletions packages/mui-base/src/FormControl/FormControl.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ describe('<FormControl />', () => {
expectedClassName: formControlClasses.root,
},
},
skip: ['componentProp'],
}));

describe('initial state', () => {
Expand Down
12 changes: 3 additions & 9 deletions packages/mui-base/src/FormControl/FormControl.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { OverridableComponent } from '@mui/types';
import { unstable_useControlled as useControlled } from '@mui/utils';
import { PolymorphicComponent } from '../utils/PolymorphicComponent';
import FormControlContext from './FormControlContext';
import { getFormControlUtilityClass } from './formControlClasses';
import {
Expand Down Expand Up @@ -80,7 +80,6 @@ const FormControl = React.forwardRef(function FormControl<
const {
defaultValue,
children,
component,
disabled = false,
error = false,
onChange,
Expand Down Expand Up @@ -145,7 +144,7 @@ const FormControl = React.forwardRef(function FormControl<
return children;
};

const Root = component ?? slots.root ?? 'div';
const Root = slots.root ?? 'div';
const rootProps: WithOptionalOwnerState<FormControlRootSlotProps> = useSlotProps({
elementType: Root,
externalSlotProps: slotProps.root,
Expand All @@ -163,7 +162,7 @@ const FormControl = React.forwardRef(function FormControl<
<Root {...rootProps} />
</FormControlContext.Provider>
);
}) as OverridableComponent<FormControlTypeMap>;
}) as PolymorphicComponent<FormControlTypeMap>;

FormControl.propTypes /* remove-proptypes */ = {
// ----------------------------- Warning --------------------------------
Expand All @@ -177,11 +176,6 @@ FormControl.propTypes /* remove-proptypes */ = {
PropTypes.node,
PropTypes.func,
]),
/**
* The component used for the root node.
* Either a string to use a HTML element or a component.
*/
component: PropTypes.elementType,
/**
* @ignore
*/
Expand Down

0 comments on commit 3a29767

Please sign in to comment.