Skip to content

Commit

Permalink
Merge pull request #1300 from youluna/feat-preview
Browse files Browse the repository at this point in the history
Feat preview
  • Loading branch information
frankqian authored Nov 12, 2019
2 parents 1f89276 + a1219b9 commit e25e236
Show file tree
Hide file tree
Showing 13 changed files with 426 additions and 41 deletions.
88 changes: 88 additions & 0 deletions docs/form/demo/preview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@

# 预览态

- order: 17

可以通过Form切换表单元素的预览态,切换前后布局结构相同

:::lang=en-us
# Preview

- order: 17

You can switch to preview state. Preview state and editor state share the same layout.

:::

---

````jsx
import { Form, Input, Switch, Rating, Grid, Field, Icon } from '@alifd/next';

const {Row, Col} = Grid;
const FormItem = Form.Item;
const formItemLayout = {
labelCol: {
span: 7
},
wrapperCol: {
span: 16
}
};
class Demo extends React.Component {
state = {
size: 'medium',
preview: false,
};
submitHandler = (e) => {
console.log(e);
};
onPreviewChange = (checked) => {
this.setState({
preview: checked
});
};
ratingPreview = (value) => {
return <p>{value} {value > 2.5 ? <Icon type="smile" /> : <Icon type="cry"/>}</p>
};
render() {
return (
<div>
<Form {...formItemLayout} isPreview={this.state.preview} size={this.state.size} style={{maxWidth: '800px'}}>
<FormItem label="preview: " style={{marginBottom: 0}}>
<Switch isPreview={false} onChange={this.onPreviewChange} />
</FormItem>
<div style={{height: 1, width: '100%', margin: '20px 0'}}/>
<FormItem required label="Username:">
<Input defaultValue="Fusion" placeholder="Please enter your username" id="username" name="username" aria-required="true" />
</FormItem>
<FormItem required label="Password:">
<Input defaultValue="Fusion@2019" htmlType="password" placeholder="Please enter your password" id="password" name="password" aria-required="true" />
</FormItem>

<FormItem required label="Link:">
<Input name="link" addonTextBefore="http://" addonTextAfter=".com" defaultValue="alibaba" aria-label="input with config of addonTextBefore and addonTextAfter" />
</FormItem>

<FormItem required label="Rating:">
<Rating defaultValue={4.5} name="rate" isPreview aria-label="what's the rate score" />
</FormItem>

<FormItem required label="Custom Render Rating:">
<Rating defaultValue={4.5} name="rate2" isPreview aria-label="what's the rate2 score" renderPreview={this.ratingPreview}/>
</FormItem>

<FormItem label="Note:">
<Input.TextArea placeholder="description" name="a11yRemark" defaultValue="Fusion 是一套企业级中后台UI的解决方案,致力于解决设计师与前端在产品体验一致性、工作协同、开发效率方面的问题。通过协助业务线构建设计系统,提供系统化工具协助设计师前端使用设计系统,下游提供一站式设计项目协作平台;打通互联网产品从设计到开发的工作流。" />
</FormItem>
<FormItem wrapperCol={{offset: 7}}>
<Form.Submit validate type="primary" onClick={this.submitHandler}>Submit</Form.Submit>
<Form.Reset style={{marginLeft: 10}}>Reset</Form.Reset>
</FormItem>
</Form>
</div>
);
}
}
ReactDOM.render(<Demo />, mountNode);
````
2 changes: 2 additions & 0 deletions src/form/form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export default class Form extends React.Component {
static childContextTypes = {
_formField: PropTypes.object,
_formSize: PropTypes.string,
_formPreview: PropTypes.bool,
_formFullWidth: PropTypes.bool,
};

Expand Down Expand Up @@ -153,6 +154,7 @@ export default class Form extends React.Component {
return {
_formField: this.props.field ? this.props.field : this._formField,
_formSize: this.props.size,
_formPreview: this.props.isPreview,
_formFullWidth: this.props.fullWidth,
};
}
Expand Down
10 changes: 9 additions & 1 deletion src/form/item.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ export default class Item extends React.Component {
static contextTypes = {
_formField: PropTypes.object,
_formSize: PropTypes.oneOf(['large', 'small', 'medium']),
_formPreview: PropTypes.bool,
_formFullWidth: PropTypes.bool,
};

Expand Down Expand Up @@ -260,6 +261,10 @@ export default class Item extends React.Component {
return this.props.size || this.context._formSize;
}

getIsPreview() {
return this.props.isPreview || this.context._formPreview;
}

getFullWidth() {
return isNil(this.props.fullWidth)
? !!this.context._formFullWidth
Expand Down Expand Up @@ -330,7 +335,10 @@ export default class Item extends React.Component {

const state = this.getState();

const childrenProps = { size: this.getSize() };
const childrenProps = {
size: this.getSize(),
isPreview: this.getIsPreview(),
};
if (state && (state === 'error' || hasFeedback)) {
childrenProps.state = state;
}
Expand Down
4 changes: 4 additions & 0 deletions src/form/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
}

@include form-enhance($form-element-medium-height - 4);
@include form-preview($form-element-medium-font-size, $form-element-medium-height);

#{$form-prefix}-item-label {
font-size: $form-element-medium-font-size;
Expand All @@ -37,6 +38,8 @@
}

@include form-enhance($form-element-large-height - 1);
@include form-preview($form-element-large-font-size, $form-element-large-height);

.#{$css-prefix}switch {
margin-top: ($form-element-large-height - 26)/2;
}
Expand All @@ -53,6 +56,7 @@
}

@include form-enhance($form-element-small-height);
@include form-preview($form-element-small-font-size, $form-element-small-height);

#{$form-prefix}-item-label {
font-size: $form-element-small-font-size;
Expand Down
19 changes: 18 additions & 1 deletion src/form/scss/mixin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,24 @@
// --------------------------------------------------

@mixin form-enhance($line-height) {
.#{$css-prefix}checkbox-wrapper, .#{$css-prefix}checkbox-group, .#{$css-prefix}radio-wrapper, .#{$css-prefix}radio-group {
.#{$css-prefix}rating,
.#{$css-prefix}checkbox-wrapper,
.#{$css-prefix}checkbox-group,
.#{$css-prefix}radio-wrapper,
.#{$css-prefix}radio-group {
line-height: $line-height;
}
}

@mixin form-preview($font-size, $line-height) {
.#{$css-prefix}form-preview {
font-size: $font-size;
line-height: $line-height;
&.#{$css-prefix}input-textarea > p {
text-align: justify;
min-height: $font-size * 1.4;
line-height: 1.4;
margin-top: ($line-height - (1.4 * $font-size)) / 2;
}
}
}
10 changes: 10 additions & 0 deletions src/input/base.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ class Base extends React.Component {
rtl: PropTypes.bool,
state: PropTypes.oneOf(['error', 'loading', 'success']),
locale: PropTypes.object,
/**
* 是否为预览态
*/
isPreview: PropTypes.bool,
/**
* 预览态模式下渲染的内容
* @param {number} value 评分值
*/
renderPreview: PropTypes.func,
};

static defaultProps = {
Expand All @@ -103,6 +112,7 @@ class Base extends React.Component {
hasLimitHint: false,
cutString: true,
readOnly: false,
isPreview: false,
trim: false,
onFocus: func.noop,
onBlur: func.noop,
Expand Down
37 changes: 37 additions & 0 deletions src/input/input.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,23 @@ export default class Input extends Base {
extra: PropTypes.node,
innerBeforeClassName: PropTypes.string,
innerAfterClassName: PropTypes.string,
/**
* 是否为预览态
*/
isPreview: PropTypes.bool,
/**
* 预览态模式下渲染的内容
* @param {number} value 评分值
*/
renderPreview: PropTypes.func,
};

static defaultProps = {
...Base.defaultProps,
size: 'medium',
autoComplete: 'off',
hasBorder: true,
isPreview: false,
onPressEnter: func.noop,
inputRender: el => el,
};
Expand Down Expand Up @@ -261,6 +271,8 @@ export default class Input extends Base {
className,
hasBorder,
prefix,
isPreview,
renderPreview,
addonBefore,
addonAfter,
addonTextBefore,
Expand Down Expand Up @@ -290,6 +302,9 @@ export default class Input extends Base {
[`${prefix}after`]: true,
[innerAfterClassName]: innerAfterClassName,
});
const previewCls = classNames({
[`${prefix}form-preview`]: true,
});

const props = this.getProps();
// custom data attributes are assigned to the top parent node
Expand All @@ -302,6 +317,28 @@ export default class Input extends Base {
this.props
);

if (isPreview) {
const { value } = props;
const { label } = this.props;
if ('renderPreview' in this.props) {
return (
<div {...others} className={previewCls}>
{renderPreview(value, this.props)}
</div>
);
}
return (
<p {...others} className={previewCls}>
{addonBefore || addonTextBefore}
{label}
{innerBefore}
{value}
{innerAfter}
{addonAfter || addonTextAfter}
</p>
);
}

const inputEl = (
<input
{...others}
Expand Down
35 changes: 35 additions & 0 deletions src/input/textarea.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,21 @@ export default class TextArea extends Base {
* 多行文本框高度 <br />(不要直接用height设置多行文本框的高度, ie9 10会有兼容性问题)
*/
rows: PropTypes.number,
/**
* 是否为预览态
*/
isPreview: PropTypes.bool,
/**
* 预览态模式下渲染的内容
* @param {number} value 评分值
*/
renderPreview: PropTypes.func,
};

static defaultProps = {
...Base.defaultProps,
hasBorder: true,
isPreview: false,
rows: 4,
autoHeight: false,
};
Expand Down Expand Up @@ -207,6 +217,8 @@ export default class TextArea extends Base {
style,
className,
autoHeight,
isPreview,
renderPreview,
prefix,
rtl,
hasBorder,
Expand Down Expand Up @@ -237,10 +249,33 @@ export default class TextArea extends Base {
overflowY: this.state.overflowY,
};

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

const wrapStyle = autoHeight
? { ...style, position: 'relative' }
: style;

if (isPreview) {
const { value } = props;
if ('renderPreview' in this.props) {
return (
<div {...others} className={previewCls}>
{renderPreview(value, this.props)}
</div>
);
}
return (
<p {...others} className={previewCls}>
{value.split('\n').map((data, i) => (
<p key={`p-${i}`}>{data}</p>
))}
</p>
);
}

return (
<span
className={cls}
Expand Down
3 changes: 3 additions & 0 deletions src/rating/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export default ConfigProvider.config(Rating, {
props = { showGrade: type === 'grade', ...others };
}

const { disabled, readOnly } = props;
props.disabled = disabled || readOnly;

return props;
},
});
Loading

0 comments on commit e25e236

Please sign in to comment.