@tagplus/components 4.7.12 → 5.0.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/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 +11 -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 +51 -50
- 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 -767
- 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 +9 -14
- package/src/mixins/floatFormatter.js +12 -16
- package/src/plugins/currency.js +100 -0
- 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
- package/src/utils/currency.js +0 -180
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { defineComponent } from 'vue'
|
|
3
|
+
import Autosuggest from './Autosuggest.vue'
|
|
4
|
+
import autosuggestCore from '@src/components/Autosuggest/core.js'
|
|
5
|
+
import multisuggestProps from '@src/components/Autosuggest/multisuggest-props.js'
|
|
6
|
+
|
|
7
|
+
const multisuggestDefinition = autosuggestCore('TpMultisuggest', multisuggestProps)
|
|
8
|
+
/**
|
|
9
|
+
* O Multisuggest é um atalho para o Autosuggest com a prop multiple default true
|
|
10
|
+
* para manter o comportamento do multisuggest do element-ui que era um componente separado
|
|
11
|
+
* */
|
|
12
|
+
export default defineComponent(
|
|
13
|
+
{
|
|
14
|
+
...multisuggestDefinition,
|
|
15
|
+
extends: Autosuggest
|
|
16
|
+
}
|
|
17
|
+
)
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<style lang="scss" scoped>
|
|
21
|
+
@import "./autosuggest-style"
|
|
22
|
+
</style>
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { placements } from '@popperjs/core'
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated
|
|
6
|
+
* Faz o retorno do input imitar o comportamento antigo que voltava idValue/[...idValues] se recebesse modelValue Object/[...Objects]
|
|
7
|
+
* na versão nova vai sempre devolver o Objeto completo quando possível
|
|
8
|
+
*/
|
|
9
|
+
legacyModel: {
|
|
10
|
+
type: Boolean,
|
|
11
|
+
default: false,
|
|
12
|
+
},
|
|
13
|
+
/**
|
|
14
|
+
* @description native input id
|
|
15
|
+
*/
|
|
16
|
+
id: String,
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @description the name attribute of select input
|
|
20
|
+
*/
|
|
21
|
+
name: String,
|
|
22
|
+
|
|
23
|
+
modelValue: {
|
|
24
|
+
type: [Array, String, Number, Boolean, Object],
|
|
25
|
+
default: ''
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Lista ou Objeto contendo conjunto de itens como opções ou sugestões do componente
|
|
30
|
+
*/
|
|
31
|
+
suggestions: {
|
|
32
|
+
type: [Array, Object],
|
|
33
|
+
required: true
|
|
34
|
+
},
|
|
35
|
+
/**
|
|
36
|
+
* Informa o campo correspondente em cada item referente ao valor sendo selecionado
|
|
37
|
+
*/
|
|
38
|
+
valueKey: {
|
|
39
|
+
type: String,
|
|
40
|
+
default: 'id'
|
|
41
|
+
},
|
|
42
|
+
/**
|
|
43
|
+
* Identificação do campo correspondente em cada item referente ao texto de exibição.
|
|
44
|
+
* Quando utilizado o slot de itens, este campo passa a não ser utilizado
|
|
45
|
+
*/
|
|
46
|
+
labelKey: {
|
|
47
|
+
type: String,
|
|
48
|
+
default: 'label'
|
|
49
|
+
},
|
|
50
|
+
/**
|
|
51
|
+
* @description placeholder, default is 'Select'
|
|
52
|
+
*/
|
|
53
|
+
placeholder: {
|
|
54
|
+
type: String,
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* Sobrescreve valor padrão do atributo no Select do ElementUI
|
|
58
|
+
*/
|
|
59
|
+
defaultFirstOption: {
|
|
60
|
+
type: Boolean,
|
|
61
|
+
required: false,
|
|
62
|
+
default: true
|
|
63
|
+
},
|
|
64
|
+
/**
|
|
65
|
+
* Se a lista vai ser carregada no create ou o labelKey não venha por padrão na requisição loadOnCreate = true,
|
|
66
|
+
* caso deva ser carregada quando o usuário clica deixar vazio ou false.
|
|
67
|
+
*/
|
|
68
|
+
loadOnCreate: {
|
|
69
|
+
type: Boolean,
|
|
70
|
+
required: false,
|
|
71
|
+
default: true
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Método que realiza a busca dos registros remotos para as opções.
|
|
76
|
+
*
|
|
77
|
+
* *IMPORTANTE*: deve considerar o "valueKey" nas consultas
|
|
78
|
+
* pois o valor selecionado será baseado nas opções remotas carregadas ao criar o componente.
|
|
79
|
+
*/
|
|
80
|
+
remoteMethod: {
|
|
81
|
+
type: Function,
|
|
82
|
+
required: true
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Informa a mensagem de cadastrar novo item
|
|
87
|
+
*/
|
|
88
|
+
msgNewItem: {
|
|
89
|
+
type: String,
|
|
90
|
+
required: false,
|
|
91
|
+
default: 'Cadastrar novo item'
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @description whether Select is disabled
|
|
96
|
+
*/
|
|
97
|
+
disabled: Boolean,
|
|
98
|
+
/**
|
|
99
|
+
* @description whether creating new items is allowed. To use this, `filterable` must be true
|
|
100
|
+
*/
|
|
101
|
+
allowCreate: Boolean,
|
|
102
|
+
/**
|
|
103
|
+
* @description whether Select is loading data from server
|
|
104
|
+
*/
|
|
105
|
+
loading: Boolean,
|
|
106
|
+
/**
|
|
107
|
+
* @description custom class name for Select's dropdown
|
|
108
|
+
*/
|
|
109
|
+
popperClass: {
|
|
110
|
+
type: String,
|
|
111
|
+
default: '',
|
|
112
|
+
},
|
|
113
|
+
/**
|
|
114
|
+
* @description [popper.js](https://popper.js.org/docs/v2/) parameters
|
|
115
|
+
*/
|
|
116
|
+
popperOptions: {
|
|
117
|
+
type: Object,
|
|
118
|
+
default: () => ({}),
|
|
119
|
+
},
|
|
120
|
+
/**
|
|
121
|
+
* @description displayed text while loading data from server, default is 'Loading'
|
|
122
|
+
*/
|
|
123
|
+
loadingText: String,
|
|
124
|
+
/**
|
|
125
|
+
* @description displayed text when no data matches the filtering query, you can also use slot `empty`, default is 'No matching data'
|
|
126
|
+
*/
|
|
127
|
+
noMatchText: String,
|
|
128
|
+
/**
|
|
129
|
+
* @description displayed text when there is no options, you can also use slot `empty`, default is 'No data'
|
|
130
|
+
*/
|
|
131
|
+
noDataText: String,
|
|
132
|
+
/**
|
|
133
|
+
* @description tooltip theme, built-in theme: `dark` / `light`
|
|
134
|
+
*/
|
|
135
|
+
effect: {
|
|
136
|
+
type: String,
|
|
137
|
+
default: 'light',
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @description tag type
|
|
142
|
+
*/
|
|
143
|
+
tagType: { default: 'info' },
|
|
144
|
+
/**
|
|
145
|
+
* @description position of dropdown
|
|
146
|
+
*/
|
|
147
|
+
placement: {
|
|
148
|
+
type: String,
|
|
149
|
+
values: placements,
|
|
150
|
+
default: 'bottom-start',
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @tagplus
|
|
155
|
+
* Sobrescrito para ter o padrão true
|
|
156
|
+
* @description whether to collapse tags to a text when multiple selecting
|
|
157
|
+
*/
|
|
158
|
+
collapseTags: {
|
|
159
|
+
type:Boolean,
|
|
160
|
+
default:true
|
|
161
|
+
},
|
|
162
|
+
/**
|
|
163
|
+
* @tagplus
|
|
164
|
+
* Sobrescrito para ter o padrão true
|
|
165
|
+
* @description whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true
|
|
166
|
+
*/
|
|
167
|
+
collapseTagsTooltip: {
|
|
168
|
+
type:Boolean,
|
|
169
|
+
default:true
|
|
170
|
+
},
|
|
171
|
+
/**
|
|
172
|
+
* @description the max tags number to be shown. To use this, `collapse-tags` must be true
|
|
173
|
+
*/
|
|
174
|
+
maxCollapseTags: {
|
|
175
|
+
type: Number,
|
|
176
|
+
default: 1,
|
|
177
|
+
},
|
|
178
|
+
/**
|
|
179
|
+
* @description whether select dropdown is teleported to the body
|
|
180
|
+
*/
|
|
181
|
+
teleported: {
|
|
182
|
+
type: Boolean,
|
|
183
|
+
default: true
|
|
184
|
+
},
|
|
185
|
+
/**
|
|
186
|
+
* @description when select dropdown is inactive and `persistent` is `false`, select dropdown will be destroyed
|
|
187
|
+
*/
|
|
188
|
+
persistent: {
|
|
189
|
+
type: Boolean,
|
|
190
|
+
default: true,
|
|
191
|
+
},
|
|
192
|
+
/**
|
|
193
|
+
* @description native input aria-label
|
|
194
|
+
*/
|
|
195
|
+
ariaLabel: {
|
|
196
|
+
type: String,
|
|
197
|
+
default: undefined,
|
|
198
|
+
},
|
|
199
|
+
multiple: {
|
|
200
|
+
type: Boolean,
|
|
201
|
+
default: false
|
|
202
|
+
},
|
|
203
|
+
/**
|
|
204
|
+
* @description maximum number of options user can select when `multiple` is `true`. No limit when set to 0
|
|
205
|
+
*/
|
|
206
|
+
multipleLimit: {
|
|
207
|
+
type: Number,
|
|
208
|
+
default: 0,
|
|
209
|
+
}
|
|
210
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
.tp-autosuggest-clear-icon {
|
|
2
|
+
margin: 6px 6px 1px 6px;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
:deep() {
|
|
6
|
+
.el-select__input-wrapper {
|
|
7
|
+
width: 100%;
|
|
8
|
+
|
|
9
|
+
.el-input {
|
|
10
|
+
.el-input__inner {
|
|
11
|
+
width: 100%;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.el-input-group__prepend {
|
|
15
|
+
padding: 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.el-input-group__prepend::after {
|
|
19
|
+
// esconde barra vertical duplicada no search
|
|
20
|
+
display: none;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.el-input__wrapper {
|
|
24
|
+
// "borda" do <input> top e bottom
|
|
25
|
+
box-shadow: none;
|
|
26
|
+
border-top: 1px solid var(--el-input-border-color);
|
|
27
|
+
border-bottom: 1px solid var(--el-input-border-color);
|
|
28
|
+
padding-left: 8px;
|
|
29
|
+
|
|
30
|
+
.el-select__placeholder {
|
|
31
|
+
padding-left: 16px !important;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&.is-disabled {
|
|
36
|
+
|
|
37
|
+
.el-input__wrapper,
|
|
38
|
+
.el-tag {
|
|
39
|
+
cursor: not-allowed;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.el-input-group__append {
|
|
44
|
+
padding: 0;
|
|
45
|
+
|
|
46
|
+
.el-input__close {
|
|
47
|
+
width: 40px;
|
|
48
|
+
|
|
49
|
+
.tp-btn-close {
|
|
50
|
+
margin: auto;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.el-input-group__prepend,
|
|
56
|
+
.el-input-group__append {
|
|
57
|
+
background-color: var(--el-input-bg-color, var(--el-fill-color-blank));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.el-input-group__prepend,
|
|
61
|
+
.el-input-group__append,
|
|
62
|
+
.tp-autosuggest-clear-icon {
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
color: #606266;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.tp-autosuggest-vertical-divider {
|
|
71
|
+
height: 33.59px;
|
|
72
|
+
margin: 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.tp-autosuggest-input-prepend-icon {
|
|
76
|
+
display: flex;
|
|
77
|
+
margin: 0 10px -2px 12px;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.tp-autosuggest-loading {
|
|
81
|
+
text-align: center;
|
|
82
|
+
font-size: 1.5em;
|
|
83
|
+
padding: 10px;
|
|
84
|
+
margin: 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.tp-select-dropdown__list.el-select-dropdown__list {
|
|
88
|
+
li.el-select-dropdown__item {
|
|
89
|
+
line-height: 1.5em;
|
|
90
|
+
height: auto;
|
|
91
|
+
padding: $--popover-padding;
|
|
92
|
+
position: relative;
|
|
93
|
+
transition: 100ms all linear;
|
|
94
|
+
|
|
95
|
+
&.hover {
|
|
96
|
+
padding-left: 20px;
|
|
97
|
+
|
|
98
|
+
&::before {
|
|
99
|
+
position: absolute;
|
|
100
|
+
display: inline-block;
|
|
101
|
+
width: 4px;
|
|
102
|
+
top: 5px;
|
|
103
|
+
bottom: 5px;
|
|
104
|
+
left: 5px;
|
|
105
|
+
background: $--color-primary;
|
|
106
|
+
border-radius: 2px;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
&.selected {
|
|
111
|
+
color: $--color-text-regular;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
&.created a {
|
|
115
|
+
color: $--color-primary;
|
|
116
|
+
font-weight: normal;
|
|
117
|
+
border-bottom: 1px solid $--color-primary;
|
|
118
|
+
line-height: 1.5em;
|
|
119
|
+
display: inline-block;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
small {
|
|
123
|
+
font-size: $--font-size-base;
|
|
124
|
+
color: color-mix($--color-white, $--color-text-secondary, 40%);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
|
|
2
|
+
import { provide, reactive } from 'vue'
|
|
3
|
+
import { ClickOutside } from 'element-plus'
|
|
4
|
+
import { ArrowDown } from '@element-plus/icons-vue'
|
|
5
|
+
import ElSelectMenu from '@/components/Autosuggest/select-dropdown.vue'
|
|
6
|
+
import ElOption from '@/components/Autosuggest/option.vue'
|
|
7
|
+
import { useSelect } from '@/components/Autosuggest/useSelect'
|
|
8
|
+
|
|
9
|
+
export default function (component_name, propsDefinition) {
|
|
10
|
+
return {
|
|
11
|
+
name: component_name,
|
|
12
|
+
componentName: component_name,
|
|
13
|
+
|
|
14
|
+
directives: {
|
|
15
|
+
ClickOutside
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
components: {
|
|
19
|
+
ArrowDown,
|
|
20
|
+
ElOption,
|
|
21
|
+
ElSelectMenu
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
props: propsDefinition,
|
|
25
|
+
|
|
26
|
+
emits: [
|
|
27
|
+
'update:modelValue',
|
|
28
|
+
'change',
|
|
29
|
+
'remove-tag',
|
|
30
|
+
'clear',
|
|
31
|
+
'visible-change',
|
|
32
|
+
'focus',
|
|
33
|
+
'blur',
|
|
34
|
+
],
|
|
35
|
+
|
|
36
|
+
setup (props, context) {
|
|
37
|
+
const API = useSelect(props, context)
|
|
38
|
+
|
|
39
|
+
provide(
|
|
40
|
+
'select',
|
|
41
|
+
reactive({
|
|
42
|
+
props,
|
|
43
|
+
states: API.states,
|
|
44
|
+
optionsArray: API.optionsArray,
|
|
45
|
+
handleOptionSelect: API.handleOptionSelect,
|
|
46
|
+
onOptionCreate: API.onOptionCreate,
|
|
47
|
+
onOptionDestroy: API.onOptionDestroy,
|
|
48
|
+
selectRef: API.selectRef,
|
|
49
|
+
setSelected: API.setSelected,
|
|
50
|
+
})
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
return API
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
data () {
|
|
57
|
+
return {
|
|
58
|
+
visible: false,
|
|
59
|
+
tooltipVisible: false
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<li
|
|
3
|
+
v-show="visible"
|
|
4
|
+
:id="id"
|
|
5
|
+
:class="containerKls"
|
|
6
|
+
role="option"
|
|
7
|
+
:aria-disabled="isDisabled || undefined"
|
|
8
|
+
:aria-selected="itemSelected"
|
|
9
|
+
@mouseenter="hoverItem"
|
|
10
|
+
@click.stop="selectOptionClick"
|
|
11
|
+
>
|
|
12
|
+
<slot>
|
|
13
|
+
<span>{{ currentLabel }}</span>
|
|
14
|
+
</slot>
|
|
15
|
+
</li>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script>
|
|
19
|
+
// @ts-nocheck
|
|
20
|
+
import {
|
|
21
|
+
computed,
|
|
22
|
+
defineComponent,
|
|
23
|
+
getCurrentInstance,
|
|
24
|
+
nextTick,
|
|
25
|
+
onBeforeUnmount,
|
|
26
|
+
reactive,
|
|
27
|
+
toRefs,
|
|
28
|
+
unref,
|
|
29
|
+
} from 'vue'
|
|
30
|
+
import { useId, useNamespace } from 'element-plus/es/hooks/index'
|
|
31
|
+
import { useOption } from '@/components/Autosuggest/useOption'
|
|
32
|
+
|
|
33
|
+
export default defineComponent({
|
|
34
|
+
name: 'ElOption',
|
|
35
|
+
componentName: 'ElOption',
|
|
36
|
+
|
|
37
|
+
props: {
|
|
38
|
+
/**
|
|
39
|
+
* @description value of option
|
|
40
|
+
*/
|
|
41
|
+
value: {
|
|
42
|
+
required: true,
|
|
43
|
+
type: [String, Number, Boolean, Object, null],
|
|
44
|
+
},
|
|
45
|
+
/**
|
|
46
|
+
* @description label of option, same as `value` if omitted
|
|
47
|
+
*/
|
|
48
|
+
label: [String, Number],
|
|
49
|
+
created: Boolean,
|
|
50
|
+
/**
|
|
51
|
+
* @description whether option is disabled
|
|
52
|
+
*/
|
|
53
|
+
disabled: Boolean,
|
|
54
|
+
/**
|
|
55
|
+
* @tagplus
|
|
56
|
+
* @description recebe o item inteiro para ser emitido, ao inves de somente key/value
|
|
57
|
+
*/
|
|
58
|
+
item: {
|
|
59
|
+
type: [String, Number, Boolean, Object],
|
|
60
|
+
required: true
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
setup (props) {
|
|
65
|
+
const ns = useNamespace('select')
|
|
66
|
+
const id = useId()
|
|
67
|
+
|
|
68
|
+
const containerKls = computed(() => [
|
|
69
|
+
ns.be('dropdown', 'item'),
|
|
70
|
+
ns.is('disabled', unref(isDisabled)),
|
|
71
|
+
ns.is('selected', unref(itemSelected)),
|
|
72
|
+
ns.is('hovering', unref(hover)),
|
|
73
|
+
])
|
|
74
|
+
|
|
75
|
+
const states = reactive({
|
|
76
|
+
index: -1,
|
|
77
|
+
groupDisabled: false,
|
|
78
|
+
visible: true,
|
|
79
|
+
hover: false,
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
const {
|
|
83
|
+
currentLabel,
|
|
84
|
+
itemSelected,
|
|
85
|
+
isDisabled,
|
|
86
|
+
select,
|
|
87
|
+
hoverItem,
|
|
88
|
+
updateOption,
|
|
89
|
+
} = useOption(props, states)
|
|
90
|
+
|
|
91
|
+
const { visible, hover } = toRefs(states)
|
|
92
|
+
|
|
93
|
+
const vm = getCurrentInstance().proxy
|
|
94
|
+
|
|
95
|
+
select.onOptionCreate(vm)
|
|
96
|
+
|
|
97
|
+
onBeforeUnmount(() => {
|
|
98
|
+
const key = vm.value
|
|
99
|
+
const { selected } = select.states
|
|
100
|
+
const selectedOptions = select.props.multiple ? selected : [selected]
|
|
101
|
+
const doesSelected = selectedOptions.some((item) => {
|
|
102
|
+
return item.value === vm.value
|
|
103
|
+
})
|
|
104
|
+
// if option is not selected, remove it from cache
|
|
105
|
+
nextTick(() => {
|
|
106
|
+
if (select.states.cachedOptions.get(key) === vm && !doesSelected) {
|
|
107
|
+
select.states.cachedOptions.delete(key)
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
select.onOptionDestroy(key, vm)
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
function selectOptionClick () {
|
|
114
|
+
if (props.disabled !== true && states.groupDisabled !== true) {
|
|
115
|
+
select.handleOptionSelect(vm)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
ns,
|
|
121
|
+
id,
|
|
122
|
+
containerKls,
|
|
123
|
+
currentLabel,
|
|
124
|
+
itemSelected,
|
|
125
|
+
isDisabled,
|
|
126
|
+
select,
|
|
127
|
+
hoverItem,
|
|
128
|
+
updateOption,
|
|
129
|
+
visible,
|
|
130
|
+
hover,
|
|
131
|
+
selectOptionClick,
|
|
132
|
+
states,
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
})
|
|
136
|
+
</script>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
:class="[ns.b('dropdown'), ns.is('multiple', isMultiple), popperClass]"
|
|
4
|
+
:style="{ [isFitInputWidth ? 'width' : 'minWidth']: minWidth }"
|
|
5
|
+
>
|
|
6
|
+
<div v-if="$slots.header" :class="ns.be('dropdown', 'header')">
|
|
7
|
+
<slot name="header" />
|
|
8
|
+
</div>
|
|
9
|
+
<slot />
|
|
10
|
+
<div v-if="$slots.footer" :class="ns.be('dropdown', 'footer')">
|
|
11
|
+
<slot name="footer" />
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<script>
|
|
17
|
+
import { defineComponent, ref } from 'vue'
|
|
18
|
+
import { useResizeObserver } from '@vueuse/core'
|
|
19
|
+
import { useNamespace } from 'element-plus/es/hooks/index'
|
|
20
|
+
|
|
21
|
+
export default defineComponent({
|
|
22
|
+
name: 'ElSelectDropdown',
|
|
23
|
+
|
|
24
|
+
componentName: 'ElSelectDropdown',
|
|
25
|
+
|
|
26
|
+
inject: ['select'],
|
|
27
|
+
|
|
28
|
+
setup () {
|
|
29
|
+
const ns = useNamespace('select')
|
|
30
|
+
const minWidth = ref('')
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
ns,
|
|
34
|
+
minWidth,
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
computed: {
|
|
39
|
+
popperClass () {
|
|
40
|
+
return this.select.popperClass
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
isMultiple (){
|
|
44
|
+
return this.select.multiple
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
isFitInputWidth (){
|
|
48
|
+
return this.select.fitInputWidth
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
mounted () {
|
|
54
|
+
this.updateMinWidth()
|
|
55
|
+
useResizeObserver(this.select.selectRef, this.updateMinWidth)
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
methods: {
|
|
59
|
+
updateMinWidth () {
|
|
60
|
+
this.minWidth = `${this.select.selectRef?.offsetWidth}px`
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
</script>
|