Skip to content

Commit

Permalink
[material-next][ButtonGroup] Change ButtonGroup files to ts (#39794)
Browse files Browse the repository at this point in the history
  • Loading branch information
lhilgert9 authored Dec 6, 2023
1 parent 355a533 commit 93fdbe0
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 85 deletions.
7 changes: 5 additions & 2 deletions packages/mui-material-next/src/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,10 @@ const Button = React.forwardRef(function Button<
>(inProps: ButtonProps<BaseComponentType>, ref: React.ForwardedRef<any>) {
const contextProps = React.useContext(ButtonGroupContext);
const buttonGroupButtonContextPositionClassName = React.useContext(ButtonGroupButtonContext);
const resolvedProps = resolveProps(contextProps as ButtonProps<BaseComponentType>, inProps);
const resolvedProps = resolveProps(
(contextProps ?? {}) as ButtonProps<BaseComponentType>,
inProps,
);
const props = useThemeProps({ props: resolvedProps, name: 'MuiButton' });
const {
children,
Expand Down Expand Up @@ -412,7 +415,7 @@ const Button = React.forwardRef(function Button<
ref,
},
ownerState,
className: clsx(contextProps.className, positionClassName),
className: clsx(contextProps?.className, positionClassName),
});

const startIcon = startIconProp && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ import { createRenderer, describeConformance, screen } from '@mui-internal/test-
import ButtonGroup, { buttonGroupClasses as classes } from '@mui/material-next/ButtonGroup';
import { CssVarsProvider, extendTheme } from '@mui/material-next/styles';
import Button, { buttonClasses } from '@mui/material-next/Button';
import ButtonGroupContext from './ButtonGroupContext';
import ButtonGroupContext, { ButtonGroupContextType } from './ButtonGroupContext';

describe('<ButtonGroup />', () => {
const { render } = createRenderer();

let originalMatchmedia;
let originalMatchmedia: typeof window.matchMedia;

beforeEach(() => {
originalMatchmedia = window.matchMedia;
window.matchMedia = () => ({
addListener: () => {},
removeListener: () => {},
});
window.matchMedia = () =>
({
addListener: () => {},
removeListener: () => {},
} as unknown as MediaQueryList);
});
afterEach(() => {
window.matchMedia = originalMatchmedia;
Expand Down Expand Up @@ -119,9 +120,10 @@ describe('<ButtonGroup />', () => {
});

it('should have a ripple by default', () => {
const props = { TouchRippleProps: { classes: { root: 'touchRipple' } } };
const { container } = render(
<ButtonGroup>
<Button TouchRippleProps={{ classes: { root: 'touchRipple' } }}>Hello World</Button>
<Button {...props}>Hello World</Button>
</ButtonGroup>,
);
expect(container.querySelector('.touchRipple')).not.to.equal(null);
Expand All @@ -138,9 +140,10 @@ describe('<ButtonGroup />', () => {
});

it('can disable the ripple', () => {
const props = { TouchRippleProps: { classes: { root: 'touchRipple' } } };
const { container } = render(
<ButtonGroup disableRipple>
<Button TouchRippleProps={{ classes: { root: 'touchRipple' } }}>Hello World</Button>
<Button {...props}>Hello World</Button>
</ButtonGroup>,
);
expect(container.querySelector('.touchRipple')).to.equal(null);
Expand Down Expand Up @@ -181,24 +184,25 @@ describe('<ButtonGroup />', () => {
});

it('should forward the context to children', () => {
let context;
let context: ButtonGroupContextType | null;
render(
<ButtonGroup size="large" variant="contained">
<ButtonGroupContext.Consumer>
{(value) => {
context = value;
return <Button />;
}}
</ButtonGroupContext.Consumer>
</ButtonGroup>,
);
expect(context.variant).to.equal('contained');
expect(context.size).to.equal('large');
expect(context.fullWidth).to.equal(false);
expect(context.disableRipple).to.equal(false);
expect(context.disableTouchRipple).to.equal(false);
expect(context.disableElevation).to.equal(false);
expect(context.disabled).to.equal(false);
expect(context.color).to.equal('primary');
expect(context!.variant).to.equal('contained');
expect(context!.size).to.equal('large');
expect(context!.fullWidth).to.equal(false);
expect(context!.disableRipple).to.equal(false);
expect(context!.disableTouchRipple).to.equal(false);
expect(context!.disableElevation).to.equal(false);
expect(context!.disabled).to.equal(false);
expect(context!.color).to.equal('primary');
});

describe('theme default props on Button', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,15 @@ import clsx from 'clsx';
import { unstable_composeClasses as composeClasses } from '@mui/base/composeClasses';
import { alpha } from '@mui/system';
import { getValidReactChildren, unstable_capitalize as capitalize } from '@mui/utils';
import { OverridableComponent } from '@mui/types';
import styled from '../styles/styled';
import useThemeProps from '../styles/useThemeProps';
import buttonGroupClasses, { getButtonGroupUtilityClass } from './buttonGroupClasses';
import ButtonGroupContext from './ButtonGroupContext';
import ButtonGroupButtonContext from './ButtonGroupButtonContext';
import { ButtonGroupOwnerState, ButtonGroupProps, ButtonGroupTypeMap } from './ButtonGroup.types';

const overridesResolver = (props, styles) => {
const { ownerState } = props;

return [
{ [`& .${buttonGroupClasses.grouped}`]: styles.grouped },
{
[`& .${buttonGroupClasses.grouped}`]: styles[`grouped${capitalize(ownerState.orientation)}`],
},
{ [`& .${buttonGroupClasses.grouped}`]: styles[`grouped${capitalize(ownerState.variant)}`] },
{
[`& .${buttonGroupClasses.grouped}`]:
styles[`grouped${capitalize(ownerState.variant)}${capitalize(ownerState.orientation)}`],
},
{
[`& .${buttonGroupClasses.grouped}`]:
styles[`grouped${capitalize(ownerState.variant)}${capitalize(ownerState.color)}`],
},
{
[`& .${buttonGroupClasses.firstButton}`]: styles.firstButton,
},
{
[`& .${buttonGroupClasses.lastButton}`]: styles.lastButton,
},
{
[`& .${buttonGroupClasses.middleButton}`]: styles.middleButton,
},
styles.root,
styles[ownerState.variant],
ownerState.disableElevation === true && styles.disableElevation,
ownerState.fullWidth && styles.fullWidth,
ownerState.orientation === 'vertical' && styles.vertical,
];
};

const useUtilityClasses = (ownerState) => {
const useUtilityClasses = (ownerState: ButtonGroupOwnerState) => {
const { classes, color, disabled, disableElevation, fullWidth, orientation, variant } =
ownerState;

Expand Down Expand Up @@ -76,8 +44,42 @@ const useUtilityClasses = (ownerState) => {
const ButtonGroupRoot = styled('div', {
name: 'MuiButtonGroup',
slot: 'Root',
overridesResolver,
})(({ theme, ownerState }) => ({
overridesResolver(props, styles) {
const {
ownerState: { color, disableElevation, fullWidth, orientation, variant },
} = props;

return [
{ [`& .${buttonGroupClasses.grouped}`]: styles.grouped },
{
[`& .${buttonGroupClasses.grouped}`]: styles[`grouped${capitalize(orientation)}`],
},
{ [`& .${buttonGroupClasses.grouped}`]: styles[`grouped${capitalize(variant)}`] },
{
[`& .${buttonGroupClasses.grouped}`]:
styles[`grouped${capitalize(variant)}${capitalize(orientation)}`],
},
{
[`& .${buttonGroupClasses.grouped}`]:
styles[`grouped${capitalize(variant)}${capitalize(color)}`],
},
{
[`& .${buttonGroupClasses.firstButton}`]: styles.firstButton,
},
{
[`& .${buttonGroupClasses.lastButton}`]: styles.lastButton,
},
{
[`& .${buttonGroupClasses.middleButton}`]: styles.middleButton,
},
styles.root,
styles[variant],
disableElevation === true && styles.disableElevation,
fullWidth && styles.fullWidth,
orientation === 'vertical' && styles.vertical,
];
},
})<{ ownerState: ButtonGroupOwnerState }>(({ theme, ownerState }) => ({
display: 'inline-flex',
borderRadius: (theme.vars || theme).shape.borderRadius,
...(ownerState.variant === 'contained' && {
Expand Down Expand Up @@ -197,7 +199,19 @@ const ButtonGroupRoot = styled('div', {
},
}));

const ButtonGroup = React.forwardRef(function ButtonGroup(inProps, ref) {
/**
*
* Demos:
*
* - [Button Group](https://mui.com/material-ui/react-button-group/)
*
* API:
*
* - [ButtonGroup API](https://mui.com/material-ui/api/button-group/)
*/
const ButtonGroup = React.forwardRef(function ButtonGroup<
BaseComponentType extends React.ElementType = ButtonGroupTypeMap['defaultComponent'],
>(inProps: ButtonGroupProps<BaseComponentType>, ref: React.ForwardedRef<HTMLDivElement>) {
const props = useThemeProps({ props: inProps, name: 'MuiButtonGroup' });
const {
children,
Expand Down Expand Up @@ -259,7 +273,7 @@ const ButtonGroup = React.forwardRef(function ButtonGroup(inProps, ref) {
const validChildren = getValidReactChildren(children);
const childrenCount = validChildren.length;

const getButtonPositionClassName = (index) => {
const getButtonPositionClassName = (index: number) => {
const isFirstButton = index === 0;
const isLastButton = index === childrenCount - 1;

Expand Down Expand Up @@ -298,12 +312,12 @@ const ButtonGroup = React.forwardRef(function ButtonGroup(inProps, ref) {
</ButtonGroupContext.Provider>
</ButtonGroupRoot>
);
});
}) as OverridableComponent<ButtonGroupTypeMap>;

ButtonGroup.propTypes /* remove-proptypes */ = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit the d.ts file and run "yarn proptypes" |
// | To update them edit TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* The content of the component.
Expand Down Expand Up @@ -387,6 +401,6 @@ ButtonGroup.propTypes /* remove-proptypes */ = {
PropTypes.oneOf(['contained', 'outlined', 'text']),
PropTypes.string,
]),
};
} as any;

export default ButtonGroup;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { SxProps } from '@mui/system';
import { OverridableComponent, OverridableStringUnion, OverrideProps } from '@mui/types';
import { OverridableStringUnion, OverrideProps, PartiallyRequired } from '@mui/types';
import { Theme } from '../styles';
import { ButtonGroupClasses } from './buttonGroupClasses';

Expand Down Expand Up @@ -85,23 +85,23 @@ export interface ButtonGroupTypeMap<
defaultComponent: RootComponent;
}

/**
*
* Demos:
*
* - [Button Group](https://mui.com/material-ui/react-button-group/)
*
* API:
*
* - [ButtonGroup API](https://mui.com/material-ui/api/button-group/)
*/
declare const ButtonGroup: OverridableComponent<ButtonGroupTypeMap>;

export type ButtonGroupProps<
RootComponent extends React.ElementType = ButtonGroupTypeMap['defaultComponent'],
AdditionalProps = {},
> = OverrideProps<ButtonGroupTypeMap<AdditionalProps, RootComponent>, RootComponent> & {
component?: React.ElementType;
};

export default ButtonGroup;
export interface ButtonGroupOwnerState
extends PartiallyRequired<
ButtonGroupProps,
| 'color'
| 'disabled'
| 'disableElevation'
| 'disableRipple'
| 'disableTouchRipple'
| 'fullWidth'
| 'orientation'
| 'size'
| 'variant'
> {}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ type ButtonPositionClassName = string;
/**
* @ignore - internal component.
*/
const ButtonGroupButtonContext = React.createContext<ButtonPositionClassName | undefined>(
undefined,
);
const ButtonGroupButtonContext = React.createContext<ButtonPositionClassName | null>(null);

if (process.env.NODE_ENV !== 'production') {
ButtonGroupButtonContext.displayName = 'ButtonGroupButtonContext';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import type { ButtonGroupProps } from './ButtonGroup';
import type { ButtonGroupProps } from './ButtonGroup.types';

interface ButtonGroupContextType {
export interface ButtonGroupContextType {
className?: string;
color?: ButtonGroupProps['color'];
disabled?: boolean;
Expand All @@ -16,7 +16,7 @@ interface ButtonGroupContextType {
/**
* @ignore - internal component.
*/
const ButtonGroupContext = React.createContext<ButtonGroupContextType>({});
const ButtonGroupContext = React.createContext<ButtonGroupContextType | null>(null);

if (process.env.NODE_ENV !== 'production') {
ButtonGroupContext.displayName = 'ButtonGroupContext';
Expand Down
4 changes: 0 additions & 4 deletions packages/mui-material-next/src/ButtonGroup/index.d.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
export { default } from './ButtonGroup';
export { default as buttonGroupClasses } from './buttonGroupClasses';
export * from './buttonGroupClasses';
export { default as ButtonGroupButtonContext } from './ButtonGroupButtonContext';
export { default as ButtonGroupContext } from './ButtonGroupContext';

0 comments on commit 93fdbe0

Please sign in to comment.