Commit e5aefaf7573588d092027d4ed287721035599f39

Authored by ly525
1 parent f6ceeddd

feat(plugin): support form input

front-end/h5/src/components/core/editor/canvas/edit.js
... ... @@ -167,7 +167,7 @@ export default {
167 167 // 添加 class 的原因:与 handleClickCanvasProp 配合,
168 168 // 当点击编辑画布上的其它区域(clickEvent.target.classList 不包含下面的 className)的时候,设置 editingElement=null
169 169 class: 'element-on-edit-canvas',
170   - props: element.pluginProps, // #6 #3
  170 + props: element.getProps(), // #6 #3
171 171 on: {
172 172 // 高亮当前点击的元素
173 173 // click: () => this.setEditingElement(element)
... ... @@ -180,7 +180,7 @@ export default {
180 180 }
181 181 return (
182 182 <Shape
183   - style={element.getStyle('absolute')}
  183 + style={element.getStyle({ position: 'absolute' })}
184 184 defaultPosition={element.commonStyle}
185 185 element={element}
186 186 active={this.editingElement === element}
... ...
front-end/h5/src/components/core/editor/canvas/preview.js
... ... @@ -15,10 +15,10 @@ export default {
15 15 * -> renderBaseElementWithEvent()
16 16 * -> renderBaseElementWithCustomStyle()
17 17 */
18   - const style = element.getStyle('absolute'/** position */)
  18 + const style = element.getStyle({ position: 'absolute' })
19 19 const data = {
20 20 style,
21   - props: element.pluginProps
  21 + props: element.getProps({ mode: 'preview' })
22 22 }
23 23 return h(element.name, data)
24 24 })
... ...
front-end/h5/src/components/core/models/element.js
... ... @@ -56,7 +56,7 @@ class Element {
56 56 return pluginProps
57 57 }
58 58  
59   - getStyle (position = 'static') {
  59 + getStyle ({ position = 'static' }) {
60 60 const pluginProps = this.pluginProps
61 61 const commonStyle = this.commonStyle
62 62 let style = {
... ... @@ -73,6 +73,13 @@ class Element {
73 73 return style
74 74 }
75 75  
  76 + getProps ({ mode = 'edit' } = {}) {
  77 + return {
  78 + ...this.pluginProps,
  79 + disabled: this.name === 'lbp-form-input' && mode === 'edit'
  80 + }
  81 + }
  82 +
76 83 getClass () {
77 84  
78 85 }
... ...
front-end/h5/src/components/plugins/lbp-form-input.js 0 → 100644
  1 +export default {
  2 + name: 'lbp-form-input',
  3 + render (h) {
  4 + const style = {
  5 + color: this.color,
  6 + textAlign: this.textAlign,
  7 + backgroundColor: this.backgroundColor,
  8 + fontSize: this.fontSize + 'px',
  9 + lineHeight: this.lineHeight + 'em',
  10 + borderColor: this.borderColor,
  11 + borderRadius: this.borderRadius + 'px',
  12 + borderWidth: this.borderWidth + 'px',
  13 + padding: '0 5px'
  14 + }
  15 + return <input
  16 + disabled={this.disabled}
  17 + type={this.type}
  18 + style={style}
  19 + name={this.name}
  20 + placeholder={this.placeholder}
  21 + autocomplete="off"
  22 + data-type="form-input"
  23 + />
  24 + },
  25 + props: {
  26 + name: {
  27 + type: String,
  28 + default () {
  29 + return 'name'
  30 + }
  31 + },
  32 + type: {
  33 + type: String,
  34 + default: 'text'
  35 + },
  36 + placeholder: {
  37 + type: String,
  38 + default: '请填写提示文字'
  39 + },
  40 + required: {
  41 + type: Boolean,
  42 + default: false
  43 + },
  44 + disabled: {
  45 + type: Boolean,
  46 + default: false
  47 + },
  48 + backgroundColor: {
  49 + type: String,
  50 + default: 'transparent'
  51 + },
  52 + color: {
  53 + type: String,
  54 + default: 'black'
  55 + },
  56 + fontSize: {
  57 + type: Number,
  58 + default: 14
  59 + },
  60 + lineHeight: {
  61 + type: Number,
  62 + default: 1
  63 + },
  64 + borderWidth: {
  65 + type: Number,
  66 + default: 1
  67 + },
  68 + borderRadius: {
  69 + type: Number,
  70 + default: 0
  71 + },
  72 + borderColor: {
  73 + type: String,
  74 + default: '#ced4da'
  75 + },
  76 + textAlign: {
  77 + type: String,
  78 + default: 'left'
  79 + }
  80 + },
  81 + editorConfig: {
  82 + propsConfig: {
  83 + type: {
  84 + type: 'lbs-select-input-type',
  85 + label: '类型',
  86 + defaultPropValue: 'text'
  87 + },
  88 + placeholder: {
  89 + type: 'a-input',
  90 + label: '提示文字',
  91 + require: true,
  92 + defaultPropValue: '请填写提示文字'
  93 + },
  94 + fontSize: {
  95 + type: 'a-input-number',
  96 + label: '字号(px)',
  97 + require: true,
  98 + prop: {
  99 + step: 1,
  100 + min: 12,
  101 + max: 144
  102 + },
  103 + defaultPropValue: 14
  104 + },
  105 + color: {
  106 + type: 'a-input',
  107 + label: '文字颜色',
  108 + // !#zh 为编辑组件指定 prop
  109 + prop: {
  110 + type: 'color'
  111 + },
  112 + require: true,
  113 + defaultPropValue: 'black'
  114 + },
  115 + backgroundColor: {
  116 + type: 'a-input', // lbs-color-picker
  117 + label: '背景颜色',
  118 + prop: {
  119 + type: 'color'
  120 + },
  121 + require: true,
  122 + defaultPropValue: '#ffffff' // TODO why logogram for color does't work?
  123 + },
  124 + borderColor: {
  125 + type: 'a-input', // lbs-color-picker
  126 + label: '边框颜色',
  127 + prop: {
  128 + type: 'color'
  129 + },
  130 + require: true,
  131 + defaultPropValue: '#eeeeee'
  132 + },
  133 + borderWidth: {
  134 + type: 'a-input-number',
  135 + label: '边框宽度(px)',
  136 + require: true,
  137 + prop: {
  138 + step: 1,
  139 + min: 1,
  140 + max: 10
  141 + },
  142 + defaultPropValue: 1
  143 + },
  144 + borderRadius: {
  145 + type: 'a-input-number',
  146 + label: '圆角(px)',
  147 + require: true,
  148 + prop: {
  149 + step: 0.1,
  150 + min: 0,
  151 + max: 10
  152 + },
  153 + defaultPropValue: 0
  154 + },
  155 + lineHeight: {
  156 + type: 'a-input-number',
  157 + label: '行高',
  158 + require: true,
  159 + prop: {
  160 + step: 0.1,
  161 + min: 0.1,
  162 + max: 10
  163 + },
  164 + defaultPropValue: 1
  165 + },
  166 + textAlign: {
  167 + type: 'lbs-text-align',
  168 + label: '文字对齐',
  169 + require: true,
  170 + defaultPropValue: 'left'
  171 + }
  172 + },
  173 + components: {
  174 + 'lbs-text-align': {
  175 + render (h) {
  176 + return (
  177 + <div class="wrap">
  178 + <a-radio-group value={this.value} onChange={value => {
  179 + this.$emit('change', value)
  180 + this.$emit('input', value)
  181 + }} size="small">
  182 + {
  183 + this.textAlignTabs.map(item => (
  184 + // <a-radio-button value={item.value} key={item.value}><i class={['fa', 'fa-align-' + item.value]} aria-hidden="true"></i></a-radio-button>
  185 + <a-tooltip effect="dark" placement="top" key={item.value} title={item.label}>
  186 + <a-radio-button value={item.value}>
  187 + <i class={['fa', 'fa-align-' + item.value]} aria-hidden="true"></i>
  188 + </a-radio-button>
  189 + </a-tooltip>
  190 + ))
  191 + }
  192 + </a-radio-group>
  193 + </div>
  194 + )
  195 + },
  196 + props: {
  197 + value: {
  198 + type: [String, Number]
  199 + }
  200 + },
  201 + data: () => ({
  202 + textAlignTabs: [{
  203 + label: '左对齐',
  204 + value: 'left'
  205 + },
  206 + {
  207 + label: '居中对齐',
  208 + value: 'center'
  209 + },
  210 + {
  211 + label: '右对齐',
  212 + value: 'right'
  213 + }]
  214 + })
  215 + },
  216 + 'lbs-select-input-type': {
  217 + props: ['value'],
  218 + computed: {
  219 + value_: {
  220 + get () {
  221 + return this.value
  222 + },
  223 + set (val) {
  224 + this.$emit('input', val)
  225 + }
  226 + }
  227 + },
  228 + render (h) {
  229 + return (
  230 + <a-select
  231 + placeholder="类型"
  232 + value={this.value}
  233 + onChange={(value) => {
  234 + this.$emit('input', value)
  235 + this.$emit('change', value)
  236 + }}
  237 + >
  238 + {
  239 + this.options.map(option => (
  240 + <a-select-option
  241 + key={option.value}
  242 + value={option.value}
  243 + >{option.label}</a-select-option>
  244 + ))
  245 + }
  246 + </a-select>
  247 + )
  248 + },
  249 + data: () => ({
  250 + options: [
  251 + {
  252 + label: '文字',
  253 + value: 'text'
  254 + },
  255 + {
  256 + label: '密码',
  257 + value: 'password'
  258 + },
  259 + {
  260 + label: '日期',
  261 + value: 'date'
  262 + },
  263 + {
  264 + label: '邮箱',
  265 + value: 'email'
  266 + },
  267 + {
  268 + label: '手机号',
  269 + value: 'tel'
  270 + }
  271 + ]
  272 + })
  273 + }
  274 + }
  275 + }
  276 +}
  277 +
  278 +// .lb-plugin__input {
  279 +// display: block;
  280 +// margin: 0;
  281 +// padding: 0 5px;
  282 +// box-sizing: border-box;
  283 +// overflow: visible;
  284 +// border: 1px solid #ced4da;
  285 +// &:focus {
  286 +// outline: none;
  287 +// }
  288 +// }
... ...
front-end/h5/src/views/Editor.vue
... ... @@ -5,6 +5,7 @@ import CoreEditor from &#39;../components/core/editor/index.js&#39;
5 5 import LbpButton from '../components/plugins/lbp-button'
6 6 import LbpPicture from '../components/plugins/lbp-picture'
7 7 import LbpText from '../components/plugins/lbp-text'
  8 +import LbpFormInput from '../components/plugins/lbp-form-input'
8 9  
9 10 const PluginList = [
10 11 {
... ... @@ -59,23 +60,32 @@ const PluginList = [
59 60 title: '表单',
60 61 icon: 'wpforms',
61 62 visible: true,
  63 + component: LbpFormInput,
  64 + name: 'lbp-form-input',
62 65 children: [
63 66 {
64   - title: '按钮',
  67 + title: '输入框',
65 68 icon: 'hand-pointer-o',
66   - component: LbpButton,
  69 + component: LbpFormInput,
67 70 visible: true,
68   - name: 'lbp-button'
  71 + name: 'lbp-form-input'
69 72 },
70   - {
71   - title: '图片',
72   - icon: 'image',
73   - component: LbpPicture,
74   - visible: true,
75   - name: 'lbp-picture'
76   - }
77 73 ]
78   - }
  74 + },
  75 + // {
  76 + // title: '表单2',
  77 + // icon: 'wpforms',
  78 + // visible: true,
  79 + // children: [
  80 + // {
  81 + // title: '输入框',
  82 + // icon: 'hand-pointer-o',
  83 + // component: LbpFormInput,
  84 + // visible: true,
  85 + // name: 'lbp-form-input'
  86 + // },
  87 + // ]
  88 + // }
79 89 ]
80 90  
81 91 export default {
... ...