@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,127 @@
1
+ <template>
2
+ <div class="c-third-party-logo" :style="{ '--size': SIZE_TO_VALUE[size] }">
3
+ <img
4
+ v-if="imageState === 'loaded' || imageState === 'loading'"
5
+ class="c-third-party-logo__img transition-opacity"
6
+ :class="{ 'opacity-0': imageState === 'loading' }"
7
+ :src="src"
8
+ :alt="alt"
9
+ @error="handleImageError"
10
+ @load="handleImageLoad"
11
+ />
12
+ <c-squared-icon
13
+ class="transition-opacity"
14
+ :class="{ 'opacity-0': imageState === 'loaded' }"
15
+ :icon="icon"
16
+ :color="color"
17
+ :large="size === 'large'"
18
+ />
19
+ </div>
20
+ </template>
21
+
22
+ <script lang="ts">
23
+ import { type PropType, defineComponent, ref } from 'vue';
24
+
25
+ import CSquaredIcon from '@propelinc/citrus-ui/src/components/CSquaredIcon.vue';
26
+
27
+ type Size = 'medium' | 'large';
28
+
29
+ type ImageState = 'loading' | 'loaded' | 'failed';
30
+
31
+ const SIZES = new Set<Size>(['medium', 'large']);
32
+
33
+ const SIZE_TO_VALUE: Record<Size, `${number}px`> = {
34
+ medium: '40px',
35
+ large: '56px',
36
+ };
37
+
38
+ /**
39
+ * A component that displays a third party logo with a fallback icon.
40
+ *
41
+ * The fallback icon is displayed while the image is loading or if the image fails to load.
42
+ *
43
+ * The image is rendered, but hidden, while loading, and displayed when loaded.
44
+ */
45
+ export default defineComponent({
46
+ name: 'CThirdPartyLogo',
47
+ components: {
48
+ CSquaredIcon,
49
+ },
50
+ props: {
51
+ /**
52
+ * The alt text for the logo.
53
+ */
54
+ alt: { type: String, required: true },
55
+ /**
56
+ * The color of the fallback icon logo
57
+ */
58
+ color: CSquaredIcon.props.color,
59
+ /**
60
+ * The Font Awesome icon to display as a fallback
61
+ */
62
+ icon: CSquaredIcon.props.icon,
63
+ /**
64
+ * The size of the logo. Defaults to `medium`.
65
+ */
66
+ size: {
67
+ type: String as PropType<Size>,
68
+ required: false,
69
+ default: 'medium',
70
+ validator: (value: string) => SIZES.has(value as Size),
71
+ },
72
+ /**
73
+ * The URL of the logo image
74
+ */
75
+ src: { type: String, required: false, default: '' },
76
+ },
77
+ setup() {
78
+ const imageState = ref<ImageState>('loading');
79
+
80
+ const handleImageError = (): void => {
81
+ imageState.value = 'failed';
82
+ };
83
+
84
+ const handleImageLoad = (): void => {
85
+ imageState.value = 'loaded';
86
+ };
87
+
88
+ return {
89
+ handleImageError,
90
+ handleImageLoad,
91
+ imageState,
92
+ SIZE_TO_VALUE,
93
+ };
94
+ },
95
+ });
96
+ </script>
97
+
98
+ <style scoped>
99
+ .c-third-party-logo {
100
+ border-radius: 8px;
101
+ height: var(--size);
102
+ isolation: isolate;
103
+ object-fit: contain;
104
+ overflow: hidden;
105
+ position: relative;
106
+ width: var(--size);
107
+ }
108
+
109
+ .c-third-party-logo__img {
110
+ display: block;
111
+ height: 100%;
112
+ left: 0;
113
+ object-fit: contain;
114
+ position: absolute;
115
+ top: 0;
116
+ width: 100%;
117
+ z-index: 1;
118
+ }
119
+
120
+ .opacity-0 {
121
+ opacity: 0;
122
+ }
123
+
124
+ .transition-opacity {
125
+ transition: opacity 0.1s ease-in-out;
126
+ }
127
+ </style>
@@ -0,0 +1,63 @@
1
+ <template>
2
+ <time v-bind="$attrs" :datetime="isoString">{{ timeago }}</time>
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
7
+
8
+ const props = withDefaults(
9
+ defineProps<{
10
+ datetime: string | number | Date;
11
+ converter: (datetime: string | number | Date, locale: string, count?: number) => string;
12
+ locale?: string;
13
+ autoUpdate?: number | false;
14
+ }>(),
15
+ {
16
+ locale: 'en',
17
+ autoUpdate: 60,
18
+ }
19
+ );
20
+
21
+ // NOTE(ram): Used to trigger reactivity in the computed property for auto updates.
22
+ const counter = ref(0);
23
+ let timer: number | null = null;
24
+
25
+ const isoString = computed((): string => new Date(props.datetime).toISOString());
26
+ const timeago = computed((): string =>
27
+ props.converter(props.datetime, props.locale, counter.value)
28
+ );
29
+
30
+ const startAutoUpdate = (): void => {
31
+ if (props.autoUpdate) {
32
+ // TODO(ram): This is a workaround to make sure the timer is of type number.
33
+ // The type of setInterval is NodeJS.Timeout in Node.js and number in the browser.
34
+ // This is causing issues in apps/healthcare-app.
35
+ timer = setInterval(() => counter.value++, props.autoUpdate * 1000) as unknown as number;
36
+ }
37
+ };
38
+
39
+ const stopAutoUpdate = (): void => {
40
+ if (timer) {
41
+ clearInterval(timer);
42
+ timer = null;
43
+ }
44
+ };
45
+
46
+ watch(
47
+ () => props.autoUpdate,
48
+ (value: number | false) => {
49
+ stopAutoUpdate();
50
+ if (value) {
51
+ startAutoUpdate();
52
+ }
53
+ }
54
+ );
55
+
56
+ onMounted(() => {
57
+ startAutoUpdate();
58
+ });
59
+
60
+ onBeforeUnmount(() => {
61
+ stopAutoUpdate();
62
+ });
63
+ </script>
@@ -0,0 +1,259 @@
1
+ <!-- eslint-disable vue/no-deprecated-slot-attribute -->
2
+ <template>
3
+ <sl-alert
4
+ ref="alert"
5
+ class="c-toast"
6
+ :data-test="dataTest"
7
+ :data-open="isOpen || undefined"
8
+ :data-variant="computedVariant"
9
+ :class="`c-toast--${computedVariant}`"
10
+ :duration="duration"
11
+ :style="{ '--toast-base-transform': transform }"
12
+ @sl-hide="onHide"
13
+ @sl-after-hide="resetAnimation"
14
+ >
15
+ <div class="flex-grow-1 d-flex flex-row align-center gap-4">
16
+ <slot name="icon">
17
+ <FontAwesomeIcon data-test="toast-icon" fixed-width class="c-toast__icon" :icon="icon" />
18
+ </slot>
19
+
20
+ <div class="c-toast__message flex-grow-1" data-test="toast-message">
21
+ <slot>{{ message }}</slot>
22
+ </div>
23
+ </div>
24
+
25
+ <CIconButton
26
+ data-test="toast-dismiss"
27
+ variant="tertiary"
28
+ :aria-label="$t('Close')"
29
+ :icon="faXmark"
30
+ @click="close"
31
+ />
32
+ </sl-alert>
33
+ </template>
34
+
35
+ <script lang="ts">
36
+ import {
37
+ faCircleCheck,
38
+ faCircleExclamation,
39
+ faInfoCircle,
40
+ faXmark,
41
+ } from '@fortawesome/pro-regular-svg-icons';
42
+ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
43
+ import '@shoelace-style/shoelace/dist/components/alert/alert.js';
44
+ import type SlAlert from '@shoelace-style/shoelace/dist/components/alert/alert.js';
45
+ import type { ElementAnimation } from '@shoelace-style/shoelace/dist/utilities/animation-registry';
46
+ import type { PropType } from 'vue';
47
+ import { computed, defineComponent, onBeforeUnmount, ref, watchEffect } from 'vue';
48
+
49
+ import CIconButton from '@propelinc/citrus-ui/src/components/CIconButton.vue';
50
+ import { useShoelaceAnimation } from '@propelinc/citrus-ui/src/composables/animation';
51
+ import { useShoelaceShadowParts } from '@propelinc/citrus-ui/src/composables/elements';
52
+ import { useDragListener } from '@propelinc/citrus-ui/src/composables/gestures';
53
+ import { slideLeft, slideRight } from '@propelinc/citrus-ui/src/services/animation';
54
+ import type { ToastVariant } from '@propelinc/citrus-ui/src/types';
55
+
56
+ /** Default duration for the toast to be visible. */
57
+ const DEFAULT_DURATION = 5000;
58
+ /** The minimum distance, in pixels, the user has to drag left or right for
59
+ * it to be considered a successful swipe. */
60
+ const MIN_SWIPE_DISTANCE = 150;
61
+ /** The minimum speed, in pixels per millisecond, the user has to swipe for
62
+ * it to be considered a successful swipe. */
63
+ const MIN_SWIPE_VELOCITY = 0.75;
64
+
65
+ export default defineComponent({
66
+ name: 'CToast',
67
+ components: { FontAwesomeIcon, CIconButton },
68
+ props: {
69
+ /** Show/hides the toast */
70
+ value: { type: Boolean, default: false },
71
+ /** The message rendered in the toast, using the default slot overrides this value */
72
+ message: { type: String, default: '' },
73
+ /**
74
+ * @deprecated use `variant` prop instead
75
+ * Renders the error state
76
+ */
77
+ error: { type: Boolean, default: false, deprecated: true },
78
+ /**
79
+ * @deprecated use `variant` prop instead
80
+ * Renders the success state
81
+ */
82
+ success: { type: Boolean, default: false, deprecated: true },
83
+ /**
84
+ * @deprecated use `variant` prop instead
85
+ * Renders the warning state
86
+ */
87
+ warning: { type: Boolean, default: false, deprecated: true },
88
+ /** The variant of the toast */
89
+ variant: { type: String as PropType<ToastVariant>, default: 'info' },
90
+ /** Controls (overrides) whether the toast is dismissible. */
91
+ dismissible: { type: Boolean as PropType<boolean | undefined>, default: undefined },
92
+ /** The data-test attribute for the toast. */
93
+ dataTest: { type: String, default: 'toast' },
94
+ },
95
+ emits: ['hide', 'input'],
96
+ setup(props, { emit }) {
97
+ const alert = ref<SlAlert | null>(null);
98
+ const isOpen = ref(props.value);
99
+
100
+ /**
101
+ * Handle merging the deprecated `error`, `success`, and `warning` props
102
+ * with the `variant` prop.
103
+ */
104
+ const computedVariant = computed(() => {
105
+ if (props.error) {
106
+ return 'error';
107
+ } else if (props.success) {
108
+ return 'success';
109
+ } else if (props.warning) {
110
+ return 'warning';
111
+ }
112
+ return props.variant;
113
+ });
114
+
115
+ const show = async (): Promise<void> => {
116
+ isOpen.value = true;
117
+ alert.value?.toast();
118
+ };
119
+
120
+ const onHide = (): void => {
121
+ isOpen.value = false;
122
+ emit('input', false);
123
+ emit('hide');
124
+ };
125
+
126
+ const close = async (): Promise<void> => {
127
+ alert.value?.hide();
128
+ };
129
+
130
+ // If our value changes, show or hide the toast respectively
131
+ watchEffect(() => (props.value ? show() : close()));
132
+
133
+ // Close the toast when the component is unmounted
134
+ onBeforeUnmount(() => close());
135
+
136
+ const shouldAutoDismiss = computed(() => {
137
+ if (props.dismissible !== undefined) {
138
+ return !props.dismissible;
139
+ }
140
+ return computedVariant.value === 'success';
141
+ });
142
+
143
+ const duration = computed(() => {
144
+ return shouldAutoDismiss.value ? DEFAULT_DURATION : Infinity;
145
+ });
146
+
147
+ const icon = computed(() => {
148
+ if (computedVariant.value === 'error') {
149
+ return faCircleExclamation;
150
+ } else if (computedVariant.value === 'success') {
151
+ return faCircleCheck;
152
+ } else {
153
+ return faInfoCircle;
154
+ }
155
+ });
156
+
157
+ const alertHideAnimation = ref<ElementAnimation | 'default'>('default');
158
+ useShoelaceAnimation(alert, 'alert.hide', alertHideAnimation);
159
+
160
+ const resetAnimation = (): void => {
161
+ alertHideAnimation.value = 'default';
162
+ };
163
+
164
+ const { base } = useShoelaceShadowParts(alert, ['base']);
165
+ const { dragDistance } = useDragListener(base, {
166
+ onDragEnd: async ({ distance, velocity }) => {
167
+ const absoluteDistance = Math.abs(distance.x);
168
+ const absoluteVelocity = Math.abs(velocity.x);
169
+ const shouldDismiss =
170
+ absoluteDistance > MIN_SWIPE_DISTANCE || absoluteVelocity > MIN_SWIPE_VELOCITY;
171
+ const dismissStart = absoluteDistance / base.value!.clientWidth;
172
+ if (shouldDismiss) {
173
+ const remainingDismissDistance = Math.max(base.value!.clientWidth - absoluteDistance, 0);
174
+ const dismissDuration =
175
+ remainingDismissDistance / Math.max(absoluteVelocity, MIN_SWIPE_VELOCITY);
176
+ const slideDirection = velocity.x > 0 ? slideRight : slideLeft;
177
+ alertHideAnimation.value = slideDirection({
178
+ start: dismissStart,
179
+ duration: dismissDuration,
180
+ end: 1.1,
181
+ });
182
+ close();
183
+ } else {
184
+ const slideDirection = velocity.x > 0 ? slideRight : slideLeft;
185
+ const slideBack = slideDirection({ start: dismissStart, end: 0 });
186
+ base.value?.animate(slideBack.keyframes, slideBack.options);
187
+ }
188
+ },
189
+ });
190
+
191
+ const transform = computed(() => {
192
+ return `translateX(${dragDistance.value?.x ?? 0}px)`;
193
+ });
194
+
195
+ return {
196
+ duration,
197
+ alert,
198
+ icon,
199
+ faXmark,
200
+ isOpen,
201
+ computedVariant,
202
+ close,
203
+ onHide,
204
+ transform,
205
+ resetAnimation,
206
+ };
207
+ },
208
+ });
209
+ </script>
210
+
211
+ <style lang="scss" scoped>
212
+ @import '@propelinc/citrus-ui/src/styles/core';
213
+
214
+ .c-toast {
215
+ margin: 16px;
216
+
217
+ &::part(base) {
218
+ background-color: $color-blue-200;
219
+ border: none;
220
+ border-radius: $border-radius-next;
221
+ box-shadow: $box-shadow-toast;
222
+ color: $color-black;
223
+ transform: var(--toast-base-transform);
224
+ }
225
+
226
+ &::part(message) {
227
+ @include body;
228
+
229
+ align-items: center;
230
+ display: flex;
231
+ padding: 16px 0 16px 16px;
232
+ }
233
+
234
+ &::part(icon) {
235
+ padding-left: 12px;
236
+ }
237
+ }
238
+
239
+ .c-toast--error::part(base) {
240
+ background-color: $color-red-200;
241
+ }
242
+
243
+ .c-toast--success::part(base) {
244
+ background-color: $color-green-200;
245
+ }
246
+
247
+ .c-toast--warning::part(base) {
248
+ background-color: $color-gold-200;
249
+ }
250
+
251
+ .c-toast__message {
252
+ flex: auto;
253
+ }
254
+
255
+ .c-toast__icon {
256
+ color: $color-black;
257
+ font-size: $font-size-icon-medium;
258
+ }
259
+ </style>
@@ -0,0 +1,32 @@
1
+ <template>
2
+ <CToast
3
+ v-for="toast in toasts"
4
+ :key="toast.id"
5
+ :value="true"
6
+ :data-test="toast.dataTest || 'c-toast'"
7
+ :message="toast.message"
8
+ :variant="toast.variant"
9
+ @hide="dismissToast(toast.id)"
10
+ />
11
+ </template>
12
+
13
+ <script lang="ts">
14
+ import { defineComponent } from 'vue';
15
+
16
+ import CToast from '@propelinc/citrus-ui/src/components/CToast.vue';
17
+
18
+ import { useToast } from '../composables/toast';
19
+
20
+ export default defineComponent({
21
+ name: 'CToastsList',
22
+ components: { CToast },
23
+ setup() {
24
+ const { toasts, dismissToast } = useToast();
25
+
26
+ return {
27
+ toasts,
28
+ dismissToast,
29
+ };
30
+ },
31
+ });
32
+ </script>
@@ -0,0 +1,70 @@
1
+ <template>
2
+ <div
3
+ v-if="!isHidden"
4
+ :data-test="dataTest"
5
+ class="c-validation-message"
6
+ :class="{ 'c-validation-message--invalid': !!validationMessage }"
7
+ >
8
+ <CFadeTransition aria-live="polite">
9
+ <span v-if="validationMessage" key="message" role="alert" :data-test="`${dataTest}-text`">
10
+ {{ validationMessage }}
11
+ </span>
12
+ <!-- NOTE(mohan): Always keep an empty span to make sure the flex layout is stable. -->
13
+ <span v-else key="empty">
14
+ <slot />
15
+ </span>
16
+ </CFadeTransition>
17
+
18
+ <slot name="append" />
19
+ </div>
20
+ </template>
21
+
22
+ <script lang="ts">
23
+ import type { PropType } from 'vue';
24
+ import { computed, defineComponent } from 'vue';
25
+
26
+ import CFadeTransition from '@propelinc/citrus-ui/src/components/CFadeTransition.vue';
27
+ import { useSlotHasContent } from '@propelinc/citrus-ui/src/composables/slots';
28
+
29
+ export default defineComponent({
30
+ name: 'CValidationMessage',
31
+ components: { CFadeTransition },
32
+ props: {
33
+ /** Test selector for the component */
34
+ dataTest: { type: String, default: 'validation-message' },
35
+ /** Validation message to display */
36
+ validationMessage: { type: String as PropType<string | null>, default: null },
37
+ /** Whether to hide the component. If "auto", the component will automatically
38
+ * hide itself if it has no content. */
39
+ hide: { type: [Boolean, String] as PropType<boolean | 'auto'>, default: false },
40
+ },
41
+ setup(props) {
42
+ const appendSlotHasContent = useSlotHasContent('append');
43
+ const isHidden = computed(() => {
44
+ if (props.hide === 'auto') {
45
+ return !props.validationMessage && !appendSlotHasContent.value;
46
+ } else {
47
+ return props.hide;
48
+ }
49
+ });
50
+
51
+ return { isHidden };
52
+ },
53
+ });
54
+ </script>
55
+
56
+ <style lang="scss" scoped>
57
+ @import '@propelinc/citrus-ui/src/styles/core';
58
+
59
+ .c-validation-message {
60
+ @include caption;
61
+
62
+ display: flex;
63
+ justify-content: space-between;
64
+ margin-bottom: 8px;
65
+ }
66
+
67
+ .c-validation-message--invalid {
68
+ color: $color-status-error;
69
+ }
70
+ </style>
@@ -0,0 +1,69 @@
1
+ <template>
2
+ <CMaskedTextField
3
+ v-bind="$attrs"
4
+ :id="id"
5
+ ref="field"
6
+ :data-test="dataTest"
7
+ :value="value"
8
+ name="zip"
9
+ :label="label || $t('ZIP Code')"
10
+ mask="#####"
11
+ :placeholder="placeholder || '12345'"
12
+ :minlength="5"
13
+ :maxlength="5"
14
+ type="tel"
15
+ autocorrect="off"
16
+ autocapitalize="none"
17
+ :rules="computedRules"
18
+ @input="$emit('input', $event)"
19
+ @focus="$emit('focus', $event)"
20
+ @blur="$emit('blur', $event)"
21
+ @change="$emit('change', $event)"
22
+ >
23
+ <template #label>
24
+ <slot name="label" />
25
+ </template>
26
+ <template #message>
27
+ <slot name="message" />
28
+ </template>
29
+ </CMaskedTextField>
30
+ </template>
31
+
32
+ <script lang="ts">
33
+ import { type PropType, computed, defineComponent } from 'vue';
34
+
35
+ import CMaskedTextField from '@propelinc/citrus-ui/src/components/CMaskedTextField.vue';
36
+ import { useFocusableField } from '@propelinc/citrus-ui/src/composables/fields';
37
+ import { useTranslation } from '@propelinc/citrus-ui/src/composables/i18n';
38
+ import type { Rules } from '@propelinc/citrus-ui/src/composables/validations';
39
+ import { minLengthRule } from '@propelinc/shared-utils';
40
+
41
+ export default defineComponent({
42
+ name: 'CZipcodeField',
43
+ components: { CMaskedTextField },
44
+ props: {
45
+ dataTest: { type: String, default: 'zipcode-field' },
46
+ id: { type: String, default: undefined },
47
+ label: { type: String as PropType<string | null>, default: null },
48
+ placeholder: { type: String as PropType<string | null>, default: null },
49
+ rules: { type: Array as PropType<Rules<string>>, default: () => [] },
50
+ value: { type: String, default: '' },
51
+ },
52
+ emits: ['input', 'focus', 'blur', 'change'],
53
+ setup(props, { expose }) {
54
+ const { t } = useTranslation();
55
+
56
+ const defaultRules = [
57
+ minLengthRule(5, t('Please enter a valid {inputLabel}', { inputLabel: t('ZIP Code') })),
58
+ ];
59
+ const computedRules = computed(() => [...defaultRules, ...props.rules]);
60
+
61
+ const { field } = useFocusableField(expose);
62
+
63
+ return {
64
+ computedRules,
65
+ field,
66
+ };
67
+ },
68
+ });
69
+ </script>