feat: add Input element for Skeleton (#20264)

* complete skeleton input element (#18237)

* update test snapshots

* update skeleton doc

* add more test for skeleton input

* fix test snapshots issue
This commit is contained in:
Rustin 2019-12-19 11:56:50 +08:00 committed by 二货机器人
parent e0aeb4f4a9
commit 1c4bae59ba
10 changed files with 365 additions and 69 deletions

View File

@ -0,0 +1,36 @@
import * as React from 'react';
import omit from 'omit.js';
import classNames from 'classnames';
import Element, { SkeletonElementProps } from './Element';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
interface SkeletonInputProps extends Omit<SkeletonElementProps, 'size' | 'shape'> {
size?: 'large' | 'small' | 'default';
}
// eslint-disable-next-line react/prefer-stateless-function
class SkeletonInput extends React.Component<SkeletonInputProps, any> {
static defaultProps: Partial<SkeletonInputProps> = {
size: 'default',
};
renderSkeletonInput = ({ getPrefixCls }: ConfigConsumerProps) => {
const { prefixCls: customizePrefixCls, className, active } = this.props;
const prefixCls = getPrefixCls('skeleton', customizePrefixCls);
const otherProps = omit(this.props, ['prefixCls']);
const cls = classNames(prefixCls, className, `${prefixCls}-element`, {
[`${prefixCls}-active`]: active,
});
return (
<div className={cls}>
<Element prefixCls={`${prefixCls}-input`} {...otherProps} />
</div>
);
};
render() {
return <ConfigConsumer>{this.renderSkeletonInput}</ConfigConsumer>;
}
}
export default SkeletonInput;

View File

@ -6,6 +6,7 @@ import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import SkeletonButton from './Button';
import Element from './Element';
import SkeletonAvatar, { AvatarProps } from './Avatar';
import SkeletonInput from './Input';
/* This only for skeleton internal. */
interface SkeletonAvatarProps extends Omit<AvatarProps, 'active'> {}
@ -72,6 +73,8 @@ class Skeleton extends React.Component<SkeletonProps, any> {
static Avatar: typeof SkeletonAvatar;
static Input: typeof SkeletonInput;
static defaultProps: Partial<SkeletonProps> = {
avatar: false,
title: true,

View File

@ -48,7 +48,60 @@ exports[`renders ./components/skeleton/demo/basic.md correctly 1`] = `
</div>
`;
exports[`renders ./components/skeleton/demo/button.md correctly 1`] = `
exports[`renders ./components/skeleton/demo/children.md correctly 1`] = `
<div
class="article"
>
<div>
<h4>
Ant Design, a design language
</h4>
<p>
We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.
</p>
</div>
<button
class="ant-btn"
type="button"
>
<span>
Show Skeleton
</span>
</button>
</div>
`;
exports[`renders ./components/skeleton/demo/complex.md correctly 1`] = `
<div
class="ant-skeleton ant-skeleton-with-avatar"
>
<div
class="ant-skeleton-header"
>
<span
class="ant-skeleton-avatar ant-skeleton-avatar-lg ant-skeleton-avatar-circle"
/>
</div>
<div
class="ant-skeleton-content"
>
<h3
class="ant-skeleton-title"
style="width:50%"
/>
<ul
class="ant-skeleton-paragraph"
>
<li />
<li />
<li />
<li />
</ul>
</div>
</div>
`;
exports[`renders ./components/skeleton/demo/element.md correctly 1`] = `
<div>
<div>
<form
@ -460,58 +513,137 @@ exports[`renders ./components/skeleton/demo/button.md correctly 1`] = `
/>
</div>
</div>
</div>
`;
exports[`renders ./components/skeleton/demo/children.md correctly 1`] = `
<div
class="article"
>
<br />
<div>
<h4>
Ant Design, a design language
</h4>
<p>
We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.
</p>
</div>
<button
class="ant-btn"
type="button"
>
<span>
Show Skeleton
</span>
</button>
</div>
`;
exports[`renders ./components/skeleton/demo/complex.md correctly 1`] = `
<div
class="ant-skeleton ant-skeleton-with-avatar"
>
<div
class="ant-skeleton-header"
>
<span
class="ant-skeleton-avatar ant-skeleton-avatar-lg ant-skeleton-avatar-circle"
/>
</div>
<div
class="ant-skeleton-content"
>
<h3
class="ant-skeleton-title"
style="width:50%"
/>
<ul
class="ant-skeleton-paragraph"
<form
class="ant-form ant-form-inline"
style="margin-bottom:16px"
>
<li />
<li />
<li />
<li />
</ul>
<div
class="ant-row ant-form-item"
>
<div
class="ant-col ant-form-item-label"
>
<label
class=""
title="InputActive"
>
InputActive
</label>
</div>
<div
class="ant-col ant-form-item-control"
>
<div
class="ant-form-item-control-input"
>
<button
aria-checked="false"
class="ant-switch"
role="switch"
type="button"
>
<span
class="ant-switch-inner"
/>
</button>
</div>
</div>
</div>
<div
class="ant-row ant-form-item"
>
<div
class="ant-col ant-form-item-label"
>
<label
class=""
title="InputSize"
>
InputSize
</label>
</div>
<div
class="ant-col ant-form-item-control"
>
<div
class="ant-form-item-control-input"
>
<div
class="ant-radio-group ant-radio-group-outline"
>
<label
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
>
<span
class="ant-radio-button ant-radio-button-checked"
>
<input
checked=""
class="ant-radio-button-input"
type="radio"
value="default"
/>
<span
class="ant-radio-button-inner"
/>
</span>
<span>
Default
</span>
</label>
<label
class="ant-radio-button-wrapper"
>
<span
class="ant-radio-button"
>
<input
class="ant-radio-button-input"
type="radio"
value="large"
/>
<span
class="ant-radio-button-inner"
/>
</span>
<span>
Large
</span>
</label>
<label
class="ant-radio-button-wrapper"
>
<span
class="ant-radio-button"
>
<input
class="ant-radio-button-input"
type="radio"
value="small"
/>
<span
class="ant-radio-button-inner"
/>
</span>
<span>
Small
</span>
</label>
</div>
</div>
</div>
</div>
</form>
<div
class="ant-skeleton ant-skeleton-element"
>
<span
class="ant-skeleton-input"
style="width:300px"
/>
</div>
</div>
</div>
`;

View File

@ -310,6 +310,46 @@ exports[`Skeleton button element size 3`] = `
</div>
`;
exports[`Skeleton input element active 1`] = `
<div
class="ant-skeleton ant-skeleton-element ant-skeleton-active"
>
<span
class="ant-skeleton-input"
/>
</div>
`;
exports[`Skeleton input element size 1`] = `
<div
class="ant-skeleton ant-skeleton-element"
>
<span
class="ant-skeleton-input ant-skeleton-input-sm"
/>
</div>
`;
exports[`Skeleton input element size 2`] = `
<div
class="ant-skeleton ant-skeleton-element"
>
<span
class="ant-skeleton-input"
/>
</div>
`;
exports[`Skeleton input element size 3`] = `
<div
class="ant-skeleton ant-skeleton-element"
>
<span
class="ant-skeleton-input ant-skeleton-input-lg"
/>
</div>
`;
exports[`Skeleton paragraph rows 1`] = `
<div
class="ant-skeleton"

View File

@ -12,6 +12,7 @@ describe('Skeleton', () => {
);
const genSkeletonButton = props => mount(<Skeleton.Button {...props} />);
const genSkeletonAvatar = props => mount(<Skeleton.Avatar {...props} />);
const genSkeletonInput = props => mount(<Skeleton.Input {...props} />);
mountTest(Skeleton);
@ -112,4 +113,19 @@ describe('Skeleton', () => {
expect(wrapperSquare.render()).toMatchSnapshot();
});
});
describe('input element', () => {
it('active', () => {
const wrapper = genSkeletonInput({ active: true });
expect(wrapper.render()).toMatchSnapshot();
});
it('size', () => {
const wrapperSmall = genSkeletonInput({ size: 'small' });
expect(wrapperSmall.render()).toMatchSnapshot();
const wrapperDefault = genSkeletonInput({ size: 'default' });
expect(wrapperDefault.render()).toMatchSnapshot();
const wrapperLarge = genSkeletonInput({ size: 'large' });
expect(wrapperLarge.render()).toMatchSnapshot();
});
});
});

View File

@ -1,17 +1,17 @@
---
order: 2
title:
zh-CN: 骨架按钮和头像
zh-CN: 骨架按钮、头像和输入框。
en-US: Skeleton button and avatar
---
## zh-CN
骨架按钮和头像
骨架按钮、头像和输入框
## en-US
Skeleton button and avatar.
Skeleton button, avatar and input.
```jsx
import { Skeleton, Switch, Form, Radio } from 'antd';
@ -20,8 +20,10 @@ class Demo extends React.Component {
state = {
buttonActive: false,
avatarActive: false,
inputActive: false,
buttonSize: 'default',
avatarSize: 'default',
inputSize: 'default',
buttonShape: 'default',
avatarShape: 'circle',
};
@ -42,8 +44,10 @@ class Demo extends React.Component {
const {
buttonActive,
avatarActive,
inputActive,
buttonSize,
avatarSize,
inputSize,
buttonShape,
avatarShape,
} = this.state;
@ -93,6 +97,22 @@ class Demo extends React.Component {
</Form>
<Skeleton.Avatar active={avatarActive} size={avatarSize} shape={avatarShape} />
</div>
<br />
<div>
<Form layout="inline" style={{ marginBottom: 16 }}>
<Form.Item label="InputActive">
<Switch checked={inputActive} onChange={this.handleActiveChange('inputActive')} />
</Form.Item>
<Form.Item label="InputSize">
<Radio.Group value={inputSize} onChange={this.handleSizeChange('inputSize')}>
<Radio.Button value="default">Default</Radio.Button>
<Radio.Button value="large">Large</Radio.Button>
<Radio.Button value="small">Small</Radio.Button>
</Radio.Group>
</Form.Item>
</Form>
<Skeleton.Input style ={{width:'300px'}} active={inputActive} size={inputSize}/>
</div>
</div>
);
}

View File

@ -54,3 +54,10 @@ Provide a placeholder while you wait for content to load, or to visualise conten
| active | Show animation effect | boolean | false |
| size | Set the size of button | Enum{ 'large', 'small', 'default' } | - |
| shape | Set the shape of button | Enum{ 'circle', 'round', 'default' } | - |
### SkeletonInputProps
| Property | Description | Type | Default |
| -------- | ---------------------- | ----------------------------------- | ------- |
| active | Show animation effect | boolean | false |
| size | Set the size of button | Enum{ 'large', 'small', 'default' } | - |

View File

@ -1,9 +1,11 @@
import Skeleton from './Skeleton';
import SkeletonButton from './Button';
import SkeletonAvatar from './Avatar';
import SkeletonInput from './Input';
export { SkeletonProps } from './Skeleton';
Skeleton.Button = SkeletonButton;
Skeleton.Avatar = SkeletonAvatar;
Skeleton.Input = SkeletonInput;
export default Skeleton;

View File

@ -55,3 +55,10 @@ cols: 1
| active | 是否展示动画效果 | boolean | false |
| size | 设置按钮的大小 | Enum{ 'large', 'small', 'default' } | - |
| shape | 指定按钮的形状 | Enum{ 'circle', 'round', 'default' } | - |
### SkeletonInputProps
| 属性 | 说明 | 类型 | 默认值 |
| ------ | ---------------- | ----------------------------------- | ------ |
| active | 是否展示动画效果 | boolean | false |
| size | 设置按钮的大小 | Enum{ 'large', 'small', 'default' } | - |

View File

@ -6,6 +6,7 @@
@skeleton-title-prefix-cls: ~'@{skeleton-prefix-cls}-title';
@skeleton-paragraph-prefix-cls: ~'@{skeleton-prefix-cls}-paragraph';
@skeleton-button-prefix-cls: ~'@{skeleton-prefix-cls}-button';
@skeleton-input-prefix-cls: ~'@{skeleton-prefix-cls}-input';
.@{skeleton-prefix-cls} {
display: table;
@ -86,35 +87,45 @@
.@{skeleton-button-prefix-cls} {
.skeleton-color();
}
.@{skeleton-input-prefix-cls} {
.skeleton-color();
}
}
// Skeleton element
&-element {
display: inline-block;
// Button
.@{skeleton-button-prefix-cls} {
display: inline-block;
vertical-align: top;
background: @skeleton-color;
border-radius: @border-radius-base;
.skeleton-element-button-size(@btn-height-base);
&-lg {
.skeleton-element-button-size(@btn-height-lg);
}
&-sm {
.skeleton-element-button-size(@btn-height-sm);
}
.skeleton-element-button();
}
.@{skeleton-avatar-prefix-cls} {
.skeleton-element-avatar();
}
.@{skeleton-input-prefix-cls} {
.skeleton-element-input();
}
}
}
// Button
.skeleton-element-button() {
display: inline-block;
vertical-align: top;
background: @skeleton-color;
border-radius: @border-radius-base;
.skeleton-element-button-size(@btn-height-base);
&-lg {
.skeleton-element-button-size(@btn-height-lg);
}
&-sm {
.skeleton-element-button-size(@btn-height-sm);
}
}
// Avatar
.skeleton-element-avatar() {
display: inline-block;
@ -132,6 +143,23 @@
}
}
// Input
.skeleton-element-input() {
display: inline-block;
vertical-align: top;
background: @skeleton-color;
.skeleton-element-input-size(@input-height-base);
&-lg {
.skeleton-element-input-size(@input-height-lg);
}
&-sm {
.skeleton-element-input-size(@input-height-sm);
}
}
.skeleton-element-avatar-size(@size) {
width: @size;
.skeleton-element-common-size(@size);
@ -155,6 +183,11 @@
}
}
.skeleton-element-input-size(@size) {
width: 100%;
.skeleton-element-common-size(@size);
}
.skeleton-element-common-size(@size) {
height: @size;
line-height: @size;