From 30273c297c59887434f44a75df75f13db6c8885c Mon Sep 17 00:00:00 2001
From: king <18310653075@163.com>
Date: 星期二, 29 九月 2020 09:15:54 +0800
Subject: [PATCH] 2020-09-29

---
 src/mob/colorsketch/index.jsx                                 |    2 
 src/menu/components/card/cardcomponent/settingform/index.jsx  |  404 +++++++++++++++++++++
 src/menu/components/card/cardcellcomponent/index.jsx          |    7 
 src/menu/components/card/cardcomponent/index.scss             |   25 +
 src/menu/stylecontroller/index.jsx                            |   57 --
 src/menu/actioncomponent/index.jsx                            |   65 ---
 src/menu/stylecontroller/styleInput/index.jsx                 |  118 ++++++
 src/menu/components/card/cardcomponent/index.jsx              |  285 +++++++++++++++
 src/menu/stylecontroller/styleInput/index.scss                |   44 ++
 src/menu/components/card/cardcomponent/settingform/index.scss |   24 +
 src/menu/components/card/data-card/index.jsx                  |   88 ----
 11 files changed, 936 insertions(+), 183 deletions(-)

diff --git a/src/menu/actioncomponent/index.jsx b/src/menu/actioncomponent/index.jsx
index ea88b06..599b4c2 100644
--- a/src/menu/actioncomponent/index.jsx
+++ b/src/menu/actioncomponent/index.jsx
@@ -464,32 +464,12 @@
           })
         }
       }).then(() => {
-        // 鍒ゆ柇鏄惁瀛樺湪鎿嶄綔鍒�
-        let _hasGridbtn = _actionlist.filter(act => act.position === 'grid').length > 0
-        let _gridBtn = config.gridBtn ? fromJS(config.gridBtn).toJS() : null
-
-        if (_gridBtn) {
-          _gridBtn.display = _hasGridbtn
-        } else {
-          _gridBtn = {
-            display: _hasGridbtn,
-            Align: 'center',
-            IsSort: 'false',
-            uuid: Utils.getuuid(),
-            label: this.state.dict['model.form.column.action'],
-            type: 'action',
-            style: 'button',
-            show: 'horizontal',
-            Width: 120
-          }
-        }
-
         this.setState({
           actionlist: _actionlist,
           copying: false,
           visible: false
         }, () => {
-          this.props.updateaction({...config, action: _actionlist, gridBtn: _gridBtn}, copyActionId)
+          this.props.updateaction({...config, action: _actionlist}, copyActionId)
         })
       })
     })
@@ -686,25 +666,6 @@
 
         _actionlist = _actionlist.filter(item => item.uuid !== card.uuid)
 
-        let _hasGridbtn = _actionlist.filter(act => act.position === 'grid').length > 0
-        let _gridBtn = config.gridBtn ? fromJS(config.gridBtn).toJS() : null
-
-        if (_gridBtn) {
-          _gridBtn.display = _hasGridbtn
-        } else {
-          _gridBtn = {
-            display: _hasGridbtn,
-            Align: 'center',
-            IsSort: 'false',
-            uuid: Utils.getuuid(),
-            label: this.state.dict['model.form.column.action'],
-            type: 'action',
-            style: 'button',
-            show: 'horizontal',
-            Width: 120
-          }
-        }
-
         let delcard = {
           type: 'action',
           card: card
@@ -713,7 +674,7 @@
         _this.setState({
           actionlist: _actionlist
         }, () => {
-          _this.props.updateaction({...config, action: _actionlist, gridBtn: _gridBtn}, '', delcard)
+          _this.props.updateaction({...config, action: _actionlist}, '', delcard)
         })
       },
       onCancel() {}
@@ -895,30 +856,10 @@
         this.refs.btnCreatFunc.exec(btn.innerFunc, newLText, DelText).then(result => {
           if (result !== 'success') return
 
-          // 鍒ゆ柇鏄惁瀛樺湪鎿嶄綔鍒�
-          let _hasGridbtn = _actionlist.filter(act => act.position === 'grid').length > 0
-          let _gridBtn = config.gridBtn ? fromJS(config.gridBtn).toJS() : null
-
-          if (_gridBtn) {
-            _gridBtn.display = _hasGridbtn
-          } else {
-            _gridBtn = {
-              display: _hasGridbtn,
-              Align: 'center',
-              IsSort: 'false',
-              uuid: Utils.getuuid(),
-              label: this.state.dict['model.form.column.action'],
-              type: 'action',
-              style: 'button',
-              show: 'horizontal',
-              Width: 120
-            }
-          }
-
           this.setState({
             actionlist: _actionlist
           }, () => {
-            this.props.updateaction({...config, action: _actionlist, gridBtn: _gridBtn})
+            this.props.updateaction({...config, action: _actionlist})
           })
         })
       })
diff --git a/src/menu/components/card/cardcellcomponent/index.jsx b/src/menu/components/card/cardcellcomponent/index.jsx
index 78c0753..8e58563 100644
--- a/src/menu/components/card/cardcellcomponent/index.jsx
+++ b/src/menu/components/card/cardcellcomponent/index.jsx
@@ -17,7 +17,8 @@
 class CardCellComponent extends Component {
   static propTpyes = {
     config: PropTypes.object,        // 鑿滃崟閰嶇疆淇℃伅
-    updateElement: PropTypes.func     // 鑿滃崟閰嶇疆鏇存柊
+    elements: PropTypes.array,       // 鍏冪礌闆�
+    updateElement: PropTypes.func    // 鑿滃崟閰嶇疆鏇存柊
   }
 
   state = {
@@ -32,10 +33,10 @@
    * @description 鎼滅储鏉′欢鍒濆鍖�
    */
   UNSAFE_componentWillMount () {
-    const { config } = this.props
+    const { elements } = this.props
 
     this.setState({
-      elements: fromJS(config.elements).toJS()
+      elements: fromJS(elements).toJS()
     })
   }
 
diff --git a/src/menu/components/card/cardcomponent/index.jsx b/src/menu/components/card/cardcomponent/index.jsx
new file mode 100644
index 0000000..7eb7da9
--- /dev/null
+++ b/src/menu/components/card/cardcomponent/index.jsx
@@ -0,0 +1,285 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Modal, Popover, Icon, Switch } from 'antd'
+
+import asyncComponent from '@/utils/asyncComponent'
+import zhCN from '@/locales/zh-CN/model.js'
+import enUS from '@/locales/en-US/model.js'
+// import { getCardCellForm } from './formconfig'
+
+import Utils from '@/utils/utils.js'
+import MKEmitter from '@/utils/events.js'
+import './index.scss'
+
+const { confirm } = Modal
+const CardCellComponent = asyncComponent(() => import('../cardcellcomponent'))
+
+class CardBoxComponent extends Component {
+  static propTpyes = {
+    config: PropTypes.object,        // 鑿滃崟閰嶇疆淇℃伅
+    card: PropTypes.object,          // 鍗$墖閰嶇疆淇℃伅
+    updateElement: PropTypes.func    // 鑿滃崟閰嶇疆鏇存柊
+  }
+
+  state = {
+    dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
+    card: null,          // 鍗$墖淇℃伅锛屽寘鎷鍙嶉潰
+    formlist: null,      // 璁剧疆琛ㄥ崟淇℃伅
+    elements: null,      // 缂栬緫缁�
+    visible: false,      // 妯℃�佹鎺у埗
+    side: 'front'
+  }
+
+  /**
+   * @description 鎼滅储鏉′欢鍒濆鍖�
+   */
+  UNSAFE_componentWillMount () {
+    const { card } = this.props
+
+    this.setState({
+      card: fromJS(card).toJS(),
+      elements: fromJS(card.elements).toJS(),
+    })
+  }
+
+  componentDidMount () {
+    MKEmitter.addListener('cardAddElement', this.cardAddElement)
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+    MKEmitter.removeListener('cardAddElement', this.cardAddElement)
+  }
+
+  cardAddElement = (cardId, element) => {
+    if (cardId !== this.props.config.uuid) return
+
+    const { elements } = this.state
+
+    this.setState({elements: [...elements, element]})
+    this.handleElement(element)
+  }
+
+  /**
+   * @description 鎸夐挳椤哄簭璋冩暣
+   */
+  handleList = (list) => {
+    const { config } = this.props
+
+    this.setState({elements: list}, () => {
+      this.props.updateElement({...config, elements: list})
+    })
+  }
+
+  /**
+   * @description 鎸夐挳缂栬緫锛岃幏鍙栨寜閽〃鍗曚俊鎭�
+   */
+  handleElement = (card) => {
+    this.setState({
+      visible: true,
+      card: card,
+      // formlist: getCardCellForm(card)
+    })
+  }
+
+  /**
+   * @description 鍙栨秷淇濆瓨锛屽鏋滃厓绱犱负鏂版坊鍏冪礌锛屽垯浠庡簭鍒椾腑鍒犻櫎
+   */
+  editModalCancel = () => {
+    const { card, elements } = this.state
+    let _elements = null
+
+    if (card.focus) {
+      _elements = elements.filter(item => item.uuid !== card.uuid)
+    } else {
+      _elements = elements
+    }
+
+    this.setState({
+      card: null,
+      elements: _elements,
+      visible: false
+    })
+  }
+
+  /**
+   * @description 鎼滅储淇敼鍚庢彁浜や繚瀛�
+   * 1銆佸幓闄ょ郴缁熼粯璁ゆ悳绱㈡潯浠�
+   * 2銆佸瓧娈靛強鎻愮ず鏂囧瓧閲嶅鏍¢獙
+   * 3銆佹洿鏂颁笅鎷夎彍鍗曞彲閫夐泦鍚�
+   * 4銆佷笅鎷夎彍鍗曟暟鎹簮璇硶楠岃瘉
+   */
+  handleSubmit = () => {
+    const { config } = this.props
+    const { elements } = this.state
+
+    this.elementFormRef.handleConfirm().then(ele => {
+      let _elements = elements.map(cell => {
+        if (cell.uuid === ele.uuid) return ele
+        return cell
+      })
+
+      this.setState({
+        elements: _elements,
+        visible: false
+      }, () => {
+        this.props.updateElement({...config, elements: _elements})
+      })
+    })
+  }
+
+  /**
+   * @description 鎸夐挳鍒犻櫎
+   */
+  deleteElement = (card) => {
+    const { config } = this.props
+    const { dict, elements } = this.state
+    let _this = this
+
+    confirm({
+      content: dict['model.confirm'] + dict['model.delete'] + '鍏冪礌鍚楋紵',
+      onOk() {
+        let _elements = elements.filter(item => item.uuid !== card.uuid)
+
+        _this.setState({
+          elements: _elements
+        }, () => {
+          _this.props.updateElement({...config, elements: _elements})
+        })
+      },
+      onCancel() {}
+    })
+  }
+
+  changeSide = () => {
+    const { card } = this.props
+    const { side } = this.state
+
+    let _side = ''
+    let _elements = null
+    if (side === 'front') {
+      _side = 'back'
+    } else {
+      _side = 'front'
+    }
+
+    if (_side === 'front') {
+      _elements = fromJS(card.elements).toJS()
+    } else {
+      _elements = fromJS(card.backElements).toJS()
+    }
+
+    this.setState({side: _side, elements: _elements})
+  }
+  
+  addElement = () => {
+    const { card } = this.state
+
+    let newcard = {}
+    newcard.uuid = Utils.getuuid()
+    newcard.focus = true
+    
+    newcard.eleType = 'text'
+    newcard.datatype = 'dynamic'
+    newcard.color = 'rgba(0,0,0,0.85)'
+    newcard.padding = '5px'
+    newcard.align = 'left'
+
+    // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
+    MKEmitter.emit('cardAddElement', card.uuid, newcard)
+  }
+
+  addButton = () => {
+    const { card } = this.state
+
+    let newcard = {}
+    newcard.uuid = Utils.getuuid()
+    newcard.focus = true
+    
+    newcard.label = 'button'
+    newcard.sqlType = ''
+    newcard.Ot = 'requiredSgl'
+    newcard.OpenType = 'prompt'
+    newcard.icon = ''
+    newcard.class = 'default'
+    newcard.intertype = 'system'
+    newcard.method = 'POST'
+    newcard.execSuccess = 'grid'
+    newcard.execError = 'never'
+    newcard.popClose = 'never'
+    newcard.errorTime = 10
+    newcard.verify = null
+    newcard.show = 'link'
+
+    // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
+    MKEmitter.emit('addButton', card.uuid, newcard)
+  }
+
+  changeStyle = () => {
+    const { card } = this.state
+
+    MKEmitter.emit('changeStyle', [card.uuid], ['font', 'background', 'border'], {})
+  }
+
+  render() {
+    // const { config } = this.props
+    const { card, elements } = this.state
+
+    return (
+      <div className={'ant-col card-item ant-col-' + (card.setting.width || 6)} style={{height: card.setting.height ? card.setting.height + 'px' : 'auto'}}>
+        <CardCellComponent config={card} elements={elements} updateElement={this.updateComponent}/>
+        <div className="card-control">
+          <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
+            <div className="mk-popover-control">
+              <Icon className="plus" title="娣诲姞鍏冪礌" onClick={this.addElement} type="plus" />
+              <Icon className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton} type="plus-square" />
+              <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
+              <Switch size="small" onClick={this.changeSide} defaultChecked />
+            </div>
+          } trigger="hover">
+            <Icon type="tool" />
+          </Popover>
+        </div>
+      </div>
+      // <div className="model-menu-card-cell-list">
+      //   <DragElement
+      //     list={elements}
+      //     handleList={this.handleList}
+      //     handleMenu={this.handleElement}
+      //     deleteMenu={this.deleteElement}
+      //   />
+      //   {/* 缂栬緫鎸夐挳锛氬鍒躲�佺紪杈� */}
+      //   <Modal
+      //     title={'缂栬緫鍏冪礌'}
+      //     visible={visible}
+      //     width={800}
+      //     maskClosable={false}
+      //     onCancel={this.editModalCancel}
+      //     onOk={this.handleSubmit}
+      //     destroyOnClose
+      //   >
+      //     <ElementForm
+      //       dict={dict}
+      //       card={card}
+      //       formlist={this.state.formlist}
+      //       inputSubmit={this.handleSubmit}
+      //       config={config}
+      //       wrappedComponentRef={(inst) => this.elementFormRef = inst}
+      //     />
+      //   </Modal>
+      // </div>
+    )
+  }
+}
+
+export default CardBoxComponent
\ No newline at end of file
diff --git a/src/menu/components/card/cardcomponent/index.scss b/src/menu/components/card/cardcomponent/index.scss
new file mode 100644
index 0000000..b5adb09
--- /dev/null
+++ b/src/menu/components/card/cardcomponent/index.scss
@@ -0,0 +1,25 @@
+.model-menu-card-cell-list {
+  position: relative;
+  .ant-form-item-label {
+    .anticon-question-circle {
+      color: #c49f47;
+      position: absolute;
+      left: 5px;
+      top: 5px;
+    }
+  }
+
+  .card-detail-row > .anticon-plus {
+    color: #26C281;
+    font-size: 16px;
+    padding: 5px;
+    cursor: pointer;
+  }
+
+  .card-cell:hover {
+    box-shadow: 0px 0px 1px #d8d8d8;
+  }
+  .ant-slider {
+    margin: 0px;
+  }
+}
diff --git a/src/menu/components/card/cardcomponent/settingform/index.jsx b/src/menu/components/card/cardcomponent/settingform/index.jsx
new file mode 100644
index 0000000..ea5a9c6
--- /dev/null
+++ b/src/menu/components/card/cardcomponent/settingform/index.jsx
@@ -0,0 +1,404 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { fromJS } from 'immutable'
+import { Form, Row, Col, Input, Select, Icon, Radio, Tooltip, InputNumber, notification } from 'antd'
+
+import { formRule } from '@/utils/option.js'
+import FileUpload from '@/tabviews/zshare/fileupload'
+import ColorSketch from '@/mob/colorsketch'
+import './index.scss'
+
+const cardTypeOptions = {
+  text: ['eleType', 'datatype', 'value', 'format', 'fontSize', 'fontWeight', 'width', 'height', 'color', 'align', 'padding', 'prefix', 'postfix'],
+  number: ['eleType', 'datatype', 'value', 'format', 'fontSize', 'fontWeight', 'width', 'height', 'color', 'align', 'padding', 'prefix', 'postfix'],
+  picture: ['eleType', 'datatype', 'width', 'lenWidRadio', 'radius', 'padding', 'url'],
+  icon: ['eleType', 'icon', 'fontSize', 'width', 'height', 'color', 'align', 'padding', 'tooltip'],
+  link: ['eleType', 'datatype', 'value', 'labelfield', 'fontSize', 'width', 'height', 'color', 'align', 'padding', 'prefix'],
+  slider: ['eleType', 'field', 'width', 'color', 'padding', 'maxValue'],
+  splitline: ['eleType', 'color', 'width', 'padding'],
+}
+
+class MainSearch extends Component {
+  static propTpyes = {
+    dict: PropTypes.object,      // 瀛楀吀椤�
+    config: PropTypes.object,    // 缁勪欢淇℃伅
+    formlist: PropTypes.any,     // 琛ㄥ崟淇℃伅
+    card: PropTypes.any,         // 鎸夐挳淇℃伅
+    inputSubmit: PropTypes.any   // 鍥炶溅鎻愪氦浜嬩欢
+  }
+
+  state = {
+    formlist: null,  // 琛ㄥ崟淇℃伅
+    eleType: '',
+    datatype: ''
+  }
+
+  
+  UNSAFE_componentWillMount () {
+    const { card, config } = this.props
+
+    let _options = this.getOptions(card.eleType, card.datatype)
+
+    this.setState({
+      eleType: card.eleType,
+      datatype: card.datatype,
+      formlist: this.props.formlist.map(item => {
+        item.hidden = !_options.includes(item.key)
+
+        if (item.key === 'field') {
+          item.options = []
+          config.columns.forEach(col => {
+            if (!/^Nvarchar/ig.test(col.datatype) && (card.eleType === 'number' || card.eleType === 'slider')) {
+              item.options.push({
+                value: col.field,
+                text: col.label
+              })
+            } else if (/^Nvarchar/ig.test(col.datatype) && card.eleType !== 'number' && card.eleType !== 'slider') {
+              item.options.push({
+                value: col.field,
+                text: col.label
+              })
+            }
+          })
+        } else if (item.key === 'labelfield') {
+          item.options = []
+          config.columns.forEach(col => {
+            if (/^Nvarchar/ig.test(col.datatype)) {
+              item.options.push({
+                value: col.field,
+                text: col.label
+              })
+            }
+          })
+        }
+
+        return item
+      })
+    })
+  }
+
+  getOptions = (eleType, datatype) => {
+    let _options = fromJS(cardTypeOptions[eleType]).toJS() // 閫夐」鍒楄〃
+    
+    if (['text', 'number', 'picture', 'link'].includes(eleType)) {
+      if (datatype === 'dynamic') {
+        _options.push('field')
+      }
+    }
+
+    return _options
+  }
+
+  /**
+   * @description 涓嬫媺鍒囨崲
+   * 1銆佹墦寮�鏂瑰紡鍒囨崲锛岄噸缃彲瑙佽〃鍗曞拰琛ㄥ崟鍊�
+   * 2銆佹樉绀轰綅缃垏鎹紝閲嶇疆閫夋嫨琛�
+   * 3銆佸垏鎹㈡爣绛剧被鍨嬶紝閲嶇疆鍙�夋爣绛�
+   */
+  selectChange = (key, value, option) => {
+    const { config } = this.props
+    const { datatype } = this.state
+
+    if (key === 'eleType') {
+      let _options = this.getOptions(value, datatype)
+      
+      let _formlist = this.state.formlist.map(item => {
+        item.hidden = !_options.includes(item.key)
+
+        if (item.key === 'field') {
+          item.options = []
+          config.columns.forEach(col => {
+            if (!/^Nvarchar/ig.test(col.datatype) && (value === 'number' || value === 'slider')) {
+              item.options.push({
+                value: col.field,
+                text: col.label
+              })
+            } else if (/^Nvarchar/ig.test(col.datatype) && value !== 'number' && value !== 'slider') {
+              item.options.push({
+                value: col.field,
+                text: col.label
+              })
+            }
+          })
+        }
+
+        return item
+      })
+
+      this.setState({
+        eleType: value,
+        formlist: _formlist
+      }, () => {
+        if (value === 'slider') {
+          this.props.form.setFieldsValue({width: 24, color: '#1890ff'})
+        } else if (value === 'splitline') {
+          this.props.form.setFieldsValue({width: 24, color: '#e8e8e8'})
+        }
+      })
+    } else if (key === 'field') {
+      if (this.props.form.getFieldValue('value') !== undefined) {
+        this.props.form.setFieldsValue({value: option.props.title})
+      }
+    }
+  }
+
+  onChange = (e, key) => {
+    const { eleType } = this.state
+    let value = e.target.value
+
+    if (key === 'datatype') {
+      let _options = this.getOptions(eleType, value)
+
+      this.setState({
+        datatype: value,
+        formlist: this.state.formlist.map(item => {
+          item.hidden = !_options.includes(item.key)
+
+          return item
+        })
+      })
+    }
+  }
+
+  handleSubmit = (e) => {
+    e.preventDefault()
+
+    if (this.props.inputSubmit) {
+      this.props.inputSubmit()
+    }
+  }
+
+  getFields() {
+    const { getFieldDecorator } = this.props.form
+    const fields = []
+
+    this.state.formlist.forEach((item, index) => {
+      if (item.hidden) return
+
+      if (item.type === 'text') { // 鏂囨湰鎼滅储
+        let rules = []
+
+        if (item.key === 'padding') {
+          rules = [{
+            pattern: /^\d+px$|^\d+px\s\d+px$|^\d+px\s\d+px\s\d+px$|^\d+px\s\d+px\s\d+px\s\d+px$/ig,
+            message: '璇锋纭緭鍏ュ唴杈硅窛锛�'
+          }]
+        }
+
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal || '',
+                rules: [
+                  {
+                    required: item.readonly ? false : !!item.required,
+                    message: this.props.dict['form.required.input'] + item.label + '!'
+                  },
+                  {
+                    max: formRule.input.max,
+                    message: formRule.input.message
+                  },
+                  ...rules
+                ]
+              })(<Input placeholder="" autoComplete="off" disabled={item.readonly} onPressEnter={this.handleSubmit} />)}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'number') {
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal,
+                rules: [
+                  {
+                    required: item.readonly ? false : !!item.required,
+                    message: this.props.dict['form.required.input'] + item.label + '!'
+                  }
+                ]
+              })(<InputNumber min={item.min || 0} max={item.max || 10000} precision={item.precision || 0} />)}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'select') { // 涓嬫媺鎼滅储
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.tooltip ?
+              <Tooltip placement="topLeft" overlayClassName={item.tooltipClass} title={item.tooltip}>
+                <Icon type="question-circle" />
+                {item.label}
+              </Tooltip> : item.label
+            }>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal || '',
+                rules: [
+                  {
+                    required: !!item.required,
+                    message: this.props.dict['form.required.select'] + item.label + '!'
+                  }
+                ]
+              })(
+                <Select
+                  showSearch
+                  filterOption={(input, option) => option.props.children[2].toLowerCase().indexOf(input.toLowerCase()) >= 0}
+                  onChange={(value, option) => {this.selectChange(item.key, value, option)}}
+                  getPopupContainer={() => document.getElementById('card-winter')}
+                >
+                  {item.options.map((option, index) =>
+                    <Select.Option id={`${index}`} title={option.text} key={`${index}`} value={option.value}>
+                      {item.key === 'icon' && option.value && <Icon type={option.value} />} {option.text}
+                    </Select.Option>
+                  )}
+                </Select>
+              )}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'radio') {
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.label}>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal,
+                rules: [
+                  {
+                    required: !!item.required,
+                    message: this.props.dict['form.required.select'] + item.label + '!'
+                  }
+                ]
+              })(
+                <Radio.Group onChange={(e) => {this.onChange(e, item.key)}} disabled={item.readonly}>
+                  {
+                    item.options.map(option => {
+                      return (
+                        <Radio key={option.value} value={option.value}>{option.text}</Radio>
+                      )
+                    })
+                  }
+                </Radio.Group>
+              )}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'color') {
+        fields.push(
+          <Col span={12} key={index} className="color-form">
+            <Form.Item label={item.label}>
+              {getFieldDecorator(item.key, {
+                initialValue: item.initVal,
+                rules: [
+                  {
+                    required: !!item.required,
+                    message: this.props.dict['form.required.select'] + item.label + '!'
+                  }
+                ]
+              })(
+                <ColorSketch />
+              )}
+            </Form.Item>
+          </Col>
+        )
+      } else if (item.type === 'file') {
+        let filelist = []
+        if (item.initVal) {
+          filelist = [{
+            uid: `1`,
+            name: item.initVal.slice(item.initVal.lastIndexOf('/') + 1),
+            status: 'done',
+            url: item.initVal,
+            origin: true
+          }]
+        }
+
+        fields.push(
+          <Col span={12} key={index}>
+            <Form.Item label={item.label}>
+              {getFieldDecorator(item.key, {
+                initialValue: filelist,
+                rules: [
+                  {
+                    required: !!item.required,
+                    message: this.props.dict['form.required.select'] + item.label + '!'
+                  }
+                ]
+              })(
+                <FileUpload maxFile={item.maxfile} fileType={'text'} />
+              )}
+            </Form.Item>
+          </Col>
+        )
+      }
+    })
+    return fields
+  }
+
+  handleConfirm = () => {
+    // 琛ㄥ崟鎻愪氦鏃舵鏌ヨ緭鍏ュ�兼槸鍚︽纭�
+    return new Promise((resolve, reject) => {
+      this.props.form.validateFieldsAndScroll((err, values) => {
+        if (!err) {
+          values.uuid = this.props.card.uuid
+          values.marks = this.props.card.marks || null
+
+          if (values.url) {
+            if (values.url.length > 0) {
+              if (values.url[0].origin && values.url[0].url) {
+                values.url = values.url[0].url
+              } else if (!values.url[0].origin && values.url[0].status === 'done' && values.url[0].response) {
+                values.url = values.url[0].response
+              } else {
+                values.url = ''
+              }
+            } else {
+              values.url = ''
+            }
+          }
+
+          if (values.eleType === 'picture' && values.datatype === 'static' && !values.url) {
+            notification.warning({
+              top: 92,
+              message: '灏氭湭娣诲姞鍥剧墖鎴栧浘鐗囦笂浼犲け璐ワ紝璇烽噸鏂版坊鍔狅紒',
+              duration: 5
+            })
+            return
+          }
+
+          resolve(values)
+        } else {
+          reject(err)
+        }
+      })
+    })
+  }
+
+  render() {
+    const formItemLayout = {
+      labelCol: {
+        xs: { span: 24 },
+        sm: { span: 7 }
+      },
+      wrapperCol: {
+        xs: { span: 24 },
+        sm: { span: 17 }
+      }
+    }
+    return (
+      <Form {...formItemLayout} className="menu-card-detail-form" id="card-winter">
+        <Row gutter={24}>{this.getFields()}</Row>
+      </Form>
+    )
+  }
+}
+
+export default Form.create()(MainSearch)
\ No newline at end of file
diff --git a/src/menu/components/card/cardcomponent/settingform/index.scss b/src/menu/components/card/cardcomponent/settingform/index.scss
new file mode 100644
index 0000000..166f28c
--- /dev/null
+++ b/src/menu/components/card/cardcomponent/settingform/index.scss
@@ -0,0 +1,24 @@
+.menu-card-detail-form {
+  min-height: 190px;
+
+  .ant-input-number {
+    width: 100%;
+  }
+  .ant-form-item-label {
+    .anticon-question-circle {
+      color: #c49f47;
+      margin-right: 5px;
+    }
+  }
+  .ant-col {
+    height: 65px;
+  }
+  .color-form {
+    .ant-form-item-control {
+      .color-sketch-block {
+        position: relative;
+        top: 7px;
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/menu/components/card/data-card/index.jsx b/src/menu/components/card/data-card/index.jsx
index fa7ef3e..2e9670f 100644
--- a/src/menu/components/card/data-card/index.jsx
+++ b/src/menu/components/card/data-card/index.jsx
@@ -2,7 +2,7 @@
 import PropTypes from 'prop-types'
 import {connect} from 'react-redux'
 import { is, fromJS } from 'immutable'
-import { Icon, Popover, Switch } from 'antd'
+import { Icon, Popover } from 'antd'
 
 import asyncComponent from '@/utils/asyncComponent'
 import asyncIconComponent from '@/utils/asyncIconComponent'
@@ -15,8 +15,7 @@
 
 const SettingComponent = asyncIconComponent(() => import('@/menu/datasource'))
 const WrapComponent = asyncIconComponent(() => import('./wrapsetting'))
-// const ActionComponent = asyncComponent(() => import('@/menu/actioncomponent'))
-const CardCellComponent = asyncComponent(() => import('../cardcellcomponent'))
+const CardComponent = asyncComponent(() => import('../cardcomponent'))
 
 class antvBarLineChart extends Component {
   static propTpyes = {
@@ -60,12 +59,17 @@
         name: card.name,
         subtype: card.subtype,
         setting: { interType: 'system' },
-        wrap: { name: card.name, width: 24, cardWidth: 6, addable: 'false', switch: 'false' },
+        wrap: { name: card.name, width: 24, addable: 'false', switch: 'false' },
         style: { marginLeft: '8px', marginRight: '8px', marginTop: '8px', marginBottom: '8px' },
         columns: [],
         scripts: [],
         // action: [],
-        elements: []
+        subcards: [{
+          uuid: Utils.getuuid(),
+          setting: { width: 6 },
+          elements: [],
+          backElements: []
+        }]
       }
       this.setState({
         card: _card
@@ -107,56 +111,7 @@
     this.props.updateConfig(component)
   }
 
-  addElement = () => {
-    const { card } = this.state
-
-    let newcard = {}
-    newcard.uuid = Utils.getuuid()
-    newcard.focus = true
-    
-    newcard.eleType = 'text'
-    newcard.datatype = 'dynamic'
-    newcard.color = 'rgba(0,0,0,0.85)'
-    newcard.padding = '5px'
-    newcard.align = 'left'
-
-    // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
-    MKEmitter.emit('cardAddElement', card.uuid, newcard)
-  }
-
-  addButton = () => {
-    const { card } = this.state
-
-    let newcard = {}
-    newcard.uuid = Utils.getuuid()
-    newcard.focus = true
-    
-    newcard.label = 'button'
-    newcard.sqlType = ''
-    newcard.Ot = 'requiredSgl'
-    newcard.OpenType = 'prompt'
-    newcard.icon = ''
-    newcard.class = 'default'
-    newcard.intertype = 'system'
-    newcard.method = 'POST'
-    newcard.execSuccess = 'grid'
-    newcard.execError = 'never'
-    newcard.popClose = 'never'
-    newcard.errorTime = 10
-    newcard.verify = null
-    newcard.show = 'link'
-
-    // 娉ㄥ唽浜嬩欢-娣诲姞鍏冪礌
-    MKEmitter.emit('addButton', card.uuid, newcard)
-  }
-
   changeStyle = () => {
-    const { card } = this.state
-
-    MKEmitter.emit('changeStyle', [card.uuid], ['font', 'background', 'border'], {})
-  }
-
-  changeOutStyle = () => {
     const { card } = this.state
 
     MKEmitter.emit('changeStyle', [card.uuid], ['background', 'border', 'padding', 'margin'], card.style)
@@ -165,16 +120,12 @@
   getStyle = (comIds, style) => {
     const { card } = this.state
 
-    if (comIds[0] !== card.uuid) return
+    if (comIds.length > 1 || comIds[0] !== card.uuid) return
 
     this.setState({
       card: {...card, style}
     })
     console.log(style)
-  }
-
-  changeSide = () => {
-    this.setState(prev => ({ back: !prev.back }))
   }
 
   render() {
@@ -185,29 +136,14 @@
         <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
           <div className="mk-popover-control">
             <WrapComponent config={card} updateConfig={this.updateComponent} />
-            <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeOutStyle} type="font-colors" />
+            <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
             <Icon className="close" title="delete" type="delete" onClick={() => this.props.deletecomponent(card.uuid)} />
             <SettingComponent config={card} updateConfig={this.updateComponent} />
           </div>
         } trigger="hover">
           <Icon type="tool" />
         </Popover>
-        <div className={'ant-col card-item ant-col-' + (card.wrap.cardWidth || 6)} style={{height: card.wrap.height ? card.wrap.height + 'px' : 'auto'}}>
-          <CardCellComponent config={card} updateElement={this.updateComponent}/>
-          {/* <ActionComponent plus="false" config={card} updateaction={this.updateComponent}/> */}
-          <div className="card-control">
-            <Popover overlayClassName="mk-popover-control-wrap" mouseLeaveDelay={0.2} mouseEnterDelay={0.2} content={
-              <div className="mk-popover-control">
-                <Icon className="plus" title="娣诲姞鍏冪礌" onClick={this.addElement} type="plus" />
-                <Icon className="plus" title="娣诲姞鎸夐挳" onClick={this.addButton} type="plus-square" />
-                <Icon className="style" title="璋冩暣鏍峰紡" onClick={this.changeStyle} type="font-colors" />
-                <Switch size="small" onClick={this.changeSide} defaultChecked />
-              </div>
-            } trigger="hover">
-              <Icon type="tool" />
-            </Popover>
-          </div>
-        </div>
+        {card.subcards.map(subcard => (<CardComponent key={subcard.uuid} config={card} card={subcard} updateElement={this.updateComponent}/>))}
         {card.wrap.addable === 'true' ? <div className="card-add-button"><Icon type="plus" /></div> : null}
       </div>
     )
diff --git a/src/menu/stylecontroller/index.jsx b/src/menu/stylecontroller/index.jsx
index 82cbd05..bd24434 100644
--- a/src/menu/stylecontroller/index.jsx
+++ b/src/menu/stylecontroller/index.jsx
@@ -7,6 +7,7 @@
 import zhCN from '@/locales/zh-CN/mob.js'
 import enUS from '@/locales/en-US/mob.js'
 import ColorSketch from '@/mob/colorsketch'
+import StyleInput from './styleInput'
 import FileUpload from '@/tabviews/zshare/fileupload'
 import './index.scss'
 
@@ -23,7 +24,6 @@
     dict: localStorage.getItem('lang') !== 'en-US' ? zhCN : enUS,
     card: null,
     comIds: [],
-    fontColor: '#000000',
     bgimages: [],
     backgroundImage: '',
     options: [],
@@ -135,19 +135,7 @@
    * @description 淇敼瀛椾綋棰滆壊 锛岄鑹叉帶浠�
    */
   changeFontColor = (val) => {
-    this.setState({
-      fontColor: val
-    })
     this.updateStyle({color: val})
-  }
-
-  /**
-   * @description 淇敼瀛椾綋棰滆壊 锛屾墜鍔ㄨ緭鍏�
-   */
-  changeFontColorInput = (e) => {
-    this.setState({
-      fontColor: e.target.value
-    })
   }
 
   /**
@@ -211,19 +199,12 @@
     this.updateStyle({border: border})
   }
 
-  changeBorderRadius = (e) => {
-    let val = e.target.value
+  changeBorderRadius = (val) => {
     this.updateStyle({borderRadius: val})
   }
 
   changeMarginOrPadding = (val, type) => {
-    val = parseInt(val)
-
-    if (isNaN(val)) {
-      val = 0
-    }
-
-    this.updateStyle({[type]: `${val}px`})
+    this.updateStyle({[type]: val})
   }
 
   render () {
@@ -243,7 +224,7 @@
       <Drawer
         title={
           <div className="header-logo">
-            <img src="http://cloud.mk9h.cn/Content/images/upload/2020-03-26/2020032615132185788026_xiazai.png" alt=""/>
+            <img src={window.GLOB.mainlogo} alt=""/>
           </div>
         }
         placement="left"
@@ -284,12 +265,12 @@
                 </Col>
                 <Col span={12}>
                   <Form.Item colon={false} label={<Icon title="琛岄棿璺�" type="line-height" />}>
-                    <InputNumber defaultValue={card.lineHeight || 1.5} min={1} max={10} precision={1} onChange={this.changeLineHeight} />
+                    <InputNumber defaultValue={card.lineHeight} 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 || 0} min={0} max={100} precision={0} onChange={this.changeLetterSpacing}/>
+                    <InputNumber defaultValue={card.letterSpacing} min={0} max={100} precision={0} onChange={this.changeLetterSpacing}/>
                   </Form.Item>
                 </Col>
                 <Col span={24}>
@@ -298,7 +279,7 @@
                     label={<Icon title="瀛椾綋棰滆壊" type="font-colors" />}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <ColorSketch value={card.color || '#000000'} onChange={this.changeFontColor} />
+                    <ColorSketch value={card.color || 'rgba(0, 0, 0, 0.85)'} onChange={this.changeFontColor} />
                   </Form.Item>
                 </Col>
                 <Col span={24}>
@@ -379,13 +360,7 @@
                     label={<Icon title="鍦嗚" type="radius-setting" />}
                     labelCol={{xs: { span: 24 }, sm: { span: 4 }}} wrapperCol={ {xs: { span: 24 }, sm: { span: 20 }} }
                   >
-                    <Radio.Group onChange={this.changeBorderRadius} defaultValue={card.borderRadius || ''}>
-                      <Radio value="0px">鏃�</Radio>
-                      <Radio value="2px">2px</Radio>
-                      <Radio value="4px">4px</Radio>
-                      <Radio value="25%">25%</Radio>
-                      <Radio value="50%">50%</Radio>
-                    </Radio.Group>
+                    <StyleInput defaultValue={card.borderRadius || ''} width={210} options={['px', '%']} onChange={this.changeBorderRadius}/>
                   </Form.Item>
                 </Col>
               </Panel> : null}
@@ -395,7 +370,7 @@
                     colon={false}
                     label={<Icon title="涓婅竟璺�" type="arrow-up"/>}
                   >
-                    <InputNumber defaultValue={card.marginTop || 0} min={0} max={1000} precision={0} onChange={(val) => this.changeMarginOrPadding(val, 'marginTop')}/>
+                    <StyleInput defaultValue={card.marginTop} width={80} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'marginTop')}/>
                   </Form.Item>
                 </Col>
                 <Col span={12}>
@@ -403,7 +378,7 @@
                     colon={false}
                     label={<Icon title="涓嬭竟璺�" type="arrow-down"/>}
                   >
-                    <InputNumber defaultValue={card.marginBottom || 0} min={0} max={1000} precision={0} onChange={(val) => this.changeMarginOrPadding(val, 'marginBottom')}/>
+                    <StyleInput defaultValue={card.marginBottom} width={80} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'marginBottom')}/>
                   </Form.Item>
                 </Col>
                 <Col span={12}>
@@ -411,7 +386,7 @@
                     colon={false}
                     label={<Icon title="宸﹁竟璺�" type="arrow-left"/>}
                   >
-                    <InputNumber defaultValue={card.marginLeft || 0} min={0} max={1000} precision={0} onChange={(val) => this.changeMarginOrPadding(val, 'marginLeft')}/>
+                    <StyleInput defaultValue={card.marginLeft} width={80} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'marginLeft')}/>
                   </Form.Item>
                 </Col>
                 <Col span={12}>
@@ -419,7 +394,7 @@
                     colon={false}
                     label={<Icon title="鍙宠竟璺�" type="arrow-right"/>}
                   >
-                    <InputNumber defaultValue={card.marginRight || 0} min={0} max={1000} precision={0} onChange={(val) => this.changeMarginOrPadding(val, 'marginRight')}/>
+                    <StyleInput defaultValue={card.marginRight} width={80} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'marginRight')}/>
                   </Form.Item>
                 </Col>
               </Panel> : null}
@@ -429,7 +404,7 @@
                     colon={false}
                     label={<Icon title="涓婅竟璺�" type="arrow-up"/>}
                   >
-                    <InputNumber defaultValue={card.paddingTop || 0} min={0} max={1000} precision={0} onChange={(val) => this.changeMarginOrPadding(val, 'paddingTop')}/>
+                    <StyleInput defaultValue={card.paddingTop} width={80} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'paddingTop')}/>
                   </Form.Item>
                 </Col>
                 <Col span={12}>
@@ -437,7 +412,7 @@
                     colon={false}
                     label={<Icon title="涓嬭竟璺�" type="arrow-down"/>}
                   >
-                    <InputNumber defaultValue={card.paddingBottom || 0} min={0} max={1000} precision={0} onChange={(val) => this.changeMarginOrPadding(val, 'paddingBottom')}/>
+                    <StyleInput defaultValue={card.paddingBottom} width={80} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'paddingBottom')}/>
                   </Form.Item>
                 </Col>
                 <Col span={12}>
@@ -445,7 +420,7 @@
                     colon={false}
                     label={<Icon title="宸﹁竟璺�" type="arrow-left"/>}
                   >
-                    <InputNumber defaultValue={card.paddingLeft || 0} min={0} max={1000} precision={0} onChange={(val) => this.changeMarginOrPadding(val, 'paddingLeft')}/>
+                    <StyleInput defaultValue={card.paddingLeft} width={80} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'paddingLeft')}/>
                   </Form.Item>
                 </Col>
                 <Col span={12}>
@@ -453,7 +428,7 @@
                     colon={false}
                     label={<Icon title="鍙宠竟璺�" type="arrow-right"/>}
                   >
-                    <InputNumber defaultValue={card.paddingRight || 0} min={0} max={1000} precision={0} onChange={(val) => this.changeMarginOrPadding(val, 'paddingRight')}/>
+                    <StyleInput defaultValue={card.paddingRight} width={80} options={['px', 'vh', 'vw']} onChange={(val) => this.changeMarginOrPadding(val, 'paddingRight')}/>
                   </Form.Item>
                 </Col>
               </Panel> : null}
diff --git a/src/menu/stylecontroller/styleInput/index.jsx b/src/menu/stylecontroller/styleInput/index.jsx
new file mode 100644
index 0000000..d2b2523
--- /dev/null
+++ b/src/menu/stylecontroller/styleInput/index.jsx
@@ -0,0 +1,118 @@
+import React, {Component} from 'react'
+import PropTypes from 'prop-types'
+import { is, fromJS } from 'immutable'
+import { Menu, Popover, Input } from 'antd'
+
+import './index.scss'
+
+class StyleInput extends Component {
+  static propTpyes = {
+    defaultValue: PropTypes.any,
+    options: PropTypes.any,
+    value: PropTypes.any,
+    onChange: PropTypes.func,
+  }
+
+  state = {
+    value: '',
+    parseVal: '',
+    width: '',
+    options: null
+  }
+
+  UNSAFE_componentWillMount () {
+    const { defaultValue, value, options } = this.props
+    let val = ''
+    let _options = ['px']
+
+    if (value !== undefined) {
+      val = value
+    } else if (defaultValue !== undefined) {
+      val = defaultValue
+    }
+
+    if (options && options.length > 0) {
+      _options = options
+    }
+
+    let _val = parseInt(val)
+
+    if (isNaN(_val)) {
+      _val = ''
+    }
+
+    this.setState({value: val, options: _options, parseVal: _val})
+  }
+
+  shouldComponentUpdate (nextProps, nextState) {
+    return !is(fromJS(this.state), fromJS(nextState))
+  }
+
+  UNSAFE_componentWillReceiveProps(nextProps) {
+    if (nextProps.value !== undefined && nextProps.value !== this.state.value) {
+      this.setState({ value: nextProps.value })
+    }
+  }
+
+  componentDidMount () {
+    this.setState({width: (this.input.offsetWidth - 10) + 'px'})
+  }
+
+  /**
+   * @description 缁勪欢閿�姣侊紝娓呴櫎state鏇存柊锛屾竻闄ゅ揩鎹烽敭璁剧疆
+   */
+  componentWillUnmount () {
+    this.setState = () => {
+      return
+    }
+  }
+
+  changeValue = (e) => {
+    let val = e.target.value
+    let _val = parseInt(val)
+
+    if (isNaN(_val)) {
+      _val = ''
+    }
+
+    this.setState({
+      value: val,
+      parseVal: _val
+    })
+
+    if (!val && this.props.onChange) {
+      this.props.onChange('0px')
+    }
+  }
+
+  submitValue = (val) => {
+    this.setState({
+      value: val
+    })
+
+    if (this.props.onChange) {
+      this.props.onChange(val)
+    }
+  }
+
+  render () {
+    const { value, options, parseVal, width } = this.state
+
+    return (
+      <Popover placement="bottom" overlayClassName="style-input-popover" content={
+        parseVal !== '' ?
+        <Menu>
+          {options.map(option => (
+            <Menu.Item key={option} style={{width: width}} onClick={() => this.submitValue(`${parseVal}${option}`)}>{parseVal} {option}</Menu.Item>
+          ))}
+        </Menu> : null
+      } trigger="click">
+        <div ref={dom => { this.input = dom }} style={{lineHeight: '32px'}}>
+          <Input value={value} onChange={this.changeValue}/>
+        </div>
+      </Popover>
+    )
+  }
+}
+
+export default StyleInput
\ No newline at end of file
diff --git a/src/menu/stylecontroller/styleInput/index.scss b/src/menu/stylecontroller/styleInput/index.scss
new file mode 100644
index 0000000..68798d5
--- /dev/null
+++ b/src/menu/stylecontroller/styleInput/index.scss
@@ -0,0 +1,44 @@
+.style-input-popover {
+  padding-top: 0px;
+  z-index: 1090!important;
+  .ant-popover-inner-content {
+    padding: 0px 5px;
+    .ant-menu-root.ant-menu-vertical {
+      border: 0;
+      .ant-menu-item {
+        height: 30px;
+        cursor: pointer;
+        line-height: 30px;
+      }
+      .ant-menu-item:not(:last-child) {
+        margin-bottom: 0px;
+      }
+      .ant-menu-item:first-child {
+        margin-top: 10px;
+      }
+      .ant-menu-item:last-child {
+        margin-bottom: 10px;
+      }
+    }
+  }
+  .ant-popover-arrow {
+    display: none;
+  }
+  .ant-popover-content::before {
+    content: ' ';
+    position: absolute;
+    width: 100%;
+    height: 5px;
+    top: -5px;
+  }
+  .ant-popover-content::after {
+    content: ' ';
+    position: absolute;
+    width: 100%;
+    height: 5px;
+    bottom: -5px;
+  }
+}
+.style-input-popover.ant-popover-placement-top {
+  padding-bottom: 0px;
+}
diff --git a/src/mob/colorsketch/index.jsx b/src/mob/colorsketch/index.jsx
index 42744cb..4f588d8 100644
--- a/src/mob/colorsketch/index.jsx
+++ b/src/mob/colorsketch/index.jsx
@@ -31,7 +31,7 @@
   }
 
   UNSAFE_componentWillReceiveProps(nextProps) {
-    if (nextProps.value && nextProps.value !== this.state.color) {
+    if (nextProps.value !== undefined && nextProps.value !== this.state.color) {
       this.setState({ color: nextProps.value })
     }
   }

--
Gitblit v1.8.0