quasar 2.17.7 → 2.18.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.
Files changed (289) hide show
  1. package/dist/api/QBtnDropdown.json +1 -1
  2. package/dist/api/QDialog.json +1 -1
  3. package/dist/api/QMenu.json +1 -1
  4. package/dist/api/QSelect.json +1 -1
  5. package/dist/api/QTable.json +1 -1
  6. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  7. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  8. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  9. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  10. package/dist/icon-set/fontawesome-v6-pro.umd.prod.js +1 -1
  11. package/dist/icon-set/fontawesome-v6.umd.prod.js +1 -1
  12. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  13. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  14. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  15. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  16. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  17. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  18. package/dist/icon-set/material-symbols-outlined.umd.prod.js +1 -1
  19. package/dist/icon-set/material-symbols-rounded.umd.prod.js +1 -1
  20. package/dist/icon-set/material-symbols-sharp.umd.prod.js +1 -1
  21. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  22. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  23. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  24. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  25. package/dist/icon-set/mdi-v7.umd.prod.js +1 -1
  26. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  27. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  28. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-fontawesome-v6.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  36. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  37. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  38. package/dist/icon-set/svg-material-symbols-outlined.umd.prod.js +1 -1
  39. package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +1 -1
  40. package/dist/icon-set/svg-material-symbols-sharp.umd.prod.js +1 -1
  41. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  42. package/dist/icon-set/svg-mdi-v7.umd.prod.js +1 -1
  43. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  44. package/dist/icon-set/themify.umd.prod.js +1 -1
  45. package/dist/lang/ar-TN.umd.prod.js +2 -2
  46. package/dist/lang/ar.umd.prod.js +2 -2
  47. package/dist/lang/az-Latn.umd.prod.js +2 -2
  48. package/dist/lang/bg.umd.prod.js +2 -2
  49. package/dist/lang/bn.umd.prod.js +2 -2
  50. package/dist/lang/bs-BA.umd.prod.js +2 -2
  51. package/dist/lang/ca.umd.prod.js +2 -2
  52. package/dist/lang/cs.umd.prod.js +2 -2
  53. package/dist/lang/da.umd.prod.js +2 -2
  54. package/dist/lang/de-CH.umd.prod.js +2 -2
  55. package/dist/lang/de-DE.umd.prod.js +2 -2
  56. package/dist/lang/de.umd.prod.js +2 -2
  57. package/dist/lang/el.umd.prod.js +2 -2
  58. package/dist/lang/en-GB.umd.prod.js +2 -2
  59. package/dist/lang/en-US.umd.prod.js +2 -2
  60. package/dist/lang/eo.umd.prod.js +2 -2
  61. package/dist/lang/es.umd.prod.js +2 -2
  62. package/dist/lang/et.umd.prod.js +2 -2
  63. package/dist/lang/eu.umd.prod.js +2 -2
  64. package/dist/lang/fa-IR.umd.prod.js +2 -2
  65. package/dist/lang/fa.umd.prod.js +2 -2
  66. package/dist/lang/fi.umd.prod.js +2 -2
  67. package/dist/lang/fr.umd.prod.js +2 -2
  68. package/dist/lang/gn.umd.prod.js +2 -2
  69. package/dist/lang/he.umd.prod.js +2 -2
  70. package/dist/lang/hi.umd.prod.js +2 -2
  71. package/dist/lang/hr.umd.prod.js +2 -2
  72. package/dist/lang/hu.umd.prod.js +2 -2
  73. package/dist/lang/id.umd.prod.js +2 -2
  74. package/dist/lang/is.umd.prod.js +2 -2
  75. package/dist/lang/it.umd.prod.js +2 -2
  76. package/dist/lang/ja.umd.prod.js +2 -2
  77. package/dist/lang/kk.umd.prod.js +2 -2
  78. package/dist/lang/km.umd.prod.js +2 -2
  79. package/dist/lang/ko-KR.umd.prod.js +2 -2
  80. package/dist/lang/kur-CKB.umd.prod.js +2 -2
  81. package/dist/lang/lt.umd.prod.js +2 -2
  82. package/dist/lang/lu.umd.prod.js +2 -2
  83. package/dist/lang/lv.umd.prod.js +2 -2
  84. package/dist/lang/mk.umd.prod.js +2 -2
  85. package/dist/lang/ml.umd.prod.js +2 -2
  86. package/dist/lang/mm.umd.prod.js +2 -2
  87. package/dist/lang/ms-MY.umd.prod.js +2 -2
  88. package/dist/lang/ms.umd.prod.js +2 -2
  89. package/dist/lang/my.umd.prod.js +2 -2
  90. package/dist/lang/nb-NO.umd.prod.js +2 -2
  91. package/dist/lang/nl.umd.prod.js +2 -2
  92. package/dist/lang/pl.umd.prod.js +2 -2
  93. package/dist/lang/pt-BR.umd.prod.js +2 -2
  94. package/dist/lang/pt.umd.prod.js +2 -2
  95. package/dist/lang/ro.umd.prod.js +2 -2
  96. package/dist/lang/ru.umd.prod.js +2 -2
  97. package/dist/lang/sk.umd.prod.js +2 -2
  98. package/dist/lang/sl.umd.prod.js +2 -2
  99. package/dist/lang/sm.umd.prod.js +2 -2
  100. package/dist/lang/sr-CYR.umd.prod.js +2 -2
  101. package/dist/lang/sr.umd.prod.js +2 -2
  102. package/dist/lang/sv.umd.prod.js +2 -2
  103. package/dist/lang/ta.umd.prod.js +2 -2
  104. package/dist/lang/th.umd.prod.js +2 -2
  105. package/dist/lang/tl.umd.prod.js +2 -2
  106. package/dist/lang/tr.umd.prod.js +2 -2
  107. package/dist/lang/ug.umd.prod.js +1 -1
  108. package/dist/lang/uk.umd.prod.js +2 -2
  109. package/dist/lang/ur-PK.umd.prod.js +7 -0
  110. package/dist/lang/uz-Cyrl.umd.prod.js +2 -2
  111. package/dist/lang/uz-Latn.umd.prod.js +2 -2
  112. package/dist/lang/vi.umd.prod.js +2 -2
  113. package/dist/lang/zh-CN.umd.prod.js +2 -2
  114. package/dist/lang/zh-TW.umd.prod.js +2 -2
  115. package/dist/quasar.client.js +237 -174
  116. package/dist/quasar.css +1 -1
  117. package/dist/quasar.prod.css +1 -1
  118. package/dist/quasar.rtl.css +1 -1
  119. package/dist/quasar.rtl.prod.css +1 -1
  120. package/dist/quasar.sass +2 -2
  121. package/dist/quasar.server.prod.cjs +15 -15
  122. package/dist/quasar.server.prod.js +8 -8
  123. package/dist/quasar.umd.js +237 -174
  124. package/dist/quasar.umd.prod.js +15 -15
  125. package/dist/types/index.d.ts +52 -3
  126. package/dist/vetur/quasar-attributes.json +1 -1
  127. package/dist/vetur/quasar-tags.json +1 -1
  128. package/dist/web-types/web-types.json +1 -1
  129. package/lang/ar-TN.js +6 -0
  130. package/lang/ar.js +6 -0
  131. package/lang/az-Latn.js +6 -0
  132. package/lang/bg.js +6 -0
  133. package/lang/bn.js +6 -0
  134. package/lang/bs-BA.js +6 -0
  135. package/lang/ca.js +6 -0
  136. package/lang/cs.js +6 -0
  137. package/lang/da.js +6 -0
  138. package/lang/de-CH.js +6 -0
  139. package/lang/de-DE.js +6 -0
  140. package/lang/de.js +6 -0
  141. package/lang/el.js +6 -0
  142. package/lang/en-GB.js +6 -0
  143. package/lang/en-US.js +6 -0
  144. package/lang/eo.js +6 -0
  145. package/lang/es.js +6 -0
  146. package/lang/et.js +6 -0
  147. package/lang/eu.js +6 -0
  148. package/lang/fa-IR.js +6 -0
  149. package/lang/fa.js +6 -0
  150. package/lang/fi.js +6 -0
  151. package/lang/fr.js +6 -0
  152. package/lang/gn.js +6 -0
  153. package/lang/he.js +6 -0
  154. package/lang/hi.js +6 -0
  155. package/lang/hr.js +6 -0
  156. package/lang/hu.js +6 -0
  157. package/lang/id.js +6 -0
  158. package/lang/index.json +1 -1
  159. package/lang/is.js +6 -0
  160. package/lang/it.js +6 -0
  161. package/lang/ja.js +6 -0
  162. package/lang/kk.js +6 -0
  163. package/lang/km.js +6 -0
  164. package/lang/ko-KR.js +6 -0
  165. package/lang/kur-CKB.js +6 -0
  166. package/lang/lt.js +6 -0
  167. package/lang/lu.js +6 -0
  168. package/lang/lv.js +6 -0
  169. package/lang/mk.js +6 -0
  170. package/lang/ml.js +6 -0
  171. package/lang/mm.js +6 -0
  172. package/lang/ms-MY.js +6 -0
  173. package/lang/ms.js +6 -0
  174. package/lang/my.js +6 -0
  175. package/lang/nb-NO.js +6 -0
  176. package/lang/nl.js +6 -0
  177. package/lang/pl.js +6 -0
  178. package/lang/pt-BR.js +6 -0
  179. package/lang/pt.js +6 -0
  180. package/lang/ro.js +6 -0
  181. package/lang/ru.js +6 -0
  182. package/lang/sk.js +6 -0
  183. package/lang/sl.js +6 -0
  184. package/lang/sm.js +6 -0
  185. package/lang/sr-CYR.js +6 -0
  186. package/lang/sr.js +6 -0
  187. package/lang/sv.js +6 -0
  188. package/lang/ta.js +6 -0
  189. package/lang/th.js +6 -0
  190. package/lang/tl.js +6 -0
  191. package/lang/tr.js +6 -0
  192. package/lang/uk.js +6 -0
  193. package/lang/ur-PK.js +111 -0
  194. package/lang/uz-Cyrl.js +6 -0
  195. package/lang/uz-Latn.js +6 -0
  196. package/lang/vi.js +6 -0
  197. package/lang/zh-CN.js +6 -0
  198. package/lang/zh-TW.js +6 -0
  199. package/package.json +3 -3
  200. package/src/components/breadcrumbs/QBreadcrumbs.js +2 -2
  201. package/src/components/btn/QBtn.js +7 -8
  202. package/src/components/btn-dropdown/QBtnDropdown.js +10 -4
  203. package/src/components/btn-dropdown/QBtnDropdown.json +21 -0
  204. package/src/components/color/QColor.js +1 -1
  205. package/src/components/date/QDate.js +1 -1
  206. package/src/components/dialog/QDialog.js +2 -2
  207. package/src/components/dialog/QDialog.json +1 -1
  208. package/src/components/drawer/QDrawer.js +3 -5
  209. package/src/components/editor/QEditor.js +1 -1
  210. package/src/components/editor/editor-caret.js +1 -1
  211. package/src/components/editor/editor-utils.js +2 -2
  212. package/src/components/expansion-item/QExpansionItem.js +6 -3
  213. package/src/components/fab/QFab.js +2 -2
  214. package/src/components/form/QForm.js +2 -2
  215. package/src/components/form/QFormChildMixin.js +6 -4
  216. package/src/components/icon/QIcon.js +2 -2
  217. package/src/components/infinite-scroll/QInfiniteScroll.js +2 -4
  218. package/src/components/input/QInput.js +3 -3
  219. package/src/components/item/QItem.js +1 -1
  220. package/src/components/menu/QMenu.js +8 -5
  221. package/src/components/menu/QMenu.json +8 -1
  222. package/src/components/pagination/QPagination.js +8 -4
  223. package/src/components/parallax/QParallax.js +1 -1
  224. package/src/components/popup-edit/QPopupEdit.js +2 -2
  225. package/src/components/pull-to-refresh/QPullToRefresh.js +1 -1
  226. package/src/components/rating/QRating.sass +1 -1
  227. package/src/components/resize-observer/QResizeObserver.js +1 -1
  228. package/src/components/scroll-observer/QScrollObserver.js +2 -2
  229. package/src/components/select/QSelect.js +8 -6
  230. package/src/components/select/QSelect.json +1 -1
  231. package/src/components/slide-transition/QSlideTransition.js +2 -2
  232. package/src/components/stepper/StepHeader.js +1 -1
  233. package/src/components/table/QTable.js +77 -36
  234. package/src/components/table/QTable.json +98 -0
  235. package/src/components/table/QTr.js +4 -1
  236. package/src/components/table/table-sort.js +1 -1
  237. package/src/components/tabs/QTabs.js +2 -2
  238. package/src/components/tabs/use-tab.js +4 -4
  239. package/src/components/time/QTime.js +1 -1
  240. package/src/components/tree/QTree.js +2 -3
  241. package/src/components/virtual-scroll/use-virtual-scroll.js +3 -3
  242. package/src/composables/private.use-field/use-field.js +5 -5
  243. package/src/composables/private.use-file/use-file.js +6 -3
  244. package/src/composables/private.use-model-toggle/use-model-toggle.js +2 -2
  245. package/src/composables/private.use-refocus-target/use-refocus-target.js +6 -5
  246. package/src/composables/private.use-validate/use-validate.js +1 -1
  247. package/src/directives/intersection/Intersection.js +2 -2
  248. package/src/directives/morph/Morph.js +2 -2
  249. package/src/directives/mutation/Mutation.js +2 -2
  250. package/src/directives/touch-hold/TouchHold.js +2 -2
  251. package/src/directives/touch-pan/TouchPan.js +2 -2
  252. package/src/directives/touch-repeat/TouchRepeat.js +3 -3
  253. package/src/directives/touch-swipe/TouchSwipe.js +3 -3
  254. package/src/plugins/lang/Lang.test.js +12 -0
  255. package/src/plugins/loading/Loading.js +1 -1
  256. package/src/plugins/notify/Notify.js +1 -1
  257. package/src/plugins/private.body/Body.js +1 -1
  258. package/src/plugins/private.history/History.js +1 -1
  259. package/src/plugins/screen/Screen.js +1 -1
  260. package/src/utils/morph/morph.js +13 -10
  261. package/src/utils/open-url/open-url.js +3 -3
  262. package/src/utils/private.dialog/create-dialog.js +2 -2
  263. package/src/utils/private.portal/portal.js +1 -1
  264. package/src/components/date/__tests__/QDate.cy.js +0 -189
  265. package/src/components/date/__tests__/use-datetime.cy.js +0 -83
  266. package/src/components/editor/__tests__/QEditor.cy.js +0 -195
  267. package/src/components/field/__tests__/QField.cy.js +0 -156
  268. package/src/components/input/__tests__/QInput.cy.js +0 -786
  269. package/src/components/input/__tests__/use-mask.cy.js +0 -124
  270. package/src/components/menu/__tests__/QMenu.cy.js +0 -634
  271. package/src/components/menu/__tests__/WrapperOne.vue +0 -51
  272. package/src/components/menu/__tests__/WrapperTwo.vue +0 -38
  273. package/src/components/select/__tests__/QSelect.cy.js +0 -2018
  274. package/src/components/table/__tests__/QTable.cy.js +0 -635
  275. package/src/components/table/__tests__/QTd.cy.js +0 -35
  276. package/src/components/table/__tests__/QTh.cy.js +0 -27
  277. package/src/components/table/__tests__/QTr.cy.js +0 -27
  278. package/src/components/tabs/__tests__/QTab.cy.js +0 -79
  279. package/src/components/tabs/__tests__/QTabs.cy.js +0 -147
  280. package/src/components/uploader/__tests__/QUploader.cy.js +0 -191
  281. package/src/composables/__tests__/FieldWrapper.vue +0 -54
  282. package/src/composables/__tests__/use-anchor.cy.js +0 -98
  283. package/src/composables/__tests__/use-field.cy.js +0 -547
  284. package/src/composables/__tests__/use-file.cy.js +0 -69
  285. package/src/composables/__tests__/use-fullscreen.cy.js +0 -37
  286. package/src/composables/__tests__/use-model-toggle.cy.js +0 -350
  287. package/src/composables/__tests__/use-portal.cy.js +0 -4
  288. package/src/composables/__tests__/use-router-link.cy.js +0 -55
  289. package/src/composables/__tests__/use-validate.cy.js +0 -257
@@ -1,786 +0,0 @@
1
- import QInput from '../QInput'
2
- import { ref } from 'vue'
3
- import { vModelAdapter } from '@quasar/quasar-app-extension-testing-e2e-cypress'
4
-
5
- function getHostElement () {
6
- return cy.get('.q-field')
7
- }
8
-
9
- function mountQInput (options) {
10
- return cy.mount(QInput, options)
11
- }
12
-
13
- describe('Input API', () => {
14
- describe('Props', () => {
15
- describe('Category: behaviour', () => {
16
- describe('(prop): error', () => {
17
- it('should mark the field as having an error', () => {
18
- mountQInput()
19
- getHostElement().should('not.have.class', 'q-field--error')
20
-
21
- mountQInput({
22
- props: {
23
- error: true
24
- }
25
- })
26
-
27
- getHostElement().should('have.class', 'q-field--error')
28
- })
29
- })
30
-
31
- describe('(prop): rules', () => {
32
- it('should validate value using custom validation logic', () => {
33
- const errorMessage = 'Use a max 3 of characters'
34
- const model = ref('')
35
- mountQInput({
36
- props: {
37
- ...vModelAdapter(model),
38
- rules: [ val => val.length <= 3 || errorMessage ]
39
- }
40
- })
41
- getHostElement().get('input').type('1234')
42
- getHostElement().get('.q-field__messages').should('contain', errorMessage)
43
- })
44
-
45
- it('should validate email using inbuilt validation logic', () => {
46
- const errorMessage = 'Enter a valid email address'
47
- const model = ref('')
48
- mountQInput({
49
- props: {
50
- ...vModelAdapter(model),
51
- rules: [ (val, rules) => rules.email(val) || errorMessage ]
52
- }
53
- })
54
- getHostElement().get('input').type('1234')
55
- getHostElement().get('.q-field__messages').should('contain', errorMessage)
56
- })
57
- })
58
-
59
- describe('(prop): loading', () => {
60
- it('should set the component into a loading state', () => {
61
- mountQInput({
62
- props: {
63
- loading: true
64
- }
65
- })
66
-
67
- getHostElement().get('.q-spinner').should('exist')
68
- })
69
- })
70
-
71
- describe('(prop): clearable', () => {
72
- it('should append a cancel icon', () => {
73
- const model = ref('')
74
-
75
- mountQInput({
76
- props: {
77
- ...vModelAdapter(model),
78
- clearable: true
79
- }
80
- })
81
-
82
- getHostElement().get('input').type('1')
83
- getHostElement().get('button').should('exist').should('contain', 'cancel')
84
- })
85
- })
86
-
87
- describe('(prop): autofocus', () => {
88
- it('should autofocus on component', () => {
89
- mountQInput({
90
- props: {
91
- autofocus: true
92
- }
93
- })
94
-
95
- getHostElement()
96
- .get('.q-field--focused')
97
- .should('exist')
98
- .get('input')
99
- .should('have.focus')
100
- })
101
- })
102
-
103
- describe('(prop): lazy-rules', () => {
104
- it('should validate the input only when component loses focus', () => {
105
- const errorMessage = 'Use a max 3 of characters'
106
- const model = ref('')
107
- mountQInput({
108
- props: {
109
- ...vModelAdapter(model),
110
- rules: [ val => val.length <= 3 || errorMessage ],
111
- lazyRules: true
112
- }
113
- })
114
-
115
- getHostElement().get('input').type('1234')
116
- getHostElement().get('.q-field__messages').should('not.contain', errorMessage)
117
-
118
- getHostElement().get('input').then(() => {
119
- Cypress.vueWrapper.vm.blur()
120
- getHostElement().get('.q-field__messages').should('contain', errorMessage)
121
- })
122
- })
123
-
124
- it('should validate the input only when component\'s validate() method is called', () => {
125
- const errorMessage = 'Use a max 3 of characters'
126
- const model = ref('')
127
- mountQInput({
128
- props: {
129
- ...vModelAdapter(model),
130
- rules: [ val => val.length <= 3 || errorMessage ],
131
- lazyRules: 'ondemand'
132
- }
133
- })
134
-
135
- getHostElement().get('input').type('1234')
136
- getHostElement().get('.q-field__messages').should('not.contain', errorMessage)
137
-
138
- getHostElement().get('input').then(() => {
139
- Cypress.vueWrapper.vm.blur()
140
- getHostElement().get('.q-field__messages').should('not.contain', errorMessage)
141
- Cypress.vueWrapper.vm.validate()
142
- getHostElement().get('.q-field__messages').should('contain', errorMessage)
143
- })
144
- })
145
- })
146
- })
147
-
148
- describe('Category: content', () => {
149
- describe('(prop): error-message', () => {
150
- it('should display validation error message if error = true', () => {
151
- const errorMessage = 'Username must have at least 3 characters'
152
- mountQInput({
153
- props: {
154
- errorMessage
155
- }
156
- })
157
- getHostElement().should('not.contain', errorMessage)
158
-
159
- mountQInput({
160
- props: {
161
- error: true,
162
- errorMessage
163
- }
164
- })
165
- getHostElement().should('contain', errorMessage)
166
- })
167
- })
168
-
169
- describe('(prop): no-error-icon', () => {
170
- it('should hide error icon when there is an error', () => {
171
- mountQInput({
172
- props: {
173
- error: true,
174
- errorMessage: 'error message'
175
- }
176
- })
177
-
178
- getHostElement().get('.q-field__append .q-icon').should('contain', 'error')
179
-
180
- mountQInput({
181
- props: {
182
- error: true,
183
- errorMessage: 'error message',
184
- noErrorIcon: true
185
- }
186
- })
187
-
188
- getHostElement().get('.q-field__append .q-icon').should('not.exist')
189
- })
190
- })
191
-
192
- describe('(prop): label', () => {
193
- it('should display the label set', () => {
194
- const label = 'Hello there!'
195
-
196
- mountQInput({
197
- props: {
198
- label
199
- }
200
- })
201
-
202
- getHostElement().get('.q-field__label').should('contain', label)
203
- })
204
- })
205
-
206
- describe('(prop): stack-label', () => {
207
- it('should stack label', () => {
208
- const label = 'Hello there!'
209
- mountQInput({
210
- props: {
211
- label
212
- }
213
- })
214
- getHostElement().should('not.have.class', 'q-field--float')
215
-
216
- mountQInput({
217
- props: {
218
- label,
219
- stackLabel: true
220
- }
221
- })
222
-
223
- getHostElement().should('have.class', 'q-field--float')
224
- })
225
- })
226
-
227
- describe('(prop): hint', () => {
228
- it('should display the hint message', () => {
229
- const hint = 'hint message'
230
- mountQInput({
231
- props: {
232
- hint
233
- }
234
- })
235
-
236
- getHostElement().get('.q-field__messages').should('contain', hint)
237
- })
238
- })
239
-
240
- describe('(prop): hide-hint', () => {
241
- it('should hide hint when element is not focused', () => {
242
- const hint = 'hint message'
243
- mountQInput({
244
- props: {
245
- hint,
246
- hideHint: true
247
- }
248
- })
249
- getHostElement().get('.q-field__messages').should('not.contain', hint)
250
-
251
- getHostElement().get('input').then(() => {
252
- Cypress.vueWrapper.vm.focus()
253
- getHostElement().get('.q-field__messages').should('contain', hint)
254
- })
255
- })
256
- })
257
-
258
- describe('(prop): prefix', () => {
259
- it('should display a prefix', () => {
260
- const prefix = 'Hello there!'
261
- mountQInput({
262
- props: {
263
- prefix
264
- }
265
- })
266
-
267
- getHostElement().get('.q-field__prefix').should('exist').should('contain', prefix)
268
- })
269
- })
270
-
271
- describe('(prop): suffix', () => {
272
- it('should display a suffix', () => {
273
- const suffix = 'Hello there!'
274
- mountQInput({
275
- props: {
276
- suffix
277
- }
278
- })
279
-
280
- getHostElement().get('.q-field__suffix').should('exist').should('contain', suffix)
281
- })
282
- })
283
-
284
- describe('(prop): clear-icon', () => {
285
- it('should display custom clear-icon when one is set', () => {
286
- const model = ref('')
287
- const clearIcon = 'custom-clear-icon'
288
- mountQInput({
289
- props: {
290
- ...vModelAdapter(model),
291
- clearable: true,
292
- clearIcon
293
- }
294
- })
295
-
296
- getHostElement().get('input').type('123')
297
- getHostElement().get('.q-field__append').get('button').should('contain', clearIcon)
298
- })
299
- })
300
-
301
- describe('(prop): label-slot', () => {
302
- it('should force use the label slot when a label is not set', () => {
303
- const labelSlot = 'Hello there'
304
- mountQInput({
305
- props: {
306
- labelSlot: true
307
- },
308
- slots: {
309
- label: () => labelSlot
310
- }
311
- })
312
-
313
- getHostElement().get('.q-field__label').should('contain', labelSlot)
314
- })
315
- })
316
-
317
- describe('(prop): counter', () => {
318
- it('should show an automatic counter on bottom right', () => {
319
- const model = ref('')
320
- mountQInput({
321
- props: {
322
- ...vModelAdapter(model),
323
- counter: true
324
- }
325
- })
326
-
327
- const value = '1234'
328
- getHostElement().get('input').type(value)
329
- getHostElement().get('.q-field__counter').should('contain', value.length)
330
- })
331
- })
332
-
333
- describe('(prop): shadow-text', () => {
334
- it('should render shadow-text', () => {
335
- const shadowText = 'Shadow Text'
336
-
337
- mountQInput({
338
- props: {
339
- shadowText
340
- }
341
- })
342
-
343
- getHostElement().get('.q-field__shadow').should('exist').contains(shadowText)
344
- })
345
- })
346
-
347
- describe('(prop): autogrow', () => {
348
- it('should use textarea for input field', () => {
349
- mountQInput()
350
- getHostElement().get('textarea').should('not.exist').get('input').should('exist')
351
-
352
- mountQInput({
353
- props: {
354
- autogrow: true
355
- }
356
- })
357
-
358
- getHostElement().get('textarea').should('exist')
359
- getHostElement().get('input').should('not.exist')
360
- })
361
- })
362
- })
363
-
364
- describe('Category: general', () => {
365
- describe('(prop): type', () => {
366
- it('should render an input text type by default', () => {
367
- mountQInput()
368
-
369
- getHostElement().get('input[type=text]').should('exist')
370
- })
371
-
372
- it('should render with the appropriate type set', () => {
373
- const types = [ 'text', 'password', 'email', 'search', 'tel', 'file', 'number', 'url', 'time', 'date' ]
374
-
375
- types.forEach((type) => {
376
- mountQInput({
377
- props: {
378
- type
379
- }
380
- })
381
-
382
- getHostElement().get(`input[type="${ type }"]`).should('exist')
383
- })
384
-
385
- mountQInput({
386
- props: {
387
- type: 'textarea'
388
- }
389
- })
390
-
391
- getHostElement().get('input').should('not.exist').get('textarea').should('exist')
392
- })
393
- })
394
- })
395
-
396
- describe('Category: model', () => {
397
- describe('(prop): model-value', () => {
398
- it('should render with the correct model value', () => {
399
- const model = ref('Input Model Value')
400
- mountQInput()
401
- getHostElement().get('input').should('not.have.value', model.value)
402
-
403
- mountQInput({
404
- props: {
405
- modelValue: model.value
406
- }
407
- })
408
-
409
- getHostElement().get('input').should('have.value', model.value)
410
- })
411
- })
412
-
413
- describe('(prop): debounce', () => {
414
- it('should no input debounce by default', () => {
415
- const fn = cy.stub()
416
- const text = 'Hello there'
417
- mountQInput({
418
- props: {
419
- 'onUpdate:modelValue': fn
420
- }
421
- })
422
- getHostElement()
423
- .get('input')
424
- .type(text)
425
- .then(() => {
426
- expect(fn).to.be.calledWith(text)
427
- })
428
- })
429
-
430
- it('should use a custom input-debounce', () => {
431
- const fn = cy.stub()
432
- const text = 'Hello there'
433
- mountQInput({
434
- props: {
435
- 'onUpdate:modelValue': fn,
436
- debounce: 800
437
- }
438
- })
439
- getHostElement()
440
- .get('input')
441
- .type(text)
442
- .wait(500)
443
- .then(() => {
444
- expect(fn).not.to.be.calledWith(text)
445
- })
446
- .wait(300)
447
- .then(() => {
448
- expect(fn).to.be.calledWith(text)
449
- })
450
- })
451
- })
452
-
453
- describe('(prop): maxlength', () => {
454
- it('should respect the maxLength specified', () => {
455
- mountQInput()
456
- getHostElement()
457
- .get('input')
458
- .type('1234567890abcdefghij')
459
- .should('have.value', '1234567890abcdefghij')
460
-
461
- mountQInput({
462
- props: {
463
- maxlength: 10
464
- }
465
- })
466
-
467
- getHostElement()
468
- .get('input')
469
- .type('1234567890abcdefghij')
470
- .should('have.value', '1234567890')
471
- })
472
- })
473
- })
474
-
475
- describe('Category: style', () => {
476
- describe('(prop): input-class', () => {
477
- it('should apply the input class to the underlying element', () => {
478
- mountQInput()
479
- getHostElement().get('input.input-class').should('not.exist')
480
-
481
- mountQInput({
482
- props: {
483
- inputClass: 'input-class'
484
- }
485
- })
486
-
487
- getHostElement().get('input.input-class').should('exist')
488
- })
489
-
490
- it('should apply the input class specified as an object', () => {
491
- mountQInput({
492
- props: {
493
- inputClass: { 'input-class': true }
494
- }
495
- })
496
-
497
- getHostElement().get('input.input-class').should('exist')
498
- })
499
- })
500
-
501
- describe('(prop): input-style', () => {
502
- it('should set input-style as string', () => {
503
- mountQInput({
504
- props: {
505
- inputStyle: 'background-color: red'
506
- }
507
- })
508
-
509
- getHostElement().get('input[style="background-color: red;"]').should('exist')
510
- })
511
-
512
- it('should set input-style as an object', () => {
513
- mountQInput({
514
- props: {
515
- inputStyle: { backgroundColor: 'red' }
516
- }
517
- })
518
-
519
- getHostElement().get('input[style="background-color: red;"]').should('exist')
520
- })
521
- })
522
-
523
- describe('(prop): label-color', () => {
524
- it('should display a label color', () => {
525
- const label = 'Hello there!'
526
- mountQInput({
527
- props: {
528
- label,
529
- labelColor: 'red'
530
- }
531
- })
532
-
533
- getHostElement().get('.q-field__label.text-red').should('contain', label)
534
- })
535
- })
536
-
537
- describe('(prop): color', () => {
538
- it('should set a color on the component', () => {
539
- mountQInput()
540
- getHostElement().get('.q-field__control.text-red').should('not.exist')
541
- mountQInput({
542
- props: {
543
- color: 'red'
544
- }
545
- })
546
-
547
- getHostElement().get('input').then(() => {
548
- Cypress.vueWrapper.vm.focus()
549
- getHostElement().get('.q-field__control.text-red').should('exist')
550
- })
551
- })
552
- })
553
-
554
- describe('(prop): bg-color', () => {
555
- it('should display a background color', () => {
556
- mountQInput({
557
- props: {
558
- bgColor: 'red'
559
- }
560
- })
561
-
562
- getHostElement().get('.q-field__control.bg-red').should('exist')
563
- })
564
- })
565
-
566
- describe('(prop): filled', () => {
567
- it('should use a filled design', () => {
568
- mountQInput({
569
- props: {
570
- filled: true
571
- }
572
- })
573
-
574
- getHostElement().get('.q-field--filled').should('exist')
575
- })
576
- })
577
-
578
- describe('(prop): outlined', () => {
579
- it('should use a outlined design', () => {
580
- mountQInput({
581
- props: {
582
- outlined: true
583
- }
584
- })
585
-
586
- getHostElement().get('.q-field--outlined').should('exist')
587
- })
588
- })
589
-
590
- describe('(prop): borderless', () => {
591
- it('should use a borderless design', () => {
592
- mountQInput({
593
- props: {
594
- borderless: true
595
- }
596
- })
597
-
598
- getHostElement().get('.q-field--borderless').should('exist')
599
- })
600
- })
601
-
602
- describe('(prop): standout', () => {
603
- it('should display a standout color', () => {
604
- mountQInput({
605
- props: {
606
- standout: true
607
- }
608
- })
609
-
610
- getHostElement().get('.q-field--standout').should('exist')
611
- })
612
- })
613
-
614
- describe('(prop): hide-bottom-space', () => {
615
- it('should hide bottom space', () => {
616
- mountQInput({
617
- props: {
618
- rules: [ (value) => !!value || '' ]
619
- }
620
- })
621
- getHostElement().get('.q-field__messages').should('exist')
622
-
623
- mountQInput({
624
- props: {
625
- rules: [ (value) => !!value || '' ],
626
- hideBottomSpace: true
627
- }
628
- })
629
-
630
- getHostElement().get('.q-field__messages').should('not.exist')
631
- })
632
- })
633
-
634
- describe('(prop): rounded', () => {
635
- it('should use a rounded design', () => {
636
- mountQInput({
637
- props: {
638
- rounded: true
639
- }
640
- })
641
-
642
- getHostElement().get('.q-field--rounded').should('exist')
643
- })
644
- })
645
-
646
- describe('(prop): square', () => {
647
- it('should use a square design', () => {
648
- mountQInput({
649
- props: {
650
- square: true
651
- }
652
- })
653
-
654
- getHostElement().get('.q-field--square').should('exist')
655
- })
656
- })
657
-
658
- describe('(prop): dense', () => {
659
- it('should use a dense design', () => {
660
- mountQInput({
661
- props: {
662
- dense: true
663
- }
664
- })
665
-
666
- getHostElement().get('.q-field--dense').should('exist')
667
- })
668
- })
669
- })
670
- })
671
-
672
- describe('Events', () => {
673
- describe('(event): update:model-value', () => {
674
- it('should emit onUpdate:modelValue event', () => {
675
- const fn = cy.stub()
676
- const text = 'Hello there'
677
- mountQInput({
678
- props: {
679
- 'onUpdate:modelValue': fn
680
- }
681
- })
682
- getHostElement()
683
- .get('input')
684
- .type(text)
685
- .then(() => {
686
- expect(fn).to.be.calledWith(text)
687
- })
688
- })
689
- })
690
-
691
- describe('(event): focus', () => {
692
- it('should emit focus event', () => {
693
- const fn = cy.stub()
694
- mountQInput({
695
- props: {
696
- onfocus: fn,
697
- autoFocus: true
698
- }
699
- })
700
-
701
- getHostElement()
702
- .get('input')
703
- .as('input')
704
- .focus()
705
-
706
- cy.get('@input').then(() => {
707
- expect(fn).to.be.calledWith()
708
- })
709
- })
710
- })
711
-
712
- describe('(event): blur', () => {
713
- it('should emit blur event', () => {
714
- const fn = cy.stub()
715
- mountQInput({
716
- props: {
717
- onblur: fn
718
- }
719
- })
720
-
721
- getHostElement()
722
- .get('input')
723
- .focus()
724
- .blur()
725
- .then(() => {
726
- expect(fn).to.be.calledWith()
727
- })
728
- })
729
- })
730
- })
731
-
732
- describe('Methods', () => {
733
- describe('(method): focus', () => {
734
- it('should focus the component', () => {
735
- mountQInput()
736
-
737
- getHostElement()
738
- .get('.q-field--focused')
739
- .should('not.exist')
740
- .get('input')
741
- .should('not.have.focus')
742
- getHostElement()
743
- .then(() => {
744
- Cypress.vueWrapper.vm.focus()
745
- })
746
- getHostElement()
747
- .get('.q-field--focused')
748
- .should('exist')
749
- .get('input')
750
- .should('have.focus')
751
- })
752
- })
753
-
754
- describe('(method): blur', () => {
755
- it('should blur the component', () => {
756
- mountQInput()
757
- getHostElement()
758
- .get('input').focus()
759
- getHostElement()
760
- .get('.q-field--focused')
761
- .should('exist')
762
- .get('input')
763
- .should('have.focus')
764
-
765
- getHostElement()
766
- .then(() => {
767
- Cypress.vueWrapper.vm.blur()
768
- })
769
-
770
- getHostElement().get('.q-field--focused').should('not.exist').get('input').should('not.have.focus')
771
- })
772
- })
773
-
774
- describe('(method): select', () => {
775
- it.skip(' ', () => {
776
- //
777
- })
778
- })
779
-
780
- describe('(method): getNativeElement', () => {
781
- it.skip(' ', () => {
782
- //
783
- })
784
- })
785
- })
786
- })