@tagplus/components 4.7.4 → 4.7.5
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/dist/tp.common.js +2 -1
- package/dist/tp.common.js.LICENSE.txt +9 -0
- package/dist/tp.common.js.map +1 -1
- package/dist/tp.common.lang-en-js.js +2 -0
- package/dist/tp.common.lang-en-js.js.map +1 -0
- package/dist/tp.css +12 -167
- package/dist/tp.umd.js +2 -1
- package/dist/tp.umd.js.LICENSE.txt +9 -0
- package/dist/tp.umd.js.map +1 -1
- package/dist/tp.umd.lang-en-js.js +2 -0
- package/dist/tp.umd.lang-en-js.js.map +1 -0
- package/dist/tp.umd.min.js +2 -1
- package/dist/tp.umd.min.js.LICENSE.txt +9 -0
- package/dist/tp.umd.min.js.map +1 -1
- package/dist/tp.umd.min.lang-en-js.js +2 -0
- package/dist/tp.umd.min.lang-en-js.js.map +1 -0
- package/package.json +39 -41
- package/src/assets/scss/_fonts.scss +24 -23
- package/src/assets/scss/_helpers.scss +4 -0
- package/src/assets/scss/_mixins.scss +2 -2
- package/src/assets/scss/_overrides.scss +5 -52
- package/src/assets/scss/_resass.scss +21 -12
- package/src/assets/scss/_variables.scss +0 -1
- package/src/assets/scss/index.scss +1 -4
- package/src/components/Autosuggest/Autosuggest.vue +340 -762
- package/src/components/Autosuggest/Multisuggest.vue +22 -0
- package/src/components/Autosuggest/autosuggest-props.js +210 -0
- package/src/components/Autosuggest/autosuggest-style.scss +127 -0
- package/src/components/Autosuggest/core.js +63 -0
- package/src/components/Autosuggest/index.js +2 -0
- package/src/components/Autosuggest/multisuggest-props.js +9 -0
- package/src/components/Autosuggest/option.vue +136 -0
- package/src/components/Autosuggest/select-dropdown.vue +64 -0
- package/src/components/Autosuggest/useOption.js +120 -0
- package/src/components/Autosuggest/useSelect.js +1133 -0
- package/src/components/AutosuggestTest.vue +56 -0
- package/src/components/CardExemplo.vue +49 -0
- package/src/components/CodeSample.vue +78 -0
- package/src/components/Inline/Inline.vue +24 -32
- package/src/components/InputNumber/InputNumber.vue +329 -378
- package/src/components/InputNumber/input-number.js +135 -0
- package/src/components/Loader/Loader.vue +42 -53
- package/src/components/Loader/animations.scss +13 -0
- package/src/components/Money/Money.vue +11 -20
- package/src/components/Multisuggest/index.js +2 -3
- package/src/components/MultisuggestTest.vue +56 -0
- package/src/components/OptionsList/OptionsList.vue +7 -6
- package/src/components/OptionsListItem/OptionsListItem.vue +46 -42
- package/src/components/Percent/Percent.vue +8 -14
- package/src/components/Skeleton/Skeleton.vue +16 -11
- package/src/components/Step/Step.vue +42 -35
- package/src/components/Steps/Steps.vue +4 -7
- package/src/components/TesteToCurrency.vue +171 -0
- package/src/components/Tip/Tip.vue +45 -30
- package/src/components/ValueSelector.vue +60 -0
- package/src/components/autosuggestMixin.js +301 -0
- package/src/components/index.js +4 -1
- package/src/locale/i18n.js +114 -0
- package/src/locale/lang/en.js +3 -2
- package/src/locale/lang/pt-br.js +3 -2
- package/src/main.js +11 -13
- package/src/mixins/floatFormatter.js +12 -16
- package/src/{utils → plugins}/currency.js +11 -71
- package/src/utils/browser.js +6 -0
- package/src/utils/constants.js +3 -0
- package/src/utils/error.js +22 -0
- package/src/utils/filters.js +1 -14
- package/src/utils/helpers.js +41 -0
- package/src/utils/i18n.js +2 -0
- package/src/utils/icon.js +35 -0
- package/src/utils/index.js +20 -0
- package/src/utils/objects.js +17 -0
- package/src/utils/runtime.js +86 -0
- package/src/utils/scroll.js +100 -0
- package/src/utils/strings.js +17 -0
- package/src/utils/style.js +80 -0
- package/src/utils/types.js +39 -0
- package/src/utils/use-derived-namespace.js +112 -0
- package/src/utils/use-form-common-props.js +41 -0
- package/src/utils/use-form-item.js +80 -0
- package/src/utils/use-id.js +40 -0
- package/src/utils/use-input.js +33 -0
- package/src/components/Dialog/Dialog.vue +0 -253
- package/src/components/Dialog/index.js +0 -3
- package/src/components/Multisuggest/Multisuggest.vue +0 -858
- package/src/locale/index.js +0 -78
- package/src/mixins/locale.js +0 -9
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { formatMoney } from 'tp-ui/utils/currency'
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Eventos para componentes tp-money e tp-percent mostratem o número formatado com a precisão correta e devolver float sem arredondar
|
|
5
3
|
*/
|
|
6
4
|
export default {
|
|
5
|
+
inject: ['formatMoney'],
|
|
6
|
+
|
|
7
7
|
data () {
|
|
8
8
|
return {
|
|
9
|
-
formattedValue: this.
|
|
9
|
+
formattedValue: this.modelValue
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
12
|
|
|
@@ -21,33 +21,29 @@ export default {
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
|
|
24
|
-
computed: {
|
|
25
|
-
locale () {
|
|
26
|
-
return this.t('locale')
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
|
|
30
24
|
watch: {
|
|
31
|
-
|
|
25
|
+
modelValue: {
|
|
32
26
|
immediate: true,
|
|
33
27
|
handler (newValue, oldValue) {
|
|
34
|
-
if (newValue === '' && this.allowEmpty) {
|
|
35
|
-
|
|
28
|
+
if (newValue === '' && this.allowEmpty) {
|
|
29
|
+
this.formattedValue = ''
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
this.formattedValue = this.formatMoney(newValue, true, this.locale, this.customPrecision)
|
|
36
33
|
}
|
|
37
34
|
}
|
|
38
35
|
},
|
|
39
36
|
|
|
40
37
|
methods: {
|
|
41
38
|
input (evt) {
|
|
42
|
-
this.formattedValue = formatMoney(evt, true, this.locale, this.customPrecision)
|
|
43
|
-
const moneyFormatado = formatMoney(evt, false, this.locale, this.customPrecision)
|
|
39
|
+
this.formattedValue = this.formatMoney(evt, true, this.locale, this.customPrecision)
|
|
40
|
+
const moneyFormatado = this.formatMoney(evt, false, this.locale, this.customPrecision)
|
|
44
41
|
|
|
45
42
|
this.$emit('input', moneyFormatado)
|
|
46
43
|
},
|
|
47
44
|
|
|
48
45
|
handleChange (evt) {
|
|
49
|
-
this.$emit('change', formatMoney(evt, false, this.locale, this.customPrecision))
|
|
46
|
+
this.$emit('change', this.formatMoney(evt, false, this.locale, this.customPrecision))
|
|
50
47
|
}
|
|
51
48
|
}
|
|
52
|
-
|
|
53
49
|
}
|
|
@@ -1,31 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ptbrLocale from 'tp-ui/locale/lang/pt-br'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
let defaults
|
|
4
4
|
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
input = input.toFixed(fixed(opt.precision))
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const negative = input.indexOf('-') >= 0 ? '-' : ''
|
|
11
|
-
|
|
12
|
-
const numbers = onlyNumbers(input)
|
|
13
|
-
const currency = numbersToCurrency(numbers, opt.precision)
|
|
14
|
-
const parts = toStr(currency).split('.')
|
|
15
|
-
let integer = parts[0]
|
|
16
|
-
const decimal = parts[1]
|
|
17
|
-
|
|
18
|
-
integer = addThousandSeparator(integer, opt.thousands)
|
|
19
|
-
|
|
20
|
-
return opt.prefix + negative + joinIntegerAndDecimal(integer, decimal, opt.decimal) + opt.suffix
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function unformat (input, precision = defaults.precision) {
|
|
24
|
-
const negative = (`${input}`).indexOf('-') >= 0 ? -1 : 1
|
|
25
|
-
const numbers = onlyNumbers(input)
|
|
26
|
-
const currency = numbersToCurrency(numbers, precision)
|
|
27
|
-
|
|
28
|
-
return currency * negative
|
|
5
|
+
function setDefaults (app) {
|
|
6
|
+
defaults = app.$i18n ? app.$i18n.t('locale.number') : ptbrLocale.locale
|
|
29
7
|
}
|
|
30
8
|
|
|
31
9
|
/**
|
|
@@ -38,10 +16,10 @@ function unformat (input, precision = defaults.precision) {
|
|
|
38
16
|
* @returns
|
|
39
17
|
*/
|
|
40
18
|
function formatMoney (input, toString = false, locale = defaults, customPrecision = false) {
|
|
41
|
-
let inputString =
|
|
19
|
+
let inputString = (`${input}`)
|
|
42
20
|
|
|
43
21
|
// Impede de digitar . ou , porque o formatador já adiciona
|
|
44
|
-
if (
|
|
22
|
+
if (inputString.slice(-1).match(/[.,]/)) {
|
|
45
23
|
inputString = inputString.substring(0, inputString.length - 1)
|
|
46
24
|
}
|
|
47
25
|
|
|
@@ -90,12 +68,6 @@ function completeZeros (customPrecision, input, locale) {
|
|
|
90
68
|
return input
|
|
91
69
|
}
|
|
92
70
|
|
|
93
|
-
// Impede que seja adicionado um segundo separadador apos o ponto ou a virgula
|
|
94
|
-
function removeSecondSeparator (input) {
|
|
95
|
-
// Identifica a segunda vírgula ou ponto e remove
|
|
96
|
-
return input.replace(/([.,])([^.,]*?)([.,])/, '$1$2')
|
|
97
|
-
}
|
|
98
|
-
|
|
99
71
|
function onlyNumbers (input) {
|
|
100
72
|
return toStr(input).replace(/\D+/g, '') || '0'
|
|
101
73
|
}
|
|
@@ -115,46 +87,14 @@ function numbersToCurrency (numbers, precision) {
|
|
|
115
87
|
return float.toFixed(fixed(precision))
|
|
116
88
|
}
|
|
117
89
|
|
|
118
|
-
function addThousandSeparator (integer, separator) {
|
|
119
|
-
return integer.replace(/(\d)(?=(?:\d{3})+\b)/g, `$1${separator}`)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// eslint-disable-next-line
|
|
123
|
-
function currencyToIntegerAndDecimal (float) {
|
|
124
|
-
return toStr(float).split('.')
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function joinIntegerAndDecimal (integer, decimal, separator) {
|
|
128
|
-
return decimal ? integer + separator + decimal : integer
|
|
129
|
-
}
|
|
130
|
-
|
|
131
90
|
function toStr (value) {
|
|
132
91
|
return value ? value.toString() : ''
|
|
133
92
|
}
|
|
134
93
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
setTimeout(setSelectionRange, 1) // Android Fix
|
|
94
|
+
export default {
|
|
95
|
+
install: (app, options) => {
|
|
96
|
+
setDefaults(app)
|
|
97
|
+
// app.messages().locale.number
|
|
98
|
+
app.provide('formatMoney', formatMoney)
|
|
141
99
|
}
|
|
142
100
|
}
|
|
143
|
-
|
|
144
|
-
// https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events#The_old-fashioned_way
|
|
145
|
-
function event (name) {
|
|
146
|
-
const evt = document.createEvent('Event')
|
|
147
|
-
|
|
148
|
-
evt.initEvent(name, true, true)
|
|
149
|
-
|
|
150
|
-
return evt
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export {
|
|
154
|
-
formatMoney,
|
|
155
|
-
format,
|
|
156
|
-
unformat,
|
|
157
|
-
setCursor,
|
|
158
|
-
completeZeros,
|
|
159
|
-
event
|
|
160
|
-
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isString } from './types'
|
|
2
|
+
|
|
3
|
+
class ElementPlusError extends Error {
|
|
4
|
+
constructor (m) {
|
|
5
|
+
super(m)
|
|
6
|
+
this.name = 'ElementPlusError'
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function throwError (scope, m) {
|
|
11
|
+
throw new ElementPlusError(`[${scope}] ${m}`)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function debugWarn (scope, message) {
|
|
15
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
16
|
+
const error = isString(scope)
|
|
17
|
+
? new ElementPlusError(`[${scope}] ${message}`)
|
|
18
|
+
: scope
|
|
19
|
+
// eslint-disable-next-line no-console
|
|
20
|
+
console.warn(error)
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/utils/filters.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// import moment from 'moment'
|
|
2
|
-
import { t } from 'tp-ui/locale'
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
*
|
|
@@ -26,7 +25,7 @@ export const toCurrency = (val, locale = false) => {
|
|
|
26
25
|
|
|
27
26
|
try {
|
|
28
27
|
if (!locale) {
|
|
29
|
-
locale =
|
|
28
|
+
locale = 'pt-BR'
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
let with2Decimals = val.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]
|
|
@@ -53,18 +52,6 @@ export const toDate = function (val) {
|
|
|
53
52
|
if (val === undefined || val === '' || val === null) return ''
|
|
54
53
|
|
|
55
54
|
if (val === '0000-00-00') return 'N/A'
|
|
56
|
-
|
|
57
|
-
// let defaultFormat = 'DD/MM/YYYY'
|
|
58
|
-
|
|
59
|
-
// switch (getCurrentLocale()) {
|
|
60
|
-
// case 'en-US':
|
|
61
|
-
// defaultFormat = 'YYYY-MM-DD'
|
|
62
|
-
// break
|
|
63
|
-
// default:
|
|
64
|
-
// defaultFormat
|
|
65
|
-
// }
|
|
66
|
-
|
|
67
|
-
// return moment(val).format(defaultFormat)
|
|
68
55
|
}
|
|
69
56
|
|
|
70
57
|
/**
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {Array} a
|
|
4
|
+
* @param {Array} b
|
|
5
|
+
* @returns {Bool}
|
|
6
|
+
*/
|
|
7
|
+
export const valueEquals = (a, b) => {
|
|
8
|
+
// see: https://stackoverflow.com/questions/3115982/how-to-check-if-two-arrays-are-equal-with-javascript
|
|
9
|
+
if (a === b) return true
|
|
10
|
+
if (!(a instanceof Array)) return false
|
|
11
|
+
if (!(b instanceof Array)) return false
|
|
12
|
+
if (a.length !== b.length) return false
|
|
13
|
+
for (let i = 0; i !== a.length; ++i) {
|
|
14
|
+
if (a[i] !== b[i]) return false
|
|
15
|
+
}
|
|
16
|
+
return true
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @param {*} object
|
|
22
|
+
* @param {*} prop
|
|
23
|
+
* @returns
|
|
24
|
+
*/
|
|
25
|
+
export const getValueByPath = function (object, prop) {
|
|
26
|
+
prop = prop || ''
|
|
27
|
+
const paths = prop.split('.')
|
|
28
|
+
let current = object
|
|
29
|
+
let result = null
|
|
30
|
+
for (let i = 0, j = paths.length; i < j; i++) {
|
|
31
|
+
const path = paths[i]
|
|
32
|
+
if (!current) break
|
|
33
|
+
|
|
34
|
+
if (i === j - 1) {
|
|
35
|
+
result = current[path]
|
|
36
|
+
break
|
|
37
|
+
}
|
|
38
|
+
current = current[path]
|
|
39
|
+
}
|
|
40
|
+
return result
|
|
41
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CircleCheck,
|
|
3
|
+
CircleClose,
|
|
4
|
+
CircleCloseFilled,
|
|
5
|
+
Close,
|
|
6
|
+
InfoFilled,
|
|
7
|
+
Loading,
|
|
8
|
+
SuccessFilled,
|
|
9
|
+
WarningFilled,
|
|
10
|
+
} from '@element-plus/icons-vue'
|
|
11
|
+
|
|
12
|
+
export const CloseComponents = {
|
|
13
|
+
Close,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const TypeComponents = {
|
|
17
|
+
Close,
|
|
18
|
+
SuccessFilled,
|
|
19
|
+
InfoFilled,
|
|
20
|
+
WarningFilled,
|
|
21
|
+
CircleCloseFilled,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const TypeComponentsMap = {
|
|
25
|
+
success: SuccessFilled,
|
|
26
|
+
warning: WarningFilled,
|
|
27
|
+
error: CircleCloseFilled,
|
|
28
|
+
info: InfoFilled,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const ValidateComponentsMap = {
|
|
32
|
+
validating: Loading,
|
|
33
|
+
success: CircleCheck,
|
|
34
|
+
error: CircleClose,
|
|
35
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * from './types'
|
|
2
|
+
export * from './error'
|
|
3
|
+
// export * from './arrays'
|
|
4
|
+
export * from './browser'
|
|
5
|
+
// export * from './rand'
|
|
6
|
+
export * from './strings'
|
|
7
|
+
export * from './icon'
|
|
8
|
+
export * from './scroll'
|
|
9
|
+
export * from './i18n'
|
|
10
|
+
export * from './use-input'
|
|
11
|
+
export * from './use-id'
|
|
12
|
+
export * from './use-form-item'
|
|
13
|
+
export * from './use-form-common-props'
|
|
14
|
+
export * from './use-derived-namespace'
|
|
15
|
+
export * from './constants'
|
|
16
|
+
export * from './runtime'
|
|
17
|
+
export * from './objects'
|
|
18
|
+
export const UPDATE_MODEL_EVENT = 'update:modelValue'
|
|
19
|
+
export const CHANGE_EVENT = 'change'
|
|
20
|
+
export const INPUT_EVENT = 'input'
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/* eslint-disable vue/prefer-import-from-vue */
|
|
2
|
+
import { get, set } from 'lodash-unified'
|
|
3
|
+
|
|
4
|
+
export const keysOf = (arr) => Object.keys(arr)
|
|
5
|
+
export const entriesOf = (arr) => Object.entries(arr)
|
|
6
|
+
export { hasOwn } from '@vue/shared'
|
|
7
|
+
|
|
8
|
+
export const getProp = (obj, path, defaultValue) => {
|
|
9
|
+
return {
|
|
10
|
+
get value () {
|
|
11
|
+
return get(obj, path, defaultValue)
|
|
12
|
+
},
|
|
13
|
+
set value (val) {
|
|
14
|
+
set(obj, path, val)
|
|
15
|
+
},
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { warn } from 'vue'
|
|
2
|
+
import { fromPairs } from 'lodash-unified'
|
|
3
|
+
import { hasOwn, isObject } from '@/utils'
|
|
4
|
+
|
|
5
|
+
export const epPropKey = '__epPropKey'
|
|
6
|
+
|
|
7
|
+
export const definePropType = (val) => val
|
|
8
|
+
|
|
9
|
+
export const isEpProp = (val) =>
|
|
10
|
+
isObject(val) && !!(val)[epPropKey]
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @description Build prop. It can better optimize prop types
|
|
14
|
+
* @description 生成 prop,能更好地优化类型
|
|
15
|
+
* @example
|
|
16
|
+
// limited options
|
|
17
|
+
// the type will be PropType<'light' | 'dark'>
|
|
18
|
+
buildProp({
|
|
19
|
+
type: String,
|
|
20
|
+
values: ['light', 'dark'],
|
|
21
|
+
} as const)
|
|
22
|
+
* @example
|
|
23
|
+
// limited options and other types
|
|
24
|
+
// the type will be PropType<'small' | 'large' | number>
|
|
25
|
+
buildProp({
|
|
26
|
+
type: [String, Number],
|
|
27
|
+
values: ['small', 'large'],
|
|
28
|
+
validator: (val: unknown): val is number => typeof val === 'number',
|
|
29
|
+
} as const)
|
|
30
|
+
@link see more: https://github.com/element-plus/element-plus/pull/3341
|
|
31
|
+
*/
|
|
32
|
+
export const buildProp = (prop, key) => {
|
|
33
|
+
// filter native prop type and nested prop, e.g `null`, `undefined` (from `buildProps`)
|
|
34
|
+
if (!isObject(prop) || isEpProp(prop)) return prop
|
|
35
|
+
|
|
36
|
+
const { values, required, default: defaultValue, type, validator } = prop
|
|
37
|
+
|
|
38
|
+
const _validator =
|
|
39
|
+
values || validator
|
|
40
|
+
? (val) => {
|
|
41
|
+
let valid = false
|
|
42
|
+
let allowedValues = []
|
|
43
|
+
|
|
44
|
+
if (values) {
|
|
45
|
+
allowedValues = Array.from(values)
|
|
46
|
+
if (hasOwn(prop, 'default')) {
|
|
47
|
+
allowedValues.push(defaultValue)
|
|
48
|
+
}
|
|
49
|
+
valid ||= allowedValues.includes(val)
|
|
50
|
+
}
|
|
51
|
+
if (validator) valid ||= validator(val)
|
|
52
|
+
|
|
53
|
+
if (!valid && allowedValues.length > 0) {
|
|
54
|
+
const allowValuesText = [...new Set(allowedValues)]
|
|
55
|
+
.map((value) => JSON.stringify(value))
|
|
56
|
+
.join(', ')
|
|
57
|
+
warn(
|
|
58
|
+
`Invalid prop: validation failed${
|
|
59
|
+
key ? ` for prop "${key}"` : ''
|
|
60
|
+
}. Expected one of [${allowValuesText}], got value ${JSON.stringify(
|
|
61
|
+
val
|
|
62
|
+
)}.`
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
return valid
|
|
66
|
+
}
|
|
67
|
+
: undefined
|
|
68
|
+
|
|
69
|
+
const epProp = {
|
|
70
|
+
type,
|
|
71
|
+
required: !!required,
|
|
72
|
+
validator: _validator,
|
|
73
|
+
[epPropKey]: true,
|
|
74
|
+
}
|
|
75
|
+
if (hasOwn(prop, 'default')) epProp.default = defaultValue
|
|
76
|
+
return epProp
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const buildProps = (
|
|
80
|
+
props
|
|
81
|
+
) => fromPairs(
|
|
82
|
+
Object.entries(props).map(([key, option]) => [
|
|
83
|
+
key,
|
|
84
|
+
buildProp(option, key),
|
|
85
|
+
])
|
|
86
|
+
)
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { isClient, getStyle } from '@/utils'
|
|
2
|
+
|
|
3
|
+
export const isScroll = (el, isVertical) => {
|
|
4
|
+
if (!isClient) return false
|
|
5
|
+
|
|
6
|
+
const key = (
|
|
7
|
+
{
|
|
8
|
+
undefined: 'overflow',
|
|
9
|
+
true: 'overflow-y',
|
|
10
|
+
false: 'overflow-x',
|
|
11
|
+
}
|
|
12
|
+
)[String(isVertical)]
|
|
13
|
+
const overflow = getStyle(el, key)
|
|
14
|
+
return ['scroll', 'auto', 'overlay'].some((s) => overflow.includes(s))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const getScrollContainer = (
|
|
18
|
+
el,
|
|
19
|
+
isVertical
|
|
20
|
+
) => {
|
|
21
|
+
if (!isClient) return
|
|
22
|
+
|
|
23
|
+
let parent = el
|
|
24
|
+
while (parent) {
|
|
25
|
+
if ([window, document, document.documentElement].includes(parent))
|
|
26
|
+
return window
|
|
27
|
+
|
|
28
|
+
if (isScroll(parent, isVertical)) return parent
|
|
29
|
+
|
|
30
|
+
parent = parent.parentNode
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return parent
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let scrollBarWidth
|
|
37
|
+
export const getScrollBarWidth = (namespace) => {
|
|
38
|
+
if (!isClient) return 0
|
|
39
|
+
if (scrollBarWidth !== undefined) return scrollBarWidth
|
|
40
|
+
|
|
41
|
+
const outer = document.createElement('div')
|
|
42
|
+
outer.className = `${namespace}-scrollbar__wrap`
|
|
43
|
+
outer.style.visibility = 'hidden'
|
|
44
|
+
outer.style.width = '100px'
|
|
45
|
+
outer.style.position = 'absolute'
|
|
46
|
+
outer.style.top = '-9999px'
|
|
47
|
+
document.body.appendChild(outer)
|
|
48
|
+
|
|
49
|
+
const widthNoScroll = outer.offsetWidth
|
|
50
|
+
outer.style.overflow = 'scroll'
|
|
51
|
+
|
|
52
|
+
const inner = document.createElement('div')
|
|
53
|
+
inner.style.width = '100%'
|
|
54
|
+
outer.appendChild(inner)
|
|
55
|
+
|
|
56
|
+
const widthWithScroll = inner.offsetWidth
|
|
57
|
+
outer.parentNode?.removeChild(outer)
|
|
58
|
+
scrollBarWidth = widthNoScroll - widthWithScroll
|
|
59
|
+
|
|
60
|
+
return scrollBarWidth
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Scroll with in the container element, positioning the **selected** element at the top
|
|
65
|
+
* of the container
|
|
66
|
+
*/
|
|
67
|
+
export function scrollIntoView (
|
|
68
|
+
container,
|
|
69
|
+
selected
|
|
70
|
+
) {
|
|
71
|
+
if (!isClient) return
|
|
72
|
+
|
|
73
|
+
if (!selected) {
|
|
74
|
+
container.scrollTop = 0
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const offsetParents = []
|
|
79
|
+
let pointer = selected.offsetParent
|
|
80
|
+
while (
|
|
81
|
+
pointer !== null &&
|
|
82
|
+
container !== pointer &&
|
|
83
|
+
container.contains(pointer)
|
|
84
|
+
) {
|
|
85
|
+
offsetParents.push(pointer )
|
|
86
|
+
pointer = (pointer ).offsetParent
|
|
87
|
+
}
|
|
88
|
+
const top =
|
|
89
|
+
selected.offsetTop +
|
|
90
|
+
offsetParents.reduce((prev, curr) => prev + curr.offsetTop, 0)
|
|
91
|
+
const bottom = top + selected.offsetHeight
|
|
92
|
+
const viewRectTop = container.scrollTop
|
|
93
|
+
const viewRectBottom = viewRectTop + container.clientHeight
|
|
94
|
+
|
|
95
|
+
if (top < viewRectTop) {
|
|
96
|
+
container.scrollTop = top
|
|
97
|
+
} else if (bottom > viewRectBottom) {
|
|
98
|
+
container.scrollTop = bottom - container.clientHeight
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/* eslint-disable vue/prefer-import-from-vue */
|
|
2
|
+
import { capitalize as toCapitalize } from '@vue/shared'
|
|
3
|
+
export {
|
|
4
|
+
camelize,
|
|
5
|
+
hyphenate,
|
|
6
|
+
hyphenate as kebabCase, // alias
|
|
7
|
+
} from '@vue/shared'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* fork from {@link https://github.com/sindresorhus/escape-string-regexp}
|
|
11
|
+
*/
|
|
12
|
+
export const escapeStringRegexp = (string = '') =>
|
|
13
|
+
string.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d')
|
|
14
|
+
|
|
15
|
+
// NOTE: improve capitalize types. Restore previous code after the [PR](https://github.com/vuejs/core/pull/6212) merge
|
|
16
|
+
export const capitalize = (str) =>
|
|
17
|
+
toCapitalize(str)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { isNumber, isObject, isString, isStringNumber, isClient, camelize, entriesOf, keysOf, debugWarn } from '@/utils'
|
|
2
|
+
|
|
3
|
+
const SCOPE = 'utils/dom/style'
|
|
4
|
+
|
|
5
|
+
export const classNameToArray = (cls = '') =>
|
|
6
|
+
cls.split(' ').filter((item) => !!item.trim())
|
|
7
|
+
|
|
8
|
+
export const hasClass = (el, cls) => {
|
|
9
|
+
if (!el || !cls) return false
|
|
10
|
+
if (cls.includes(' ')) throw new Error('className should not contain space.')
|
|
11
|
+
return el.classList.contains(cls)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const addClass = (el, cls) => {
|
|
15
|
+
if (!el || !cls.trim()) return
|
|
16
|
+
el.classList.add(...classNameToArray(cls))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const removeClass = (el, cls) => {
|
|
20
|
+
if (!el || !cls.trim()) return
|
|
21
|
+
el.classList.remove(...classNameToArray(cls))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const getStyle = (
|
|
25
|
+
element,
|
|
26
|
+
styleName
|
|
27
|
+
) => {
|
|
28
|
+
if (!isClient || !element || !styleName) return ''
|
|
29
|
+
|
|
30
|
+
let key = camelize(styleName)
|
|
31
|
+
if (key === 'float') key = 'cssFloat'
|
|
32
|
+
try {
|
|
33
|
+
const style = (element.style)[key]
|
|
34
|
+
if (style) return style
|
|
35
|
+
const computed = document.defaultView?.getComputedStyle(element, '')
|
|
36
|
+
return computed ? computed[key] : ''
|
|
37
|
+
} catch {
|
|
38
|
+
return (element.style)[key]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const setStyle = (
|
|
43
|
+
element,
|
|
44
|
+
styleName,
|
|
45
|
+
value
|
|
46
|
+
) => {
|
|
47
|
+
if (!element || !styleName) return
|
|
48
|
+
|
|
49
|
+
if (isObject(styleName)) {
|
|
50
|
+
entriesOf(styleName).forEach(([prop, value]) =>
|
|
51
|
+
setStyle(element, prop, value)
|
|
52
|
+
)
|
|
53
|
+
} else {
|
|
54
|
+
const key = camelize(styleName)
|
|
55
|
+
element.style[key] = value
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const removeStyle = (
|
|
60
|
+
element,
|
|
61
|
+
style
|
|
62
|
+
) => {
|
|
63
|
+
if (!element || !style) return
|
|
64
|
+
|
|
65
|
+
if (isObject(style)) {
|
|
66
|
+
keysOf(style).forEach((prop) => removeStyle(element, prop))
|
|
67
|
+
} else {
|
|
68
|
+
setStyle(element, style, '')
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function addUnit (value, defaultUnit = 'px') {
|
|
73
|
+
if (!value) return ''
|
|
74
|
+
if (isNumber(value) || isStringNumber(value)) {
|
|
75
|
+
return `${value}${defaultUnit}`
|
|
76
|
+
} else if (isString(value)) {
|
|
77
|
+
return value
|
|
78
|
+
}
|
|
79
|
+
debugWarn(SCOPE, 'binding value must be a string or number')
|
|
80
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/* eslint-disable vue/prefer-import-from-vue */
|
|
2
|
+
import { isArray, isObject, isString } from '@vue/shared'
|
|
3
|
+
import { isNil } from 'lodash-unified'
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
isArray,
|
|
7
|
+
isFunction,
|
|
8
|
+
isObject,
|
|
9
|
+
isString,
|
|
10
|
+
isDate,
|
|
11
|
+
isPromise,
|
|
12
|
+
isSymbol,
|
|
13
|
+
} from '@vue/shared'
|
|
14
|
+
export { isVNode } from 'vue'
|
|
15
|
+
|
|
16
|
+
export const isUndefined = (val) => val === undefined
|
|
17
|
+
export const isBoolean = (val) => typeof val === 'boolean'
|
|
18
|
+
export const isNumber = (val) => typeof val === 'number'
|
|
19
|
+
|
|
20
|
+
export const isEmpty = (val) =>
|
|
21
|
+
(!val && val !== 0) ||
|
|
22
|
+
(isArray(val) && val.length === 0) ||
|
|
23
|
+
(isObject(val) && !Object.keys(val).length)
|
|
24
|
+
|
|
25
|
+
export const isElement = (e) => {
|
|
26
|
+
if (typeof Element === 'undefined') return false
|
|
27
|
+
return e instanceof Element
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const isPropAbsent = (prop) => {
|
|
31
|
+
return isNil(prop)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const isStringNumber = (val) => {
|
|
35
|
+
if (!isString(val)) {
|
|
36
|
+
return false
|
|
37
|
+
}
|
|
38
|
+
return !Number.isNaN(Number(val))
|
|
39
|
+
}
|