quasar 2.8.3 → 2.8.4
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/api/QBtnDropdown.json +9 -0
- package/dist/api/QChip.json +9 -0
- package/dist/api/QCircularProgress.json +6 -0
- package/dist/api/QExpansionItem.json +59 -0
- package/dist/api/QTable.json +2 -2
- package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
- package/dist/icon-set/eva-icons.umd.prod.js +1 -1
- package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
- package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
- package/dist/icon-set/fontawesome-v6-pro.umd.prod.js +1 -1
- package/dist/icon-set/fontawesome-v6.umd.prod.js +1 -1
- package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
- package/dist/icon-set/line-awesome.umd.prod.js +1 -1
- package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
- package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
- package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
- package/dist/icon-set/material-icons.umd.prod.js +1 -1
- package/dist/icon-set/material-symbols-outlined.umd.prod.js +1 -1
- package/dist/icon-set/material-symbols-rounded.umd.prod.js +1 -1
- package/dist/icon-set/material-symbols-sharp.umd.prod.js +1 -1
- package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
- package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
- package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
- package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
- package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
- package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
- package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
- package/dist/icon-set/svg-fontawesome-v6.umd.prod.js +1 -1
- package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
- package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
- package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
- package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
- package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
- package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
- package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
- package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
- package/dist/icon-set/svg-material-symbols-outlined.umd.prod.js +1 -1
- package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +1 -1
- package/dist/icon-set/svg-material-symbols-sharp.umd.prod.js +1 -1
- package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
- package/dist/icon-set/svg-themify.umd.prod.js +1 -1
- package/dist/icon-set/themify.umd.prod.js +1 -1
- package/dist/lang/ar-TN.umd.prod.js +2 -2
- package/dist/lang/ar.umd.prod.js +2 -2
- package/dist/lang/az-Latn.umd.prod.js +2 -2
- package/dist/lang/bg.umd.prod.js +2 -2
- package/dist/lang/bn.umd.prod.js +2 -2
- package/dist/lang/ca.umd.prod.js +2 -2
- package/dist/lang/cs.umd.prod.js +2 -2
- package/dist/lang/da.umd.prod.js +2 -2
- package/dist/lang/de.umd.prod.js +2 -2
- package/dist/lang/el.umd.prod.js +2 -2
- package/dist/lang/en-GB.umd.prod.js +2 -2
- package/dist/lang/en-US.umd.prod.js +2 -2
- package/dist/lang/eo.umd.prod.js +2 -2
- package/dist/lang/es.umd.prod.js +2 -2
- package/dist/lang/et.umd.prod.js +2 -2
- package/dist/lang/eu.umd.prod.js +2 -2
- package/dist/lang/fa-IR.umd.prod.js +2 -2
- package/dist/lang/fa.umd.prod.js +2 -2
- package/dist/lang/fi.umd.prod.js +2 -2
- package/dist/lang/fr.umd.prod.js +2 -2
- package/dist/lang/gn.umd.prod.js +2 -2
- package/dist/lang/he.umd.prod.js +2 -2
- package/dist/lang/hr.umd.prod.js +2 -2
- package/dist/lang/hu.umd.prod.js +2 -2
- package/dist/lang/id.umd.prod.js +2 -2
- package/dist/lang/is.umd.prod.js +2 -2
- package/dist/lang/it.umd.prod.js +2 -2
- package/dist/lang/ja.umd.prod.js +2 -2
- package/dist/lang/km.umd.prod.js +2 -2
- package/dist/lang/ko-KR.umd.prod.js +2 -2
- package/dist/lang/kur-CKB.umd.prod.js +2 -2
- package/dist/lang/kz.umd.prod.js +2 -2
- package/dist/lang/lt.umd.prod.js +2 -2
- package/dist/lang/lu.umd.prod.js +2 -2
- package/dist/lang/lv.umd.prod.js +2 -2
- package/dist/lang/ml.umd.prod.js +2 -2
- package/dist/lang/mm.umd.prod.js +2 -2
- package/dist/lang/ms.umd.prod.js +2 -2
- package/dist/lang/my.umd.prod.js +2 -2
- package/dist/lang/nb-NO.umd.prod.js +2 -2
- package/dist/lang/nl.umd.prod.js +2 -2
- package/dist/lang/pl.umd.prod.js +2 -2
- package/dist/lang/pt-BR.umd.prod.js +2 -2
- package/dist/lang/pt.umd.prod.js +2 -2
- package/dist/lang/ro.umd.prod.js +2 -2
- package/dist/lang/ru.umd.prod.js +2 -2
- package/dist/lang/sk.umd.prod.js +2 -2
- package/dist/lang/sl.umd.prod.js +2 -2
- package/dist/lang/sm.umd.prod.js +2 -2
- package/dist/lang/sr-CYR.umd.prod.js +2 -2
- package/dist/lang/sr.umd.prod.js +2 -2
- package/dist/lang/sv.umd.prod.js +2 -2
- package/dist/lang/ta.umd.prod.js +2 -2
- package/dist/lang/th.umd.prod.js +2 -2
- package/dist/lang/tr.umd.prod.js +2 -2
- package/dist/lang/ug.umd.prod.js +2 -2
- package/dist/lang/uk.umd.prod.js +2 -2
- package/dist/lang/uz-Cyrl.umd.prod.js +2 -2
- package/dist/lang/uz-Latn.umd.prod.js +2 -2
- package/dist/lang/vi.umd.prod.js +2 -2
- package/dist/lang/zh-CN.umd.prod.js +2 -2
- package/dist/lang/zh-TW.umd.prod.js +2 -2
- package/dist/quasar.cjs.prod.js +2 -2
- package/dist/quasar.esm.js +15693 -15455
- package/dist/quasar.esm.prod.js +2 -2
- package/dist/quasar.sass +1 -1
- package/dist/quasar.umd.js +15866 -15626
- package/dist/quasar.umd.prod.js +2 -2
- package/dist/transforms/import-map.json +2 -0
- package/dist/types/api/qloading.d.ts +5 -0
- package/dist/types/api.d.ts +1 -0
- package/dist/types/index.d.ts +40 -1
- package/dist/types/utils/is.d.ts +67 -0
- package/dist/types/utils/run-sequential-promises.d.ts +119 -0
- package/dist/types/utils.d.ts +9 -0
- package/dist/vetur/quasar-attributes.json +21 -1
- package/dist/vetur/quasar-tags.json +6 -1
- package/dist/web-types/web-types.json +49 -2
- package/lang/ar-TN.js +3 -1
- package/lang/ar-TN.mjs +3 -1
- package/lang/ar.js +3 -1
- package/lang/ar.mjs +3 -1
- package/lang/az-Latn.js +3 -1
- package/lang/az-Latn.mjs +3 -1
- package/lang/bg.js +3 -1
- package/lang/bg.mjs +3 -1
- package/lang/bn.js +3 -1
- package/lang/bn.mjs +3 -1
- package/lang/ca.js +3 -1
- package/lang/ca.mjs +3 -1
- package/lang/cs.js +3 -1
- package/lang/cs.mjs +3 -1
- package/lang/da.js +3 -1
- package/lang/da.mjs +3 -1
- package/lang/de.js +3 -1
- package/lang/de.mjs +3 -1
- package/lang/el.js +3 -1
- package/lang/el.mjs +3 -1
- package/lang/en-GB.js +3 -1
- package/lang/en-GB.mjs +3 -1
- package/lang/en-US.js +3 -1
- package/lang/en-US.mjs +3 -1
- package/lang/eo.js +3 -1
- package/lang/eo.mjs +3 -1
- package/lang/es.js +3 -1
- package/lang/es.mjs +3 -1
- package/lang/et.js +3 -1
- package/lang/et.mjs +3 -1
- package/lang/eu.js +3 -1
- package/lang/eu.mjs +3 -1
- package/lang/fa-IR.js +5 -3
- package/lang/fa-IR.mjs +5 -3
- package/lang/fa.js +5 -3
- package/lang/fa.mjs +5 -3
- package/lang/fi.js +3 -1
- package/lang/fi.mjs +3 -1
- package/lang/fr.js +3 -1
- package/lang/fr.mjs +3 -1
- package/lang/gn.js +3 -1
- package/lang/gn.mjs +3 -1
- package/lang/he.js +3 -1
- package/lang/he.mjs +3 -1
- package/lang/hr.js +3 -1
- package/lang/hr.mjs +3 -1
- package/lang/hu.js +3 -1
- package/lang/hu.mjs +3 -1
- package/lang/id.js +3 -1
- package/lang/id.mjs +3 -1
- package/lang/is.js +3 -1
- package/lang/is.mjs +3 -1
- package/lang/it.js +3 -1
- package/lang/it.mjs +3 -1
- package/lang/ja.js +3 -1
- package/lang/ja.mjs +3 -1
- package/lang/km.js +3 -1
- package/lang/km.mjs +3 -1
- package/lang/ko-KR.js +3 -1
- package/lang/ko-KR.mjs +3 -1
- package/lang/kur-CKB.js +3 -1
- package/lang/kur-CKB.mjs +3 -1
- package/lang/kz.js +3 -1
- package/lang/kz.mjs +3 -1
- package/lang/lt.js +3 -1
- package/lang/lt.mjs +3 -1
- package/lang/lu.js +3 -1
- package/lang/lu.mjs +3 -1
- package/lang/lv.js +3 -1
- package/lang/lv.mjs +3 -1
- package/lang/ml.js +3 -1
- package/lang/ml.mjs +3 -1
- package/lang/mm.js +4 -1
- package/lang/mm.mjs +4 -1
- package/lang/ms.js +3 -1
- package/lang/ms.mjs +3 -1
- package/lang/my.js +3 -1
- package/lang/my.mjs +3 -1
- package/lang/nb-NO.js +3 -1
- package/lang/nb-NO.mjs +3 -1
- package/lang/nl.js +3 -1
- package/lang/nl.mjs +3 -1
- package/lang/pl.js +3 -1
- package/lang/pl.mjs +3 -1
- package/lang/pt-BR.js +3 -1
- package/lang/pt-BR.mjs +3 -1
- package/lang/pt.js +3 -1
- package/lang/pt.mjs +3 -1
- package/lang/ro.js +3 -1
- package/lang/ro.mjs +3 -1
- package/lang/ru.js +3 -1
- package/lang/ru.mjs +3 -1
- package/lang/sk.js +3 -1
- package/lang/sk.mjs +3 -1
- package/lang/sl.js +3 -1
- package/lang/sl.mjs +3 -1
- package/lang/sm.js +3 -1
- package/lang/sm.mjs +3 -1
- package/lang/sr-CYR.js +3 -1
- package/lang/sr-CYR.mjs +3 -1
- package/lang/sr.js +3 -1
- package/lang/sr.mjs +3 -1
- package/lang/sv.js +3 -1
- package/lang/sv.mjs +3 -1
- package/lang/ta.js +3 -1
- package/lang/ta.mjs +3 -1
- package/lang/th.js +3 -1
- package/lang/th.mjs +3 -1
- package/lang/tr.js +3 -1
- package/lang/tr.mjs +3 -1
- package/lang/ug.js +5 -3
- package/lang/ug.mjs +5 -3
- package/lang/uk.js +3 -1
- package/lang/uk.mjs +3 -1
- package/lang/uz-Cyrl.js +3 -1
- package/lang/uz-Cyrl.mjs +3 -1
- package/lang/uz-Latn.js +3 -1
- package/lang/uz-Latn.mjs +3 -1
- package/lang/vi.js +3 -1
- package/lang/vi.mjs +3 -1
- package/lang/zh-CN.js +3 -1
- package/lang/zh-CN.mjs +3 -1
- package/lang/zh-TW.js +3 -1
- package/lang/zh-TW.mjs +3 -1
- package/package.json +4 -5
- package/src/components/btn-dropdown/QBtnDropdown.js +10 -2
- package/src/components/btn-dropdown/QBtnDropdown.json +8 -0
- package/src/components/chip/QChip.js +9 -2
- package/src/components/chip/QChip.json +8 -0
- package/src/components/chip/__tests__/QChip.spec.js +359 -46
- package/src/components/circular-progress/QCircularProgress.js +4 -2
- package/src/components/circular-progress/QCircularProgress.json +7 -0
- package/src/components/circular-progress/use-circular-progress.js +1 -0
- package/src/components/dialog/QDialog.js +1 -0
- package/src/components/expansion-item/QExpansionItem.js +37 -8
- package/src/components/expansion-item/QExpansionItem.json +67 -0
- package/src/components/fab/QFab.js +20 -1
- package/src/components/form/QForm.js +35 -40
- package/src/components/form/QFormChildMixin.js +3 -1
- package/src/components/menu/QMenu.js +1 -0
- package/src/components/page/QPage.js +1 -1
- package/src/components/select/QSelect.js +1 -4
- package/src/components/table/QTable.js +1 -1
- package/src/components/table/QTable.json +2 -2
- package/src/components/tabs/QTabs.js +2 -1
- package/src/components/time/QTime.js +2 -2
- package/src/components/uploader/uploader-core.js +2 -3
- package/src/composables/private/use-file.js +1 -1
- package/src/composables/private/use-validate.js +7 -13
- package/src/composables/use-form-child.js +6 -4
- package/src/utils/EventBus.js +64 -0
- package/src/utils/private/vm.js +4 -0
- package/src/utils/run-sequential-promises.js +115 -0
- package/src/utils.js +4 -0
|
@@ -33,6 +33,14 @@
|
|
|
33
33
|
"category": "style"
|
|
34
34
|
},
|
|
35
35
|
|
|
36
|
+
"toggle-aria-label": {
|
|
37
|
+
"type": "String",
|
|
38
|
+
"desc": "aria-label to be used on the expansion toggle element",
|
|
39
|
+
"examples": [ "Open details" ],
|
|
40
|
+
"category": "content",
|
|
41
|
+
"addedIn": "v2.8.4"
|
|
42
|
+
},
|
|
43
|
+
|
|
36
44
|
"label": {
|
|
37
45
|
"type": "String",
|
|
38
46
|
"desc": "Header label (unless using 'header' slot)",
|
|
@@ -103,6 +111,13 @@
|
|
|
103
111
|
"category": "behavior"
|
|
104
112
|
},
|
|
105
113
|
|
|
114
|
+
"hide-expand-icon": {
|
|
115
|
+
"type": "Boolean",
|
|
116
|
+
"desc": "Do not show the expand icon",
|
|
117
|
+
"category": "content",
|
|
118
|
+
"addedIn": "v2.8.4"
|
|
119
|
+
},
|
|
120
|
+
|
|
106
121
|
"expand-icon-toggle": {
|
|
107
122
|
"type": "Boolean",
|
|
108
123
|
"desc": "Applies the expansion events to the expand icon only and not to the whole header",
|
|
@@ -169,6 +184,58 @@
|
|
|
169
184
|
"type": "Boolean",
|
|
170
185
|
"desc": "QExpansionItem expanded status",
|
|
171
186
|
"addedIn": "v2.7.6"
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
"detailsId": {
|
|
190
|
+
"type": "String",
|
|
191
|
+
"desc": "QExpansionItem details panel id (for use in aria-controls)",
|
|
192
|
+
"__exemption": [ "examples" ],
|
|
193
|
+
"addedIn": "v2.8.4"
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
"show": {
|
|
197
|
+
"type": "Function",
|
|
198
|
+
"desc": "Triggers component to show",
|
|
199
|
+
"params": {
|
|
200
|
+
"evt": {
|
|
201
|
+
"type": "Object",
|
|
202
|
+
"required": false,
|
|
203
|
+
"desc": "JS event object",
|
|
204
|
+
"__exemption": [ "examples" ]
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"returns": null,
|
|
208
|
+
"addedIn": "v2.8.4"
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
"hide": {
|
|
212
|
+
"type": "Function",
|
|
213
|
+
"desc": "Triggers component to hide",
|
|
214
|
+
"params": {
|
|
215
|
+
"evt": {
|
|
216
|
+
"type": "Object",
|
|
217
|
+
"required": false,
|
|
218
|
+
"desc": "JS event object",
|
|
219
|
+
"__exemption": [ "examples" ]
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
"returns": null,
|
|
223
|
+
"addedIn": "v2.8.4"
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
"toggle": {
|
|
227
|
+
"type": "Function",
|
|
228
|
+
"desc": "Triggers component to toggle between show/hide",
|
|
229
|
+
"params": {
|
|
230
|
+
"evt": {
|
|
231
|
+
"type": "Object",
|
|
232
|
+
"required": false,
|
|
233
|
+
"desc": "JS event object",
|
|
234
|
+
"__exemption": [ "examples" ]
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
"returns": null,
|
|
238
|
+
"addedIn": "v2.8.4"
|
|
172
239
|
}
|
|
173
240
|
}
|
|
174
241
|
}
|
|
@@ -9,6 +9,7 @@ import useModelToggle, { useModelToggleProps, useModelToggleEmits } from '../../
|
|
|
9
9
|
import { createComponent } from '../../utils/private/create.js'
|
|
10
10
|
import { hSlot, hMergeSlot } from '../../utils/private/render.js'
|
|
11
11
|
import { fabKey } from '../../utils/private/symbols.js'
|
|
12
|
+
import uid from '../../utils/uid.js'
|
|
12
13
|
|
|
13
14
|
const directions = [ 'up', 'right', 'down', 'left' ]
|
|
14
15
|
const alignValues = [ 'left', 'center', 'right' ]
|
|
@@ -48,6 +49,7 @@ export default createComponent({
|
|
|
48
49
|
setup (props, { slots }) {
|
|
49
50
|
const triggerRef = ref(null)
|
|
50
51
|
const showing = ref(props.modelValue === true)
|
|
52
|
+
const targetUid = uid()
|
|
51
53
|
|
|
52
54
|
const { proxy: { $q } } = getCurrentInstance()
|
|
53
55
|
const { formClass, labelProps } = useFab(props, showing)
|
|
@@ -73,6 +75,21 @@ export default createComponent({
|
|
|
73
75
|
+ ` q-fab__actions--${ showing.value === true ? 'opened' : 'closed' }`
|
|
74
76
|
)
|
|
75
77
|
|
|
78
|
+
const actionAttrs = computed(() => {
|
|
79
|
+
const attrs = {
|
|
80
|
+
id: targetUid
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (showing.value === true) {
|
|
84
|
+
attrs.role = 'menu'
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
attrs[ 'aria-hidden' ] = 'true'
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return attrs
|
|
91
|
+
})
|
|
92
|
+
|
|
76
93
|
const iconHolderClass = computed(() =>
|
|
77
94
|
'q-fab__icon-holder '
|
|
78
95
|
+ ` q-fab__icon-holder--${ showing.value === true ? 'opened' : 'closed' }`
|
|
@@ -134,10 +151,12 @@ export default createComponent({
|
|
|
134
151
|
fab: true,
|
|
135
152
|
'aria-expanded': showing.value === true ? 'true' : 'false',
|
|
136
153
|
'aria-haspopup': 'true',
|
|
154
|
+
'aria-controls': targetUid,
|
|
155
|
+
'aria-owns': targetUid,
|
|
137
156
|
onClick: toggle
|
|
138
157
|
}, getTriggerContent),
|
|
139
158
|
|
|
140
|
-
h('div', { class: actionClass.value }, hSlot(slots.default))
|
|
159
|
+
h('div', { class: actionClass.value, ...actionAttrs.value }, hSlot(slots.default))
|
|
141
160
|
])
|
|
142
161
|
}
|
|
143
162
|
})
|
|
@@ -5,6 +5,7 @@ import { stopAndPrevent } from '../../utils/event.js'
|
|
|
5
5
|
import { addFocusFn } from '../../utils/private/focus-manager.js'
|
|
6
6
|
import { hSlot } from '../../utils/private/render.js'
|
|
7
7
|
import { formKey } from '../../utils/private/symbols.js'
|
|
8
|
+
import { vmIsDestroyed } from '../../utils/private/vm.js'
|
|
8
9
|
|
|
9
10
|
export default createComponent({
|
|
10
11
|
name: 'QForm',
|
|
@@ -28,7 +29,6 @@ export default createComponent({
|
|
|
28
29
|
const registeredComponents = []
|
|
29
30
|
|
|
30
31
|
function validate (shouldFocus) {
|
|
31
|
-
const promises = []
|
|
32
32
|
const focus = typeof shouldFocus === 'boolean'
|
|
33
33
|
? shouldFocus
|
|
34
34
|
: props.noErrorFocus !== true
|
|
@@ -39,60 +39,55 @@ export default createComponent({
|
|
|
39
39
|
emit('validation-' + (res === true ? 'success' : 'error'), ref)
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
const comp = registeredComponents[ i ]
|
|
42
|
+
const validateComponent = comp => {
|
|
44
43
|
const valid = comp.validate()
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
valid
|
|
49
|
-
|
|
50
|
-
err => ({ valid: false, comp, err })
|
|
51
|
-
)
|
|
45
|
+
return typeof valid.then === 'function'
|
|
46
|
+
? valid.then(
|
|
47
|
+
valid => ({ valid, comp }),
|
|
48
|
+
err => ({ valid: false, comp, err })
|
|
52
49
|
)
|
|
53
|
-
|
|
54
|
-
else if (valid !== true) {
|
|
55
|
-
if (props.greedy === false) {
|
|
56
|
-
emitEvent(false, comp)
|
|
57
|
-
|
|
58
|
-
if (focus === true && typeof comp.focus === 'function') {
|
|
59
|
-
comp.focus()
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return Promise.resolve(false)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
promises.push({ valid: false, comp })
|
|
66
|
-
}
|
|
50
|
+
: Promise.resolve({ valid, comp })
|
|
67
51
|
}
|
|
68
52
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
53
|
+
const errorsPromise = props.greedy === true
|
|
54
|
+
? Promise
|
|
55
|
+
.all(registeredComponents.map(validateComponent))
|
|
56
|
+
.then(res => res.filter(r => r.valid !== true))
|
|
57
|
+
: registeredComponents
|
|
58
|
+
.reduce(
|
|
59
|
+
(acc, comp) => acc.then(() => {
|
|
60
|
+
return validateComponent(comp).then(r => {
|
|
61
|
+
if (r.valid === false) { return Promise.reject(r) }
|
|
62
|
+
})
|
|
63
|
+
}),
|
|
64
|
+
Promise.resolve()
|
|
65
|
+
)
|
|
66
|
+
.catch(error => [ error ])
|
|
76
67
|
|
|
77
|
-
|
|
68
|
+
return errorsPromise.then(errors => {
|
|
69
|
+
if (errors === void 0 || errors.length === 0) {
|
|
78
70
|
index === validateIndex && emitEvent(true)
|
|
79
71
|
return true
|
|
80
72
|
}
|
|
81
73
|
|
|
82
|
-
const { valid, comp, err } = errors[ 0 ]
|
|
83
|
-
|
|
84
74
|
// if not outdated already
|
|
85
75
|
if (index === validateIndex) {
|
|
86
|
-
err
|
|
76
|
+
const { comp, err } = errors[ 0 ]
|
|
87
77
|
|
|
78
|
+
err !== void 0 && console.error(err)
|
|
88
79
|
emitEvent(false, comp)
|
|
89
80
|
|
|
90
|
-
if (
|
|
91
|
-
focus
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
81
|
+
if (focus === true) {
|
|
82
|
+
// Try to focus first mounted and active component
|
|
83
|
+
const activeError = errors.find(({ comp }) => (
|
|
84
|
+
typeof comp.focus === 'function'
|
|
85
|
+
&& vmIsDestroyed(comp.$) === false
|
|
86
|
+
))
|
|
87
|
+
|
|
88
|
+
if (activeError !== void 0) {
|
|
89
|
+
activeError.comp.focus()
|
|
90
|
+
}
|
|
96
91
|
}
|
|
97
92
|
}
|
|
98
93
|
|
|
@@ -28,12 +28,14 @@ export default {
|
|
|
28
28
|
resetValidation () {}
|
|
29
29
|
},
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
mounted () {
|
|
32
|
+
// register to parent QForm
|
|
32
33
|
const $form = this.$.provides[ formKey ]
|
|
33
34
|
$form !== void 0 && this.disable !== true && $form.bindComponent(this)
|
|
34
35
|
},
|
|
35
36
|
|
|
36
37
|
beforeUnmount () {
|
|
38
|
+
// un-register from parent QForm
|
|
37
39
|
const $form = this.$.provides[ formKey ]
|
|
38
40
|
$form !== void 0 && this.disable !== true && $form.unbindComponent(this)
|
|
39
41
|
}
|
|
@@ -273,16 +273,13 @@ export default createComponent({
|
|
|
273
273
|
tabindex: props.tabindex,
|
|
274
274
|
role: 'combobox',
|
|
275
275
|
'aria-label': props.label,
|
|
276
|
+
'aria-readonly': props.readonly === true ? 'true' : 'false',
|
|
276
277
|
'aria-autocomplete': props.useInput === true ? 'list' : 'none',
|
|
277
278
|
'aria-expanded': menu.value === true ? 'true' : 'false',
|
|
278
279
|
'aria-owns': `${ state.targetUid.value }_lb`,
|
|
279
280
|
'aria-controls': `${ state.targetUid.value }_lb`
|
|
280
281
|
}
|
|
281
282
|
|
|
282
|
-
if (optionIndex.value >= 0) {
|
|
283
|
-
attrs[ 'aria-activedescendant' ] = `${ state.targetUid.value }_${ optionIndex.value }`
|
|
284
|
-
}
|
|
285
|
-
|
|
286
283
|
return attrs
|
|
287
284
|
})
|
|
288
285
|
|
|
@@ -348,7 +348,7 @@ export default createComponent({
|
|
|
348
348
|
|
|
349
349
|
if (rowEl !== null) {
|
|
350
350
|
const scrollTarget = rootRef.value.querySelector('.q-table__middle.scroll')
|
|
351
|
-
const
|
|
351
|
+
const offsetTop = rowEl.offsetTop - props.virtualScrollStickySizeStart
|
|
352
352
|
const direction = offsetTop < scrollTarget.scrollTop ? 'decrease' : 'increase'
|
|
353
353
|
|
|
354
354
|
scrollTarget.scrollTop = offsetTop
|
|
@@ -77,10 +77,10 @@
|
|
|
77
77
|
|
|
78
78
|
"virtual-scroll-sticky-size-start": {
|
|
79
79
|
"type": [ "Number", "String" ],
|
|
80
|
-
"desc": "Size in pixels of the sticky header (if using one); A correct value will improve scroll precision",
|
|
80
|
+
"desc": "Size in pixels of the sticky header (if using one); A correct value will improve scroll precision; Will be also used for non-virtual-scroll tables for fixing top alignment when using scrollTo method",
|
|
81
81
|
"default": "0",
|
|
82
82
|
"examples": [ "virtual-scroll-sticky-size-start=\"48\"" ],
|
|
83
|
-
"category": "virtual-scroll"
|
|
83
|
+
"category": "virtual-scroll|behavior"
|
|
84
84
|
},
|
|
85
85
|
|
|
86
86
|
"virtual-scroll-sticky-size-end": {
|
|
@@ -11,6 +11,7 @@ import { noop } from '../../utils/event.js'
|
|
|
11
11
|
import { hSlot } from '../../utils/private/render.js'
|
|
12
12
|
import { tabsKey } from '../../utils/private/symbols.js'
|
|
13
13
|
import { rtlHasScrollBug } from '../../utils/private/rtl.js'
|
|
14
|
+
import { vmIsDestroyed } from '../../utils/private/vm.js'
|
|
14
15
|
|
|
15
16
|
function getIndicatorClass (color, top, vertical) {
|
|
16
17
|
const pos = vertical === true
|
|
@@ -180,7 +181,7 @@ export default createComponent({
|
|
|
180
181
|
|
|
181
182
|
function recalculateScroll () {
|
|
182
183
|
registerScrollTick(() => {
|
|
183
|
-
if (vm
|
|
184
|
+
if (vmIsDestroyed(vm) === false) {
|
|
184
185
|
updateContainer({
|
|
185
186
|
width: rootRef.value.offsetWidth,
|
|
186
187
|
height: rootRef.value.offsetHeight
|
|
@@ -12,6 +12,7 @@ import { hSlot } from '../../utils/private/render.js'
|
|
|
12
12
|
import { formatDate, __splitDate } from '../../utils/date.js'
|
|
13
13
|
import { position } from '../../utils/event.js'
|
|
14
14
|
import { pad } from '../../utils/format.js'
|
|
15
|
+
import { vmIsDestroyed } from '../../utils/private/vm.js'
|
|
15
16
|
|
|
16
17
|
function getViewByModel (model, withSeconds) {
|
|
17
18
|
if (model.hour !== null) {
|
|
@@ -386,8 +387,7 @@ export default createComponent({
|
|
|
386
387
|
}
|
|
387
388
|
|
|
388
389
|
function shouldAbortInteraction () {
|
|
389
|
-
return vm
|
|
390
|
-
|| vm.isUnmounted === true
|
|
390
|
+
return vmIsDestroyed(vm) === true
|
|
391
391
|
// if we have limited options, can we actually set any?
|
|
392
392
|
|| (
|
|
393
393
|
viewValidOptions.value !== null
|
|
@@ -12,6 +12,7 @@ import { stop } from '../../utils/event.js'
|
|
|
12
12
|
import { humanStorageSize } from '../../utils/format.js'
|
|
13
13
|
import { uploaderKey } from '../../utils/private/symbols.js'
|
|
14
14
|
import { injectProp, injectMultipleProps } from '../../utils/private/inject-obj-prop.js'
|
|
15
|
+
import { vmIsDestroyed } from '../../utils/private/vm.js'
|
|
15
16
|
|
|
16
17
|
function getProgressLabel (p) {
|
|
17
18
|
return (p * 100).toFixed(2) + '%'
|
|
@@ -90,9 +91,7 @@ export function getRenderer (getPlugin) {
|
|
|
90
91
|
uploadedSize: ref(0),
|
|
91
92
|
|
|
92
93
|
updateFileStatus,
|
|
93
|
-
isAlive ()
|
|
94
|
-
return vm.isDeactivated !== true && vm.isUnmounted !== true
|
|
95
|
-
}
|
|
94
|
+
isAlive: () => vmIsDestroyed(vm) === false
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
const {
|
|
@@ -129,7 +129,7 @@ export default function ({
|
|
|
129
129
|
file.__key = file.webkitRelativePath + file.lastModified + file.name + file.size
|
|
130
130
|
})
|
|
131
131
|
|
|
132
|
-
if (append
|
|
132
|
+
if (append === true) {
|
|
133
133
|
// Avoid duplicate files
|
|
134
134
|
const filenameMap = currentFileList.map(entry => entry.__key)
|
|
135
135
|
files = filterFiles(files, rejectedFiles, 'duplicate', file => {
|
|
@@ -2,7 +2,7 @@ import { ref, computed, watch, onBeforeUnmount, getCurrentInstance } from 'vue'
|
|
|
2
2
|
|
|
3
3
|
import useFormChild from '../use-form-child.js'
|
|
4
4
|
import { testPattern } from '../../utils/patterns.js'
|
|
5
|
-
import
|
|
5
|
+
import debounce from '../../utils/debounce.js'
|
|
6
6
|
import { injectProp } from '../../utils/private/inject-obj-prop.js'
|
|
7
7
|
|
|
8
8
|
const lazyRulesValues = [ true, false, 'ondemand' ]
|
|
@@ -119,21 +119,15 @@ export default function (focused, innerLoading) {
|
|
|
119
119
|
|
|
120
120
|
const index = ++validateIndex
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
isDirtyModel.value = true
|
|
124
|
-
|
|
122
|
+
const setDirty = innerLoading.value !== true
|
|
123
|
+
? () => { isDirtyModel.value = true }
|
|
124
|
+
: () => {}
|
|
125
125
|
|
|
126
126
|
const update = (err, msg) => {
|
|
127
|
-
|
|
128
|
-
innerError.value = err
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const m = msg || void 0
|
|
132
|
-
|
|
133
|
-
if (innerErrorMessage.value !== m) {
|
|
134
|
-
innerErrorMessage.value = m
|
|
135
|
-
}
|
|
127
|
+
err === true && setDirty()
|
|
136
128
|
|
|
129
|
+
innerError.value = err
|
|
130
|
+
innerErrorMessage.value = msg || null
|
|
137
131
|
innerLoading.value = false
|
|
138
132
|
}
|
|
139
133
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { inject, watch,
|
|
1
|
+
import { inject, watch, getCurrentInstance, onMounted, onBeforeUnmount } from 'vue'
|
|
2
2
|
|
|
3
3
|
import { formKey } from '../utils/private/symbols.js'
|
|
4
4
|
|
|
@@ -21,11 +21,13 @@ export default function ({ validate, resetValidation, requiresQForm }) {
|
|
|
21
21
|
}
|
|
22
22
|
})
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
onMounted(() => {
|
|
25
|
+
// register to parent QForm
|
|
26
|
+
props.disable !== true && $form.bindComponent(proxy)
|
|
27
|
+
})
|
|
26
28
|
|
|
27
29
|
onBeforeUnmount(() => {
|
|
28
|
-
//
|
|
30
|
+
// un-register from parent QForm
|
|
29
31
|
props.disable !== true && $form.unbindComponent(proxy)
|
|
30
32
|
})
|
|
31
33
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forked from tiny-emitter
|
|
3
|
+
* Copyright (c) 2017 Scott Corgan
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export default class EventBus {
|
|
7
|
+
constructor () {
|
|
8
|
+
this.__stack = {}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
on (name, callback, ctx) {
|
|
12
|
+
(this.__stack[ name ] || (this.__stack[ name ] = [])).push({
|
|
13
|
+
fn: callback,
|
|
14
|
+
ctx
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
return this // chainable
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
once (name, callback, ctx) {
|
|
21
|
+
const listener = () => {
|
|
22
|
+
this.off(name, listener)
|
|
23
|
+
callback.apply(ctx, arguments)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
listener.__callback = callback
|
|
27
|
+
return this.on(name, listener, ctx) // chainable
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
emit (name) {
|
|
31
|
+
const list = this.__stack[ name ]
|
|
32
|
+
|
|
33
|
+
if (list !== void 0) {
|
|
34
|
+
const params = [].slice.call(arguments, 1)
|
|
35
|
+
list.forEach(entry => {
|
|
36
|
+
entry.fn.apply(entry.ctx, params)
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return this // chainable
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
off (name, callback) {
|
|
44
|
+
const list = this.__stack[ name ]
|
|
45
|
+
const liveEvents = []
|
|
46
|
+
|
|
47
|
+
if (list !== void 0 && callback) {
|
|
48
|
+
list.forEach(entry => {
|
|
49
|
+
if (entry.fn !== callback && entry.fn.__callback !== callback) {
|
|
50
|
+
liveEvents.push(entry)
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
if (liveEvents.length !== 0) {
|
|
55
|
+
this.__stack[ name ] = liveEvents
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
delete this.__stack[ name ]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return this // chainable
|
|
63
|
+
}
|
|
64
|
+
}
|
package/src/utils/private/vm.js
CHANGED
|
@@ -43,3 +43,7 @@ export function getNormalizedVNodes (vnodes) {
|
|
|
43
43
|
export function vmHasRouter (vm) {
|
|
44
44
|
return vm.appContext.config.globalProperties.$router !== void 0
|
|
45
45
|
}
|
|
46
|
+
|
|
47
|
+
export function vmIsDestroyed (vm) {
|
|
48
|
+
return vm.isUnmounted === true || vm.isDeactivated === true
|
|
49
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
|
|
2
|
+
function parsePromises (sequentialPromises) {
|
|
3
|
+
const isList = Array.isArray(sequentialPromises)
|
|
4
|
+
|
|
5
|
+
if (isList === true) {
|
|
6
|
+
const totalJobs = sequentialPromises.length
|
|
7
|
+
return {
|
|
8
|
+
isList,
|
|
9
|
+
totalJobs,
|
|
10
|
+
resultAggregator: Array(totalJobs).fill(null)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const resultKeys = Object.keys(sequentialPromises)
|
|
15
|
+
const resultAggregator = {}
|
|
16
|
+
resultKeys.forEach(keyName => { resultAggregator[ keyName ] = null })
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
isList,
|
|
20
|
+
totalJobs: resultKeys.length,
|
|
21
|
+
resultAggregator,
|
|
22
|
+
resultKeys
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Run a list of Promises sequentially, optionally on multiple threads.
|
|
28
|
+
*
|
|
29
|
+
* @param {*} sequentialPromises - Array of Functions or Object with Functions as values
|
|
30
|
+
* Array of Function form: [ (resultAggregator: Array) => Promise<any>, ... ]
|
|
31
|
+
* Object form: { [key: string]: (resultAggregator: object) => Promise<any>, ... }
|
|
32
|
+
* @param {*} opts - Optional options Object
|
|
33
|
+
* Object form: { threadsNumber?: number, abortOnFail?: boolean }
|
|
34
|
+
* Default: { threadsNumber: 1, abortOnFail: true }
|
|
35
|
+
* When configuring threadsNumber AND using http requests, be
|
|
36
|
+
* aware of the maximum threads that the hosting browser
|
|
37
|
+
* supports (usually 3); any number of threads above that
|
|
38
|
+
* won't add any real benefits
|
|
39
|
+
* @returns Promise<Array<Object> | Object>
|
|
40
|
+
* With opts.abortOnFail set to true (which is default):
|
|
41
|
+
* When sequentialPromises param is Array:
|
|
42
|
+
* The Promise resolves with an Array of Objects of the following form:
|
|
43
|
+
* [ { key: number, status: 'fulfilled', value: any }, ... ]
|
|
44
|
+
* The Promise rejects with an Object of the following form:
|
|
45
|
+
* { key: number, status: 'rejected', reason: Error, resultAggregator: array }
|
|
46
|
+
* When sequentialPromises param is Object:
|
|
47
|
+
* The Promise resolves with an Object of the following form:
|
|
48
|
+
* { [key: string]: { key: string, status: 'fulfilled', value: any }, ... }
|
|
49
|
+
* The Promise rejects with an Object of the following form:
|
|
50
|
+
* { key: string, status: 'rejected', reason: Error, resultAggregator: object }
|
|
51
|
+
* With opts.abortOnFail set to false:
|
|
52
|
+
* The Promise is never rejected (no catch() needed)
|
|
53
|
+
* The Promise resolves with:
|
|
54
|
+
* An Array of Objects (when sequentialPromises param is also an Array) of the following form:
|
|
55
|
+
* [ { key: number, status: 'fulfilled', value: any } | { status: 'rejected', reason: Error }, ... ]
|
|
56
|
+
* An Object (when sequentialPromises param is also an Object) of the following form:
|
|
57
|
+
* { [key: string]: { key: string, status: 'fulfilled', value: any } | { key: string, status: 'rejected', reason: Error }, ... }
|
|
58
|
+
*/
|
|
59
|
+
export default function runSequentialPromises (
|
|
60
|
+
sequentialPromises,
|
|
61
|
+
{ threadsNumber = 1, abortOnFail = true } = {}
|
|
62
|
+
) {
|
|
63
|
+
let jobIndex = -1, hasAborted = false
|
|
64
|
+
|
|
65
|
+
const { isList, totalJobs, resultAggregator, resultKeys } = parsePromises(sequentialPromises)
|
|
66
|
+
|
|
67
|
+
const getPromiseThread = () => new Promise((resolve, reject) => {
|
|
68
|
+
function runNextPromise () {
|
|
69
|
+
const currentJobIndex = ++jobIndex
|
|
70
|
+
|
|
71
|
+
if (hasAborted === true || currentJobIndex >= totalJobs) {
|
|
72
|
+
resolve()
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const key = isList === true ? currentJobIndex : resultKeys[ currentJobIndex ]
|
|
77
|
+
|
|
78
|
+
sequentialPromises[ key ](resultAggregator)
|
|
79
|
+
.then(value => {
|
|
80
|
+
if (hasAborted === true) {
|
|
81
|
+
resolve()
|
|
82
|
+
return // early exit
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
resultAggregator[ key ] = { key, status: 'fulfilled', value }
|
|
86
|
+
|
|
87
|
+
// timeout so it doesn't interfere with the .catch() below
|
|
88
|
+
setTimeout(runNextPromise)
|
|
89
|
+
})
|
|
90
|
+
.catch(reason => {
|
|
91
|
+
if (hasAborted === true) {
|
|
92
|
+
resolve()
|
|
93
|
+
return // early exit
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const result = { key, status: 'rejected', reason }
|
|
97
|
+
resultAggregator[ key ] = result
|
|
98
|
+
|
|
99
|
+
if (abortOnFail === true) {
|
|
100
|
+
hasAborted = true
|
|
101
|
+
reject({ ...result, resultAggregator })
|
|
102
|
+
return // early exit
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// timeout so no interference
|
|
106
|
+
setTimeout(runNextPromise)
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
runNextPromise()
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
const threads = Array(threadsNumber).fill(getPromiseThread())
|
|
114
|
+
return Promise.all(threads).then(() => resultAggregator)
|
|
115
|
+
}
|
package/src/utils.js
CHANGED
|
@@ -6,6 +6,7 @@ import createUploaderComponent from './utils/create-uploader-component.js'
|
|
|
6
6
|
import date from './utils/date.js'
|
|
7
7
|
import debounce from './utils/debounce.js'
|
|
8
8
|
import dom from './utils/dom.js'
|
|
9
|
+
import EventBus from './utils/EventBus.js'
|
|
9
10
|
import event, { noop } from './utils/event.js'
|
|
10
11
|
import exportFile from './utils/export-file.js'
|
|
11
12
|
import extend from './utils/extend.js'
|
|
@@ -16,6 +17,7 @@ import is from './utils/is.js'
|
|
|
16
17
|
import morph from './utils/morph.js'
|
|
17
18
|
import openURL from './utils/open-url.js'
|
|
18
19
|
import patterns from './utils/patterns.js'
|
|
20
|
+
import runSequentialPromises from './utils/run-sequential-promises.js'
|
|
19
21
|
import scroll from './utils/scroll.js'
|
|
20
22
|
import setCssVar from './utils/set-css-var.js'
|
|
21
23
|
import throttle from './utils/throttle.js'
|
|
@@ -30,6 +32,7 @@ export {
|
|
|
30
32
|
date,
|
|
31
33
|
debounce,
|
|
32
34
|
dom,
|
|
35
|
+
EventBus,
|
|
33
36
|
event,
|
|
34
37
|
exportFile,
|
|
35
38
|
extend,
|
|
@@ -41,6 +44,7 @@ export {
|
|
|
41
44
|
morph,
|
|
42
45
|
openURL,
|
|
43
46
|
patterns,
|
|
47
|
+
runSequentialPromises,
|
|
44
48
|
scroll,
|
|
45
49
|
setCssVar,
|
|
46
50
|
throttle,
|