@propelinc/citrus-ui 0.5.1 → 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.
- package/README.md +56 -86
- package/dist/colors/colors.d.ts +31 -0
- package/dist/colors/theme.d.ts +2 -11
- package/dist/colors/util-classes.d.ts +11 -0
- package/dist/components/CAccordion.vue.d.ts +21 -0
- package/dist/components/CAccordionItem.vue.d.ts +41 -0
- package/dist/components/CAppBar.vue.d.ts +156 -0
- package/dist/components/CBadge.vue.d.ts +52 -0
- package/dist/components/CBottomSheet.vue.d.ts +226 -0
- package/dist/components/CButton/CButton.vue.d.ts +231 -0
- package/dist/components/CButton/types.d.ts +5 -0
- package/dist/components/CButtonStack.vue.d.ts +24 -0
- package/dist/components/CCard.vue.d.ts +107 -0
- package/dist/components/CCardFooter.vue.d.ts +26 -0
- package/dist/components/CCardHeader.vue.d.ts +3 -0
- package/dist/components/CCardSection.vue.d.ts +17 -0
- package/dist/components/CCheckbox.vue.d.ts +145 -0
- package/dist/components/CCol.vue.d.ts +21 -0
- package/dist/components/CDivider.vue.d.ts +17 -0
- package/dist/components/CDobField.vue.d.ts +2109 -0
- package/dist/components/CDobSelect.vue.d.ts +398 -0
- package/dist/components/CEmailField.vue.d.ts +699 -0
- package/dist/components/CExpandTransition.vue.d.ts +19 -0
- package/dist/components/CFadeTransition.vue.d.ts +3 -0
- package/dist/components/CFileInput.vue.d.ts +98 -0
- package/dist/components/CFixedPageFooter.vue.d.ts +106 -0
- package/dist/components/CForm.vue.d.ts +29 -0
- package/dist/components/CFormFieldCounter.vue.d.ts +42 -0
- package/dist/components/CIconButton.vue.d.ts +390 -0
- package/dist/components/CLabel.vue.d.ts +32 -0
- package/dist/components/CListItem.vue.d.ts +208 -0
- package/dist/components/CListItemContent.vue.d.ts +27 -0
- package/dist/components/CListItemIcon.vue.d.ts +54 -0
- package/dist/components/CLoader.vue.d.ts +73 -0
- package/dist/components/CLogo.vue.d.ts +19 -0
- package/dist/components/CMaskedTextField.vue.d.ts +2012 -0
- package/dist/components/CMenu.vue.d.ts +6 -0
- package/dist/components/CMenuItem.vue.d.ts +170 -0
- package/dist/components/CMenuLabel.vue.d.ts +3 -0
- package/dist/components/CModal.vue.d.ts +206 -0
- package/dist/components/CModalLoading.vue.d.ts +230 -0
- package/dist/components/CNotification.vue.d.ts +589 -0
- package/dist/components/CPhoneField.vue.d.ts +2088 -0
- package/dist/components/CPill.vue.d.ts +42 -0
- package/dist/components/CPillGroup.vue.d.ts +70 -0
- package/dist/components/CPopup.vue.d.ts +21 -0
- package/dist/components/CProgressLinear.vue.d.ts +61 -0
- package/dist/components/CProgressRing.vue.d.ts +103 -0
- package/dist/components/CRadio.vue.d.ts +73 -0
- package/dist/components/CRadioGroup.vue.d.ts +123 -0
- package/dist/components/CRebrand.vue.d.ts +28 -0
- package/dist/components/CRow.vue.d.ts +67 -0
- package/dist/components/CSafeArea.vue.d.ts +18 -0
- package/dist/components/CSectionHeader.vue.d.ts +28 -0
- package/dist/components/CSelect.vue.d.ts +293 -0
- package/dist/components/CSkeleton.vue.d.ts +3 -0
- package/dist/components/CSkeletonLoaderCard.vue.d.ts +21 -0
- package/dist/components/CSkeletonLoaderCircle.vue.d.ts +5 -0
- package/dist/components/CSkeletonLoaderText.vue.d.ts +44 -0
- package/dist/components/CSlideFadeTransition.vue.d.ts +58 -0
- package/dist/components/CSplitInput.vue.d.ts +2131 -0
- package/dist/components/CSquaredIcon.vue.d.ts +47 -0
- package/dist/components/CSsnField.vue.d.ts +2083 -0
- package/dist/components/CStatusDot.vue.d.ts +27 -0
- package/dist/components/CSwitch.vue.d.ts +54 -0
- package/dist/components/CSwitchListItem.vue.d.ts +392 -0
- package/dist/components/CTextArea.vue.d.ts +240 -0
- package/dist/components/CTextField.vue.d.ts +647 -0
- package/dist/components/CTextLink.vue.d.ts +55 -0
- package/dist/components/CThirdPartyLogo.vue.d.ts +128 -0
- package/dist/components/CTimeago.vue.d.ts +12 -0
- package/dist/components/CToast.vue.d.ts +458 -0
- package/dist/components/CToastsList.vue.d.ts +430 -0
- package/dist/components/CValidationMessage.vue.d.ts +45 -0
- package/dist/components/CZipcodeField.vue.d.ts +2080 -0
- package/dist/components/index.d.ts +66 -25
- package/dist/components/internal/CCloseButton.vue.d.ts +14 -0
- package/dist/composables/accessibility.d.ts +1 -0
- package/dist/composables/animation.d.ts +12 -0
- package/dist/composables/binding.d.ts +19 -0
- package/dist/composables/colors.d.ts +13 -0
- package/dist/composables/elements.d.ts +3 -0
- package/dist/composables/fields.d.ts +9 -0
- package/dist/composables/gestures.d.ts +53 -0
- package/dist/composables/i18n.d.ts +3 -0
- package/dist/composables/id.d.ts +11 -0
- package/dist/composables/input-mask.d.ts +18 -0
- package/dist/composables/router.d.ts +30 -0
- package/dist/composables/slots.d.ts +2 -0
- package/dist/composables/toast.d.ts +21 -0
- package/dist/composables/validations.d.ts +77 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.mjs +11738 -0
- package/dist/index.mjs.map +1 -0
- package/dist/plugin.d.ts +2 -2
- package/dist/services/animation.d.ts +17 -0
- package/dist/services/directives/index.d.ts +2 -0
- package/dist/services/directives/scroll-into-view.d.ts +7 -0
- package/dist/services/directives/tap-animation.d.ts +6 -0
- package/dist/services/id.d.ts +22 -0
- package/dist/services/injections/accordions.d.ts +3 -0
- package/dist/services/injections/animations.d.ts +2 -0
- package/dist/services/injections/buttons.d.ts +4 -0
- package/dist/services/injections/forms.d.ts +6 -0
- package/dist/services/injections/icon-buttons.d.ts +3 -0
- package/dist/services/injections/pills.d.ts +4 -0
- package/dist/services/injections/radio.d.ts +10 -0
- package/dist/styles/main.css +3002 -0
- package/dist/styles/utils.css +2319 -0
- package/dist/theme/icons.d.ts +35 -2
- package/dist/types/CForm.d.ts +12 -0
- package/dist/types/font-awesome.d.ts +5 -0
- package/dist/types.d.ts +12 -0
- package/index.ts +2 -0
- package/package.json +63 -77
- package/src/assets/fonts/grenette-regular.woff2 +0 -0
- package/src/assets/fonts/grenette-semibold.woff2 +0 -0
- package/src/assets/fonts/polymath.woff2 +0 -0
- package/src/assets/logos/propel/icon.svg +15 -0
- package/src/assets/logos/propel/lockup.svg +11 -0
- package/src/colors/colors.ts +173 -0
- package/src/colors/theme.ts +8 -14
- package/src/colors/util-classes.ts +49 -0
- package/src/componentResolver.js +33 -0
- package/src/components/CAccordion.vue +32 -7
- package/src/components/CAccordionItem.vue +109 -36
- package/src/components/CAppBar.vue +237 -0
- package/src/components/CBadge.vue +74 -0
- package/src/components/CBottomSheet.vue +430 -0
- package/src/components/CButton/CButton.vue +347 -0
- package/src/components/CButton/types.ts +5 -0
- package/src/components/CButtonStack.vue +36 -0
- package/src/components/CCard.vue +149 -41
- package/src/components/CCardFooter.vue +11 -27
- package/src/components/CCardHeader.vue +30 -21
- package/src/components/CCardSection.vue +23 -12
- package/src/components/CCheckbox.vue +191 -21
- package/src/components/CCol.vue +55 -0
- package/src/components/CDivider.vue +46 -0
- package/src/components/CDobField.vue +153 -0
- package/src/components/CDobSelect.vue +274 -0
- package/src/components/CEmailField.vue +61 -0
- package/src/components/CExpandTransition.vue +55 -0
- package/src/components/CFadeTransition.vue +23 -0
- package/src/components/CFileInput.vue +186 -0
- package/src/components/CFixedPageFooter.vue +76 -0
- package/src/components/CForm.vue +86 -0
- package/src/components/CFormFieldCounter.vue +40 -0
- package/src/components/CIconButton.vue +175 -59
- package/src/components/CLabel.vue +52 -0
- package/src/components/CListItem.vue +149 -45
- package/src/components/CListItemContent.vue +60 -0
- package/src/components/CListItemIcon.vue +27 -31
- package/src/components/CLoader.vue +156 -0
- package/src/components/CLogo.vue +23 -0
- package/src/components/CMaskedTextField.vue +118 -0
- package/src/components/CMenu.vue +24 -0
- package/src/components/CMenuItem.vue +106 -0
- package/src/components/CMenuLabel.vue +26 -0
- package/src/components/CModal.vue +198 -79
- package/src/components/CModalLoading.vue +27 -9
- package/src/components/CNotification.vue +86 -53
- package/src/components/CPhoneField.vue +69 -0
- package/src/components/CPill.vue +162 -0
- package/src/components/CPillGroup.vue +73 -0
- package/src/components/CPopup.vue +66 -0
- package/src/components/CProgressLinear.vue +52 -0
- package/src/components/CProgressRing.vue +126 -0
- package/src/components/CRadio.vue +138 -0
- package/src/components/CRadioGroup.vue +142 -0
- package/src/components/CRebrand.vue +28 -0
- package/src/components/CRow.vue +62 -0
- package/src/components/CSafeArea.vue +23 -0
- package/src/components/CSectionHeader.vue +50 -0
- package/src/components/CSelect.vue +223 -74
- package/src/components/CSkeleton.vue +65 -0
- package/src/components/CSkeletonLoaderCard.vue +29 -0
- package/src/components/CSkeletonLoaderCircle.vue +18 -14
- package/src/components/CSkeletonLoaderText.vue +127 -17
- package/src/components/CSlideFadeTransition.vue +100 -0
- package/src/components/CSplitInput.vue +111 -0
- package/src/components/CSquaredIcon.vue +83 -0
- package/src/components/CSsnField.vue +86 -0
- package/src/components/CStatusDot.vue +70 -0
- package/src/components/CSwitch.vue +125 -0
- package/src/components/CSwitchListItem.vue +110 -0
- package/src/components/CTextArea.vue +193 -47
- package/src/components/CTextField.vue +450 -93
- package/src/components/CTextLink.vue +48 -38
- package/src/components/CThirdPartyLogo.vue +127 -0
- package/src/components/CTimeago.vue +63 -0
- package/src/components/CToast.vue +259 -0
- package/src/components/CToastsList.vue +32 -0
- package/src/components/CValidationMessage.vue +70 -0
- package/src/components/CZipcodeField.vue +69 -0
- package/src/components/index.ts +66 -25
- package/src/components/internal/CCloseButton.vue +57 -0
- package/src/composables/accessibility.ts +29 -0
- package/src/composables/animation.ts +95 -0
- package/src/composables/binding.ts +34 -0
- package/src/composables/colors.ts +59 -0
- package/src/composables/elements.ts +72 -0
- package/src/composables/fields.ts +19 -0
- package/src/composables/gestures.ts +197 -0
- package/src/composables/i18n.ts +13 -0
- package/src/composables/id.ts +23 -0
- package/src/composables/input-mask.ts +139 -0
- package/src/composables/router.ts +64 -0
- package/src/composables/slots.ts +57 -0
- package/src/composables/toast.ts +64 -0
- package/src/composables/validations.ts +214 -0
- package/src/index.ts +7 -7
- package/src/plugin.ts +13 -6
- package/src/services/animation.ts +101 -0
- package/src/services/directives/index.ts +2 -0
- package/src/services/directives/scroll-into-view.ts +86 -0
- package/src/services/directives/tap-animation.ts +71 -0
- package/src/services/id.ts +31 -0
- package/src/services/injections/accordions.ts +4 -0
- package/src/services/injections/animations.ts +3 -0
- package/src/services/injections/buttons.ts +5 -0
- package/src/services/injections/forms.ts +8 -0
- package/src/services/injections/icon-buttons.ts +4 -0
- package/src/services/injections/pills.ts +7 -0
- package/src/services/injections/radio.ts +12 -0
- package/src/shims-vue.d.ts +6 -3
- package/src/styles/_animation.scss +19 -0
- package/src/styles/_button.scss +61 -0
- package/src/styles/_colors.scss +58 -11
- package/src/styles/_core.scss +280 -119
- package/src/styles/_form-fields.scss +69 -16
- package/src/styles/_grenette.scss +13 -0
- package/src/styles/_polymath.scss +14 -0
- package/src/styles/_reset.scss +105 -0
- package/src/styles/_shoelace.scss +46 -0
- package/src/styles/_typography.scss +39 -10
- package/src/styles/main.scss +6 -3
- package/src/styles/utils/a11y.scss +18 -0
- package/src/styles/utils/typography.scss +13 -0
- package/src/styles/utils.scss +560 -0
- package/src/styles/variables.scss +57 -45
- package/src/theme/icons.ts +16 -5
- package/src/types/CForm.ts +15 -0
- package/src/types/font-awesome.ts +6 -0
- package/src/types.ts +15 -0
- package/.browserslistrc +0 -3
- package/.eslintrc.js +0 -4
- package/.nvmrc +0 -1
- package/.stylelintrc.js +0 -3
- package/babel.config.js +0 -3
- package/dist/citrus-ui.common.js +0 -42228
- package/dist/citrus-ui.common.js.map +0 -1
- package/dist/citrus-ui.css +0 -1
- package/dist/citrus-ui.umd.js +0 -42238
- package/dist/citrus-ui.umd.js.map +0 -1
- package/dist/citrus-ui.umd.min.js +0 -27
- package/dist/citrus-ui.umd.min.js.map +0 -1
- package/dist/demo.html +0 -10
- package/dist/fonts/Blitz-Script.85ed9abe.woff2 +0 -0
- package/dist/fonts/ObjectSans-Bold.5492f3d5.woff2 +0 -0
- package/dist/fonts/ObjectSans-BoldSlanted.29e2a87e.woff2 +0 -0
- package/dist/fonts/ObjectSans-Heavy.d0b2f035.woff2 +0 -0
- package/dist/fonts/ObjectSans-HeavySlanted.45e9c063.woff2 +0 -0
- package/dist/fonts/ObjectSans-Light.f885dec3.woff2 +0 -0
- package/dist/fonts/ObjectSans-LightSlanted.b8eb7c12.woff2 +0 -0
- package/dist/fonts/ObjectSans-Regular.e4ea0b90.woff2 +0 -0
- package/dist/fonts/ObjectSans-Slanted.57a90be9.woff2 +0 -0
- package/dist/fonts/ObjectSans-Thin.86d44227.woff2 +0 -0
- package/dist/fonts/ObjectSans-ThinSlanted.20342160.woff2 +0 -0
- package/jest.config.js +0 -9
- package/plopfile.js +0 -67
- package/postcss.config.js +0 -5
- package/src/assets/fonts/Blitz-Script.woff2 +0 -0
- package/src/assets/fonts/ObjectSans-Bold.woff2 +0 -0
- package/src/assets/fonts/ObjectSans-BoldSlanted.woff2 +0 -0
- package/src/assets/fonts/ObjectSans-Heavy.woff2 +0 -0
- package/src/assets/fonts/ObjectSans-HeavySlanted.woff2 +0 -0
- package/src/assets/fonts/ObjectSans-Light.woff2 +0 -0
- package/src/assets/fonts/ObjectSans-LightSlanted.woff2 +0 -0
- package/src/assets/fonts/ObjectSans-Regular.woff2 +0 -0
- package/src/assets/fonts/ObjectSans-Slanted.woff2 +0 -0
- package/src/assets/fonts/ObjectSans-Thin.woff2 +0 -0
- package/src/assets/fonts/ObjectSans-ThinSlanted.woff2 +0 -0
- package/src/components/CAlert.vue +0 -73
- package/src/components/CBanner.vue +0 -47
- package/src/components/CButton.vue +0 -146
- package/src/components/CListItemAction.vue +0 -29
- package/src/components/CSegmentedButton.vue +0 -47
- package/src/components/CSegmentedButtonOption.vue +0 -42
- package/src/components/helpers/FormField.vue +0 -48
- package/src/components/helpers/SelectInput.vue +0 -115
- package/src/shims-scss.d.ts +0 -4
- package/src/shims-vuetify.d.ts +0 -4
- package/src/styles/_blitz.scss +0 -8
- package/src/styles/_object-sans.scss +0 -23
- package/tsconfig.dist.json +0 -9
- package/tsconfig.json +0 -42
- package/vue.config.js +0 -5
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="c-skeleton-loader-card"
|
|
4
|
+
data-test="skeleton-loader-card"
|
|
5
|
+
:style="{ height: `${height}px` }"
|
|
6
|
+
>
|
|
7
|
+
<CSkeleton />
|
|
8
|
+
</div>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script lang="ts">
|
|
12
|
+
import { defineComponent } from 'vue';
|
|
13
|
+
|
|
14
|
+
import CSkeleton from '@propelinc/citrus-ui/src/components/CSkeleton.vue';
|
|
15
|
+
|
|
16
|
+
export default defineComponent({
|
|
17
|
+
components: {
|
|
18
|
+
CSkeleton,
|
|
19
|
+
},
|
|
20
|
+
props: {
|
|
21
|
+
/** Controls the height of the skeleton loader card */
|
|
22
|
+
height: {
|
|
23
|
+
type: [Number, String],
|
|
24
|
+
required: false,
|
|
25
|
+
default: 100,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
</script>
|
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div class="c-skeleton-loader-circle" data-test="skeleton-loader-circle">
|
|
3
|
+
<CSkeleton />
|
|
4
|
+
</div>
|
|
3
5
|
</template>
|
|
4
6
|
|
|
5
7
|
<script lang="ts">
|
|
6
|
-
import {
|
|
8
|
+
import { defineComponent } from 'vue';
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
export default class CSkeletonLoaderCircle extends Vue {}
|
|
10
|
-
</script>
|
|
11
|
-
|
|
12
|
-
<style lang="scss" scoped>
|
|
13
|
-
@import '@/styles/core.scss';
|
|
10
|
+
import CSkeleton from '@propelinc/citrus-ui/src/components/CSkeleton.vue';
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
export default defineComponent({
|
|
13
|
+
components: {
|
|
14
|
+
CSkeleton,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
</script>
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
<style scoped>
|
|
20
|
+
.c-skeleton-loader-circle {
|
|
21
|
+
--size: 36px;
|
|
19
22
|
|
|
20
|
-
border-radius:
|
|
21
|
-
height:
|
|
22
|
-
|
|
23
|
+
border-radius: calc(var(--size) / 2);
|
|
24
|
+
height: var(--size);
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
width: var(--size);
|
|
23
27
|
}
|
|
24
28
|
</style>
|
|
@@ -1,38 +1,148 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
2
|
+
<div
|
|
3
|
+
data-test="skeleton-loader-text"
|
|
4
|
+
class="c-skeleton-loader-text"
|
|
5
|
+
:class="{ [`align-${align}`]: align }"
|
|
6
|
+
>
|
|
7
|
+
<div
|
|
8
|
+
v-for="x in rows"
|
|
9
|
+
:key="x"
|
|
10
|
+
:class="lineTypeClass"
|
|
11
|
+
class="c-skeleton-loader-text__line"
|
|
12
|
+
data-test="skeleton-loader-text-line"
|
|
13
|
+
>
|
|
14
|
+
<CSkeleton class="c-skeleton-loader-text__line__skeleton" />
|
|
15
|
+
<!-- This invisible text ensures the line height matches the real text. -->
|
|
16
|
+
|
|
17
|
+
</div>
|
|
4
18
|
</div>
|
|
5
19
|
</template>
|
|
6
20
|
|
|
7
21
|
<script lang="ts">
|
|
8
|
-
import {
|
|
22
|
+
import { type PropType, computed, defineComponent } from 'vue';
|
|
9
23
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
24
|
+
import CSkeleton from '@propelinc/citrus-ui/src/components/CSkeleton.vue';
|
|
25
|
+
|
|
26
|
+
type SkeletonLoaderType =
|
|
27
|
+
| 'balance'
|
|
28
|
+
| 'body'
|
|
29
|
+
| 'caption'
|
|
30
|
+
| 'eyebrow'
|
|
31
|
+
| 'headline'
|
|
32
|
+
| 'large-headline'
|
|
33
|
+
// @deprecated use 'eyebrow' instead
|
|
34
|
+
| 'overline'
|
|
35
|
+
| 'statement'
|
|
36
|
+
| 'subheadline'
|
|
37
|
+
| 'wallet-caption'
|
|
38
|
+
| 'x-large-headline';
|
|
39
|
+
|
|
40
|
+
const LINE_TYPE_TO_CLASS: Record<SkeletonLoaderType, string> = {
|
|
41
|
+
'balance': 'c-skeleton-loader-text__line--balance',
|
|
42
|
+
'body': 'c-skeleton-loader-text__line--body',
|
|
43
|
+
'caption': 'c-skeleton-loader-text__line--caption',
|
|
44
|
+
'eyebrow': 'c-skeleton-loader-text__line--eyebrow',
|
|
45
|
+
'headline': 'c-skeleton-loader-text__line--headline',
|
|
46
|
+
'large-headline': 'c-skeleton-loader-text__line--large-headline',
|
|
47
|
+
// @deprecated use 'eyebrow' instead
|
|
48
|
+
'overline': 'c-skeleton-loader-text__line--eyebrow',
|
|
49
|
+
'statement': 'c-skeleton-loader-text__line--statement',
|
|
50
|
+
'subheadline': 'c-skeleton-loader-text__line--subheadline',
|
|
51
|
+
'wallet-caption': 'c-skeleton-loader-text__line--wallet-caption',
|
|
52
|
+
'x-large-headline': 'c-skeleton-loader-text__line--x-large-headline',
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export default defineComponent({
|
|
56
|
+
components: {
|
|
57
|
+
CSkeleton,
|
|
58
|
+
},
|
|
59
|
+
props: {
|
|
60
|
+
/** Applies the align-items css property. */
|
|
61
|
+
align: { type: String as PropType<'center' | 'start' | 'end'>, default: 'start' },
|
|
62
|
+
/** Controls how many rows of loading text are shown */
|
|
63
|
+
rows: { type: Number, default: 2 },
|
|
64
|
+
/** Controls the appearance of the loading text */
|
|
65
|
+
type: { type: String as PropType<SkeletonLoaderType>, default: 'body' },
|
|
66
|
+
},
|
|
67
|
+
setup(props) {
|
|
68
|
+
const lineTypeClass = computed(() => {
|
|
69
|
+
return LINE_TYPE_TO_CLASS[props.type];
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return { lineTypeClass };
|
|
73
|
+
},
|
|
74
|
+
});
|
|
14
75
|
</script>
|
|
15
76
|
|
|
16
77
|
<style lang="scss" scoped>
|
|
17
|
-
@import '
|
|
78
|
+
@import '@propelinc/citrus-ui/src/styles/core';
|
|
79
|
+
|
|
80
|
+
// NOTE(mohan): This ensures that the skeleton loader text is exactly the same size as the text it
|
|
81
|
+
// is replacing including the extra space around the text itself added by the line height.
|
|
82
|
+
@mixin skeleton-loader-text-sizing($font-style) {
|
|
83
|
+
font-size: map-get($font-style, 'size');
|
|
84
|
+
line-height: map-get($font-style, 'line-height');
|
|
18
85
|
|
|
19
|
-
|
|
86
|
+
// By applying a height equal to the font size, the skeleton takes up the space of the text,
|
|
87
|
+
// leaving whitespace between each row
|
|
88
|
+
.c-skeleton-loader-text__line__skeleton {
|
|
89
|
+
height: map-get($font-style, 'size');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.c-skeleton-loader-text {
|
|
94
|
+
display: flex;
|
|
95
|
+
flex-direction: column;
|
|
20
96
|
width: 100%;
|
|
21
97
|
}
|
|
22
98
|
|
|
23
|
-
.skeleton-loader-text__line {
|
|
24
|
-
@include skeleton-loader;
|
|
99
|
+
.c-skeleton-loader-text__line {
|
|
100
|
+
@include skeleton-loader-text-sizing($body);
|
|
25
101
|
|
|
26
|
-
|
|
27
|
-
|
|
102
|
+
align-items: center;
|
|
103
|
+
display: flex;
|
|
28
104
|
width: 100%;
|
|
29
105
|
|
|
30
|
-
& + & {
|
|
31
|
-
margin-top: 4px;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
106
|
&:last-child {
|
|
35
107
|
width: calc(100% - 32px);
|
|
36
108
|
}
|
|
37
109
|
}
|
|
110
|
+
|
|
111
|
+
.c-skeleton-loader-text__line--balance {
|
|
112
|
+
@include skeleton-loader-text-sizing($balance);
|
|
113
|
+
|
|
114
|
+
max-width: 120px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.c-skeleton-loader-text__line--caption {
|
|
118
|
+
@include skeleton-loader-text-sizing($caption);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.c-skeleton-loader-text__line--eyebrow {
|
|
122
|
+
@include skeleton-loader-text-sizing($eyebrow);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.c-skeleton-loader-text__line--headline {
|
|
126
|
+
@include skeleton-loader-text-sizing($headline);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.c-skeleton-loader-text__line--large-headline {
|
|
130
|
+
@include skeleton-loader-text-sizing($large-headline);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.c-skeleton-loader-text__line--statement {
|
|
134
|
+
@include skeleton-loader-text-sizing($statement);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.c-skeleton-loader-text__line--subheadline {
|
|
138
|
+
@include skeleton-loader-text-sizing($subheadline);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.c-skeleton-loader-text__line--wallet-caption {
|
|
142
|
+
@include skeleton-loader-text-sizing($wallet-caption);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.c-skeleton-loader-text__line--x-large-headline {
|
|
146
|
+
@include skeleton-loader-text-sizing($x-large-headline);
|
|
147
|
+
}
|
|
38
148
|
</style>
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="direction" :style="{ '--slide-fade-amount': `${amount}px` }">
|
|
3
|
+
<Transition name="slide-fade" mode="out-in">
|
|
4
|
+
<slot />
|
|
5
|
+
</Transition>
|
|
6
|
+
</div>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script lang="ts">
|
|
10
|
+
import { type PropType, defineComponent } from 'vue';
|
|
11
|
+
|
|
12
|
+
type Direction = 'to-left' | 'to-right' | 'to-top' | 'to-bottom';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* This component can be used to create a slide-fade transition for children.
|
|
16
|
+
*
|
|
17
|
+
* FIXME: Vue 3 Conversion - Remove this comment when Vue 3 conversion is complete.
|
|
18
|
+
* NOTE: For Vue 2 usage: if you are conditionally rendering children, be sure to add unique
|
|
19
|
+
* keys to each child!
|
|
20
|
+
*
|
|
21
|
+
* Example:
|
|
22
|
+
* ```vue
|
|
23
|
+
* <CSlideFadeTransition>
|
|
24
|
+
* <div v-if="condition" :key="if">This will slide in</div>
|
|
25
|
+
* <div v-else :key="else">This will slide out</div>
|
|
26
|
+
* </CSlideFadeTransition>
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export default defineComponent({
|
|
30
|
+
name: 'CSlideFadeTransition',
|
|
31
|
+
props: {
|
|
32
|
+
/**
|
|
33
|
+
* The amount of pixels to slide the elements in or out
|
|
34
|
+
* @default 20
|
|
35
|
+
*/
|
|
36
|
+
amount: {
|
|
37
|
+
type: Number,
|
|
38
|
+
default: 20,
|
|
39
|
+
validator(value: number) {
|
|
40
|
+
return value >= 0;
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
/**
|
|
44
|
+
* Changes the direction of the slide fade transition
|
|
45
|
+
* @default 'to-left'
|
|
46
|
+
*/
|
|
47
|
+
direction: {
|
|
48
|
+
type: String as PropType<Direction>,
|
|
49
|
+
default: 'to-left',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<style scoped>
|
|
56
|
+
.slide-fade-enter-active,
|
|
57
|
+
.slide-fade-leave-active {
|
|
58
|
+
transition: all 0.3s ease-out;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* TODO: Can remove `*-enter` classes when we upgrade to Vue 3 */
|
|
62
|
+
.slide-fade-enter,
|
|
63
|
+
/* Preemptively adding Vue 3 classes */
|
|
64
|
+
.slide-fade-enter-from,
|
|
65
|
+
.slide-fade-leave-to {
|
|
66
|
+
opacity: 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* TODO: Can remove `*-enter` classes when we upgrade to Vue 3 */
|
|
70
|
+
.to-left .slide-fade-enter,
|
|
71
|
+
/* Preemptively adding Vue 3 classes */
|
|
72
|
+
.to-left .slide-fade-enter-from,
|
|
73
|
+
.to-left .slide-fade-leave-to {
|
|
74
|
+
transform: translateX(calc(-1 * var(--slide-fade-amount)));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* TODO: Can remove `*-enter` classes when we upgrade to Vue 3 */
|
|
78
|
+
.to-right .slide-fade-enter,
|
|
79
|
+
/* Preemptively adding Vue 3 classes */
|
|
80
|
+
.to-right .slide-fade-enter-from,
|
|
81
|
+
.to-right .slide-fade-leave-to {
|
|
82
|
+
transform: translateX(var(--slide-fade-amount));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* TODO: Can remove `*-enter` classes when we upgrade to Vue 3 */
|
|
86
|
+
.to-top .slide-fade-enter,
|
|
87
|
+
/* Preemptively adding Vue 3 classes */
|
|
88
|
+
.to-top .slide-fade-enter-from,
|
|
89
|
+
.to-top .slide-fade-leave-to {
|
|
90
|
+
transform: translateY(calc(-1 * var(--slide-fade-amount)));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* TODO: Can remove `*-enter` classes when we upgrade to Vue 3 */
|
|
94
|
+
.to-bottom .slide-fade-enter,
|
|
95
|
+
/* Preemptively adding Vue 3 classes */
|
|
96
|
+
.to-bottom .slide-fade-enter-from,
|
|
97
|
+
.to-bottom .slide-fade-leave-to {
|
|
98
|
+
transform: translateY(var(--slide-fade-amount));
|
|
99
|
+
}
|
|
100
|
+
</style>
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<CMaskedTextField
|
|
3
|
+
v-bind="$attrs"
|
|
4
|
+
:data-test="dataTest"
|
|
5
|
+
class="c-split-input"
|
|
6
|
+
:type="type"
|
|
7
|
+
:label="label"
|
|
8
|
+
:name="name"
|
|
9
|
+
:inputmode="inputmode"
|
|
10
|
+
:value="value"
|
|
11
|
+
:rules="rules"
|
|
12
|
+
:placeholder="placeholder"
|
|
13
|
+
:disabled="disabled"
|
|
14
|
+
:autocomplete="autocomplete"
|
|
15
|
+
size="large"
|
|
16
|
+
:mask="mask"
|
|
17
|
+
@input:masked="maskedValue = $event"
|
|
18
|
+
>
|
|
19
|
+
<template #label>
|
|
20
|
+
<slot name="label" />
|
|
21
|
+
</template>
|
|
22
|
+
<template #message>
|
|
23
|
+
<slot name="message" />
|
|
24
|
+
</template>
|
|
25
|
+
</CMaskedTextField>
|
|
26
|
+
</template>
|
|
27
|
+
|
|
28
|
+
<script lang="ts">
|
|
29
|
+
import type { HTMLAttributes, PropType } from 'vue';
|
|
30
|
+
import { computed, defineComponent, ref, toRefs } from 'vue';
|
|
31
|
+
|
|
32
|
+
import CMaskedTextField from '@propelinc/citrus-ui/src/components/CMaskedTextField.vue';
|
|
33
|
+
import type { Rules } from '@propelinc/citrus-ui/src/composables/validations';
|
|
34
|
+
import type { SplitInputField } from '@propelinc/citrus-ui/src/types';
|
|
35
|
+
|
|
36
|
+
export default defineComponent({
|
|
37
|
+
name: 'CSplitInput',
|
|
38
|
+
components: { CMaskedTextField },
|
|
39
|
+
props: {
|
|
40
|
+
/** Custom data-test selector */
|
|
41
|
+
dataTest: { type: String, default: 'split-input' },
|
|
42
|
+
/** The input's type, either text or tel */
|
|
43
|
+
type: { type: String as PropType<'text' | 'tel'>, default: 'text' },
|
|
44
|
+
/** The input's label */
|
|
45
|
+
label: { type: String as PropType<string | null>, default: null },
|
|
46
|
+
/** The input's name */
|
|
47
|
+
name: { type: String as PropType<string | undefined>, default: undefined },
|
|
48
|
+
/** A hint to show the appropriate virtual keyboard, e.g. "numeric". */
|
|
49
|
+
inputmode: {
|
|
50
|
+
type: String as PropType<HTMLAttributes['inputmode'] | undefined>,
|
|
51
|
+
default: undefined,
|
|
52
|
+
},
|
|
53
|
+
/** The input's value */
|
|
54
|
+
value: { type: String, default: '' },
|
|
55
|
+
/** The fields for each of the split inputs of type SplitInputField */
|
|
56
|
+
fields: {
|
|
57
|
+
type: Array as PropType<SplitInputField[]>,
|
|
58
|
+
required: true,
|
|
59
|
+
},
|
|
60
|
+
/** Validation rules */
|
|
61
|
+
rules: { type: Array as PropType<Rules<string>>, default: () => [] },
|
|
62
|
+
/** Controls whether the input is disabled */
|
|
63
|
+
disabled: { type: Boolean, default: false },
|
|
64
|
+
/** Controls the underlying input's autocomplete attribute */
|
|
65
|
+
autocomplete: { type: String, default: undefined },
|
|
66
|
+
},
|
|
67
|
+
setup(props) {
|
|
68
|
+
const { fields } = toRefs(props);
|
|
69
|
+
|
|
70
|
+
const maskedValue = ref('');
|
|
71
|
+
|
|
72
|
+
const placeholder = computed(() => {
|
|
73
|
+
return fields.value
|
|
74
|
+
.map((field) => `${field.placeholder ?? ''}${field.separator ?? ''}`)
|
|
75
|
+
.join('');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const mask = computed(() => {
|
|
79
|
+
return fields.value
|
|
80
|
+
.map((field) => `${Array(field.characters).fill('*').join('')}${field.separator ?? ''}`)
|
|
81
|
+
.join('');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
return { placeholder, mask, maskedValue };
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
</script>
|
|
88
|
+
|
|
89
|
+
<style lang="scss" scoped>
|
|
90
|
+
@import '@propelinc/citrus-ui/src/styles/core';
|
|
91
|
+
|
|
92
|
+
@mixin split-input-text {
|
|
93
|
+
@include headline;
|
|
94
|
+
|
|
95
|
+
letter-spacing: 12px;
|
|
96
|
+
line-height: 1;
|
|
97
|
+
text-align: center;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.c-split-input {
|
|
101
|
+
&::part(input) {
|
|
102
|
+
@include split-input-text;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
&::part(input)::placeholder {
|
|
106
|
+
@include split-input-text;
|
|
107
|
+
|
|
108
|
+
font-weight: $font-weight-normal;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
</style>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
data-test="squared-icon"
|
|
4
|
+
:data-icon="icon"
|
|
5
|
+
:data-color="cssColor"
|
|
6
|
+
class="c-squared-icon"
|
|
7
|
+
:class="{ 'c-squared-icon--white-icon': useWhiteIcon, 'c-squared-icon--large': large }"
|
|
8
|
+
:style="{ backgroundColor: cssColor }"
|
|
9
|
+
>
|
|
10
|
+
<slot>
|
|
11
|
+
<FontAwesomeIcon v-if="icon" data-test="squared-icon-icon" :icon="icon" />
|
|
12
|
+
</slot>
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<script lang="ts">
|
|
17
|
+
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
|
18
|
+
import { computed, defineComponent, onMounted } from 'vue';
|
|
19
|
+
|
|
20
|
+
import { useCssColor } from '@propelinc/citrus-ui/src/composables/colors';
|
|
21
|
+
import type { FaIconArray, FaPropType } from '@propelinc/citrus-ui/src/types/font-awesome';
|
|
22
|
+
|
|
23
|
+
export default defineComponent({
|
|
24
|
+
components: { FontAwesomeIcon },
|
|
25
|
+
props: {
|
|
26
|
+
/** The Font Awesome icon to display */
|
|
27
|
+
icon: { type: [String, Array, Object] as FaPropType, default: null },
|
|
28
|
+
/** The background color */
|
|
29
|
+
color: { type: String, default: 'gray-100' },
|
|
30
|
+
/** Makes the icon and background larger */
|
|
31
|
+
large: { type: Boolean, default: false },
|
|
32
|
+
},
|
|
33
|
+
setup(props) {
|
|
34
|
+
onMounted(() => {
|
|
35
|
+
const enableCheck = process.env.VUE_APP_DEBUG === 'yes' || process.env.NODE_ENV === 'test';
|
|
36
|
+
if (enableCheck && Array.isArray(props.icon)) {
|
|
37
|
+
const [prefix, iconName] = props.icon as FaIconArray;
|
|
38
|
+
if (prefix === 'fal') {
|
|
39
|
+
console.error(
|
|
40
|
+
`We no longer use light Font Awesome icons. Please change ['${prefix}', '${iconName}'] to ['far', '${iconName}'].`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const { cssColor } = useCssColor(() => props.color);
|
|
47
|
+
|
|
48
|
+
const useWhiteIcon = computed(() => props.color === 'black');
|
|
49
|
+
|
|
50
|
+
return { cssColor, useWhiteIcon };
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<style lang="scss" scoped>
|
|
56
|
+
@import '@propelinc/citrus-ui/src/styles/core';
|
|
57
|
+
|
|
58
|
+
$squared-icon-size: 40px;
|
|
59
|
+
$squared-icon-large-size: 56px;
|
|
60
|
+
|
|
61
|
+
.c-squared-icon {
|
|
62
|
+
align-items: center;
|
|
63
|
+
border-radius: $border-radius;
|
|
64
|
+
color: $color-text-primary;
|
|
65
|
+
display: flex;
|
|
66
|
+
font-size: $font-size-icon-medium;
|
|
67
|
+
height: $squared-icon-size;
|
|
68
|
+
justify-content: center;
|
|
69
|
+
position: relative;
|
|
70
|
+
width: $squared-icon-size;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.c-squared-icon--white-icon {
|
|
74
|
+
color: $color-white;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.c-squared-icon--large {
|
|
78
|
+
border-radius: $border-radius-next;
|
|
79
|
+
font-size: $font-size-icon-large;
|
|
80
|
+
height: $squared-icon-large-size;
|
|
81
|
+
width: $squared-icon-large-size;
|
|
82
|
+
}
|
|
83
|
+
</style>
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<CMaskedTextField
|
|
3
|
+
v-bind="$attrs"
|
|
4
|
+
:id="id"
|
|
5
|
+
ref="field"
|
|
6
|
+
:data-test="dataTest"
|
|
7
|
+
:value="value"
|
|
8
|
+
:label="label || defaultLabel"
|
|
9
|
+
:placeholder="fourDigitSsn ? 'XXXX' : 'XXX-XX-XXXX'"
|
|
10
|
+
inputmode="numeric"
|
|
11
|
+
:mask="fourDigitSsn ? '####' : '###-##-####'"
|
|
12
|
+
:minlength="fourDigitSsn ? 4 : 9"
|
|
13
|
+
:maxlength="fourDigitSsn ? 4 : 9"
|
|
14
|
+
:hideable="!fourDigitSsn"
|
|
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
|
+
<template #append>
|
|
30
|
+
<!-- NOTE(mohan): When requesting the full SSN, we have to leave space for
|
|
31
|
+
the hide/show icon. -->
|
|
32
|
+
<FontAwesomeIcon v-if="fourDigitSsn" :icon="faLock" fixed-width />
|
|
33
|
+
</template>
|
|
34
|
+
</CMaskedTextField>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<script lang="ts">
|
|
38
|
+
import { faLock } from '@fortawesome/pro-regular-svg-icons';
|
|
39
|
+
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
|
40
|
+
import { type PropType, computed, defineComponent } from 'vue';
|
|
41
|
+
|
|
42
|
+
import CMaskedTextField from '@propelinc/citrus-ui/src/components/CMaskedTextField.vue';
|
|
43
|
+
import { useFocusableField } from '@propelinc/citrus-ui/src/composables/fields';
|
|
44
|
+
import { useTranslation } from '@propelinc/citrus-ui/src/composables/i18n';
|
|
45
|
+
import type { Rules } from '@propelinc/citrus-ui/src/composables/validations';
|
|
46
|
+
import { minLengthRule } from '@propelinc/shared-utils';
|
|
47
|
+
|
|
48
|
+
export default defineComponent({
|
|
49
|
+
name: 'CSsnField',
|
|
50
|
+
components: { CMaskedTextField, FontAwesomeIcon },
|
|
51
|
+
props: {
|
|
52
|
+
dataTest: { type: String, default: 'ssn-field' },
|
|
53
|
+
id: { type: String, default: undefined },
|
|
54
|
+
label: { type: String as PropType<string | null>, default: null },
|
|
55
|
+
rules: { type: Array as PropType<Rules<string>>, default: () => [] },
|
|
56
|
+
value: { type: String, default: '' },
|
|
57
|
+
fourDigitSsn: { type: Boolean, default: false },
|
|
58
|
+
},
|
|
59
|
+
emits: ['input', 'focus', 'blur', 'change'],
|
|
60
|
+
setup(props, { expose }) {
|
|
61
|
+
const { t } = useTranslation();
|
|
62
|
+
const defaultLabel = computed(() => {
|
|
63
|
+
return props.fourDigitSsn ? t('Last 4 digits of SSN') : t('Social Security number');
|
|
64
|
+
});
|
|
65
|
+
const defaultRules = computed(() => {
|
|
66
|
+
const fourDigitRule = minLengthRule(4, t('Please enter the last four digits of your SSN'));
|
|
67
|
+
const fullSsnRule = minLengthRule(
|
|
68
|
+
9,
|
|
69
|
+
t('Please enter a valid {inputLabel}', { inputLabel: t('Social Security number') })
|
|
70
|
+
);
|
|
71
|
+
return [props.fourDigitSsn ? fourDigitRule : fullSsnRule];
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const computedRules = computed(() => [...defaultRules.value, ...props.rules]);
|
|
75
|
+
|
|
76
|
+
const { field } = useFocusableField(expose);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
defaultLabel,
|
|
80
|
+
computedRules,
|
|
81
|
+
faLock,
|
|
82
|
+
field,
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
</script>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="c-status-dot"
|
|
4
|
+
:class="{
|
|
5
|
+
'c-status-dot--count': hasCount,
|
|
6
|
+
'c-status-dot--bordered': bordered,
|
|
7
|
+
}"
|
|
8
|
+
data-test="status-dot"
|
|
9
|
+
role="img"
|
|
10
|
+
>
|
|
11
|
+
{{ displayCount }}
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script lang="ts">
|
|
16
|
+
import type { PropType } from 'vue';
|
|
17
|
+
import { computed, defineComponent } from 'vue';
|
|
18
|
+
|
|
19
|
+
import { useA11yLabelCheck } from '@propelinc/citrus-ui/src/composables/accessibility';
|
|
20
|
+
|
|
21
|
+
export default defineComponent({
|
|
22
|
+
props: {
|
|
23
|
+
count: { type: Number as PropType<number | null>, default: null },
|
|
24
|
+
bordered: { type: Boolean, default: false },
|
|
25
|
+
},
|
|
26
|
+
setup(props) {
|
|
27
|
+
useA11yLabelCheck('CStatusDot');
|
|
28
|
+
|
|
29
|
+
const hasCount = computed(() => props.count !== null);
|
|
30
|
+
const displayCount = computed(() => {
|
|
31
|
+
return props.count && props.count > 9 ? '9+' : props.count;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return { displayCount, hasCount };
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<style lang="scss" scoped>
|
|
40
|
+
@import '@propelinc/citrus-ui/src/styles/core';
|
|
41
|
+
|
|
42
|
+
.c-status-dot {
|
|
43
|
+
background-color: $color-status-error;
|
|
44
|
+
border-radius: 9999px;
|
|
45
|
+
display: inline-block;
|
|
46
|
+
height: 8px;
|
|
47
|
+
width: 8px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.c-status-dot--bordered {
|
|
51
|
+
box-shadow: 0 0 0 1.5px $color-white;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* For users that may increase their font size for legibility,
|
|
56
|
+
* we use rems so the circle grows if the font size increases.
|
|
57
|
+
*/
|
|
58
|
+
.c-status-dot--count {
|
|
59
|
+
align-items: center;
|
|
60
|
+
color: $color-white;
|
|
61
|
+
display: flex;
|
|
62
|
+
font-size: 0.625rem;
|
|
63
|
+
font-weight: $font-weight-bold;
|
|
64
|
+
height: 1rem;
|
|
65
|
+
justify-content: center;
|
|
66
|
+
line-height: 1;
|
|
67
|
+
text-align: center;
|
|
68
|
+
width: 1rem;
|
|
69
|
+
}
|
|
70
|
+
</style>
|