Skip to content

Commit

Permalink
refactor: Simplify Button Group Style (#35175)
Browse files Browse the repository at this point in the history
* chore: refactor grp with context

* test: Update snapshot

* chore: clean up

* test: fix test case

* chore: clean up

* test: fix test
  • Loading branch information
zombieJ committed Apr 22, 2022
1 parent e14ec00 commit f8e7cba
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 111 deletions.
8 changes: 0 additions & 8 deletions components/_util/__tests__/unreachableException.test.js

This file was deleted.

7 changes: 0 additions & 7 deletions components/_util/unreachableException.ts

This file was deleted.

Expand Up @@ -1016,15 +1016,15 @@ Array [
class="ant-btn-group ant-btn-group-sm"
>
<button
class="ant-btn ant-btn-primary"
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
<span>
Button 1
</span>
</button>
<button
class="ant-btn ant-btn-primary"
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
<span>
Expand All @@ -1036,7 +1036,7 @@ Array [
style="display:inline-block;cursor:not-allowed"
>
<button
class="ant-btn ant-btn-primary ant-btn-icon-only"
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
disabled=""
style="pointer-events:none"
type="button"
Expand Down Expand Up @@ -1087,7 +1087,7 @@ Array [
</div>
</div>
<button
class="ant-btn ant-btn-primary ant-btn-icon-only"
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
type="button"
>
<span
Expand Down Expand Up @@ -1268,15 +1268,15 @@ Array [
class="ant-btn-group ant-btn-group-lg"
>
<button
class="ant-btn ant-btn-primary"
class="ant-btn ant-btn-primary ant-btn-lg"
type="button"
>
<span>
Button 1
</span>
</button>
<button
class="ant-btn ant-btn-primary"
class="ant-btn ant-btn-primary ant-btn-lg"
type="button"
>
<span>
Expand All @@ -1288,7 +1288,7 @@ Array [
style="display:inline-block;cursor:not-allowed"
>
<button
class="ant-btn ant-btn-primary ant-btn-icon-only"
class="ant-btn ant-btn-primary ant-btn-lg ant-btn-icon-only"
disabled=""
style="pointer-events:none"
type="button"
Expand Down Expand Up @@ -1339,7 +1339,7 @@ Array [
</div>
</div>
<button
class="ant-btn ant-btn-primary ant-btn-icon-only"
class="ant-btn ant-btn-primary ant-btn-lg ant-btn-icon-only"
type="button"
>
<span
Expand Down
16 changes: 8 additions & 8 deletions components/button/__tests__/__snapshots__/demo.test.ts.snap
Expand Up @@ -824,15 +824,15 @@ Array [
class="ant-btn-group ant-btn-group-sm"
>
<button
class="ant-btn ant-btn-primary"
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
<span>
Button 1
</span>
</button>
<button
class="ant-btn ant-btn-primary"
class="ant-btn ant-btn-primary ant-btn-sm"
type="button"
>
<span>
Expand All @@ -844,7 +844,7 @@ Array [
style="display:inline-block;cursor:not-allowed"
>
<button
class="ant-btn ant-btn-primary ant-btn-icon-only"
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
disabled=""
style="pointer-events:none"
type="button"
Expand All @@ -871,7 +871,7 @@ Array [
</button>
</span>
<button
class="ant-btn ant-btn-primary ant-btn-icon-only"
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-icon-only"
type="button"
>
<span
Expand Down Expand Up @@ -980,15 +980,15 @@ Array [
class="ant-btn-group ant-btn-group-lg"
>
<button
class="ant-btn ant-btn-primary"
class="ant-btn ant-btn-primary ant-btn-lg"
type="button"
>
<span>
Button 1
</span>
</button>
<button
class="ant-btn ant-btn-primary"
class="ant-btn ant-btn-primary ant-btn-lg"
type="button"
>
<span>
Expand All @@ -1000,7 +1000,7 @@ Array [
style="display:inline-block;cursor:not-allowed"
>
<button
class="ant-btn ant-btn-primary ant-btn-icon-only"
class="ant-btn ant-btn-primary ant-btn-lg ant-btn-icon-only"
disabled=""
style="pointer-events:none"
type="button"
Expand All @@ -1027,7 +1027,7 @@ Array [
</button>
</span>
<button
class="ant-btn ant-btn-primary ant-btn-icon-only"
class="ant-btn ant-btn-primary ant-btn-lg ant-btn-icon-only"
type="button"
>
<span
Expand Down
13 changes: 6 additions & 7 deletions components/button/__tests__/index.test.tsx
Expand Up @@ -36,14 +36,13 @@ describe('Button', () => {
});

it('warns if size is wrong', () => {
const mockWarn = jest.fn();
jest.spyOn(console, 'warn').mockImplementation(mockWarn);
resetWarned();
const mockWarn = jest.spyOn(console, 'error').mockImplementation(() => {});
const size = 'who am I' as any as SizeType;
mount(<Button.Group size={size} />);
expect(mockWarn).toHaveBeenCalledTimes(1);
expect(mockWarn.mock.calls[0][0]).toMatchObject({
message: 'unreachable case: "who am I"',
});
render(<Button.Group size={size} />);
expect(mockWarn).toHaveBeenCalledWith('Warning: [antd: Button.Group] Invalid prop `size`.');

mockWarn.mockRestore();
});

it('renders Chinese characters correctly', () => {
Expand Down
81 changes: 42 additions & 39 deletions components/button/button-group.tsx
@@ -1,8 +1,8 @@
import * as React from 'react';
import classNames from 'classnames';
import { SizeType } from '../config-provider/SizeContext';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import UnreachableException from '../_util/unreachableException';
import { ConfigContext } from '../config-provider';
import devWarning from '../_util/devWarning';

export interface ButtonGroupProps {
size?: SizeType;
Expand All @@ -12,42 +12,45 @@ export interface ButtonGroupProps {
children?: React.ReactNode;
}

const ButtonGroup: React.FC<ButtonGroupProps> = props => (
<ConfigConsumer>
{({ getPrefixCls, direction }: ConfigConsumerProps) => {
const { prefixCls: customizePrefixCls, size, className, ...others } = props;
const prefixCls = getPrefixCls('btn-group', customizePrefixCls);

// large => lg
// small => sm
let sizeCls = '';
switch (size) {
case 'large':
sizeCls = 'lg';
break;
case 'small':
sizeCls = 'sm';
break;
case 'middle':
case undefined:
break;
default:
// eslint-disable-next-line no-console
console.warn(new UnreachableException(size).error);
}

const classes = classNames(
prefixCls,
{
[`${prefixCls}-${sizeCls}`]: sizeCls,
[`${prefixCls}-rtl`]: direction === 'rtl',
},
className,
);

return <div {...others} className={classes} />;
}}
</ConfigConsumer>
);
export const GroupSizeContext = React.createContext<SizeType | undefined>(undefined);

const ButtonGroup: React.FC<ButtonGroupProps> = props => {
const { getPrefixCls, direction } = React.useContext(ConfigContext);

const { prefixCls: customizePrefixCls, size, className, ...others } = props;
const prefixCls = getPrefixCls('btn-group', customizePrefixCls);

// large => lg
// small => sm
let sizeCls = '';
switch (size) {
case 'large':
sizeCls = 'lg';
break;
case 'small':
sizeCls = 'sm';
break;
case 'middle':
case undefined:
break;
default:
devWarning(!size, 'Button.Group', 'Invalid prop `size`.');
}

const classes = classNames(
prefixCls,
{
[`${prefixCls}-${sizeCls}`]: sizeCls,
[`${prefixCls}-rtl`]: direction === 'rtl',
},
className,
);

return (
<GroupSizeContext.Provider value={size}>
<div {...others} className={classes} />
</GroupSizeContext.Provider>
);
};

export default ButtonGroup;
21 changes: 13 additions & 8 deletions components/button/button.tsx
Expand Up @@ -3,7 +3,7 @@ import * as React from 'react';
import classNames from 'classnames';
import omit from 'rc-util/lib/omit';

import Group from './button-group';
import Group, { GroupSizeContext } from './button-group';
import { ConfigContext } from '../config-provider';
import Wave from '../_util/wave';
import { tuple } from '../_util/type';
Expand All @@ -18,7 +18,7 @@ function isString(str: any) {
return typeof str === 'string';
}

function isUnborderedButtonType(type: ButtonType | undefined) {
function isUnBorderedButtonType(type: ButtonType | undefined) {
return type === 'text' || type === 'link';
}

Expand Down Expand Up @@ -94,7 +94,11 @@ export function convertLegacyProps(type?: LegacyButtonType): ButtonProps {
export interface BaseButtonProps {
type?: ButtonType;
icon?: React.ReactNode;
/** @default default */
/**
* Shape of Button
*
* @default default
*/
shape?: ButtonShape;
size?: SizeType;
loading?: boolean | { delay?: number };
Expand Down Expand Up @@ -152,13 +156,14 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
} = props;

const size = React.useContext(SizeContext);
const groupSize = React.useContext(GroupSizeContext);
const [innerLoading, setLoading] = React.useState<Loading>(!!loading);
const [hasTwoCNChar, setHasTwoCNChar] = React.useState(false);
const { getPrefixCls, autoInsertSpaceInButton, direction } = React.useContext(ConfigContext);
const buttonRef = (ref as any) || React.createRef<HTMLElement>();

const isNeedInserted = () =>
React.Children.count(children) === 1 && !icon && !isUnborderedButtonType(type);
React.Children.count(children) === 1 && !icon && !isUnBorderedButtonType(type);

const fixTwoCNChar = () => {
// Fix for HOC usage like <FormatMessage />
Expand Down Expand Up @@ -220,7 +225,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
);

devWarning(
!(ghost && isUnborderedButtonType(type)),
!(ghost && isUnBorderedButtonType(type)),
'Button',
"`link` or `text` button can't be a `ghost` button.",
);
Expand All @@ -229,7 +234,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
const autoInsertSpace = autoInsertSpaceInButton !== false;

const sizeClassNameMap = { large: 'lg', small: 'sm', middle: undefined };
const sizeFullname = customizeSize || size;
const sizeFullname = groupSize || customizeSize || size;
const sizeCls = sizeFullname ? sizeClassNameMap[sizeFullname] || '' : '';

const iconType = innerLoading ? 'loading' : icon;
Expand All @@ -241,7 +246,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
[`${prefixCls}-${type}`]: type,
[`${prefixCls}-${sizeCls}`]: sizeCls,
[`${prefixCls}-icon-only`]: !children && children !== 0 && !!iconType,
[`${prefixCls}-background-ghost`]: ghost && !isUnborderedButtonType(type),
[`${prefixCls}-background-ghost`]: ghost && !isUnBorderedButtonType(type),
[`${prefixCls}-loading`]: innerLoading,
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar && autoInsertSpace,
[`${prefixCls}-block`]: block,
Expand Down Expand Up @@ -286,7 +291,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
</button>
);

if (isUnborderedButtonType(type)) {
if (isUnBorderedButtonType(type)) {
return buttonNode;
}

Expand Down
22 changes: 0 additions & 22 deletions components/button/style/mixin.less
Expand Up @@ -210,28 +210,6 @@
.@{btnClassName}-icon-only {
font-size: @font-size-base;
}
// size
&-lg > .@{btnClassName},
&-lg > span > .@{btnClassName} {
.button-size(@btn-height-lg; @btn-padding-horizontal-lg; @btn-font-size-lg; 0);
}
&-lg .@{btnClassName}.@{btnClassName}-icon-only {
.square(@btn-height-lg);
padding-right: 0;
padding-left: 0;
}
&-sm > .@{btnClassName},
&-sm > span > .@{btnClassName} {
.button-size(@btn-height-sm; @btn-padding-horizontal-sm; @font-size-base; 0);
> .@{iconfont-css-prefix} {
font-size: @font-size-base;
}
}
&-sm .@{btnClassName}.@{btnClassName}-icon-only {
.square(@btn-height-sm);
padding-right: 0;
padding-left: 0;
}
}
// Base styles of buttons
// --------------------------------------------------
Expand Down

0 comments on commit f8e7cba

Please sign in to comment.