Skip to content

Commit

Permalink
feat(Upload): preview state for number-picker/select/upload (#1374)
Browse files Browse the repository at this point in the history
* feat(Upload): preview state for number-picker/select/upload

* fix(Typescript): add ts for Input.Password
  • Loading branch information
bindoon authored and youluna committed Nov 20, 2019
1 parent 589c274 commit 7ee63e3
Show file tree
Hide file tree
Showing 8 changed files with 251 additions and 24 deletions.
49 changes: 48 additions & 1 deletion docs/form/demo/preview.md
Expand Up @@ -17,7 +17,8 @@ You can switch to preview state. Preview state and editor state share the same l
---

````jsx
import { Form, Input, Switch, Rating, Grid, Field, Icon, Radio, Range, Checkbox } from '@alifd/next';
import { Form, Input, Switch, Rating, Grid, Field, Icon, Radio, Range, Checkbox, NumberPicker, Select, Upload } from '@alifd/next';


const {Row, Col} = Grid;
const FormItem = Form.Item;
Expand All @@ -29,6 +30,30 @@ const formItemLayout = {
span: 16
}
};
const fileList = [{
uid: '0',
name: 'IMG.png',
state: 'done',
url: 'https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg',
downloadURL: 'https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg',
imgURL: 'https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg'
}, {
uid: '1',
name: 'IMG.png',
percent: 50,
state: 'uploading',
url: 'https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg',
downloadURL: 'https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg',
imgURL: 'https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg'
}, {
uid: '2',
name: 'IMG.png',
state: 'error',
url: 'https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg',
downloadURL: 'https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg',
imgURL: 'https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg'
}];

class Demo extends React.Component {
state = {
size: 'medium',
Expand Down Expand Up @@ -64,6 +89,21 @@ class Demo extends React.Component {
<Input name="link" addonTextBefore="http://" addonTextAfter=".com" defaultValue="alibaba" aria-label="input with config of addonTextBefore and addonTextAfter" />
</FormItem>

<FormItem required label="Number:">
<NumberPicker name="number" isPreview defaultValue={1} />
</FormItem>

<FormItem required label="autoComplete:">
<Select.AutoComplete name="autoComplete" isPreview defaultValue="selected" />
</FormItem>

<FormItem required label="multiple Select:">
<Select name="select" isPreview defaultValue={["a", "b"]} mode="multiple" >
<Select.Option value="a">a</Select.Option>
<Select.Option value="b">b</Select.Option>
</Select>
</FormItem>

<FormItem required label="Rating:">
<Rating defaultValue={4.5} name="rate" isPreview aria-label="what's the rate score" />
</FormItem>
Expand Down Expand Up @@ -97,6 +137,13 @@ class Demo extends React.Component {
<FormItem label="Note:">
<Input.TextArea placeholder="description" name="a11yRemark" defaultValue="Fusion 是一套企业级中后台UI的解决方案,致力于解决设计师与前端在产品体验一致性、工作协同、开发效率方面的问题。通过协助业务线构建设计系统,提供系统化工具协助设计师前端使用设计系统,下游提供一站式设计项目协作平台;打通互联网产品从设计到开发的工作流。" />
</FormItem>

<FormItem label="Upload:">
<Upload defaultValue={fileList} listType="text" />
</FormItem>
<FormItem label="Upload:">
<Upload defaultValue={fileList} listType="image" />
</FormItem>
<FormItem wrapperCol={{offset: 7}}>
<Form.Submit validate type="primary" onClick={this.submitHandler}>Submit</Form.Submit>
<Form.Reset style={{marginLeft: 10}}>Reset</Form.Reset>
Expand Down
2 changes: 1 addition & 1 deletion src/input/input.jsx
Expand Up @@ -323,7 +323,7 @@ export default class Input extends Base {
if (isPreview) {
const { value } = props;
const { label } = this.props;
if ('renderPreview' in this.props) {
if (typeof renderPreview === 'function') {
return (
<div {...others} className={previewCls}>
{renderPreview(value, this.props)}
Expand Down
3 changes: 3 additions & 0 deletions src/input/password.jsx
Expand Up @@ -16,6 +16,9 @@ export default class Password extends Input {

static propTypes = {
...Input.propTypes,
/**
* 是否展示切换按钮
*/
showToggle: PropTypes.bool,
};
static defaultProps = {
Expand Down
31 changes: 31 additions & 0 deletions src/number-picker/number-picker.jsx
Expand Up @@ -117,6 +117,15 @@ class NumberPicker extends React.Component {
*/
innerAfter: PropTypes.node,
rtl: PropTypes.bool,
/**
* 是否为预览态
*/
isPreview: PropTypes.bool,
/**
* 预览态模式下渲染的内容
* @param {number} value 评分值
*/
renderPreview: PropTypes.func,
/**
* 预设屏幕宽度
*/
Expand Down Expand Up @@ -463,6 +472,8 @@ class NumberPicker extends React.Component {
upBtnProps = {},
downBtnProps = {},
innerAfter,
isPreview,
renderPreview,
} = this.props;

const type = device === 'phone' ? 'inline' : this.props.type;
Expand Down Expand Up @@ -552,6 +563,26 @@ class NumberPicker extends React.Component {
const others = obj.pickOthers(NumberPicker.propTypes, this.props);
const dataAttrs = obj.pickAttrsWith(this.props, 'data-');

const previewCls = classNames({
[`${prefix}form-preview`]: true,
[className]: !!className,
});

if (isPreview) {
if (typeof renderPreview === 'function') {
return (
<div {...others} style={style} className={previewCls}>
{renderPreview(this.renderValue(), this.props)}
</div>
);
}
return (
<p {...others} style={{ style }} className={previewCls}>
{this.renderValue()}
</p>
);
}

return (
<span
className={cls}
Expand Down
67 changes: 67 additions & 0 deletions src/select/base.jsx
Expand Up @@ -5,6 +5,8 @@ import classNames from 'classnames';
import { func, dom, events } from '../util';
import Menu from '../menu';
import Overlay from '../overlay';
import Input from '../input';

import zhCN from '../locale/zh-cn';
import DataStore from './data-store';
import VirtualList from '../virtual-list';
Expand Down Expand Up @@ -125,6 +127,15 @@ export default class Base extends React.Component {
locale: PropTypes.object,
rtl: PropTypes.bool,
popupComponent: PropTypes.any,
/**
* 是否为预览态
*/
isPreview: PropTypes.bool,
/**
* 预览态模式下渲染的内容
* @param {number} value 评分值
*/
renderPreview: PropTypes.func,
};

static defaultProps = {
Expand Down Expand Up @@ -583,6 +594,10 @@ export default class Base extends React.Component {
followTrigger,
cache,
popupComponent,
isPreview,
renderPreview,
style,
className,
} = props;

const cls = classNames(
Expand All @@ -594,6 +609,58 @@ export default class Base extends React.Component {
popupClassName || popupProps.className
);

if (isPreview) {
if (this.isAutoComplete) {
return (
<Input
style={style}
className={className}
isPreview={isPreview}
renderPreview={renderPreview}
value={this.state.value}
/>
);
} else {
const valueDS = this.valueDataSource.valueDS;
if (typeof renderPreview === 'function') {
const previewCls = classNames({
[`${prefix}form-preview`]: true,
[className]: !!className,
});
return (
<div style={style} className={previewCls}>
{renderPreview(valueDS, this.props)}
</div>
);
} else {
const { fillProps } = this.props;
if (mode === 'single') {
return (
<Input
style={style}
className={className}
isPreview={isPreview}
value={
fillProps
? valueDS[fillProps]
: valueDS.label
}
/>
);
} else {
return (
<Input
style={style}
className={className}
isPreview={isPreview}
value={valueDS.map(i => i.label).join(', ')}
/>
);
}
}
}
}

const _props = {
triggerType: 'click',
autoFocus: false,
Expand Down
75 changes: 53 additions & 22 deletions src/upload/list.jsx
Expand Up @@ -57,6 +57,7 @@ class List extends Component {
*/
useDataURL: PropTypes.bool,
rtl: PropTypes.bool,
isPreview: PropTypes.bool,
};

static defaultProps = {
Expand Down Expand Up @@ -328,19 +329,17 @@ class List extends Component {
);
}

getPictureCardList(file) {
getPictureCardList(file, isPreview) {
const { locale, progressProps } = this.props;

const { prefixCls, downloadURL, imgURL, itemCls, alt } = this.getInfo(
file
);
const state = isPreview ? '' : file.state;

let img = null;

if (
file.state === 'uploading' ||
(file.state === 'selected' && !imgURL)
) {
if (state === 'uploading' || (state === 'selected' && !imgURL)) {
img = (
<div className={`${prefixCls}-list-item-handler`}>
<Icon type="picture" />
Expand All @@ -349,7 +348,7 @@ class List extends Component {
</Button>
</div>
);
} else if (file.state === 'error') {
} else if (state === 'error') {
img = (
<div className={`${prefixCls}-list-item-handler`}>
<Icon type="cry" />
Expand Down Expand Up @@ -379,7 +378,7 @@ class List extends Component {
<div className={`${prefixCls}-list-item-thumbnail`}>
{img}
</div>
{file.state === 'uploading' ? (
{state === 'uploading' ? (
<div className={`${prefixCls}-list-item-progress`}>
<Progress
size="medium"
Expand All @@ -389,11 +388,11 @@ class List extends Component {
/>
</div>
) : null}
{file.state !== 'uploading' ? (
{state !== 'uploading' ? (
<span
className={`${prefixCls}-tool ${
!this.props.closable
? '`${prefixCls}-noclose'
? `${prefixCls}-noclose`
: ''
}`}
>
Expand All @@ -413,7 +412,7 @@ class List extends Component {
/>
</a>

{this.props.closable ? (
{this.props.closable && !isPreview ? (
<span className={`${prefixCls}-tool-close`}>
<Icon
type="ashbin"
Expand All @@ -439,27 +438,59 @@ class List extends Component {
}

render() {
const { listType, children, prefix, rtl, className } = this.props;
const {
listType,
children,
prefix,
rtl,
className,
isPreview,
} = this.props;
const prefixCls = `${prefix}upload`;

let list = this.props.value.map(file => {
if (listType === 'text') {
return this.getTextList(file);
} else if (listType === 'image') {
return this.getImageList(file);
} else if (listType === 'card') {
return this.getPictureCardList(file);
}
return null;
});
let list = [];
if (isPreview) {
const previewCls = classNames({
[`${prefix}form-preview`]: true,
[className]: !!className,
});
list = this.props.value.map(file => {
const { downloadURL, imgURL, name } = file;
if (listType === 'text') {
return (
<div className={previewCls}>
<a href={downloadURL} target="_blank">
{name}
</a>
</div>
);
} else if (listType === 'image' || listType === 'card') {
return this.getPictureCardList(file, true);
}
return null;
});
} else {
list = this.props.value.map(file => {
if (listType === 'text') {
return this.getTextList(file);
} else if (listType === 'image') {
return this.getImageList(file);
} else if (listType === 'card') {
return this.getPictureCardList(file);
}
return null;
});
}

if (rtl && listType === 'card' && Array.isArray(list)) {
list = list.reverse();
}
const _listType =
isPreview && listType === 'image' ? 'card' : this.props.listType;
const listclassNames = classNames(
{
[`${prefixCls}-list`]: true,
[`${prefixCls}-list-${this.props.listType}`]: true,
[`${prefixCls}-list-${_listType}`]: true,
},
className
);
Expand Down

0 comments on commit 7ee63e3

Please sign in to comment.