Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/pankod/material-ui
Browse files Browse the repository at this point in the history
  • Loading branch information
omeraplak committed Jun 21, 2022
2 parents 3c645f6 + dba967d commit 0e9ba31
Show file tree
Hide file tree
Showing 13 changed files with 109 additions and 97 deletions.
1 change: 0 additions & 1 deletion docs/pages/base/api/form-control-unstyled.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" } },
"className": { "type": { "name": "string" } },
"component": { "type": { "name": "elementType" } },
"components": {
"type": { "name": "shape", "description": "{ Root?: elementType }" },
Expand Down
1 change: 0 additions & 1 deletion docs/pages/base/api/switch-unstyled.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"props": {
"checked": { "type": { "name": "bool" } },
"className": { "type": { "name": "string" } },
"component": { "type": { "name": "elementType" } },
"components": {
"type": {
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.",
"className": "Class name applied to the root element.",
"component": "The component used for the root node. Either a string to use a HTML element or a component.",
"components": "The components used for each slot inside the FormControl. 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.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"componentDescription": "The foundation for building custom-styled switches.",
"propDescriptions": {
"checked": "If <code>true</code>, the component is checked.",
"className": "Class name applied to the root element.",
"component": "The component used for the Root slot. Either a string to use a HTML element or a component. This is equivalent to <code>components.Root</code>. If both are provided, the <code>component</code> is used.",
"components": "The components used for each slot inside the Switch. Either a string to use a HTML element or a component.",
"componentsProps": "The props used for each slot inside the Switch.",
Expand Down
7 changes: 1 addition & 6 deletions packages/mui-base/src/ButtonUnstyled/ButtonUnstyled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ const ButtonUnstyled = React.forwardRef(function ButtonUnstyled<
const {
action,
children,
className,
component,
components = {},
componentsProps = {},
Expand Down Expand Up @@ -96,7 +95,7 @@ const ButtonUnstyled = React.forwardRef(function ButtonUnstyled<
ref: forwardedRef,
},
ownerState,
className: [classes.root, className],
className: classes.root,
});

return <Root {...rootProps}>{children}</Root>;
Expand All @@ -122,10 +121,6 @@ ButtonUnstyled.propTypes /* remove-proptypes */ = {
* @ignore
*/
children: PropTypes.node,
/**
* @ignore
*/
className: PropTypes.string,
/**
* The component used for the Root slot.
* Either a string to use a HTML element or a component.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import FormControlUnstyled from '@mui/base/FormControlUnstyled';
import { expectType } from '@mui/types';
import { FormControlUnstyledRootSlotProps } from './FormControlUnstyled.types';

const CustomComponent: React.FC<{ stringProp: string; numberProp: number }> = () => <div />;

Expand Down Expand Up @@ -33,3 +34,10 @@ const FormControlUnstyledTest = () => (
/>
</div>
);

function Root(props: FormControlUnstyledRootSlotProps) {
const { ownerState, ...other } = props;
return <div data-filled={ownerState.filled} {...other} />;
}

const StyledFormControl = <FormControlUnstyled components={{ Root }} />;
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ describe('<FormControlUnstyled />', () => {
expectedClassName: formControlUnstyledClasses.root,
},
},
skip: ['componentsPropsCallbacks'], // not implemented yet
}));

describe('initial state', () => {
Expand Down
61 changes: 35 additions & 26 deletions packages/mui-base/src/FormControlUnstyled/FormControlUnstyled.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,41 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { OverridableComponent } from '@mui/types';
import { unstable_useControlled as useControlled } from '@mui/utils';
import FormControlUnstyledContext from './FormControlUnstyledContext';
import appendOwnerState from '../utils/appendOwnerState';
import classes from './formControlUnstyledClasses';
import { getFormControlUnstyledUtilityClass } from './formControlUnstyledClasses';
import {
FormControlUnstyledProps,
NativeFormControlElement,
FormControlUnstyledTypeMap,
FormControlUnstyledOwnerState,
FormControlUnstyledState,
FormControlUnstyledRootSlotProps,
} from './FormControlUnstyled.types';
import { useSlotProps, WithOptionalOwnerState } from '../utils';
import composeClasses from '../composeClasses';

function hasValue(value: unknown) {
return value != null && !(Array.isArray(value) && value.length === 0) && value !== '';
}

function useUtilityClasses(ownerState: FormControlUnstyledOwnerState) {
const { disabled, error, filled, focused, required } = ownerState;

const slots = {
root: [
'root',
disabled && 'disabled',
focused && 'focused',
error && 'error',
filled && 'filled',
required && 'required',
],
};

return composeClasses(slots, getFormControlUnstyledUtilityClass, {});
}

/**
* Provides context such as filled/focused/error/required for form inputs.
* Relying on the context provides high flexibility and ensures that the state always stays
Expand Down Expand Up @@ -56,7 +74,6 @@ const FormControlUnstyled = React.forwardRef(function FormControlUnstyled<
const {
defaultValue,
children,
className,
component,
components = {},
componentsProps = {},
Expand Down Expand Up @@ -112,8 +129,19 @@ const FormControlUnstyled = React.forwardRef(function FormControlUnstyled<
value: value ?? '',
};

const classes = useUtilityClasses(ownerState);

const Root = component ?? components.Root ?? 'div';
const rootProps = appendOwnerState(Root, { ...other, ...componentsProps.root }, ownerState);
const rootProps: WithOptionalOwnerState<FormControlUnstyledRootSlotProps> = useSlotProps({
elementType: Root,
externalSlotProps: componentsProps.root,
externalForwardedProps: other,
additionalProps: {
ref,
},
ownerState,
className: classes.root,
});

const renderChildren = () => {
if (typeof children === 'function') {
Expand All @@ -125,22 +153,7 @@ const FormControlUnstyled = React.forwardRef(function FormControlUnstyled<

return (
<FormControlUnstyledContext.Provider value={childContext}>
<Root
ref={ref}
{...rootProps}
className={clsx(
classes.root,
className,
rootProps?.className,
disabled && classes.disabled,
error && classes.error,
filled && classes.filled,
focused && classes.focused,
required && classes.required,
)}
>
{renderChildren()}
</Root>
<Root {...rootProps}>{renderChildren()}</Root>
</FormControlUnstyledContext.Provider>
);
}) as OverridableComponent<FormControlUnstyledTypeMap>;
Expand All @@ -157,10 +170,6 @@ FormControlUnstyled.propTypes /* remove-proptypes */ = {
PropTypes.node,
PropTypes.func,
]),
/**
* Class name applied to the root element.
*/
className: PropTypes.string,
/**
* The component used for the root node.
* Either a string to use a HTML element or a component.
Expand All @@ -178,7 +187,7 @@ FormControlUnstyled.propTypes /* remove-proptypes */ = {
* @ignore
*/
componentsProps: PropTypes.shape({
root: PropTypes.object,
root: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
}),
/**
* @ignore
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react';
import { OverrideProps, Simplify } from '@mui/types';
import { SlotComponentProps } from '../utils';

export type NativeFormControlElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;

Expand All @@ -23,7 +24,11 @@ export interface FormControlUnstyledOwnProps {
Root?: React.ElementType;
};
componentsProps?: {
root?: React.HTMLAttributes<HTMLDivElement> & FormControlUnstyledComponentsPropsOverrides;
root?: SlotComponentProps<
'div',
FormControlUnstyledComponentsPropsOverrides,
FormControlUnstyledOwnerState
>;
};
defaultValue?: unknown;
/**
Expand Down Expand Up @@ -68,6 +73,7 @@ export type FormControlUnstyledOwnerState = Simplify<
Omit<FormControlUnstyledOwnProps, NonOptionalOwnerState> &
Required<Pick<FormControlUnstyledProps, NonOptionalOwnerState>> & {
filled: boolean;
focused: boolean;
}
>;

Expand All @@ -81,3 +87,9 @@ export type FormControlUnstyledState = Simplify<
onFocus: () => void;
}
>;

export type FormControlUnstyledRootSlotProps = {
children: React.ReactNode | ((state: FormControlUnstyledState) => React.ReactNode);
className?: string;
ownerState: FormControlUnstyledOwnerState;
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface FormControlUnstyledClasses {

export type FormControlUnstyledClassKey = keyof FormControlUnstyledClasses;

export function getFormControlUnstyledUtilityClasses(slot: string): string {
export function getFormControlUnstyledUtilityClass(slot: string): string {
return generateUtilityClass('BaseFormControl', slot);
}

Expand Down
7 changes: 1 addition & 6 deletions packages/mui-base/src/MenuItemUnstyled/MenuItemUnstyled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const MenuItemUnstyled = React.forwardRef(function MenuItemUnstyled(
) {
const {
children,
className,
disabled: disabledProp = false,
component,
components = {},
Expand All @@ -57,7 +56,7 @@ const MenuItemUnstyled = React.forwardRef(function MenuItemUnstyled(
getSlotProps: getRootProps,
externalSlotProps: componentsProps.root,
externalForwardedProps: other,
className: [classes.root, className],
className: classes.root,
ownerState,
});

Expand All @@ -73,10 +72,6 @@ MenuItemUnstyled.propTypes /* remove-proptypes */ = {
* @ignore
*/
children: PropTypes.node,
/**
* @ignore
*/
className: PropTypes.string,
/**
* @ignore
*/
Expand Down
8 changes: 1 addition & 7 deletions packages/mui-base/src/MenuUnstyled/MenuUnstyled.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { HTMLElementType, refType } from '@mui/utils';
import MenuUnstyledContext, { MenuUnstyledContextType } from './MenuUnstyledContext';
import {
Expand Down Expand Up @@ -41,7 +40,6 @@ const MenuUnstyled = React.forwardRef(function MenuUnstyled(
actions,
anchorEl,
children,
className,
component,
components = {},
componentsProps = {},
Expand Down Expand Up @@ -94,7 +92,7 @@ const MenuUnstyled = React.forwardRef(function MenuUnstyled(
role: undefined,
ref: forwardedRef,
},
className: clsx(classes.root, className),
className: classes.root,
ownerState,
}) as MenuUnstyledRootSlotProps;

Expand Down Expand Up @@ -148,10 +146,6 @@ MenuUnstyled.propTypes /* remove-proptypes */ = {
* @ignore
*/
children: PropTypes.node,
/**
* @ignore
*/
className: PropTypes.string,
/**
* @ignore
*/
Expand Down
Loading

0 comments on commit 0e9ba31

Please sign in to comment.