| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Collapse, Form, Input, Col, Icon, InputNumber, Select, Radio } from 'antd' |
| | | import { Collapse, Form, Input, Col, Icon, InputNumber, Select, Radio, Popover, Menu } from 'antd' |
| | | |
| | | import zhCN from '@/locales/zh-CN/mob.js' |
| | | import enUS from '@/locales/en-US/mob.js' |
| | | import ColorSketch from '@/mob/colorsketch' |
| | | import FileUpload from '@/tabviews/zshare/fileupload' |
| | | import './index.scss' |
| | | |
| | | const { Panel } = Collapse |
| | |
| | | dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS, |
| | | card: null, |
| | | fontColor: '#000000', |
| | | backgroundColor: '#ffffff' |
| | | backgroundColor: '#ffffff', |
| | | bgimages: [], |
| | | marginTop: '', |
| | | marginTopVal: '', |
| | | marginBottom: '', |
| | | marginBottomVal: '', |
| | | } |
| | | |
| | | UNSAFE_componentWillReceiveProps (nextProps) { |
| | |
| | | }, () => { |
| | | if (!nextProps.editElem) return |
| | | let _card = fromJS(nextProps.editElem).toJS() |
| | | let bgImg = _card.backgroundImage || '' |
| | | |
| | | if (bgImg && /^linear-gradient/.test(bgImg)) { |
| | | bgImg = bgImg.replace('linear-gradient(', '') |
| | | bgImg = bgImg.replace(')', '') |
| | | } else if (bgImg && /^url/.test(bgImg)) { |
| | | bgImg = bgImg.replace('url(', '') |
| | | bgImg = bgImg.replace(')', '') |
| | | } |
| | | |
| | | this.setState({ |
| | | card: _card, |
| | | fontColor: _card.color || '#000000', |
| | | backgroundColor: _card.backgroundColor || '#ffffff' |
| | | backgroundColor: _card.backgroundColor || '#ffffff', |
| | | backgroundImage: bgImg, |
| | | marginTop: _card.marginTop ? _card.marginTop : '', |
| | | marginTopVal: _card.marginTop ? parseInt(_card.marginTop) : '', |
| | | marginBottom: _card.marginBottom ? _card.marginBottom : '', |
| | | marginBottomVal: _card.marginBottomVal ? parseInt(_card.marginBottomVal) : '' |
| | | }) |
| | | }) |
| | | } |
| | |
| | | return !is(fromJS(this.state), fromJS(nextState)) |
| | | } |
| | | |
| | | updateStyle = (style) => { |
| | | const { card } = this.state |
| | | |
| | | this.props.updateStyle({componentId: card.componentId, classId: card.classId, uuid: card.uuid, style}) |
| | | } |
| | | |
| | | /** |
| | | * @description 字体大小切换,超出范围忽略 |
| | | */ |
| | | changeFontSize = (val) => { |
| | | const { card } = this.state |
| | | let value = parseInt(val) |
| | | |
| | | if (isNaN(value) || value < 12 || value > 100) return |
| | | |
| | | this.props.updateStyle({componentId: card.componentId, uuid: card.uuid, style: {fontSize: `${value}px`}}) |
| | | this.updateStyle({fontSize: `${value}px`}) |
| | | } |
| | | |
| | | /** |
| | | * @description 修改行间距,超出范围忽略 |
| | | */ |
| | | changeLineHeight = (val) => { |
| | | const { card } = this.state |
| | | let value = parseFloat(val) |
| | | |
| | | if (isNaN(value) || value < 1 || value > 10) return |
| | | |
| | | this.props.updateStyle({componentId: card.componentId, uuid: card.uuid, style: {lineHeight: value}}) |
| | | this.updateStyle({lineHeight: value}) |
| | | } |
| | | |
| | | /** |
| | | * @description 字体间距修改,超出范围忽略 |
| | | */ |
| | | changeLetterSpacing = (val) => { |
| | | const { card } = this.state |
| | | let value = parseFloat(val) |
| | | |
| | | if (isNaN(value) || value < 0 || value > 100) return |
| | | |
| | | this.props.updateStyle({componentId: card.componentId, uuid: card.uuid, style: {letterSpacing: `${value}px`}}) |
| | | this.updateStyle({letterSpacing: `${value}px`}) |
| | | } |
| | | |
| | | /** |
| | | * @description 修改字体粗细 |
| | | */ |
| | | boldChange = (val) => { |
| | | const { card } = this.state |
| | | |
| | | this.props.updateStyle({componentId: card.componentId, uuid: card.uuid, style: {fontWeight: val}}) |
| | | this.updateStyle({fontWeight: val}) |
| | | } |
| | | |
| | | /** |
| | | * @description 修改字体颜色 ,颜色控件 |
| | | */ |
| | | changeFontColor = (val) => { |
| | | const { card } = this.state |
| | | |
| | | this.setState({ |
| | | fontColor: val |
| | | }) |
| | | this.props.updateStyle({componentId: card.componentId, uuid: card.uuid, style: {color: val}}) |
| | | this.updateStyle({color: val}) |
| | | } |
| | | |
| | | /** |
| | |
| | | * @description 字体对齐 |
| | | */ |
| | | changeTextAlign = (e) => { |
| | | const { card } = this.state |
| | | |
| | | this.props.updateStyle({componentId: card.componentId, uuid: card.uuid, style: {textAlign: e.target.value}}) |
| | | this.updateStyle({textAlign: e.target.value}) |
| | | } |
| | | |
| | | /** |
| | | * @description 字体样式,倾斜 |
| | | */ |
| | | changeFontStyle = (e) => { |
| | | const { card } = this.state |
| | | |
| | | this.props.updateStyle({componentId: card.componentId, uuid: card.uuid, style: {fontStyle: e.target.value}}) |
| | | this.updateStyle({fontStyle: e.target.value}) |
| | | } |
| | | |
| | | /** |
| | | * @description 字体装饰,下划线、贯穿线、上划线 |
| | | */ |
| | | changeTextDecoration = (e) => { |
| | | const { card } = this.state |
| | | |
| | | this.props.updateStyle({componentId: card.componentId, uuid: card.uuid, style: {textDecoration: e.target.value}}) |
| | | this.updateStyle({textDecoration: e.target.value}) |
| | | } |
| | | |
| | | /** |
| | | * @description 修改背景颜色 ,颜色控件 |
| | | */ |
| | | changeBackgroundColor = (val) => { |
| | | const { card } = this.state |
| | | |
| | | this.setState({ |
| | | backgroundColor: val |
| | | }) |
| | | this.props.updateStyle({componentId: card.componentId, uuid: card.uuid, style: {backgroundColor: val}}) |
| | | this.updateStyle({backgroundColor: val}) |
| | | } |
| | | |
| | | /** |
| | |
| | | }) |
| | | } |
| | | |
| | | imgChange = (list) => { |
| | | if (list[0] && list[0].response) { |
| | | this.setState({ |
| | | bgimages: [], |
| | | backgroundImage: list[0].response |
| | | }) |
| | | this.updateStyle({backgroundImage: `url(${list[0].response})`}) |
| | | } else { |
| | | this.setState({bgimages: list}) |
| | | } |
| | | } |
| | | |
| | | changeBackgroundImageInput = (e) => { |
| | | this.setState({ |
| | | backgroundImage: e.target.value |
| | | }) |
| | | } |
| | | |
| | | submitBackgroundImage = (e) => { |
| | | let val = e.target.value |
| | | val = val.replace(/^\s*|\s*$/ig, '') |
| | | |
| | | if (/^http|^\/\//.test(val)) { |
| | | val = `url(${val})` |
| | | } else if (/^#|,/ig.test(val)) { |
| | | val = `linear-gradient(${val})` |
| | | } |
| | | |
| | | this.updateStyle({backgroundImage: val}) |
| | | } |
| | | |
| | | submitBorder = (val, type) => { |
| | | this.updateStyle({[type]: val}) |
| | | } |
| | | |
| | | changeBorderRadius = (val) => { |
| | | let value = parseFloat(val) |
| | | |
| | | if (isNaN(value) || value < 0 || value > 500) return |
| | | |
| | | this.updateStyle({borderRadius: `${value}px`}) |
| | | } |
| | | |
| | | changeMarginTop = (e) => { |
| | | let val = e.target.value |
| | | let _val = parseInt(val) |
| | | |
| | | this.setState({ |
| | | marginTop: val |
| | | }) |
| | | |
| | | if (isNaN(_val)) return |
| | | |
| | | this.setState({ |
| | | marginTopVal: _val |
| | | }) |
| | | } |
| | | |
| | | submitMarginTop = (val) => { |
| | | this.setState({ |
| | | marginTop: val |
| | | }) |
| | | this.updateStyle({marginTop: val}) |
| | | } |
| | | |
| | | changeMarginBottom = (e) => { |
| | | let val = e.target.value |
| | | let _val = parseInt(val) |
| | | |
| | | this.setState({ |
| | | marginBottom: val |
| | | }) |
| | | |
| | | if (isNaN(_val)) return |
| | | |
| | | this.setState({ |
| | | marginBottomVal: _val |
| | | }) |
| | | } |
| | | |
| | | submitMarginBottom = (val) => { |
| | | this.setState({ |
| | | marginBottom: val |
| | | }) |
| | | this.updateStyle({marginBottom: val}) |
| | | } |
| | | |
| | | render () { |
| | | const { card, fontColor, backgroundColor } = this.state |
| | | const { card, backgroundImage, bgimages, marginTop, marginTopVal, marginBottom, marginBottomVal } = this.state |
| | | const formItemLayout = { |
| | | labelCol: { |
| | | xs: { span: 24 }, |
| | |
| | | label={<Icon title="字体颜色" type="font-colors" />} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <ColorSketch color={card.color || '#000000'} changeColor={this.changeFontColor} /> |
| | | <Input value={fontColor} onChange={this.changeFontColorInput} /> |
| | | <ColorSketch value={card.color || '#000000'} onChange={this.changeFontColor} /> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | {card.items.includes('background') ? <Panel header="背景" key="1"> |
| | | {card.items.includes('background') ? <Panel header="背景" key="background"> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="背景颜色" type="bg-colors" />} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <ColorSketch color={card.backgroundColor || '#ffffff'} changeColor={this.changeBackgroundColor} /> |
| | | <Input value={backgroundColor} onChange={this.changeBackgroundColorInput} /> |
| | | <ColorSketch value={card.backgroundColor || '#ffffff'} onChange={this.changeBackgroundColor} /> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | |
| | | label={<Icon title="背景图片" type="picture" />} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <ColorSketch color={card.backgroundColor || '#ffffff'} changeColor={this.changeBackgroundColor} /> |
| | | <Input value={backgroundColor} onChange={this.changeBackgroundColorInput} /> |
| | | <FileUpload accept=".jpg,.png,.gif,.svg" value={bgimages} maxFile={2} fileType="text" onChange={this.imgChange}/> |
| | | <Input placeholder="" value={backgroundImage} autoComplete="off" onBlur={this.submitBackgroundImage} onPressEnter={this.submitBackgroundImage} onChange={this.changeBackgroundImageInput} /> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | <Panel header="边距" key="2"> |
| | | 边距 |
| | | </Panel> |
| | | <Panel header="其他" key="3"> |
| | | 其他 |
| | | </Panel> |
| | | {card.items.includes('border') ? <Panel header="边框" key="border"> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="外边框" type="border-outer" />} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <Input placeholder="" defaultValue={card.border || ''} autoComplete="off" onBlur={(e) => this.submitBorder(e.target.value, 'border')} onPressEnter={(e) => this.submitBorder(e.target.value, 'border')}/> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="左边框" type="border-left" />} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <Input placeholder="" defaultValue={card.borderLeft || ''} autoComplete="off" onBlur={(e) => this.submitBorder(e.target.value, 'borderLeft')} onPressEnter={(e) => this.submitBorder(e.target.value, 'borderLeft')}/> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="右边框" type="border-right" />} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <Input placeholder="" defaultValue={card.borderRight || ''} autoComplete="off" onBlur={(e) => this.submitBorder(e.target.value, 'borderRight')} onPressEnter={(e) => this.submitBorder(e.target.value, 'borderRight')}/> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="上边框" type="border-top" />} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <Input placeholder="" defaultValue={card.borderTop || ''} autoComplete="off" onBlur={(e) => this.submitBorder(e.target.value, 'borderTop')} onPressEnter={(e) => this.submitBorder(e.target.value, 'borderTop')}/> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="下边框" type="border-bottom" />} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <Input placeholder="" defaultValue={card.borderBottom || ''} autoComplete="off" onBlur={(e) => this.submitBorder(e.target.value, 'borderBottom')} onPressEnter={(e) => this.submitBorder(e.target.value, 'borderBottom')}/> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={24}> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="圆角" type="radius-setting" />} |
| | | labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} } |
| | | > |
| | | <InputNumber defaultValue={card.borderRadius || 0} min={0} max={500} precision={0} onChange={this.changeBorderRadius}/> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | {card.items.includes('margin') ? <Panel header="外边距" key="margin"> |
| | | <Col span={12}> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="上边距" type="vertical-align-top"/>} |
| | | > |
| | | <Popover placement="bottom" overlayClassName="margin-popover" content={ |
| | | marginTopVal !== '' ? |
| | | <Menu> |
| | | <Menu.Item onClick={() => this.submitMarginTop(`${marginTopVal}px`)}>{marginTopVal} px</Menu.Item> |
| | | <Menu.Item onClick={() => this.submitMarginTop(`${marginTopVal}vh`)}>{marginTopVal} vh</Menu.Item> |
| | | </Menu> : null |
| | | } trigger="hover"> |
| | | <Input value={marginTop} onChange={this.changeMarginTop}/> |
| | | </Popover> |
| | | </Form.Item> |
| | | </Col> |
| | | <Col span={12}> |
| | | <Form.Item |
| | | colon={false} |
| | | label={<Icon title="下边距" type="vertical-align-bottom"/>} |
| | | > |
| | | <Popover placement="bottom" overlayClassName="margin-popover" content={ |
| | | marginBottomVal !== '' ? |
| | | <Menu> |
| | | <Menu.Item onClick={() => this.submitMarginBottom(`${marginBottomVal}px`)}>{marginBottomVal} px</Menu.Item> |
| | | <Menu.Item onClick={() => this.submitMarginBottom(`${marginBottomVal}vh`)}>{marginBottomVal} vh</Menu.Item> |
| | | </Menu> : null |
| | | } trigger="hover"> |
| | | <Input value={marginBottom} onChange={this.changeMarginBottom}/> |
| | | </Popover> |
| | | </Form.Item> |
| | | </Col> |
| | | </Panel> : null} |
| | | </Collapse> : null} |
| | | </Form> |
| | | </div> |