@propelinc/citrus-ui 0.6.0 → 1.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.
Files changed (355) hide show
  1. package/README.md +54 -60
  2. package/dist/colors/colors.d.ts +31 -0
  3. package/dist/colors/theme.d.ts +2 -11
  4. package/dist/colors/util-classes.d.ts +11 -0
  5. package/dist/components/CAccordion.vue.d.ts +21 -0
  6. package/dist/components/CAccordionItem.vue.d.ts +41 -0
  7. package/dist/components/CAppBar.vue.d.ts +156 -0
  8. package/dist/components/CBadge.vue.d.ts +52 -0
  9. package/dist/components/CBottomSheet.vue.d.ts +226 -0
  10. package/dist/components/CButton/CButton.vue.d.ts +231 -0
  11. package/dist/components/CButton/types.d.ts +5 -0
  12. package/dist/components/CButtonStack.vue.d.ts +24 -0
  13. package/dist/components/CCard.vue.d.ts +107 -0
  14. package/dist/components/CCardFooter.vue.d.ts +26 -0
  15. package/dist/components/CCardHeader.vue.d.ts +3 -0
  16. package/dist/components/CCardSection.vue.d.ts +17 -0
  17. package/dist/components/CCheckbox.vue.d.ts +145 -0
  18. package/dist/components/CCol.vue.d.ts +21 -0
  19. package/dist/components/CDivider.vue.d.ts +17 -0
  20. package/dist/components/CDobField.vue.d.ts +2109 -0
  21. package/dist/components/CDobSelect.vue.d.ts +398 -0
  22. package/dist/components/CEmailField.vue.d.ts +699 -0
  23. package/dist/components/CExpandTransition.vue.d.ts +19 -0
  24. package/dist/components/CFadeTransition.vue.d.ts +3 -0
  25. package/dist/components/CFileInput.vue.d.ts +98 -0
  26. package/dist/components/CFixedPageFooter.vue.d.ts +106 -0
  27. package/dist/components/CForm.vue.d.ts +29 -0
  28. package/dist/components/CFormFieldCounter.vue.d.ts +42 -0
  29. package/dist/components/CIconButton.vue.d.ts +390 -0
  30. package/dist/components/CLabel.vue.d.ts +32 -0
  31. package/dist/components/CListItem.vue.d.ts +208 -0
  32. package/dist/components/CListItemContent.vue.d.ts +27 -0
  33. package/dist/components/CListItemIcon.vue.d.ts +54 -0
  34. package/dist/components/CLoader.vue.d.ts +73 -0
  35. package/dist/components/CLogo.vue.d.ts +19 -0
  36. package/dist/components/CMaskedTextField.vue.d.ts +2012 -0
  37. package/dist/components/CMenu.vue.d.ts +6 -0
  38. package/dist/components/CMenuItem.vue.d.ts +170 -0
  39. package/dist/components/CMenuLabel.vue.d.ts +3 -0
  40. package/dist/components/CModal.vue.d.ts +206 -0
  41. package/dist/components/CModalLoading.vue.d.ts +230 -0
  42. package/dist/components/CNotification.vue.d.ts +589 -0
  43. package/dist/components/CPhoneField.vue.d.ts +2088 -0
  44. package/dist/components/CPill.vue.d.ts +42 -0
  45. package/dist/components/CPillGroup.vue.d.ts +70 -0
  46. package/dist/components/CPopup.vue.d.ts +21 -0
  47. package/dist/components/CProgressLinear.vue.d.ts +61 -0
  48. package/dist/components/CProgressRing.vue.d.ts +103 -0
  49. package/dist/components/CRadio.vue.d.ts +73 -0
  50. package/dist/components/CRadioGroup.vue.d.ts +123 -0
  51. package/dist/components/CRebrand.vue.d.ts +28 -0
  52. package/dist/components/CRow.vue.d.ts +67 -0
  53. package/dist/components/CSafeArea.vue.d.ts +18 -0
  54. package/dist/components/CSectionHeader.vue.d.ts +28 -0
  55. package/dist/components/CSelect.vue.d.ts +293 -0
  56. package/dist/components/CSkeleton.vue.d.ts +3 -0
  57. package/dist/components/CSkeletonLoaderCard.vue.d.ts +21 -0
  58. package/dist/components/CSkeletonLoaderCircle.vue.d.ts +5 -0
  59. package/dist/components/CSkeletonLoaderText.vue.d.ts +44 -0
  60. package/dist/components/CSlideFadeTransition.vue.d.ts +58 -0
  61. package/dist/components/CSplitInput.vue.d.ts +2131 -0
  62. package/dist/components/CSquaredIcon.vue.d.ts +47 -0
  63. package/dist/components/CSsnField.vue.d.ts +2083 -0
  64. package/dist/components/CStatusDot.vue.d.ts +27 -0
  65. package/dist/components/CSwitch.vue.d.ts +54 -0
  66. package/dist/components/CSwitchListItem.vue.d.ts +392 -0
  67. package/dist/components/CTextArea.vue.d.ts +240 -0
  68. package/dist/components/CTextField.vue.d.ts +647 -0
  69. package/dist/components/CTextLink.vue.d.ts +55 -0
  70. package/dist/components/CThirdPartyLogo.vue.d.ts +128 -0
  71. package/dist/components/CTimeago.vue.d.ts +12 -0
  72. package/dist/components/CToast.vue.d.ts +458 -0
  73. package/dist/components/CToastsList.vue.d.ts +430 -0
  74. package/dist/components/CValidationMessage.vue.d.ts +45 -0
  75. package/dist/components/CZipcodeField.vue.d.ts +2080 -0
  76. package/dist/components/index.d.ts +66 -25
  77. package/dist/components/internal/CCloseButton.vue.d.ts +14 -0
  78. package/dist/composables/accessibility.d.ts +1 -0
  79. package/dist/composables/animation.d.ts +12 -0
  80. package/dist/composables/binding.d.ts +19 -0
  81. package/dist/composables/colors.d.ts +13 -0
  82. package/dist/composables/elements.d.ts +3 -0
  83. package/dist/composables/fields.d.ts +9 -0
  84. package/dist/composables/gestures.d.ts +53 -0
  85. package/dist/composables/i18n.d.ts +3 -0
  86. package/dist/composables/id.d.ts +11 -0
  87. package/dist/composables/input-mask.d.ts +18 -0
  88. package/dist/composables/router.d.ts +30 -0
  89. package/dist/composables/slots.d.ts +2 -0
  90. package/dist/composables/toast.d.ts +21 -0
  91. package/dist/composables/validations.d.ts +77 -0
  92. package/dist/index.css +1 -0
  93. package/dist/index.d.ts +5 -4
  94. package/dist/index.mjs +11738 -0
  95. package/dist/index.mjs.map +1 -0
  96. package/dist/plugin.d.ts +2 -2
  97. package/dist/services/animation.d.ts +17 -0
  98. package/dist/services/directives/index.d.ts +2 -0
  99. package/dist/services/directives/scroll-into-view.d.ts +7 -0
  100. package/dist/services/directives/tap-animation.d.ts +6 -0
  101. package/dist/services/id.d.ts +22 -0
  102. package/dist/services/injections/accordions.d.ts +3 -0
  103. package/dist/services/injections/animations.d.ts +2 -0
  104. package/dist/services/injections/buttons.d.ts +4 -0
  105. package/dist/services/injections/forms.d.ts +6 -0
  106. package/dist/services/injections/icon-buttons.d.ts +3 -0
  107. package/dist/services/injections/pills.d.ts +4 -0
  108. package/dist/services/injections/radio.d.ts +10 -0
  109. package/dist/styles/main.css +3002 -0
  110. package/dist/styles/utils.css +2319 -0
  111. package/dist/theme/icons.d.ts +35 -2
  112. package/dist/types/CForm.d.ts +12 -0
  113. package/dist/types/font-awesome.d.ts +5 -0
  114. package/dist/types.d.ts +12 -0
  115. package/index.ts +2 -0
  116. package/package.json +60 -45
  117. package/src/assets/fonts/grenette-regular.woff2 +0 -0
  118. package/src/assets/fonts/grenette-semibold.woff2 +0 -0
  119. package/src/assets/fonts/polymath.woff2 +0 -0
  120. package/src/assets/logos/propel/icon.svg +15 -0
  121. package/src/assets/logos/propel/lockup.svg +11 -0
  122. package/src/colors/colors.ts +173 -0
  123. package/src/colors/theme.ts +8 -14
  124. package/src/colors/util-classes.ts +49 -0
  125. package/src/componentResolver.js +33 -0
  126. package/src/components/CAccordion.vue +32 -7
  127. package/src/components/CAccordionItem.vue +109 -36
  128. package/src/components/CAppBar.vue +237 -0
  129. package/src/components/CBadge.vue +74 -0
  130. package/src/components/CBottomSheet.vue +430 -0
  131. package/src/components/CButton/CButton.vue +347 -0
  132. package/src/components/CButton/types.ts +5 -0
  133. package/src/components/CButtonStack.vue +36 -0
  134. package/src/components/CCard.vue +149 -41
  135. package/src/components/CCardFooter.vue +11 -27
  136. package/src/components/CCardHeader.vue +30 -21
  137. package/src/components/CCardSection.vue +23 -12
  138. package/src/components/CCheckbox.vue +191 -21
  139. package/src/components/CCol.vue +55 -0
  140. package/src/components/CDivider.vue +46 -0
  141. package/src/components/CDobField.vue +153 -0
  142. package/src/components/CDobSelect.vue +274 -0
  143. package/src/components/CEmailField.vue +61 -0
  144. package/src/components/CExpandTransition.vue +55 -0
  145. package/src/components/CFadeTransition.vue +23 -0
  146. package/src/components/CFileInput.vue +186 -0
  147. package/src/components/CFixedPageFooter.vue +76 -0
  148. package/src/components/CForm.vue +86 -0
  149. package/src/components/CFormFieldCounter.vue +40 -0
  150. package/src/components/CIconButton.vue +175 -59
  151. package/src/components/CLabel.vue +52 -0
  152. package/src/components/CListItem.vue +149 -45
  153. package/src/components/CListItemContent.vue +60 -0
  154. package/src/components/CListItemIcon.vue +27 -31
  155. package/src/components/CLoader.vue +156 -0
  156. package/src/components/CLogo.vue +23 -0
  157. package/src/components/CMaskedTextField.vue +118 -0
  158. package/src/components/CMenu.vue +24 -0
  159. package/src/components/CMenuItem.vue +106 -0
  160. package/src/components/CMenuLabel.vue +26 -0
  161. package/src/components/CModal.vue +198 -79
  162. package/src/components/CModalLoading.vue +27 -9
  163. package/src/components/CNotification.vue +86 -53
  164. package/src/components/CPhoneField.vue +69 -0
  165. package/src/components/CPill.vue +162 -0
  166. package/src/components/CPillGroup.vue +73 -0
  167. package/src/components/CPopup.vue +66 -0
  168. package/src/components/CProgressLinear.vue +52 -0
  169. package/src/components/CProgressRing.vue +126 -0
  170. package/src/components/CRadio.vue +138 -0
  171. package/src/components/CRadioGroup.vue +142 -0
  172. package/src/components/CRebrand.vue +28 -0
  173. package/src/components/CRow.vue +62 -0
  174. package/src/components/CSafeArea.vue +23 -0
  175. package/src/components/CSectionHeader.vue +50 -0
  176. package/src/components/CSelect.vue +223 -74
  177. package/src/components/CSkeleton.vue +65 -0
  178. package/src/components/CSkeletonLoaderCard.vue +29 -0
  179. package/src/components/CSkeletonLoaderCircle.vue +18 -14
  180. package/src/components/CSkeletonLoaderText.vue +127 -17
  181. package/src/components/CSlideFadeTransition.vue +100 -0
  182. package/src/components/CSplitInput.vue +111 -0
  183. package/src/components/CSquaredIcon.vue +83 -0
  184. package/src/components/CSsnField.vue +86 -0
  185. package/src/components/CStatusDot.vue +70 -0
  186. package/src/components/CSwitch.vue +125 -0
  187. package/src/components/CSwitchListItem.vue +110 -0
  188. package/src/components/CTextArea.vue +193 -47
  189. package/src/components/CTextField.vue +450 -93
  190. package/src/components/CTextLink.vue +48 -38
  191. package/src/components/CThirdPartyLogo.vue +127 -0
  192. package/src/components/CTimeago.vue +63 -0
  193. package/src/components/CToast.vue +259 -0
  194. package/src/components/CToastsList.vue +32 -0
  195. package/src/components/CValidationMessage.vue +70 -0
  196. package/src/components/CZipcodeField.vue +69 -0
  197. package/src/components/index.ts +66 -25
  198. package/src/components/internal/CCloseButton.vue +57 -0
  199. package/src/composables/accessibility.ts +29 -0
  200. package/src/composables/animation.ts +95 -0
  201. package/src/composables/binding.ts +34 -0
  202. package/src/composables/colors.ts +59 -0
  203. package/src/composables/elements.ts +72 -0
  204. package/src/composables/fields.ts +19 -0
  205. package/src/composables/gestures.ts +197 -0
  206. package/src/composables/i18n.ts +13 -0
  207. package/src/composables/id.ts +23 -0
  208. package/src/composables/input-mask.ts +139 -0
  209. package/src/composables/router.ts +64 -0
  210. package/src/composables/slots.ts +57 -0
  211. package/src/composables/toast.ts +64 -0
  212. package/src/composables/validations.ts +214 -0
  213. package/src/index.ts +7 -7
  214. package/src/plugin.ts +13 -6
  215. package/src/services/animation.ts +101 -0
  216. package/src/services/directives/index.ts +2 -0
  217. package/src/services/directives/scroll-into-view.ts +86 -0
  218. package/src/services/directives/tap-animation.ts +71 -0
  219. package/src/services/id.ts +31 -0
  220. package/src/services/injections/accordions.ts +4 -0
  221. package/src/services/injections/animations.ts +3 -0
  222. package/src/services/injections/buttons.ts +5 -0
  223. package/src/services/injections/forms.ts +8 -0
  224. package/src/services/injections/icon-buttons.ts +4 -0
  225. package/src/services/injections/pills.ts +7 -0
  226. package/src/services/injections/radio.ts +12 -0
  227. package/src/shims-vue.d.ts +6 -3
  228. package/src/styles/_animation.scss +19 -0
  229. package/src/styles/_button.scss +61 -0
  230. package/src/styles/_colors.scss +58 -11
  231. package/src/styles/_core.scss +248 -87
  232. package/src/styles/_form-fields.scss +68 -15
  233. package/src/styles/_grenette.scss +13 -0
  234. package/src/styles/_polymath.scss +14 -0
  235. package/src/styles/_reset.scss +105 -0
  236. package/src/styles/_shoelace.scss +46 -0
  237. package/src/styles/_typography.scss +40 -10
  238. package/src/styles/main.scss +6 -3
  239. package/src/styles/utils/a11y.scss +18 -0
  240. package/src/styles/utils/typography.scss +13 -0
  241. package/src/styles/utils.scss +560 -0
  242. package/src/styles/variables.scss +27 -15
  243. package/src/theme/icons.ts +16 -5
  244. package/src/types/CForm.ts +15 -0
  245. package/src/types/font-awesome.ts +6 -0
  246. package/src/types.ts +15 -0
  247. package/.browserslistrc +0 -3
  248. package/.eslintrc.js +0 -4
  249. package/.stylelintrc.js +0 -3
  250. package/babel.config.js +0 -3
  251. package/dist/citrus-ui.common.js +0 -43434
  252. package/dist/citrus-ui.common.js.map +0 -1
  253. package/dist/citrus-ui.css +0 -1
  254. package/dist/citrus-ui.umd.js +0 -43444
  255. package/dist/citrus-ui.umd.js.map +0 -1
  256. package/dist/citrus-ui.umd.min.js +0 -27
  257. package/dist/citrus-ui.umd.min.js.map +0 -1
  258. package/dist/demo.html +0 -10
  259. package/dist/fonts/Blitz-Script.85ed9abe.woff2 +0 -0
  260. package/dist/fonts/ObjectSans-Bold.5492f3d5.woff2 +0 -0
  261. package/dist/fonts/ObjectSans-BoldSlanted.29e2a87e.woff2 +0 -0
  262. package/dist/fonts/ObjectSans-Heavy.d0b2f035.woff2 +0 -0
  263. package/dist/fonts/ObjectSans-HeavySlanted.45e9c063.woff2 +0 -0
  264. package/dist/fonts/ObjectSans-Light.f885dec3.woff2 +0 -0
  265. package/dist/fonts/ObjectSans-LightSlanted.b8eb7c12.woff2 +0 -0
  266. package/dist/fonts/ObjectSans-Regular.e4ea0b90.woff2 +0 -0
  267. package/dist/fonts/ObjectSans-Slanted.57a90be9.woff2 +0 -0
  268. package/dist/fonts/ObjectSans-Thin.86d44227.woff2 +0 -0
  269. package/dist/fonts/ObjectSans-ThinSlanted.20342160.woff2 +0 -0
  270. package/jest.config.js +0 -9
  271. package/plopfile.js +0 -67
  272. package/project.json +0 -69
  273. package/src/assets/fonts/Blitz-Script.woff2 +0 -0
  274. package/src/assets/fonts/ObjectSans-Bold.woff2 +0 -0
  275. package/src/assets/fonts/ObjectSans-BoldSlanted.woff2 +0 -0
  276. package/src/assets/fonts/ObjectSans-Heavy.woff2 +0 -0
  277. package/src/assets/fonts/ObjectSans-HeavySlanted.woff2 +0 -0
  278. package/src/assets/fonts/ObjectSans-Light.woff2 +0 -0
  279. package/src/assets/fonts/ObjectSans-LightSlanted.woff2 +0 -0
  280. package/src/assets/fonts/ObjectSans-Regular.woff2 +0 -0
  281. package/src/assets/fonts/ObjectSans-Slanted.woff2 +0 -0
  282. package/src/assets/fonts/ObjectSans-Thin.woff2 +0 -0
  283. package/src/assets/fonts/ObjectSans-ThinSlanted.woff2 +0 -0
  284. package/src/components/CAlert.vue +0 -78
  285. package/src/components/CBanner.vue +0 -47
  286. package/src/components/CButton.vue +0 -146
  287. package/src/components/CListItemAction.vue +0 -29
  288. package/src/components/CSegmentedButton.vue +0 -47
  289. package/src/components/CSegmentedButtonOption.vue +0 -42
  290. package/src/components/helpers/FormField.vue +0 -48
  291. package/src/components/helpers/SelectInput.vue +0 -115
  292. package/src/shims-scss.d.ts +0 -4
  293. package/src/shims-vuetify.d.ts +0 -4
  294. package/src/styles/_blitz.scss +0 -8
  295. package/src/styles/_object-sans.scss +0 -23
  296. package/storybook-static/0.799c368cbe88266827ba.manager.bundle.js +0 -1
  297. package/storybook-static/0.a9f0a9ad.iframe.bundle.js +0 -3
  298. package/storybook-static/0.a9f0a9ad.iframe.bundle.js.LICENSE.txt +0 -8
  299. package/storybook-static/0.a9f0a9ad.iframe.bundle.js.map +0 -1
  300. package/storybook-static/1.0438fd8d.iframe.bundle.js +0 -3
  301. package/storybook-static/1.0438fd8d.iframe.bundle.js.LICENSE.txt +0 -17
  302. package/storybook-static/1.0438fd8d.iframe.bundle.js.map +0 -1
  303. package/storybook-static/1.9ebd2fb519f6726108de.manager.bundle.js +0 -1
  304. package/storybook-static/10.348d8814.iframe.bundle.js +0 -3
  305. package/storybook-static/10.348d8814.iframe.bundle.js.LICENSE.txt +0 -30
  306. package/storybook-static/10.348d8814.iframe.bundle.js.map +0 -1
  307. package/storybook-static/10.a85ea1a67689be8e19ff.manager.bundle.js +0 -1
  308. package/storybook-static/11.f4e922583ae35da460f3.manager.bundle.js +0 -2
  309. package/storybook-static/11.f4e922583ae35da460f3.manager.bundle.js.LICENSE.txt +0 -12
  310. package/storybook-static/12.1415460941f0bdcb8fa8.manager.bundle.js +0 -1
  311. package/storybook-static/2.75a17459.iframe.bundle.js +0 -3
  312. package/storybook-static/2.75a17459.iframe.bundle.js.LICENSE.txt +0 -26
  313. package/storybook-static/2.75a17459.iframe.bundle.js.map +0 -1
  314. package/storybook-static/5.f459d151315e6780c20f.manager.bundle.js +0 -2
  315. package/storybook-static/5.f459d151315e6780c20f.manager.bundle.js.LICENSE.txt +0 -8
  316. package/storybook-static/6.3bd64d820f3745f262ff.manager.bundle.js +0 -1
  317. package/storybook-static/6.ce8d99b4.iframe.bundle.js +0 -1
  318. package/storybook-static/7.3d04765dbf3f1dcd706c.manager.bundle.js +0 -1
  319. package/storybook-static/7.6633a922.iframe.bundle.js +0 -3
  320. package/storybook-static/7.6633a922.iframe.bundle.js.LICENSE.txt +0 -12
  321. package/storybook-static/7.6633a922.iframe.bundle.js.map +0 -1
  322. package/storybook-static/8.b541eadfcb9164835dfc.manager.bundle.js +0 -1
  323. package/storybook-static/8.fc5e1ebf.iframe.bundle.js +0 -1
  324. package/storybook-static/9.411ac8e451bbb10926c7.manager.bundle.js +0 -1
  325. package/storybook-static/9.724ac3ed.iframe.bundle.js +0 -3
  326. package/storybook-static/9.724ac3ed.iframe.bundle.js.LICENSE.txt +0 -15
  327. package/storybook-static/9.724ac3ed.iframe.bundle.js.map +0 -1
  328. package/storybook-static/css/main.95216119.css +0 -1
  329. package/storybook-static/css/vendors~main.02dc89bf.css +0 -1
  330. package/storybook-static/favicon.ico +0 -0
  331. package/storybook-static/fonts/Blitz-Script.85ed9abe.woff2 +0 -0
  332. package/storybook-static/fonts/ObjectSans-Bold.5492f3d5.woff2 +0 -0
  333. package/storybook-static/fonts/ObjectSans-BoldSlanted.29e2a87e.woff2 +0 -0
  334. package/storybook-static/fonts/ObjectSans-Heavy.d0b2f035.woff2 +0 -0
  335. package/storybook-static/fonts/ObjectSans-HeavySlanted.45e9c063.woff2 +0 -0
  336. package/storybook-static/fonts/ObjectSans-Light.f885dec3.woff2 +0 -0
  337. package/storybook-static/fonts/ObjectSans-LightSlanted.b8eb7c12.woff2 +0 -0
  338. package/storybook-static/fonts/ObjectSans-Regular.e4ea0b90.woff2 +0 -0
  339. package/storybook-static/fonts/ObjectSans-Slanted.57a90be9.woff2 +0 -0
  340. package/storybook-static/fonts/ObjectSans-Thin.86d44227.woff2 +0 -0
  341. package/storybook-static/fonts/ObjectSans-ThinSlanted.20342160.woff2 +0 -0
  342. package/storybook-static/iframe.html +0 -348
  343. package/storybook-static/index.html +0 -51
  344. package/storybook-static/main.7b4aec9c4352d4bb535b.manager.bundle.js +0 -1
  345. package/storybook-static/main.9e8c64c7.iframe.bundle.js +0 -1
  346. package/storybook-static/runtime~main.91a0c7330ab317d35c4a.manager.bundle.js +0 -1
  347. package/storybook-static/runtime~main.e4da100f.iframe.bundle.js +0 -1
  348. package/storybook-static/vendors~main.6660eda6.iframe.bundle.js +0 -7
  349. package/storybook-static/vendors~main.6660eda6.iframe.bundle.js.LICENSE.txt +0 -80
  350. package/storybook-static/vendors~main.6660eda6.iframe.bundle.js.map +0 -1
  351. package/storybook-static/vendors~main.f7f16cebbf3aa96a4f89.manager.bundle.js +0 -2
  352. package/storybook-static/vendors~main.f7f16cebbf3aa96a4f89.manager.bundle.js.LICENSE.txt +0 -110
  353. package/tsconfig.dist.json +0 -7
  354. package/tsconfig.json +0 -24
  355. package/vue.config.js +0 -5
@@ -0,0 +1,86 @@
1
+ <template>
2
+ <form ref="form" :data-test="dataTest" novalidate @submit.prevent="$emit('submit', $event)">
3
+ <slot />
4
+ </form>
5
+ </template>
6
+
7
+ <script lang="ts">
8
+ import scrollIntoViewIfNeeded from 'scroll-into-view-if-needed';
9
+ import { computed, defineComponent, onMounted, provide, ref, watch } from 'vue';
10
+
11
+ import { VALIDATIONS } from '@propelinc/citrus-ui/src/services/injections/forms';
12
+ import type { ValidationState } from '@propelinc/citrus-ui/src/types/CForm';
13
+
14
+ interface FormValidation {
15
+ id: string;
16
+ validate: () => boolean;
17
+ valid: boolean;
18
+ field?: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement | null;
19
+ }
20
+
21
+ export default defineComponent({
22
+ name: 'CForm',
23
+ props: {
24
+ dataTest: { type: String, default: 'form' },
25
+ // eslint-disable-next-line vue/no-unused-properties
26
+ value: { type: Boolean, default: false },
27
+ },
28
+ emits: ['submit', 'input'],
29
+ setup(_, { expose, emit }) {
30
+ const form = ref<HTMLFormElement | null>(null);
31
+ const inputs = ref<Record<string, FormValidation>>({});
32
+
33
+ provide(VALIDATIONS, {
34
+ register: (input: ValidationState) => {
35
+ // NOTE(ram): Vue collapses the ref to input.field automatically so we need to adjust types.
36
+ inputs.value = { ...inputs.value, [input.id]: input as unknown as FormValidation };
37
+ },
38
+ unregister: (id: string) => {
39
+ const filteredInputs = { ...inputs.value };
40
+ delete filteredInputs[id];
41
+ inputs.value = filteredInputs;
42
+ },
43
+ });
44
+
45
+ const inputArray = computed(() => Object.values(inputs.value));
46
+ const getInvalidInputs = (startValidating?: boolean): FormValidation[] => {
47
+ return inputArray.value.filter((input) => {
48
+ return startValidating ? !input.validate() : !input.valid;
49
+ });
50
+ };
51
+
52
+ // NOTE(mohan): I would love for this to be a computed property, but Vue 2's
53
+ // the reactivity system can't seem to track refs inside of refs, though it
54
+ // should work in Vue 3.
55
+ watch(getInvalidInputs, (newInvalidInputs, oldInvalidInputs) => {
56
+ const newValid = newInvalidInputs.length === 0;
57
+ const oldValid = oldInvalidInputs?.length === 0;
58
+ if (newValid !== oldValid) {
59
+ emit('input', newValid);
60
+ }
61
+ });
62
+ onMounted(() => emit('input', getInvalidInputs().length === 0));
63
+
64
+ const validate = (): boolean => {
65
+ if (!form.value) {
66
+ return false;
67
+ }
68
+
69
+ const invalidInputs = getInvalidInputs(true);
70
+ const firstInvalidField = invalidInputs.find((input) => input.field)?.field;
71
+ if (firstInvalidField) {
72
+ scrollIntoViewIfNeeded(firstInvalidField, {
73
+ behavior: 'smooth',
74
+ block: 'center',
75
+ scrollMode: 'if-needed',
76
+ });
77
+ }
78
+
79
+ return invalidInputs.length === 0;
80
+ };
81
+
82
+ expose({ validate, inputs: inputArray });
83
+ return { form };
84
+ },
85
+ });
86
+ </script>
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <div>{{ displayText }}</div>
3
+ </template>
4
+
5
+ <script lang="ts">
6
+ import type { PropType } from 'vue';
7
+ import { computed, defineComponent } from 'vue';
8
+
9
+ export default defineComponent({
10
+ name: 'CFormFieldCounter',
11
+ props: {
12
+ /** Sets the denominator of the counter. */
13
+ counter: { type: Number as PropType<number | null>, default: null },
14
+ /** Function or number that determines the numerator of the counter. */
15
+ counterValue: {
16
+ type: [Number, Function] as PropType<number | (() => number | null)>,
17
+ default: null,
18
+ },
19
+ /** Input value of the parent form field */
20
+ value: { type: String, default: '' },
21
+ },
22
+ setup(props) {
23
+ const numerator = computed(() => {
24
+ if (typeof props.counterValue === 'function') {
25
+ return props.counterValue();
26
+ } else if (typeof props.counterValue === 'number') {
27
+ return props.counterValue;
28
+ } else {
29
+ return props.value.length;
30
+ }
31
+ });
32
+
33
+ const displayText = computed(() => {
34
+ return `${numerator.value}/${props.counter}`;
35
+ });
36
+
37
+ return { numerator, displayText };
38
+ },
39
+ });
40
+ </script>
@@ -1,73 +1,189 @@
1
1
  <template>
2
- <v-btn
3
- class="icon-button"
2
+ <CButton
3
+ v-bind="$attrs"
4
+ class="c-icon-button"
5
+ :class="{
6
+ 'c-icon-button--inherit': inheritColor,
7
+ [`c-icon-button-size--${computedSize}`]: computedSize,
8
+ }"
9
+ :data-inherit-color="inheritColor"
10
+ :data-size="computedSize"
4
11
  data-test="icon-button"
5
- :class="{ [colorScheme.container]: colorScheme.container }"
6
- icon
7
- :color="colorScheme.icon"
8
- :ripple="false"
9
- :to="to"
12
+ :disabled="disabled"
10
13
  :href="href"
14
+ :level="level"
15
+ :loading="loading"
16
+ :size="computedSize"
11
17
  :target="target"
12
- v-on="$listeners"
18
+ :to="to"
19
+ :variant="computedVariant"
20
+ @blur="$emit('blur', $event)"
21
+ @click="$emit('click', $event)"
22
+ @focus="$emit('focus', $event)"
13
23
  >
14
- <font-awesome-icon data-test="icon-button-icon" :class="{ 'fa-spin': spinIcon }" :icon="icon" />
15
- </v-btn>
24
+ <div
25
+ role="img"
26
+ data-test="icon-button-a11y"
27
+ :aria-label="ariaLabel"
28
+ :aria-labelledby="ariaLabelledby"
29
+ >
30
+ <slot>
31
+ <font-awesome-icon
32
+ v-if="icon"
33
+ class="c-icon-button__icon"
34
+ :class="{ 'c-icon-button__icon--spin': spinIcon }"
35
+ data-test="icon-button-icon"
36
+ :icon="icon"
37
+ />
38
+ </slot>
39
+ </div>
40
+ </CButton>
16
41
  </template>
17
42
 
18
43
  <script lang="ts">
19
- import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
44
+ import type { IconDefinition } from '@fortawesome/pro-light-svg-icons';
20
45
  import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
21
- import { Component, Vue, Prop } from 'vue-property-decorator';
22
- import { RawLocation } from 'vue-router';
46
+ import type { PropType } from 'vue';
47
+ import { computed, defineComponent, inject, provide } from 'vue';
48
+ import type { RouteLocationRaw } from 'vue-router';
23
49
 
24
- interface ColorScheme {
25
- icon: string;
26
- container?: string;
27
- }
50
+ import CButton from '@propelinc/citrus-ui/src/components/CButton/CButton.vue';
51
+ import type {
52
+ ButtonLevel,
53
+ ButtonSize,
54
+ ButtonVariant,
55
+ } from '@propelinc/citrus-ui/src/components/CButton/types';
56
+ import { useA11yLabelCheck } from '@propelinc/citrus-ui/src/composables/accessibility';
57
+ import { BOUNCE_AMOUNT } from '@propelinc/citrus-ui/src/services/injections/buttons';
58
+ import { INHERIT_COLOR, TERTIARY } from '@propelinc/citrus-ui/src/services/injections/icon-buttons';
28
59
 
29
- @Component({ name: 'CIconButton', components: { FontAwesomeIcon } })
30
- export default class CIconButton extends Vue {
31
- /** Renders a filled circle around the button */
32
- @Prop({ type: Boolean, default: false }) contained!: boolean;
33
- /** Renders the navy variant */
34
- @Prop({ type: Boolean, default: false }) dark!: boolean;
35
- /** Renders the white variant */
36
- @Prop({ type: Boolean, default: false }) light!: boolean;
37
- @Prop({ type: [String, Array, Object], required: true }) icon!: IconDefinition;
38
- /** Spins the icon for loading states */
39
- @Prop({ type: Boolean, default: false }) spinIcon!: boolean;
40
- @Prop([Object, String]) to?: RawLocation;
41
- @Prop(String) href?: string;
42
- @Prop(String) target?: string;
43
-
44
- get colorScheme(): ColorScheme {
45
- if (this.contained) {
46
- if (this.light) {
47
- return {
48
- icon: 'navy',
49
- container: 'white',
50
- };
51
- } else if (this.dark) {
52
- return {
53
- icon: 'white',
54
- container: 'navy',
55
- };
56
- } else {
57
- return {
58
- icon: 'white',
59
- container: 'primary',
60
- };
60
+ export default defineComponent({
61
+ components: { FontAwesomeIcon, CButton },
62
+ props: {
63
+ /** ARIA label for the button. You must use either this or ariaLabelledby. */
64
+ ariaLabel: { type: String, default: undefined },
65
+ /** ARIA labelledby for the button. You must use either this or ariaLabel. */
66
+ ariaLabelledby: { type: String, default: undefined },
67
+ /** Controls whether button is disabled */
68
+ disabled: { type: Boolean, default: false },
69
+ /** Designates the button as an anchor and applies the href attribute */
70
+ href: { type: String, default: undefined },
71
+ /** Specifies a Font Awesome icon */
72
+ icon: {
73
+ type: [String, Array, Object] as PropType<string | string[] | IconDefinition>,
74
+ default: undefined,
75
+ },
76
+ /**
77
+ * Controls whether button uses the large variant
78
+ * @deprecated Use `size="large"` instead
79
+ */
80
+ large: { type: Boolean, default: false, deprecated: true },
81
+ /**
82
+ * Controls the level of the button
83
+ * @default 'normal'
84
+ */
85
+ level: { type: String as PropType<ButtonLevel>, default: 'normal' },
86
+ /** Controls whether button is loading */
87
+ loading: { type: Boolean, default: false },
88
+ /**
89
+ * Controls whether button uses the secondary variant
90
+ * @deprecated Use `variant="secondary"` instead
91
+ */
92
+ secondary: { type: Boolean, default: false, deprecated: true },
93
+ /**
94
+ * Controls the size of the button
95
+ * @default 'medium'
96
+ */
97
+ size: { type: String as PropType<ButtonSize>, default: 'medium' },
98
+ /** Spins the icon for loading states */
99
+ spinIcon: { type: Boolean, default: false },
100
+ /** Designates the target attribute. Only use with the href prop. */
101
+ target: { type: String, default: undefined },
102
+ /**
103
+ * Controls whether button uses the tertiary variant
104
+ * @deprecated Use `variant="tertiary"` instead
105
+ */
106
+ tertiary: { type: Boolean, default: false, deprecated: true },
107
+ /** Controls whether button functions as a router-link */
108
+ to: { type: [Object, String] as PropType<RouteLocationRaw>, default: undefined },
109
+ /**
110
+ * Controls the variant of the button
111
+ * @default 'primary'
112
+ */
113
+ variant: { type: String as PropType<ButtonVariant>, default: 'primary' },
114
+ },
115
+ emits: ['blur', 'click', 'focus'],
116
+ setup(props) {
117
+ useA11yLabelCheck('CIconButton', props);
118
+
119
+ const injectedTertiary = inject(TERTIARY, undefined);
120
+ const injectedOrPropTertiary = computed(() => injectedTertiary?.value ?? props.tertiary);
121
+ /**
122
+ * Handle the `variant` prop. `secondary` and `tertiary` are deprecated, but because we set a
123
+ * default `variant`, we need to give them precedence.
124
+ *
125
+ * This is slightly different than the implementation of `computedVariant` in CButton, as
126
+ * `CButton` does not make use of an injected `TERTIARY` value.
127
+ */
128
+ const computedVariant = computed((): ButtonVariant => {
129
+ if (props.secondary) {
130
+ return 'secondary';
61
131
  }
62
- } else {
63
- if (this.light) {
64
- return { icon: 'white' };
65
- } else if (this.dark) {
66
- return { icon: 'navy' };
67
- } else {
68
- return { icon: 'primary' };
132
+
133
+ if (injectedOrPropTertiary.value) {
134
+ return 'tertiary';
69
135
  }
70
- }
71
- }
72
- }
136
+
137
+ return props.variant;
138
+ });
139
+
140
+ /**
141
+ * Handle the `size` prop. `large` is deprecated, but because we set a default `size`, we need
142
+ * to give it precedence.
143
+ */
144
+ const computedSize = computed((): ButtonSize => {
145
+ if (props.large) {
146
+ return 'large';
147
+ }
148
+
149
+ return props.size;
150
+ });
151
+
152
+ const inheritColor = inject(INHERIT_COLOR, undefined);
153
+
154
+ provide(BOUNCE_AMOUNT, 0.9);
155
+
156
+ return { computedSize, computedVariant, inheritColor };
157
+ },
158
+ });
73
159
  </script>
160
+
161
+ <style lang="scss" scoped>
162
+ @import '@propelinc/citrus-ui/src/styles/core';
163
+
164
+ .c-icon-button::part(base) {
165
+ font-size: $font-size-icon-medium;
166
+ line-height: 0;
167
+ padding: 0;
168
+ width: $button-size-medium;
169
+ }
170
+
171
+ .c-icon-button--inherit::part(base) {
172
+ color: inherit;
173
+ }
174
+
175
+ .c-icon-button::part(label) {
176
+ align-items: center;
177
+ display: flex;
178
+ justify-content: center;
179
+ padding: 0;
180
+ }
181
+
182
+ .c-icon-button-size--large::part(base) {
183
+ width: $button-size-large;
184
+ }
185
+
186
+ .c-icon-button__icon--spin {
187
+ animation: $loader-spin-animation;
188
+ }
189
+ </style>
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <div class="c-label" :data-test="dataTest">
3
+ <slot name="icon">
4
+ <FontAwesomeIcon v-if="icon" data-test="label-icon" :icon="icon" size="xs" />
5
+ </slot>
6
+ <div class="c-label__text" data-test="label-text">
7
+ <slot />
8
+ </div>
9
+ </div>
10
+ </template>
11
+
12
+ <script lang="ts">
13
+ import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
14
+ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
15
+ import type { PropType } from 'vue';
16
+ import { defineComponent } from 'vue';
17
+
18
+ export default defineComponent({
19
+ components: { FontAwesomeIcon },
20
+ props: {
21
+ /** Specifies the label's icon, overwritten if icon slot is used */
22
+ icon: {
23
+ type: [Array, String, Object] as PropType<string | string[] | IconDefinition>,
24
+ default: null,
25
+ },
26
+ /** A custom data test string */
27
+ dataTest: { type: String, default: 'label' },
28
+ },
29
+ });
30
+ </script>
31
+
32
+ <style lang="scss" scoped>
33
+ @import '@propelinc/citrus-ui/src/styles/core';
34
+
35
+ .c-label {
36
+ align-items: center;
37
+ background-color: $color-gray-100;
38
+ border-radius: 4px;
39
+ color: $color-text-secondary;
40
+ display: inline-flex;
41
+ font-size: $font-size-small;
42
+ font-weight: $font-weight-semibold;
43
+ gap: 4px;
44
+ height: 24px;
45
+ margin-bottom: 6px;
46
+ padding: 0 12px;
47
+ }
48
+
49
+ .c-label:not(:last-child) {
50
+ margin-right: 8px;
51
+ }
52
+ </style>
@@ -1,69 +1,173 @@
1
1
  <template>
2
- <v-list-item
3
- :role="isButton ? 'button' : undefined"
4
- :to="to"
5
- :href="href"
2
+ <component
3
+ :is="tag"
4
+ v-bind="allAttrs"
5
+ class="c-list-item d-flex flex-col justify-center w-full"
6
+ :class="{ 'c-list-item--is-tappable': isTappable }"
7
+ :href="routerDestinationOrHref"
6
8
  :target="target"
7
- :ripple="false"
8
- class="c-list-item"
9
- v-on="$listeners"
9
+ @click="navigate"
10
10
  >
11
- <slot name="icon">
12
- <c-list-item-icon v-if="icon" :icon="icon" class="c-list-item__icon" />
13
- </slot>
14
-
15
- <v-list-item-content>
16
- <v-list-item-title class="c-list-item__title" data-test="list-item-content">
17
- <slot />
18
- </v-list-item-title>
19
- </v-list-item-content>
20
-
21
- <slot name="action">
22
- <c-list-item-action v-if="isTappable" />
23
- </slot>
24
- </v-list-item>
11
+ <div
12
+ class="d-flex flex-row gap-3 justify-between w-full p-4"
13
+ :class="{
14
+ 'align-start': align === 'top',
15
+ 'align-center': align !== 'top',
16
+ }"
17
+ >
18
+ <slot name="prepend">
19
+ <CListItemIcon v-if="icon || iconSlotHasContent" :icon="icon" :icon-color="iconColor">
20
+ <template #icon>
21
+ <slot name="icon" />
22
+ </template>
23
+ </CListItemIcon>
24
+ </slot>
25
+
26
+ <div class="flex-1 d-flex flex-row gap-3 justify-between align-center">
27
+ <CListItemContent :title="title" :label="label">
28
+ <template v-for="slotName in ['title', 'label', 'default']" #[slotName]>
29
+ <slot :name="slotName" />
30
+ </template>
31
+ </CListItemContent>
32
+
33
+ <slot name="append">
34
+ <div
35
+ v-if="renderActionSlot"
36
+ data-test="list-item-action"
37
+ class="c-list-item__append__action flex-shrink-0"
38
+ >
39
+ <slot name="action">
40
+ <FontAwesomeIcon
41
+ data-test="list-item-action-icon"
42
+ class="c-list-item__append__action-icon"
43
+ fixed-width
44
+ :icon="actionIcon ? actionIcon : faChevronRight"
45
+ />
46
+ </slot>
47
+ </div>
48
+ </slot>
49
+ </div>
50
+ </div>
51
+ </component>
25
52
  </template>
26
53
 
27
54
  <script lang="ts">
28
- import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
55
+ import { faChevronRight } from '@fortawesome/pro-regular-svg-icons';
29
56
  import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
30
- import { Component, Vue, Prop } from 'vue-property-decorator';
31
- import { RawLocation } from 'vue-router';
57
+ import { type PropType, computed, defineComponent, mergeProps, toRefs } from 'vue';
58
+ import type { RouteLocationRaw } from 'vue-router';
32
59
 
33
- import CListItemAction from '@/components/CListItemAction.vue';
34
- import CListItemIcon from '@/components/CListItemIcon.vue';
60
+ import CListItemContent from '@propelinc/citrus-ui/src/components/CListItemContent.vue';
61
+ import CListItemIcon from '@propelinc/citrus-ui/src/components/CListItemIcon.vue';
62
+ import { useRouterLink } from '@propelinc/citrus-ui/src/composables/router';
63
+ import { useSlotHasContent } from '@propelinc/citrus-ui/src/composables/slots';
64
+ import type { FaPropType } from '@propelinc/citrus-ui/src/types/font-awesome';
35
65
 
36
- @Component({ name: 'CListItem', components: { FontAwesomeIcon, CListItemIcon, CListItemAction } })
37
- export default class CListItem extends Vue {
38
- @Prop({ type: [String, Array, Object] }) icon?: IconDefinition;
39
- @Prop([String, Object]) to?: RawLocation;
40
- @Prop(String) target?: string;
41
- @Prop(String) href?: string;
66
+ export default defineComponent({
67
+ components: { FontAwesomeIcon, CListItemIcon, CListItemContent },
68
+ props: {
69
+ /** The Font Awesome icon to display */
70
+ icon: { type: [String, Array, Object] as FaPropType, default: null },
71
+ /** The icon to display on the right side for clickable items, defaulting to right arrow */
72
+ actionIcon: { type: [String, Array, Object] as FaPropType, default: null },
73
+ /** Color of the icon background */
74
+ iconColor: { type: String, default: 'gray-100' },
75
+ /** Emphasized text above body text. Overridden by the default slot. */
76
+ title: { type: String, default: undefined },
77
+ /** Plain body copy. Overridden by the default slot. */
78
+ label: { type: String, default: undefined },
79
+ /** Router location for links within the app */
80
+ to: { type: [String, Object] as PropType<RouteLocationRaw>, default: undefined },
81
+ /** HTML target attribute for links to outside the app */
82
+ target: { type: String, default: undefined },
83
+ /** Location for links to outside the app */
84
+ href: { type: String, default: undefined },
85
+ /** Changes alignment of icon and action icon */
86
+ align: { type: String as PropType<'top' | 'center'>, default: 'center' },
87
+ /** Overrides default behavior to display a chevron in the action slot */
88
+ hideAction: { type: Boolean, default: false },
89
+ },
90
+ setup(props, { attrs }) {
91
+ const { to } = toRefs(props);
92
+ const { href: routerDestination, navigate } = useRouterLink(to);
93
+ const routerDestinationOrHref = computed(() => routerDestination.value ?? props.href);
42
94
 
43
- get isLink(): boolean {
44
- return !!this.to || !!this.href;
45
- }
95
+ const isLink = computed(() => !!routerDestinationOrHref.value);
96
+ const isButton = computed(() => !!attrs.onClick);
97
+ const isTappable = computed(() => isLink.value || isButton.value);
46
98
 
47
- get isButton(): boolean {
48
- return !!this.$listeners.click;
49
- }
99
+ const tag = computed(() => {
100
+ if (isLink.value) {
101
+ return 'a';
102
+ } else if (isButton.value) {
103
+ return 'button';
104
+ } else {
105
+ return 'div';
106
+ }
107
+ });
108
+ const tagAttrs = computed(() => {
109
+ if (isButton.value) {
110
+ return { type: 'button' };
111
+ }
112
+ return {};
113
+ });
50
114
 
51
- get isTappable(): boolean {
52
- return this.isButton || this.isLink;
53
- }
54
- }
115
+ const actionSlotHasContent = useSlotHasContent('action');
116
+
117
+ const renderActionSlot = computed(() => {
118
+ if (props.hideAction) {
119
+ return false;
120
+ }
121
+
122
+ return isTappable.value || actionSlotHasContent.value;
123
+ });
124
+ const iconSlotHasContent = useSlotHasContent('icon');
125
+
126
+ const allAttrs = computed(() => mergeProps(attrs, tagAttrs.value));
127
+
128
+ return {
129
+ allAttrs,
130
+ faChevronRight,
131
+ iconSlotHasContent,
132
+ isTappable,
133
+ navigate,
134
+ renderActionSlot,
135
+ routerDestinationOrHref,
136
+ tag,
137
+ };
138
+ },
139
+ });
55
140
  </script>
56
141
 
57
142
  <style lang="scss" scoped>
58
- @import '~@/styles/core.scss';
143
+ @import '@propelinc/citrus-ui/src/styles/core';
144
+ @import '@propelinc/citrus-ui/src/styles/utils/a11y';
59
145
 
60
146
  .c-list-item {
147
+ background: transparent;
148
+ color: $color-text-primary;
149
+ min-height: 64px;
150
+ outline: none;
151
+ text-align: left;
152
+ text-decoration: none;
153
+
61
154
  & + & {
62
155
  border-top: $border;
63
156
  }
157
+
158
+ &:focus-visible {
159
+ @include focus-ring;
160
+ }
161
+ }
162
+
163
+ .c-list-item--is-tappable {
164
+ appearance: none; // Needed to avoid browser default styles for buttons
165
+ border: none; // Needed to avoid browser default styles for buttons
166
+ cursor: pointer;
64
167
  }
65
168
 
66
- .c-list-item__title {
67
- white-space: normal;
169
+ .c-list-item__append__action-icon {
170
+ color: $color-text-secondary;
171
+ font-size: $font-size-medium;
68
172
  }
69
173
  </style>