@tagplus/components 1.0.8 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "email": "bruno@tagplus.com.br"
9
9
  }
10
10
  ],
11
- "version": "1.0.8",
11
+ "version": "1.2.0",
12
12
  "main": "./dist/tp.common.js",
13
13
  "directories": {
14
14
  "lib": "src/lib"
@@ -0,0 +1,232 @@
1
+ <template>
2
+ <transition
3
+ name="dialog-fade"
4
+ @after-enter="afterEnter"
5
+ @after-leave="afterLeave"
6
+ >
7
+ <div
8
+ v-show="visible"
9
+ class="el-dialog__wrapper"
10
+ @click.self="handleWrapperClick"
11
+ >
12
+ <div
13
+ :key="key"
14
+ ref="dialog"
15
+ role="dialog"
16
+ aria-modal="true"
17
+ :aria-label="title || 'dialog'"
18
+ :class="['el-dialog', { 'is-fullscreen': fullscreen, 'el-dialog--center': center }, customClass]"
19
+ :style="style"
20
+ >
21
+ <div class="el-dialog__header">
22
+ <slot name="title">
23
+ <span class="el-dialog__title">{{ title }}</span>
24
+ </slot>
25
+ <button
26
+ v-if="showClose"
27
+ type="button"
28
+ class="el-dialog__headerbtn"
29
+ aria-label="Close"
30
+ @click="handleClose"
31
+ >
32
+ <i class="el-dialog__close el-icon el-icon-close" />
33
+ </button>
34
+ </div>
35
+ <div
36
+ v-if="rendered"
37
+ class="el-dialog__body"
38
+ >
39
+ <slot />
40
+ </div>
41
+ <div
42
+ v-if="$slots.footer"
43
+ class="el-dialog__footer"
44
+ >
45
+ <slot name="footer" />
46
+ </div>
47
+ </div>
48
+ </div>
49
+ </transition>
50
+ </template>
51
+
52
+ <script>
53
+ import Popup from 'element-ui/src/utils/popup'
54
+ import Migrating from 'element-ui/src/mixins/migrating'
55
+ import emitter from 'element-ui/src/mixins/emitter'
56
+
57
+ /**
58
+ * Sobrescreve o Dialog original sem usar o extends porque trocou um watch e watch não sobrescreve
59
+ * <BR /> A nossa versão chama o $emit open quando tem v-if
60
+ */
61
+ export default {
62
+ name: 'TpDialog',
63
+
64
+ mixins: [Popup, emitter, Migrating],
65
+
66
+ props: {
67
+ title: {
68
+ type: String,
69
+ default: ''
70
+ },
71
+
72
+ modal: {
73
+ type: Boolean,
74
+ default: true
75
+ },
76
+
77
+ modalAppendToBody: {
78
+ type: Boolean,
79
+ default: true
80
+ },
81
+
82
+ appendToBody: {
83
+ type: Boolean,
84
+ default: false
85
+ },
86
+
87
+ lockScroll: {
88
+ type: Boolean,
89
+ default: true
90
+ },
91
+
92
+ closeOnClickModal: {
93
+ type: Boolean,
94
+ default: true
95
+ },
96
+
97
+ closeOnPressEscape: {
98
+ type: Boolean,
99
+ default: true
100
+ },
101
+
102
+ showClose: {
103
+ type: Boolean,
104
+ default: true
105
+ },
106
+
107
+ width: String,
108
+
109
+ fullscreen: Boolean,
110
+
111
+ customClass: {
112
+ type: String,
113
+ default: ''
114
+ },
115
+
116
+ top: {
117
+ type: String,
118
+ default: '15vh'
119
+ },
120
+ beforeClose: Function,
121
+ center: {
122
+ type: Boolean,
123
+ default: false
124
+ },
125
+
126
+ destroyOnClose: Boolean
127
+ },
128
+
129
+ data () {
130
+ return {
131
+ closed: false,
132
+ key: 0
133
+ }
134
+ },
135
+
136
+ computed: {
137
+ style () {
138
+ const style = {}
139
+ if (!this.fullscreen) {
140
+ style.marginTop = this.top
141
+ if (this.width) {
142
+ style.width = this.width
143
+ }
144
+ }
145
+ return style
146
+ }
147
+ },
148
+
149
+ watch: {
150
+ // CORREÇÂO Sobrescreve o watch visible do dialog original para rodar o open quando tem v-if
151
+ visible: {
152
+ immediate: true,
153
+ handler (val, oldValue) {
154
+ if (val) {
155
+ this.closed = false
156
+ this.$emit('open')
157
+ this.$el.addEventListener('scroll', this.updatePopper)
158
+ this.$nextTick(() => {
159
+ this.$refs.dialog.scrollTop = 0
160
+ })
161
+ if (this.appendToBody) {
162
+ document.body.appendChild(this.$el)
163
+ }
164
+ } else {
165
+ this.$el.removeEventListener('scroll', this.updatePopper)
166
+ if (!this.closed) this.$emit('close')
167
+ if (this.destroyOnClose) {
168
+ this.$nextTick(() => {
169
+ this.key++
170
+ })
171
+ }
172
+ }
173
+ }
174
+ }
175
+ },
176
+
177
+ mounted () {
178
+ if (this.visible) {
179
+ this.rendered = true
180
+ this.open()
181
+ if (this.appendToBody) {
182
+ document.body.appendChild(this.$el)
183
+ }
184
+ }
185
+ },
186
+
187
+ destroyed () {
188
+ // if appendToBody is true, remove DOM node after destroy
189
+ if (this.appendToBody && this.$el && this.$el.parentNode) {
190
+ this.$el.parentNode.removeChild(this.$el)
191
+ }
192
+ },
193
+
194
+ methods: {
195
+ getMigratingConfig () {
196
+ return {
197
+ props: {
198
+ size: 'size is removed.'
199
+ }
200
+ }
201
+ },
202
+ handleWrapperClick () {
203
+ if (!this.closeOnClickModal) return
204
+ this.handleClose()
205
+ },
206
+ handleClose () {
207
+ if (typeof this.beforeClose === 'function') {
208
+ this.beforeClose(this.hide)
209
+ } else {
210
+ this.hide()
211
+ }
212
+ },
213
+ hide (cancel) {
214
+ if (cancel !== false) {
215
+ this.$emit('update:visible', false)
216
+ this.$emit('close')
217
+ this.closed = true
218
+ }
219
+ },
220
+ updatePopper () {
221
+ this.broadcast('ElSelectDropdown', 'updatePopper')
222
+ this.broadcast('ElDropdownMenu', 'updatePopper')
223
+ },
224
+ afterEnter () {
225
+ this.$emit('opened')
226
+ },
227
+ afterLeave () {
228
+ this.$emit('closed')
229
+ }
230
+ }
231
+ }
232
+ </script>
@@ -0,0 +1,3 @@
1
+ import Dialog from './Dialog'
2
+
3
+ export default Dialog
@@ -1,17 +1,123 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ 'el-input-number',
5
+ inputNumberSize ? 'el-input-number--' + inputNumberSize : '',
6
+ { 'is-disabled': inputNumberDisabled },
7
+ { 'is-without-controls': !controls },
8
+ { 'is-controls-right': controlsAtRight }
9
+ ]"
10
+ @dragstart.prevent
11
+ >
12
+ <span
13
+ v-if="controls"
14
+ v-repeat-click="decrease"
15
+ class="el-input-number__decrease"
16
+ role="button"
17
+ :class="{'is-disabled': minDisabled}"
18
+ @keydown.enter="decrease"
19
+ >
20
+ <i :class="`el-icon-${controlsAtRight ? 'arrow-down' : 'minus'}`" />
21
+ </span>
22
+ <span
23
+ v-if="controls"
24
+ v-repeat-click="increase"
25
+ class="el-input-number__increase"
26
+ role="button"
27
+ :class="{'is-disabled': maxDisabled}"
28
+ @keydown.enter="increase"
29
+ >
30
+ <i :class="`el-icon-${controlsAtRight ? 'arrow-up' : 'plus'}`" />
31
+ </span>
32
+ <el-input
33
+ ref="input"
34
+ :value="displayValue"
35
+ :placeholder="placeholder"
36
+ :disabled="inputNumberDisabled"
37
+ :size="inputNumberSize"
38
+ :max="max"
39
+ :min="min"
40
+ :name="name"
41
+ :label="label"
42
+ @keydown.up.native.prevent="increase"
43
+ @keydown.down.native.prevent="decrease"
44
+ @blur="handleBlur"
45
+ @focus="handleFocus"
46
+ @input="handleInput"
47
+ @change="handleInputChange"
48
+ />
49
+ </div>
50
+ </template>
51
+
1
52
  <script>
2
- import { InputNumber } from 'element-ui'
53
+ import ElInput from 'element-ui/packages/input'
54
+ import Focus from 'element-ui/src/mixins/focus'
55
+ import RepeatClick from 'element-ui/src/directives/repeat-click'
3
56
 
4
57
  export default {
5
58
  name: 'TpInputNumber',
6
59
 
7
- extends: InputNumber,
60
+ directives: {
61
+ repeatClick: RepeatClick
62
+ },
63
+
64
+ components: {
65
+ ElInput
66
+ },
67
+
68
+ mixins: [Focus('input')],
69
+ inject: {
70
+ elForm: {
71
+ default: ''
72
+ },
73
+ elFormItem: {
74
+ default: ''
75
+ }
76
+ },
8
77
 
9
78
  props: {
79
+ step: {
80
+ type: Number,
81
+ default: 1
82
+ },
83
+ stepStrictly: {
84
+ type: Boolean,
85
+ default: false
86
+ },
87
+ max: {
88
+ type: Number,
89
+ default: Infinity
90
+ },
91
+ min: {
92
+ type: Number,
93
+ default: -Infinity
94
+ },
95
+ value: {},
96
+ disabled: Boolean,
97
+ size: String,
98
+ controls: {
99
+ type: Boolean,
100
+ default: true
101
+ },
102
+ controlsPosition: {
103
+ type: String,
104
+ default: ''
105
+ },
106
+ name: String,
107
+ label: String,
108
+ placeholder: String,
109
+ precision: {
110
+ type: Number,
111
+ validator (val) {
112
+ return val >= 0 && val === parseInt(val, 10)
113
+ }
114
+ },
115
+ // Customizada
10
116
  usarVirgula: {
11
117
  type: Boolean,
12
118
  default: true
13
119
  },
14
- // Se false permite campo vazio
120
+ // Customizada - Se false permite campo vazio
15
121
  stringDefaultsZero: {
16
122
  type: Boolean,
17
123
  default: true
@@ -20,19 +126,52 @@ export default {
20
126
 
21
127
  data () {
22
128
  return {
23
- currentValue: ''
129
+ currentValue: '',
130
+ userInput: null
24
131
  }
25
132
  },
26
133
 
27
134
  computed: {
135
+ /**
136
+ * Sobrescrito do element
137
+ */
28
138
  minDisabled () {
29
139
  return this.value < this.min
30
140
  },
31
141
 
142
+ /**
143
+ * Sobrescrito do element
144
+ */
32
145
  maxDisabled () {
33
146
  return this.value > this.max
34
147
  },
35
-
148
+ numPrecision () {
149
+ const { value, step, getPrecision, precision } = this
150
+ const stepPrecision = getPrecision(step)
151
+ if (precision !== undefined) {
152
+ if (stepPrecision > precision) {
153
+ console.warn('[Element Warn][InputNumber]precision should not be less than the decimal places of step')
154
+ }
155
+ return precision
156
+ } else {
157
+ return Math.max(getPrecision(value), stepPrecision)
158
+ }
159
+ },
160
+ controlsAtRight () {
161
+ return this.controls && this.controlsPosition === 'right'
162
+ },
163
+ _elFormItemSize () {
164
+ return (this.elFormItem || {}).elFormItemSize
165
+ },
166
+ inputNumberSize () {
167
+ return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size
168
+ },
169
+ inputNumberDisabled () {
170
+ return this.disabled || !!(this.elForm || {}).disabled
171
+ },
172
+ /**
173
+ * Sobrescrito do element
174
+ */
36
175
  displayValue () {
37
176
  if (this.userInput !== null) {
38
177
  // corrige o bug para deixar limpar o campo
@@ -73,6 +212,9 @@ export default {
73
212
  },
74
213
 
75
214
  watch: {
215
+ /**
216
+ * Sobrescrito do element
217
+ */
76
218
  value: {
77
219
  immediate: true,
78
220
  handler (value) {
@@ -109,7 +251,72 @@ export default {
109
251
  }
110
252
  },
111
253
 
254
+ mounted () {
255
+ const innerInput = this.$refs.input.$refs.input
256
+ innerInput.setAttribute('role', 'spinbutton')
257
+ innerInput.setAttribute('aria-valuemax', this.max)
258
+ innerInput.setAttribute('aria-valuemin', this.min)
259
+ innerInput.setAttribute('aria-valuenow', this.currentValue)
260
+ innerInput.setAttribute('aria-disabled', this.inputNumberDisabled)
261
+ },
262
+
263
+ updated () {
264
+ if (!this.$refs || !this.$refs.input) return
265
+ const innerInput = this.$refs.input.$refs.input
266
+ innerInput.setAttribute('aria-valuenow', this.currentValue)
267
+ },
268
+
112
269
  methods: {
270
+ toPrecision (num, precision) {
271
+ if (precision === undefined) precision = this.numPrecision
272
+ return parseFloat(Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision))
273
+ },
274
+ getPrecision (value) {
275
+ if (value === undefined) return 0
276
+ const valueString = value.toString()
277
+ const dotPosition = valueString.indexOf('.')
278
+ let precision = 0
279
+ if (dotPosition !== -1) {
280
+ precision = valueString.length - dotPosition - 1
281
+ }
282
+ return precision
283
+ },
284
+ _increase (val, step) {
285
+ if (typeof val !== 'number' && val !== undefined) return this.currentValue
286
+
287
+ const precisionFactor = Math.pow(10, this.numPrecision)
288
+ // Solve the accuracy problem of JS decimal calculation by converting the value to integer.
289
+ return this.toPrecision((precisionFactor * val + precisionFactor * step) / precisionFactor)
290
+ },
291
+ _decrease (val, step) {
292
+ if (typeof val !== 'number' && val !== undefined) return this.currentValue
293
+
294
+ const precisionFactor = Math.pow(10, this.numPrecision)
295
+
296
+ return this.toPrecision((precisionFactor * val - precisionFactor * step) / precisionFactor)
297
+ },
298
+ increase () {
299
+ if (this.inputNumberDisabled || this.maxDisabled) return
300
+ const value = this.value || 0
301
+ const newVal = this._increase(value, this.step)
302
+ this.setCurrentValue(newVal)
303
+ },
304
+ decrease () {
305
+ if (this.inputNumberDisabled || this.minDisabled) return
306
+ const value = this.value || 0
307
+ const newVal = this._decrease(value, this.step)
308
+ this.setCurrentValue(newVal)
309
+ },
310
+ handleBlur (event) {
311
+ this.$emit('blur', event)
312
+ },
313
+ handleFocus (event) {
314
+ this.$emit('focus', event)
315
+ },
316
+
317
+ /**
318
+ * Sobrescrito do element
319
+ */
113
320
  handleInput (value) {
114
321
  this.userInput = value
115
322
  let newVal
@@ -122,6 +329,9 @@ export default {
122
329
  this.$emit('change', newVal)
123
330
  },
124
331
 
332
+ /**
333
+ * Sobrescrito do element
334
+ */
125
335
  handleInputChange (value) {
126
336
  let newVal
127
337
  if (value === '') {
@@ -141,6 +351,9 @@ export default {
141
351
  this.userInput = null
142
352
  },
143
353
 
354
+ /**
355
+ * Sobrescrito do element
356
+ */
144
357
  setCurrentValue (newVal) {
145
358
  const oldVal = this.currentValue
146
359
  if (typeof newVal === 'number' && this.precision !== undefined) {
@@ -148,11 +361,14 @@ export default {
148
361
  }
149
362
  if (newVal >= this.max) newVal = this.max
150
363
  if (newVal <= this.min) newVal = this.min
151
- if (oldVal === newVal && newVal !== '') return
364
+ if (oldVal === newVal && newVal === this.value) return
152
365
  this.userInput = null
153
366
  this.$emit('input', newVal)
154
367
  this.$emit('change', newVal, oldVal)
155
- this.currentValue = newVal
368
+ },
369
+
370
+ select () {
371
+ this.$refs.input.select()
156
372
  }
157
373
  }
158
374
  }
@@ -11,6 +11,7 @@ import Multisuggest from './Multisuggest'
11
11
  import Step from './Step'
12
12
  import Steps from './Steps'
13
13
  import InputNumber from './InputNumber'
14
+ import Dialog from './Dialog'
14
15
 
15
16
  export {
16
17
  Autosuggest,
@@ -25,5 +26,6 @@ export {
25
26
  Multisuggest,
26
27
  Step,
27
28
  Steps,
28
- InputNumber
29
+ InputNumber,
30
+ Dialog
29
31
  }