king
2023-08-27 da64ab0923bf8817fc8599a6e37b953ce38f64c8
src/menu/stylecontroller/index.jsx
@@ -1,34 +1,61 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import { is, fromJS } from 'immutable'
import { Collapse, Form, Input, Col, Icon, InputNumber, Select, Radio, Drawer } from 'antd'
import { Collapse, Form, Col, InputNumber, Input, Select, Radio, Drawer, Button, message } from 'antd'
import {
  ColumnHeightOutlined,
  FontSizeOutlined,
  BoldOutlined,
  LineHeightOutlined,
  ColumnWidthOutlined,
  FontColorsOutlined,
  ItalicOutlined,
  AlignLeftOutlined,
  AlignCenterOutlined,
  AlignRightOutlined,
  UnderlineOutlined,
  StrikethroughOutlined,
  BgColorsOutlined,
  PictureOutlined,
  BorderOutlined,
  BorderOuterOutlined,
  BorderLeftOutlined,
  BorderRightOutlined,
  BorderTopOutlined,
  BorderBottomOutlined,
  RadiusSettingOutlined,
  ArrowUpOutlined,
  ArrowDownOutlined,
  ArrowLeftOutlined,
  ArrowRightOutlined,
  SwapOutlined,
  EnterOutlined,
  DragOutlined
} from '@ant-design/icons'
import MKEmitter from '@/utils/events.js'
import zhCN from '@/locales/zh-CN/mob.js'
import enUS from '@/locales/en-US/mob.js'
import ColorSketch from '@/mob/colorsketch'
import asyncComponent from '@/utils/asyncComponent'
import StyleInput from './styleInput'
import FileUpload from '@/tabviews/zshare/fileupload'
import SysColorSketch from './syscolorsketch'
import MainLogo from '@/assets/img/main-logo.png'
import './index.scss'
const { Panel } = Collapse
const { Option } = Select
const ColorSketch = asyncComponent(() => import('@/mob/colorsketch'))
const PasteBoard = asyncComponent(() => import('@/components/pasteboard'))
const SourceComponent = asyncComponent(() => import('@/menu/components/share/sourcecomponent'))
class MobController extends Component {
  static propTpyes = {
    editElem: PropTypes.any,
    updateStyle: PropTypes.func,
  }
  state = {
    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
    card: null,
    comIds: [],
    bgimages: [],
    fonts: null,
    backgroundImage: '',
    options: [],
    borposition: 'outer'
    borposition: 'outer',
    type: ''
  }
  callback = null
  shouldComponentUpdate (nextProps, nextState) {
    return !is(fromJS(this.state), fromJS(nextState))
@@ -48,49 +75,123 @@
    MKEmitter.removeListener('changeStyle', this.initStyle)
  }
  initStyle = (comIds, options, style = {}) => {
  initStyle = (options, style = {}, callback, type) => {
    let backgroundImage = ''
    if (style.backgroundImage) {
      if (/^url/ig.test(style.backgroundImage)) {
        backgroundImage = style.backgroundImage.replace(/^url\(/ig, '').replace(/\)$/ig, '')
      } else if (/^linear-gradient/ig.test(style.backgroundImage)) {
        backgroundImage = style.backgroundImage.replace(/^linear-gradient\(/ig, '').replace(/\)$/ig, '')
    if (style.backgroundImage && /^url/ig.test(style.backgroundImage)) {
      backgroundImage = style.backgroundImage.replace(/^url\(/ig, '').replace(/\)$/ig, '')
    }
    let fonts = null
    if (options.includes('font')) {
      fonts = ['fontSize', 'fontWeight', 'lineHeight', 'letterSpacing', 'color', 'fontStyle', 'textAlign', 'textDecoration']
    } else if (options.includes('font1')) {
      fonts = ['fontSize', 'fontWeight', 'color']
      if (options[0] === 'font1') {
        options[0] = 'font'
      }
    } else if (options.includes('font2')) {
      fonts = ['fontSize', 'fontWeight', 'lineHeight', 'letterSpacing', 'color', 'fontStyle', 'textAlign', 'textDecoration', 'textIndent', 'wordBreak']
      if (options[0] === 'font2') {
        options[0] = 'font'
      }
    }
    this.callback = callback
    let card = fromJS(style).toJS()
    let borposition = 'outer'
    if (!card.borderWidth) {
      if (card.borderLeftWidth) {
        borposition = 'left'
      } else if (card.borderRightWidth) {
        borposition = 'right'
      } else if (card.borderTopWidth) {
        borposition = 'top'
      } else if (card.borderBottomWidth) {
        borposition = 'bottom'
      }
    }
    this.setState({
      visible: true,
      comIds: comIds,
      card: fromJS(style).toJS(),
      type: type || '',
      fonts: fonts,
      card: card,
      options: options,
      borposition: 'outer',
      borposition: borposition,
      backgroundImage
    })
    window.GLOB.styling = true
  }
  onCloseDrawer = () => {
    let card = fromJS(this.state.card).toJS()
    let check = false
    if (card.borderWidth === '0px') {
      delete card.borderWidth
      delete card.borderColor
      check = true
    } else if (card.borderLeftWidth === '0px') {
      delete card.borderLeftWidth
      delete card.borderLeftColor
      check = true
    } else if (card.borderRightWidth === '0px') {
      delete card.borderRightWidth
      delete card.borderRightColor
      check = true
    } else if (card.borderTopWidth === '0px') {
      delete card.borderTopWidth
      delete card.borderTopColor
      check = true
    } else if (card.borderBottomWidth === '0px') {
      delete card.borderBottomWidth
      delete card.borderBottomColor
      check = true
    }
    if (check) {
      this.callback && this.callback(card)
    }
    this.setState({
      visible: false,
      comIds: [],
      card: null,
      options: [],
      backgroundImage: ''
    })
    window.GLOB.styling = false
    this.callback = null
  }
  updateStyle = (style) => {
    const { comIds, card } = this.state
    const { card } = this.state
    let _style = {
      ...card,
      ...style
    }
    Object.keys(style).forEach(key => {
      if (!_style[key] && _style[key] !== 0) {
        delete _style[key]
      }
    })
    if (_style.position === 'relative') {
      _style.zIndex = 1
    } else if (_style.position === 'absolute') {
      _style.zIndex = 2
    } else if (_style.position === 'fixed') {
      _style.zIndex = 3
    } else {
      delete _style.zIndex
    }
    this.setState({
      card: _style,
    })
    MKEmitter.emit('submitStyle', comIds, _style)
    this.callback && this.callback(_style)
  }
  /**
@@ -99,7 +200,13 @@
  changeFontSize = (val) => {
    let value = parseInt(val)
    if (isNaN(value) || value < 12 || value > 100) return
    if (isNaN(value)) return
    if (value < 12) {
      value = 12
    } else if (value > 300) {
      value = 300
    }
    this.updateStyle({fontSize: `${value}px`})
  }
@@ -127,71 +234,92 @@
  }
  /**
   * @description 修改字体粗细
   * @description 首行缩进
   */
  boldChange = (val) => {
    this.updateStyle({fontWeight: val})
  changeTextIndent = (val) => {
    let value = parseFloat(val)
    if (isNaN(value) || value < 0 || value > 100) return
    this.updateStyle({textIndent: `${value}px`})
  }
  changeBackground = (val) => {
    const { card } = this.state
    let _style = { ...card }
    _style.background = val
    delete _style.backgroundColor
    delete _style.backgroundImage
    if (!val) {
      delete _style.background
    }
    this.setState({
      card: _style,
    })
    if (!val || /(^linear-gradient|^radial-gradient)\(.*\)$/.test(val)) {
      this.callback && this.callback(_style)
    }
  }
  /**
   * @description 修改字体颜色 ,颜色控件
   * @description 修改阴影颜色 ,颜色控件
   */
  changeFontColor = (val) => {
    this.updateStyle({color: val})
  changeShadowColor = (val) => {
    const { card } = this.state
    let boxShadow = `${card.hShadow || '0px'} ${card.vShadow || '0px'} ${card.shadowBlur || '0px'} ${val}`
    this.updateStyle({shadowColor: val, boxShadow})
  }
  /**
   * @description 字体对齐
   * @description 修改阴影颜色 ,颜色控件
   */
  changeTextAlign = (e) => {
    this.updateStyle({textAlign: e.target.value})
  changeShadowBlur = (val) => {
    const { card } = this.state
    let boxShadow = `${card.hShadow || '0px'} ${card.vShadow || '0px'} ${val || '0px'} ${card.shadowColor || 'transparent'}`
    this.updateStyle({shadowBlur: val, boxShadow})
  }
  /**
   * @description 字体样式,倾斜
   * @description 修改阴影颜色 ,颜色控件
   */
  changeFontStyle = (e) => {
    this.updateStyle({fontStyle: e.target.value})
  changeHShadow = (val) => {
    const { card } = this.state
    let boxShadow = `${val || '0px'} ${card.vShadow || '0px'} ${card.shadowBlur || '0px'} ${card.shadowColor || 'transparent'}`
    this.updateStyle({hShadow: val, boxShadow})
  }
  /**
   * @description 字体装饰,下划线、贯穿线、上划线
   * @description 修改阴影颜色 ,颜色控件
   */
  changeTextDecoration = (e) => {
    this.updateStyle({textDecoration: e.target.value})
  changeVShadow = (val) => {
    const { card } = this.state
    let boxShadow = `${card.hShadow || '0px'} ${val || '0px'} ${card.shadowBlur || '0px'} ${card.shadowColor || 'transparent'}`
    this.updateStyle({vShadow: val, boxShadow})
  }
  /**
   * @description 修改背景颜色 ,颜色控件
   */
  changeBackgroundColor = (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})`})
  imgChange = (val) => {
    this.setState({
      backgroundImage: val
    })
    if (val) {
      this.updateStyle({backgroundImage: `url(${val})`})
    } else {
      this.setState({bgimages: list})
      this.updateStyle({backgroundImage: ''})
    }
  }
  changeBackgroundImageInput = (e) => {
    let val = e.target.value
    val = val.replace(/^\s*|\s*$/ig, '')
    if (/^http|^\/\//.test(val)) {
      val = `url(${val})`
    } else if (/,/ig.test(val) && !/^(radial-gradient|linear-gradient)/ig.test(val)) {
      val = `linear-gradient(${val})`
    }
    this.setState({backgroundImage: e.target.value})
    this.updateStyle({backgroundImage: val})
  }
  changeBorderStyle = (val) => {
@@ -251,21 +379,83 @@
    this.updateStyle(_style)
  }
  changeHeight = (val) => {
    let _val = val
    if (_val === '0px') {
      _val = 'auto'
    }
    this.updateStyle({height: _val})
  }
  changeNormalStyle = (val, type) => {
    this.updateStyle({[type]: val})
  }
  copy = () => {
    const { card, options } = this.state
    let msg = { copyType: 'style' }
    msg.data = card
    msg.options = options
    try {
      msg = window.btoa(window.encodeURIComponent(JSON.stringify(msg)))
    } catch (e) {
      console.warn('Stringify Failure')
      msg = ''
    }
    if (msg) {
      let oInput = document.createElement('input')
      oInput.value = msg
      document.body.appendChild(oInput)
      oInput.select()
      document.execCommand('Copy')
      document.body.removeChild(oInput)
      message.success('复制成功。')
    }
  }
  paste = (res, callback) => {
    const { options } = this.state
    if (res.copyType !== 'style') {
      message.warning('配置信息格式错误!', 5)
      return
    } else if (JSON.stringify(res.options) !== JSON.stringify(options)) {
      message.warning('样式选项不一致,不可粘贴!', 5)
      return
    }
    let style = res.data || {}
    let backgroundImage = ''
    if (style.backgroundImage && /^url/ig.test(style.backgroundImage)) {
      backgroundImage = style.backgroundImage.replace(/^url\(/ig, '').replace(/\)$/ig, '')
    }
    let borposition = 'outer'
    if (!style.borderWidth) {
      if (style.borderLeftWidth) {
        borposition = 'left'
      } else if (style.borderRightWidth) {
        borposition = 'right'
      } else if (style.borderTopWidth) {
        borposition = 'top'
      } else if (style.borderBottomWidth) {
        borposition = 'bottom'
      }
    }
    this.setState({
      card: style,
      borposition,
      backgroundImage
    })
    this.callback && this.callback(style)
    callback()
    message.success('粘贴成功。')
  }
  render () {
    const { card, options, backgroundImage, bgimages, borposition } = this.state
    const { card, options, backgroundImage, borposition, fonts, type } = this.state
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
@@ -281,40 +471,52 @@
      <Drawer
        title={
          <div className="header-logo">
            <img src={window.GLOB.mainlogo} alt=""/>
            <img src={MainLogo} alt=""/>
          </div>
        }
        placement="left"
        width="300"
        className="menu-style-drawer"
        closable={true}
        maskClosable={false}
        onClose={this.onCloseDrawer}
        maskStyle={{opacity: 0.1}}
        visible={this.state.visible}
      >
        <div className="menu-style-controller">
        <div className={'menu-style-controller ' + (type || '')}>
          <Form {...formItemLayout}>
            {card ? <Collapse expandIconPosition="right" destroyInactivePanel={true} defaultActiveKey={options[0]} accordion={true}>
            {card ? <Collapse expandIconPosition="right" destroyInactivePanel={true} defaultActiveKey={options[0]}>
              {options.includes('width') ? <Panel header="宽度" key="width">
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<ColumnWidthOutlined title="宽度"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.width || ''} options={['px', 'vh', 'vw', '%', 'auto']} onChange={(val) => this.changeNormalStyle(val, 'width')}/>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('height') ? <Panel header="高度" key="height">
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="高度" type="column-height" />}
                    label={<ColumnHeightOutlined title="高度"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput defaultValue={card.height || ''} options={['px']} onChange={this.changeHeight}/>
                    <StyleInput clear={true} defaultValue={card.height || ''} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'height')}/>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('font') ? <Panel header="字体" key="font">
                <Col span={12}>
                  <Form.Item colon={false} label={<Icon title="字体大小" type="font-size" />}>
                    <InputNumber defaultValue={card.fontSize} min={12} max={100} precision={0} onChange={this.changeFontSize} />
              {fonts ? <Panel header="字体" key="font">
                {fonts.includes('fontSize') ? <Col span={12}>
                  <Form.Item colon={false} label={<FontSizeOutlined title="字体大小"/>}>
                    <InputNumber defaultValue={card.fontSize || 14} min={12} max={300} precision={0} onChange={this.changeFontSize} />
                  </Form.Item>
                </Col>
                <Col span={12}>
                  <Form.Item colon={false} label={<Icon title="字体粗细" type="bold" />}>
                    <Select defaultValue={card.fontWeight || 'normal'} onChange={this.boldChange}>
                </Col> : null}
                {fonts.includes('fontWeight') ? <Col span={12}>
                  <Form.Item colon={false} label={<BoldOutlined title="字体粗细"/>}>
                    <Select defaultValue={card.fontWeight || 'normal'} onChange={(val) => this.changeNormalStyle(val, 'fontWeight')}>
                      <Option value="normal">normal</Option>
                      <Option value="bold">bold</Option>
                      <Option value="bolder">bolder</Option>
@@ -330,108 +532,193 @@
                      <Option value="900">900</Option>
                    </Select>
                  </Form.Item>
                </Col>
                <Col span={12}>
                  <Form.Item colon={false} label={<Icon title="行高" type="line-height" />}>
                    <InputNumber defaultValue={card.lineHeight} min={1} max={10} precision={1} onChange={this.changeLineHeight} />
                </Col> : null}
                {fonts.includes('lineHeight') ? <Col span={12}>
                  <Form.Item colon={false} label={<LineHeightOutlined title="行高"/>}>
                    <InputNumber defaultValue={card.lineHeight || 1.5} min={1} max={10} precision={1} onChange={this.changeLineHeight} />
                  </Form.Item>
                </Col>
                <Col span={12}>
                  <Form.Item colon={false} label={<Icon title="字间距" type="column-width" />}>
                    <InputNumber defaultValue={card.letterSpacing} min={0} max={100} precision={0} onChange={this.changeLetterSpacing}/>
                </Col> : null}
                {fonts.includes('letterSpacing') ? <Col span={12}>
                  <Form.Item colon={false} label={<ColumnWidthOutlined title="字间距"/>}>
                    <InputNumber defaultValue={card.letterSpacing || 0} min={0} max={100} precision={0} onChange={this.changeLetterSpacing}/>
                  </Form.Item>
                </Col>
                <Col span={24}>
                </Col> : null}
                {fonts.includes('textIndent') ? <Col span={12}>
                  <Form.Item colon={false} label={<AlignRightOutlined title="首行缩进"/>}>
                    <InputNumber defaultValue={card.textIndent || 0} min={0} max={100} precision={0} onChange={this.changeTextIndent}/>
                  </Form.Item>
                </Col> : null}
                {fonts.includes('wordBreak') ? <Col span={12}>
                  <Form.Item colon={false} label={<EnterOutlined title="自动换行"/>}>
                    <Select defaultValue={card.wordBreak || 'normal'} onChange={(val) => this.changeNormalStyle(val, 'wordBreak')}>
                      <Option value="normal">normal</Option>
                      <Option value="break-all">break-all</Option>
                    </Select>
                  </Form.Item>
                </Col> : null}
                {fonts.includes('color') ? <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="字体颜色" type="font-colors" />}
                    label={<FontColorsOutlined title="字体颜色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <ColorSketch value={card.color || 'rgba(0, 0, 0, 0.85)'} onChange={this.changeFontColor} />
                    <ColorSketch value={card.color || ''} onChange={(val) => this.changeNormalStyle(val, 'color')} />
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<BgColorsOutlined title="系统色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <SysColorSketch onChange={(val) => this.changeNormalStyle(val, 'color')} />
                  </Form.Item>
                </Col> : null}
                {fonts.includes('fontStyle') ? <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={' '}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group defaultValue={card.fontStyle || 'normal'} onChange={this.changeFontStyle}>
                    <Radio.Group defaultValue={card.fontStyle || 'normal'} onChange={(e) => this.changeNormalStyle(e.target.value, 'fontStyle')}>
                      <Radio.Button value="normal"><span title="标准">N</span></Radio.Button>
                      <Radio.Button value="italic"><Icon title="斜体" type="italic" /></Radio.Button>
                      <Radio.Button value="italic"><ItalicOutlined title="斜体"/></Radio.Button>
                      <Radio.Button value="oblique" style={{fontStyle: 'oblique'}}><span title="倾斜">B</span></Radio.Button>
                    </Radio.Group>
                  </Form.Item>
                </Col>
                <Col span={24}>
                </Col> : null}
                {fonts.includes('textAlign') ? <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={' '}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group className="text-align" defaultValue={card.textAlign || 'left'} onChange={this.changeTextAlign}>
                      <Radio.Button value="left"><Icon title="左对齐" type="align-left" /></Radio.Button>
                      <Radio.Button value="center"><Icon title="居中对齐" type="align-center" /></Radio.Button>
                      <Radio.Button value="right"><Icon title="右对齐" type="align-right" /></Radio.Button>
                    <Radio.Group className="text-align" defaultValue={card.textAlign || 'left'} onChange={(e) => this.changeNormalStyle(e.target.value, 'textAlign')}>
                      <Radio.Button value="left"><AlignLeftOutlined title="左对齐"/></Radio.Button>
                      <Radio.Button value="center"><AlignCenterOutlined title="居中对齐"/></Radio.Button>
                      <Radio.Button value="right"><AlignRightOutlined title="右对齐"/></Radio.Button>
                    </Radio.Group>
                  </Form.Item>
                </Col>
                <Col span={24}>
                </Col> : null}
                {fonts.includes('textDecoration') ? <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={' '}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group className="text-decoration" defaultValue={card.textDecoration || 'none'} onChange={this.changeTextDecoration}>
                    <Radio.Group className="text-decoration" defaultValue={card.textDecoration || 'none'} onChange={(e) => this.changeNormalStyle(e.target.value, 'textDecoration')}>
                      <Radio.Button value="none"><span title="标准">N</span></Radio.Button>
                      <Radio.Button value="underline"><Icon title="下划线" type="underline" /></Radio.Button>
                      <Radio.Button value="line-through"><Icon title="中划线" type="strikethrough" /></Radio.Button>
                      <Radio.Button value="underline"><UnderlineOutlined title="下划线"/></Radio.Button>
                      <Radio.Button value="line-through"><StrikethroughOutlined title="中划线"/></Radio.Button>
                      <Radio.Button value="overline" style={{textDecoration: 'overline'}}><span title="上划线">O</span></Radio.Button>
                    </Radio.Group>
                  </Form.Item>
                </Col>
                </Col> : null}
              </Panel> : null}
              {options.includes('background') ? <Panel header="背景" key="background">
                <Col span={24}>
              {options.includes('background') || options.includes('backgroundColor') ? <Panel header="背景" key="background">
                <Col span={24} className="bg-color-panel">
                  <Form.Item
                    colon={false}
                    label={<Icon title="背景颜色" type="bg-colors" />}
                    label={<BgColorsOutlined title="背景颜色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <ColorSketch value={card.backgroundColor || '#ffffff'} onChange={this.changeBackgroundColor} />
                    <ColorSketch allowClear={true} value={card.backgroundColor || ''} onChange={(val) => this.changeNormalStyle(val, 'backgroundColor')} />
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="背景图片" type="picture" />}
                    label={<BgColorsOutlined title="系统色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <FileUpload value={bgimages} maxFile={2} fileType="text" onChange={this.imgChange}/>
                    <Input placeholder="" value={backgroundImage} autoComplete="off" onChange={this.changeBackgroundImageInput} />
                    <SysColorSketch onChange={(val) => this.changeNormalStyle(val, 'backgroundColor')} />
                  </Form.Item>
                </Col>
                {window.develop === true ? <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<BgColorsOutlined title="背景颜色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Input value={card.background || ''} onChange={(e) => this.changeBackground(e.target.value)} />
                  </Form.Item>
                </Col> : null}
                {!options.includes('backgroundColor') ? <Col span={24} className="bg-image-panel">
                  <Form.Item
                    colon={false}
                    label={<PictureOutlined title="背景图片"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <SourceComponent value={backgroundImage} type="" placement="right" onChange={this.imgChange}/>
                  </Form.Item>
                </Col> : null}
                {!options.includes('backgroundColor') ? <Col span={24}>
                  <Form.Item
                    colon={false}
                    label="比例"
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Select defaultValue={card.backgroundSize || 'cover'} onChange={(val) => this.changeNormalStyle(val, 'backgroundSize')}>
                      <Option value="100%">100%</Option>
                      <Option value="100% 100%">100% 100%</Option>
                      <Option value="auto 100%">auto 100%</Option>
                      <Option value="100% auto">100% auto</Option>
                      <Option value="auto">auto</Option>
                      <Option value="contain">contain</Option>
                      <Option value="cover">cover</Option>
                    </Select>
                  </Form.Item>
                </Col> : null}
                {!options.includes('backgroundColor') ? <Col span={24}>
                  <Form.Item
                    colon={false}
                    label="重复"
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Select defaultValue={card.backgroundRepeat || 'no-repeat'} onChange={(val) => this.changeNormalStyle(val, 'backgroundRepeat')}>
                      <Option value="repeat">repeat</Option>
                      <Option value="no-repeat">no-repeat</Option>
                      <Option value="repeat-x">repeat-x</Option>
                      <Option value="repeat-y">repeat-y</Option>
                    </Select>
                  </Form.Item>
                </Col> : null}
                {!options.includes('backgroundColor') ? <Col span={24}>
                  <Form.Item
                    colon={false}
                    label="位置"
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Select defaultValue={card.backgroundPosition || 'center'} onChange={(val) => this.changeNormalStyle(val, 'backgroundPosition')}>
                      <Option value="center">center</Option>
                      <Option value="center top">center top</Option>
                      <Option value="center bottom">center bottom</Option>
                      <Option value="left top">left top</Option>
                      <Option value="left center">left center</Option>
                      <Option value="left bottom">left bottom</Option>
                      <Option value="right top">right top</Option>
                      <Option value="right center">right center</Option>
                      <Option value="right bottom">right bottom</Option>
                    </Select>
                  </Form.Item>
                </Col> : null}
              </Panel> : null}
              {options.includes('border') ? <Panel header="边框" key="border">
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="边框位置" type="border" />}
                    label={<BorderOutlined title="边框位置"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group className="border-position" defaultValue={'outer'} onChange={(e) => this.setState({borposition: e.target.value})}>
                      <Radio value="outer"><Icon title="外边框" type="border-outer" /></Radio>
                      <Radio value="left"><Icon title="左边框" type="border-left" /></Radio>
                      <Radio value="right"><Icon title="右边框" type="border-right" /></Radio>
                      <Radio value="top"><Icon title="上边框" type="border-top" /></Radio>
                      <Radio value="bottom"><Icon title="下边框" type="border-bottom" /></Radio>
                    <Radio.Group className="border-position" defaultValue={borposition} onChange={(e) => this.setState({borposition: e.target.value})}>
                      <Radio value="outer"><BorderOuterOutlined title="外边框"/></Radio>
                      <Radio value="left"><BorderLeftOutlined title="左边框"/></Radio>
                      <Radio value="right"><BorderRightOutlined title="右边框"/></Radio>
                      <Radio value="top"><BorderTopOutlined title="上边框"/></Radio>
                      <Radio value="bottom"><BorderBottomOutlined title="下边框"/></Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="边框样式" type="border-outer" />}
                    label={<BorderOuterOutlined title="边框样式"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    {borposition === 'outer' ? <Select defaultValue={card.borderStyle || 'solid'} onChange={this.changeBorderStyle}>
@@ -469,124 +756,306 @@
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="边框宽度" type="column-width" />}
                    label={<ColumnWidthOutlined title="边框宽度"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    {borposition === 'outer' ? <StyleInput defaultValue={card.borderWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'left' ? <StyleInput defaultValue={card.borderLeftWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'right' ? <StyleInput defaultValue={card.borderRightWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'top' ? <StyleInput defaultValue={card.borderTopWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'bottom' ? <StyleInput defaultValue={card.borderBottomWidth || ''} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'outer' ? <StyleInput defaultValue={card.borderWidth || '0px'} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'left' ? <StyleInput defaultValue={card.borderLeftWidth || '0px'} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'right' ? <StyleInput defaultValue={card.borderRightWidth || '0px'} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'top' ? <StyleInput defaultValue={card.borderTopWidth || '0px'} options={['px']} onChange={this.changeBorderWidth}/> : null}
                    {borposition === 'bottom' ? <StyleInput defaultValue={card.borderBottomWidth || '0px'} options={['px']} onChange={this.changeBorderWidth}/> : null}
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="边框颜色" type="bg-colors" />}
                    label={<BgColorsOutlined title="边框颜色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    {borposition === 'outer' ? <ColorSketch defaultValue={card.borderColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'left' ? <ColorSketch defaultValue={card.borderLeftColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'right' ? <ColorSketch defaultValue={card.borderRightColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'top' ? <ColorSketch defaultValue={card.borderTopColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'bottom' ? <ColorSketch defaultValue={card.borderBottomColor || 'transparent'} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'outer' ? <ColorSketch value={card.borderColor || ''} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'left' ? <ColorSketch value={card.borderLeftColor || ''} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'right' ? <ColorSketch value={card.borderRightColor || ''} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'top' ? <ColorSketch value={card.borderTopColor || ''} onChange={this.changeBorderColor} /> : null}
                    {borposition === 'bottom' ? <ColorSketch value={card.borderBottomColor || ''} onChange={this.changeBorderColor} /> : null}
                  </Form.Item>
                  <Form.Item
                    colon={false}
                    label={<BgColorsOutlined title="系统色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <SysColorSketch onChange={this.changeBorderColor} />
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="圆角" type="radius-setting" />}
                    label={<RadiusSettingOutlined title="圆角"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput defaultValue={card.borderRadius || ''} options={['px', '%']} onChange={(val) => this.changeNormalStyle(val, 'borderRadius')}/>
                    <StyleInput clear={true} defaultValue={card.borderRadius || ''} options={['px', '%']} onChange={(val) => this.changeNormalStyle(val, 'borderRadius')}/>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('shadow') ? <Panel header="阴影" key="shadow">
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<BgColorsOutlined title="阴影颜色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <ColorSketch value={card.shadowColor || ''} onChange={this.changeShadowColor} />
                  </Form.Item>
                  <Form.Item
                    colon={false}
                    label={<BgColorsOutlined title="系统色"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <SysColorSketch onChange={this.changeShadowColor} />
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<ColumnWidthOutlined title="模糊距离"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput defaultValue={card.shadowBlur || '0px'} options={['px']} onChange={this.changeShadowBlur}/>
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<ArrowRightOutlined title="水平位置"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput defaultValue={card.hShadow || '0px'} options={['px']} onChange={this.changeHShadow}/>
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<ArrowDownOutlined title="垂直位置"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput defaultValue={card.vShadow || '0px'} options={['px']} onChange={this.changeVShadow}/>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('margin') ? <Panel header="外边距" key="margin">
                <Col span={12}>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="上边距" type="arrow-up"/>}
                    label={<ArrowUpOutlined title="上边距"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput defaultValue={card.marginTop} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'marginTop')}/>
                    <StyleInput clear={true} defaultValue={card.marginTop || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'marginTop')}/>
                  </Form.Item>
                </Col>
                <Col span={12}>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="下边距" type="arrow-down"/>}
                    label={<ArrowDownOutlined title="下边距"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput defaultValue={card.marginBottom} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'marginBottom')}/>
                    <StyleInput clear={true} defaultValue={card.marginBottom || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'marginBottom')}/>
                  </Form.Item>
                </Col>
                <Col span={12}>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="左边距" type="arrow-left"/>}
                    label={<ArrowLeftOutlined title="左边距"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput defaultValue={card.marginLeft} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'marginLeft')}/>
                    <StyleInput clear={true} defaultValue={card.marginLeft || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'marginLeft')}/>
                  </Form.Item>
                </Col>
                <Col span={12}>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="右边距" type="arrow-right"/>}
                    label={<ArrowRightOutlined title="右边距"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput defaultValue={card.marginRight} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'marginRight')}/>
                    <StyleInput clear={true} defaultValue={card.marginRight || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'marginRight')}/>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('padding') ? <Panel header="内边距" key="padding">
                <Col span={12}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="上边距" type="arrow-up"/>}
                  >
                    <StyleInput defaultValue={card.paddingTop} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'paddingTop')}/>
                  </Form.Item>
                </Col>
                <Col span={12}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="下边距" type="arrow-down"/>}
                  >
                    <StyleInput defaultValue={card.paddingBottom} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'paddingBottom')}/>
                  </Form.Item>
                </Col>
                <Col span={12}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="左边距" type="arrow-left"/>}
                  >
                    <StyleInput defaultValue={card.paddingLeft} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'paddingLeft')}/>
                  </Form.Item>
                </Col>
                <Col span={12}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="右边距" type="arrow-right"/>}
                  >
                    <StyleInput defaultValue={card.paddingRight} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'paddingRight')}/>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('float') ? <Panel header="浮动" key="float">
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<Icon title="浮动" type="swap" />}
                    label={<ArrowUpOutlined title="上边距"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group defaultValue={card.float || 'left'} onChange={(e) => this.changeNormalStyle(e.target.value, 'float')}>
                      <Radio value="left">左浮动</Radio>
                      <Radio value="right">右浮动</Radio>
                      <Radio value="none">不浮动</Radio>
                    <StyleInput clear={true} defaultValue={card.paddingTop || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'paddingTop')}/>
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<ArrowDownOutlined title="下边距"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.paddingBottom || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'paddingBottom')}/>
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<ArrowLeftOutlined title="左边距"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.paddingLeft || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'paddingLeft')}/>
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<ArrowRightOutlined title="右边距"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.paddingRight || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'paddingRight')}/>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('float') ? <Panel header="对齐方式" key="float">
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<SwapOutlined title="对齐"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group style={{whiteSpace: 'nowrap'}} defaultValue={card.float || 'left'} onChange={(e) => this.changeNormalStyle(e.target.value, 'float')}>
                      <Radio value="left">左</Radio>
                      <Radio value="center">居中</Radio>
                      <Radio value="right">右</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('minHeight') ? <Panel header="最小高度" key="minHeight">
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<ColumnHeightOutlined title="最小高度"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.minHeight || ''} options={['px', 'vh', 'vw']} onChange={(val) => this.changeNormalStyle(val, 'minHeight')}/>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('clear') ? <Panel header="浮动" key="clear">
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<SwapOutlined title="浮动"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group style={{whiteSpace: 'nowrap'}} defaultValue={card.clear || 'none'} onChange={(e) => this.changeNormalStyle(e.target.value, 'clear')}>
                      <Radio value="none">左浮动</Radio>
                      <Radio value="left">不浮动</Radio>
                      <Radio value="right">右浮动</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('display') ? <Panel header="显示" key="display">
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<SwapOutlined title="浮动"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Radio.Group style={{whiteSpace: 'nowrap'}} defaultValue={card.display || 'block'} onChange={(e) => this.changeNormalStyle(e.target.value, 'display')}>
                      <Radio value="block">块级元素</Radio>
                      <Radio value="inline-block">行内块元素</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('position') ? <Panel header="定位" key="position">
                <div style={{paddingLeft: '35px', fontSize: '12px'}}>注:定位效果请在运行环境中查看。</div>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<SwapOutlined title="定位"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 3 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 21 }} }
                  >
                    <Radio.Group style={{whiteSpace: 'nowrap'}} defaultValue={card.position || 'unset'} onChange={(e) => this.changeNormalStyle(e.target.value, 'position')}>
                      <Radio value="unset">无</Radio>
                      <Radio value="relative">相对</Radio>
                      <Radio value="absolute">绝对</Radio>
                      <Radio value="fixed">固定</Radio>
                    </Radio.Group>
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<ArrowUpOutlined title="上"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 3 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 21 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.top || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'top')}/>
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<ArrowDownOutlined title="下"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 3 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 21 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.bottom || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'bottom')}/>
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<ArrowLeftOutlined title="左"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 3 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 21 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.left || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'left')}/>
                  </Form.Item>
                </Col>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<ArrowRightOutlined title="右"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 3 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 21 }} }
                  >
                    <StyleInput clear={true} defaultValue={card.right || ''} options={['px', 'vh', 'vw', '%']} onChange={(val) => this.changeNormalStyle(val, 'right')}/>
                  </Form.Item>
                </Col>
              </Panel> : null}
              {options.includes('transform') ? <Panel header="位置变换" key="transform">
                <div style={{paddingLeft: '50px', fontSize: '12px'}}>注:变换效果请在运行环境中查看。</div>
                <Col span={24}>
                  <Form.Item
                    colon={false}
                    label={<DragOutlined title="变换"/>}
                    labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                  >
                    <Select defaultValue={card.transform || ''} onChange={(val) => this.changeNormalStyle(val, 'transform')}>
                      <Option value="">无</Option>
                      <Option value="translateY(-50%)">上移50%</Option>
                      <Option value="translateY(50%)">下移50%</Option>
                      <Option value="translateX(-50%)">左移50%</Option>
                      <Option value="translateX(50%)">右移50%</Option>
                      <Option value="translate(-50%, -50%)">左上移50%</Option>
                      <Option value="translate(-50%, 50%)">左下移50%</Option>
                      <Option value="translate(50%, -50%)">右上移50%</Option>
                      <Option value="translate(50%, 50%)">右下移50%</Option>
                    </Select>
                  </Form.Item>
                </Col>
              </Panel> : null}
            </Collapse> : null}
          </Form>
          <div style={{textAlign: 'right', lineHeight: '60px', marginBottom: '30px'}}>
            <div style={{float: 'left'}}>
              <Button onClick={() => this.copy()} className="mk-border-green" style={{marginRight: '10px'}}>复制</Button>
              <PasteBoard getPasteValue={this.paste}><Button style={{borderColor: 'rgb(64, 169, 255)', color: 'rgb(64, 169, 255)'}}>粘贴</Button></PasteBoard>
            </div>
            <Button style={{marginRight: '10px'}} onClick={this.onCloseDrawer}>关闭</Button>
          </div>
        </div>
      </Drawer>
    )