@propelinc/citrus-ui 1.0.4 → 1.3.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 +51 -14
- package/dist/citrus-ui.cdn.css +1 -0
- package/dist/citrus-ui.css +1 -0
- package/dist/colors/colors.d.ts +31 -0
- package/dist/colors/theme.d.ts +3 -0
- package/dist/colors/util-classes.d.ts +11 -0
- package/dist/components/CAccordion.vue.d.ts +34 -0
- package/dist/components/CAccordionItem.vue.d.ts +39 -0
- package/dist/components/CAppBar.vue.d.ts +59 -0
- package/dist/components/CBadge.vue.d.ts +35 -0
- package/dist/components/CBottomSheet.vue.d.ts +90 -0
- package/dist/components/CButton/CButton.vue.d.ts +97 -0
- package/dist/components/CButton/types.d.ts +5 -0
- package/dist/components/CButtonStack.vue.d.ts +27 -0
- package/dist/components/CCard.vue.d.ts +53 -0
- package/dist/components/CCardFooter.vue.d.ts +20 -0
- package/dist/components/CCardHeader.vue.d.ts +22 -0
- package/dist/components/CCardSection.vue.d.ts +26 -0
- package/dist/components/CCheckbox.vue.d.ts +62 -0
- package/dist/components/CCol.vue.d.ts +30 -0
- package/dist/components/CDivider.vue.d.ts +9 -0
- package/dist/components/CDobField.vue.d.ts +60 -0
- package/dist/components/CDobSelect.vue.d.ts +50 -0
- package/dist/components/CEmailField.vue.d.ts +48 -0
- package/dist/components/CExpandTransition.vue.d.ts +29 -0
- package/dist/components/CFadeTransition.vue.d.ts +20 -0
- package/dist/components/CFileInput.vue.d.ts +50 -0
- package/dist/components/CFixedPageFooter.vue.d.ts +153 -0
- package/dist/components/CForm.vue.d.ts +44 -0
- package/dist/components/CFormFieldCounter.vue.d.ts +15 -0
- package/dist/components/CIconButton.vue.d.ts +97 -0
- package/dist/components/CLabel.vue.d.ts +36 -0
- package/dist/components/CListItem.vue.d.ts +56 -0
- package/dist/components/CListItemContent.vue.d.ts +27 -0
- package/dist/components/CListItemIcon.vue.d.ts +28 -0
- package/dist/components/CLoader.vue.d.ts +23 -0
- package/dist/components/CLogo.vue.d.ts +9 -0
- package/dist/components/CMaskedTextField.vue.d.ts +511 -0
- package/dist/components/CMenu.vue.d.ts +17 -0
- package/dist/components/CMenuItem.vue.d.ts +37 -0
- package/dist/components/CMenuLabel.vue.d.ts +20 -0
- package/dist/components/CModal.vue.d.ts +59 -0
- package/dist/components/CModalLoading.vue.d.ts +36 -0
- package/dist/components/CNotification.vue.d.ts +64 -0
- package/dist/components/CPhoneField.vue.d.ts +792 -0
- package/dist/components/CPill.vue.d.ts +41 -0
- package/dist/components/CPillGroup.vue.d.ts +39 -0
- package/dist/components/CPopup.vue.d.ts +37 -0
- package/dist/components/CProgressLinear.vue.d.ts +21 -0
- package/dist/components/CProgressRing.vue.d.ts +48 -0
- package/dist/components/CRadio.vue.d.ts +40 -0
- package/dist/components/CRadioGroup.vue.d.ts +54 -0
- package/dist/components/CRebrand.vue.d.ts +28 -0
- package/dist/components/CRow.vue.d.ts +41 -0
- package/dist/components/CSafeArea.vue.d.ts +18 -0
- package/dist/components/CSectionHeader.vue.d.ts +29 -0
- package/dist/components/CSelect.vue.d.ts +96 -0
- package/dist/components/CSkeleton.vue.d.ts +3 -0
- package/dist/components/CSkeletonLoaderCard.vue.d.ts +9 -0
- package/dist/components/CSkeletonLoaderCircle.vue.d.ts +3 -0
- package/dist/components/CSkeletonLoaderText.vue.d.ts +16 -0
- package/dist/components/CSlideFadeTransition.vue.d.ts +36 -0
- package/dist/components/CSplitInput.vue.d.ts +56 -0
- package/dist/components/CSquaredIcon.vue.d.ts +33 -0
- package/dist/components/CSsnField.vue.d.ts +798 -0
- package/dist/components/CStatusDot.vue.d.ts +10 -0
- package/dist/components/CSwitch.vue.d.ts +39 -0
- package/dist/components/CSwitchListItem.vue.d.ts +48 -0
- package/dist/components/CTextArea.vue.d.ts +96 -0
- package/dist/components/CTextField.vue.d.ts +129 -0
- package/dist/components/CTextLink.vue.d.ts +36 -0
- package/dist/components/CThirdPartyLogo.vue.d.ts +22 -0
- package/dist/components/CTimeago.vue.d.ts +12 -0
- package/dist/components/CToast.vue.d.ts +69 -0
- package/dist/components/CToastsList.vue.d.ts +3 -0
- package/dist/components/CValidationMessage.vue.d.ts +37 -0
- package/dist/components/CZipcodeField.vue.d.ts +796 -0
- package/dist/components/index.d.ts +66 -0
- 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 +10 -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/icons.cdn.mjs +3 -0
- package/dist/icons.cdn.mjs.map +1 -0
- package/dist/icons.d.ts +1 -0
- package/dist/icons.mjs +6 -0
- package/dist/icons.mjs.map +1 -0
- package/dist/index.cdn.mjs +9328 -12875
- package/dist/index.cdn.mjs.map +1 -1
- package/dist/index.cdn2.mjs +55255 -0
- package/dist/index.cdn2.mjs.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.mjs +3946 -0
- package/dist/index.mjs.map +1 -0
- package/dist/plugin.d.ts +3 -0
- 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 → styles.css} +40 -2
- package/dist/theme/icons.d.ts +36 -0
- package/dist/types/CForm.d.ts +12 -0
- package/dist/types/font-awesome.d.ts +5 -0
- package/dist/types.d.ts +13 -0
- package/package.json +11 -4
- package/src/colors/colors.ts +8 -3
- package/src/components/CAccordion.vue +31 -24
- package/src/components/CAccordionItem.vue +46 -45
- package/src/components/CAppBar.vue +108 -101
- package/src/components/CBadge.vue +33 -25
- package/src/components/CBottomSheet.vue +212 -199
- package/src/components/CButton/CButton.vue +135 -147
- package/src/components/CButtonStack.vue +21 -13
- package/src/components/CCard.vue +72 -69
- package/src/components/CCardFooter.vue +5 -5
- package/src/components/CCardHeader.vue +9 -7
- package/src/components/CCardSection.vue +15 -8
- package/src/components/CCheckbox.vue +68 -69
- package/src/components/CCol.vue +21 -22
- package/src/components/CDivider.vue +9 -8
- package/src/components/CDobField.vue +114 -105
- package/src/components/CDobSelect.vue +162 -164
- package/src/components/CEmailField.vue +39 -27
- package/src/components/CExpandTransition.vue +14 -17
- package/src/components/CFadeTransition.vue +3 -3
- package/src/components/CFileInput.vue +57 -50
- package/src/components/CFixedPageFooter.vue +23 -17
- package/src/components/CForm.vue +67 -60
- package/src/components/CFormFieldCounter.vue +25 -28
- package/src/components/CIconButton.vue +84 -65
- package/src/components/CLabel.vue +19 -13
- package/src/components/CListItem.vue +67 -66
- package/src/components/CListItemContent.vue +14 -16
- package/src/components/CListItemIcon.vue +18 -14
- package/src/components/CLoader.vue +47 -56
- package/src/components/CLogo.vue +13 -12
- package/src/components/CMaskedTextField.vue +80 -64
- package/src/components/CMenu.vue +14 -6
- package/src/components/CMenuItem.vue +28 -22
- package/src/components/CMenuLabel.vue +6 -5
- package/src/components/CModal.vue +76 -71
- package/src/components/CModalLoading.vue +24 -15
- package/src/components/CNotification.vue +77 -28
- package/src/components/CPhoneField.vue +34 -25
- package/src/components/CPill.vue +92 -88
- package/src/components/CPillGroup.vue +30 -21
- package/src/components/CPopup.vue +46 -37
- package/src/components/CProgressLinear.vue +17 -11
- package/src/components/CProgressRing.vue +33 -33
- package/src/components/CRadio.vue +57 -57
- package/src/components/CRadioGroup.vue +85 -72
- package/src/components/CRow.vue +22 -20
- package/src/components/CSectionHeader.vue +20 -12
- package/src/components/CSelect.vue +89 -73
- package/src/components/CSkeletonLoaderCard.vue +9 -15
- package/src/components/CSkeletonLoaderCircle.vue +1 -9
- package/src/components/CSkeletonLoaderText.vue +17 -18
- package/src/components/CSlideFadeTransition.vue +12 -34
- package/src/components/CSplitInput.vue +46 -45
- package/src/components/CSquaredIcon.vue +39 -29
- package/src/components/CSsnField.vue +48 -36
- package/src/components/CStatusDot.vue +16 -16
- package/src/components/CSwitch.vue +31 -22
- package/src/components/CSwitchListItem.vue +27 -28
- package/src/components/CTextArea.vue +116 -83
- package/src/components/CTextField.vue +194 -198
- package/src/components/CTextLink.vue +28 -25
- package/src/components/CThirdPartyLogo.vue +30 -59
- package/src/components/CToast.vue +135 -132
- package/src/components/CToastsList.vue +2 -15
- package/src/components/CValidationMessage.vue +31 -24
- package/src/components/CZipcodeField.vue +40 -27
- package/src/composables/elements.ts +1 -1
- package/src/composables/fields.ts +4 -4
- package/src/composables/router.ts +6 -5
- package/src/icons.ts +6 -0
- package/src/services/injections/buttons.ts +1 -1
- package/src/styles/_core.scss +1 -2
- package/src/styles/_reset.scss +1 -1
- package/src/styles/main.scss +2 -0
- package/src/types.ts +2 -0
- package/dist/index.cdn.css +0 -1
- package/dist/styles/utils.css +0 -2709
|
@@ -62,10 +62,11 @@
|
|
|
62
62
|
</div>
|
|
63
63
|
</template>
|
|
64
64
|
|
|
65
|
-
<script lang="ts">
|
|
65
|
+
<script setup lang="ts">
|
|
66
66
|
import { faChevronDown } from '@fortawesome/pro-regular-svg-icons';
|
|
67
67
|
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
|
68
|
-
import
|
|
68
|
+
import type { VNode } from 'vue';
|
|
69
|
+
import { ref, toRefs } from 'vue';
|
|
69
70
|
|
|
70
71
|
import CLoader from '@propelinc/citrus-ui/src/components/CLoader.vue';
|
|
71
72
|
import CValidationMessage from '@propelinc/citrus-ui/src/components/CValidationMessage.vue';
|
|
@@ -73,92 +74,107 @@ import { useInternalValue } from '@propelinc/citrus-ui/src/composables/binding';
|
|
|
73
74
|
import { useId } from '@propelinc/citrus-ui/src/composables/id';
|
|
74
75
|
import { useValidations } from '@propelinc/citrus-ui/src/composables/validations';
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
interface SelectItem {
|
|
78
|
+
label: string;
|
|
79
|
+
value: string;
|
|
80
|
+
disabled?: boolean;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const props = withDefaults(
|
|
84
|
+
defineProps<{
|
|
82
85
|
/** Overrides label for screenreader-only */
|
|
83
|
-
ariaLabel
|
|
84
|
-
/** Set the select's placeholder text */
|
|
85
|
-
placeholder: { type: String, default: undefined },
|
|
86
|
-
/** Assigns the select input's id */
|
|
87
|
-
id: { type: String, default: undefined },
|
|
88
|
-
/** List of options like `{ label: 'Yes', value: 'yes' }` */
|
|
89
|
-
items: {
|
|
90
|
-
type: Array as PropType<{ label: string; value: string; disabled?: boolean }[]>,
|
|
91
|
-
default: () => [],
|
|
92
|
-
},
|
|
93
|
-
/** Controls whether the select is disabled */
|
|
94
|
-
disabled: { type: Boolean, default: false },
|
|
95
|
-
/** Controls the value of the select */
|
|
96
|
-
value: { type: String, default: '' },
|
|
86
|
+
ariaLabel?: string;
|
|
97
87
|
/** Prefix for test selectors */
|
|
98
|
-
dataTest
|
|
99
|
-
/**
|
|
100
|
-
|
|
88
|
+
dataTest?: string;
|
|
89
|
+
/** Controls whether the select is disabled */
|
|
90
|
+
disabled?: boolean;
|
|
101
91
|
/**
|
|
102
92
|
* Hides the validation message area. Defaults to `false` (show message area even
|
|
103
93
|
* when valid), so validations transition in gracefully.
|
|
104
94
|
*
|
|
105
95
|
* If set to 'auto', the validation message area will only display if there is a message.
|
|
106
96
|
*/
|
|
107
|
-
hideDetails
|
|
97
|
+
hideDetails?: boolean | 'auto';
|
|
98
|
+
/** Hides the label and instead labels the field with `aria-label` */
|
|
99
|
+
hideLabel?: boolean;
|
|
100
|
+
/** Assigns the select input's id */
|
|
101
|
+
id?: string;
|
|
102
|
+
/** List of options like `{ label: 'Yes', value: 'yes' }` */
|
|
103
|
+
items?: SelectItem[];
|
|
104
|
+
/** The select's label, both visual and screenreader-only */
|
|
105
|
+
label?: string;
|
|
108
106
|
/** Controls whether the select is loading */
|
|
109
|
-
loading
|
|
107
|
+
loading?: boolean;
|
|
108
|
+
/** Set the select's placeholder text */
|
|
109
|
+
placeholder?: string;
|
|
110
|
+
/** If true, the select will be required */
|
|
111
|
+
required?: boolean;
|
|
110
112
|
/**
|
|
111
113
|
* An array of functions that either return either true / false or a string
|
|
112
114
|
* containing an error message. The component passes the input value as an
|
|
113
115
|
* argument. The input field will enter an error state if a function does
|
|
114
116
|
* not return true.
|
|
115
|
-
|
|
116
|
-
rules
|
|
117
|
-
/**
|
|
118
|
-
|
|
119
|
-
},
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
117
|
+
*/
|
|
118
|
+
rules?: ((value: string) => string | boolean)[];
|
|
119
|
+
/** Controls the value of the select */
|
|
120
|
+
value?: string;
|
|
121
|
+
}>(),
|
|
122
|
+
{
|
|
123
|
+
ariaLabel: undefined,
|
|
124
|
+
dataTest: 'select',
|
|
125
|
+
disabled: false,
|
|
126
|
+
hideDetails: false,
|
|
127
|
+
hideLabel: false,
|
|
128
|
+
id: undefined,
|
|
129
|
+
items: () => [],
|
|
130
|
+
label: undefined,
|
|
131
|
+
loading: false,
|
|
132
|
+
placeholder: undefined,
|
|
133
|
+
required: false,
|
|
134
|
+
rules: () => [],
|
|
135
|
+
value: '',
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const emit = defineEmits<{
|
|
140
|
+
(e: 'input', value: string): void;
|
|
141
|
+
(e: 'focus', event: FocusEvent): void;
|
|
142
|
+
(e: 'blur', event: FocusEvent): void;
|
|
143
|
+
(e: 'keydown', event: KeyboardEvent): void;
|
|
144
|
+
}>();
|
|
145
|
+
|
|
146
|
+
defineSlots<{
|
|
147
|
+
label?: () => VNode[];
|
|
148
|
+
message?: () => VNode[];
|
|
149
|
+
}>();
|
|
150
|
+
|
|
151
|
+
const { id, value, rules, required } = toRefs(props);
|
|
152
|
+
const idWithFallback = useId(id);
|
|
153
|
+
const inputValue = useInternalValue(value, {
|
|
154
|
+
onChange: (newValue) => emit('input', newValue),
|
|
155
|
+
});
|
|
156
|
+
const select = ref<HTMLSelectElement | null>(null);
|
|
157
|
+
const {
|
|
158
|
+
message: validationMessage,
|
|
159
|
+
valid: isValidationValid,
|
|
160
|
+
listeners: validationListeners,
|
|
161
|
+
startValidating,
|
|
162
|
+
clearValidations,
|
|
163
|
+
} = useValidations({
|
|
164
|
+
id: idWithFallback,
|
|
165
|
+
field: select,
|
|
166
|
+
value: inputValue,
|
|
167
|
+
rules,
|
|
168
|
+
required,
|
|
169
|
+
validateOn: 'blur',
|
|
161
170
|
});
|
|
171
|
+
|
|
172
|
+
function onInput(event: Event): void {
|
|
173
|
+
const target = event.target as HTMLSelectElement;
|
|
174
|
+
inputValue.value = target.value;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
defineExpose({ startValidating, clearValidations });
|
|
162
178
|
</script>
|
|
163
179
|
|
|
164
180
|
<style scoped lang="scss">
|
|
@@ -8,22 +8,16 @@
|
|
|
8
8
|
</div>
|
|
9
9
|
</template>
|
|
10
10
|
|
|
11
|
-
<script lang="ts">
|
|
12
|
-
import { defineComponent } from 'vue';
|
|
13
|
-
|
|
11
|
+
<script setup lang="ts">
|
|
14
12
|
import CSkeleton from '@propelinc/citrus-ui/src/components/CSkeleton.vue';
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
CSkeleton,
|
|
19
|
-
},
|
|
20
|
-
props: {
|
|
14
|
+
withDefaults(
|
|
15
|
+
defineProps<{
|
|
21
16
|
/** Controls the height of the skeleton loader card */
|
|
22
|
-
height
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
});
|
|
17
|
+
height?: number | string;
|
|
18
|
+
}>(),
|
|
19
|
+
{
|
|
20
|
+
height: 100,
|
|
21
|
+
}
|
|
22
|
+
);
|
|
29
23
|
</script>
|
|
@@ -4,16 +4,8 @@
|
|
|
4
4
|
</div>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
|
-
<script lang="ts">
|
|
8
|
-
import { defineComponent } from 'vue';
|
|
9
|
-
|
|
7
|
+
<script setup lang="ts">
|
|
10
8
|
import CSkeleton from '@propelinc/citrus-ui/src/components/CSkeleton.vue';
|
|
11
|
-
|
|
12
|
-
export default defineComponent({
|
|
13
|
-
components: {
|
|
14
|
-
CSkeleton,
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
9
|
</script>
|
|
18
10
|
|
|
19
11
|
<style scoped>
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
</div>
|
|
19
19
|
</template>
|
|
20
20
|
|
|
21
|
-
<script lang="ts">
|
|
22
|
-
import {
|
|
21
|
+
<script setup lang="ts">
|
|
22
|
+
import { computed } from 'vue';
|
|
23
23
|
|
|
24
24
|
import CSkeleton from '@propelinc/citrus-ui/src/components/CSkeleton.vue';
|
|
25
25
|
|
|
@@ -52,25 +52,24 @@ const LINE_TYPE_TO_CLASS: Record<SkeletonLoaderType, string> = {
|
|
|
52
52
|
'x-large-headline': 'c-skeleton-loader-text__line--x-large-headline',
|
|
53
53
|
};
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
CSkeleton,
|
|
58
|
-
},
|
|
59
|
-
props: {
|
|
55
|
+
const props = withDefaults(
|
|
56
|
+
defineProps<{
|
|
60
57
|
/** Applies the align-items css property. */
|
|
61
|
-
align
|
|
58
|
+
align?: 'center' | 'start' | 'end';
|
|
62
59
|
/** Controls how many rows of loading text are shown */
|
|
63
|
-
rows
|
|
60
|
+
rows?: number;
|
|
64
61
|
/** Controls the appearance of the loading text */
|
|
65
|
-
type
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
62
|
+
type?: SkeletonLoaderType;
|
|
63
|
+
}>(),
|
|
64
|
+
{
|
|
65
|
+
align: 'start',
|
|
66
|
+
rows: 2,
|
|
67
|
+
type: 'body',
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const lineTypeClass = computed(() => {
|
|
72
|
+
return LINE_TYPE_TO_CLASS[props.type];
|
|
74
73
|
});
|
|
75
74
|
</script>
|
|
76
75
|
|
|
@@ -6,50 +6,28 @@
|
|
|
6
6
|
</div>
|
|
7
7
|
</template>
|
|
8
8
|
|
|
9
|
-
<script lang="ts">
|
|
10
|
-
import
|
|
9
|
+
<script setup lang="ts">
|
|
10
|
+
import type { VNode } from 'vue';
|
|
11
11
|
|
|
12
12
|
type Direction = 'to-left' | 'to-right' | 'to-top' | 'to-bottom';
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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: {
|
|
14
|
+
defineSlots<{ default: () => VNode[] }>();
|
|
15
|
+
|
|
16
|
+
withDefaults(
|
|
17
|
+
defineProps<{
|
|
32
18
|
/**
|
|
33
|
-
* The amount of pixels to slide the elements in or out
|
|
19
|
+
* The amount of pixels to slide the elements in or out. Should be >= 0
|
|
34
20
|
* @default 20
|
|
35
21
|
*/
|
|
36
|
-
amount
|
|
37
|
-
type: Number,
|
|
38
|
-
default: 20,
|
|
39
|
-
validator(value: number) {
|
|
40
|
-
return value >= 0;
|
|
41
|
-
},
|
|
42
|
-
},
|
|
22
|
+
amount?: number;
|
|
43
23
|
/**
|
|
44
24
|
* Changes the direction of the slide fade transition
|
|
45
25
|
* @default 'to-left'
|
|
46
26
|
*/
|
|
47
|
-
direction
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
},
|
|
52
|
-
});
|
|
27
|
+
direction?: Direction;
|
|
28
|
+
}>(),
|
|
29
|
+
{ amount: 20, direction: 'to-left' }
|
|
30
|
+
);
|
|
53
31
|
</script>
|
|
54
32
|
|
|
55
33
|
<style scoped>
|
|
@@ -25,64 +25,65 @@
|
|
|
25
25
|
</CMaskedTextField>
|
|
26
26
|
</template>
|
|
27
27
|
|
|
28
|
-
<script lang="ts">
|
|
29
|
-
import type { HTMLAttributes,
|
|
30
|
-
import { computed,
|
|
28
|
+
<script setup lang="ts">
|
|
29
|
+
import type { HTMLAttributes, VNode } from 'vue';
|
|
30
|
+
import { computed, ref } from 'vue';
|
|
31
31
|
|
|
32
32
|
import CMaskedTextField from '@propelinc/citrus-ui/src/components/CMaskedTextField.vue';
|
|
33
33
|
import type { Rules } from '@propelinc/citrus-ui/src/composables/validations';
|
|
34
34
|
import type { SplitInputField } from '@propelinc/citrus-ui/src/types';
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
const props = withDefaults(
|
|
37
|
+
defineProps<{
|
|
38
|
+
/** Controls the underlying input's autocomplete attribute */
|
|
39
|
+
autocomplete?: string;
|
|
40
40
|
/** Custom data-test selector */
|
|
41
|
-
dataTest
|
|
42
|
-
/**
|
|
43
|
-
|
|
41
|
+
dataTest?: string;
|
|
42
|
+
/** Controls whether the input is disabled */
|
|
43
|
+
disabled?: boolean;
|
|
44
|
+
/** The fields for each of the split inputs of type SplitInputField */
|
|
45
|
+
fields: SplitInputField[];
|
|
46
|
+
/** A hint to show the appropriate virtual keyboard, e.g. "numeric". */
|
|
47
|
+
inputmode?: HTMLAttributes['inputmode'];
|
|
44
48
|
/** The input's label */
|
|
45
|
-
label
|
|
49
|
+
label?: string | null;
|
|
46
50
|
/** The input's name */
|
|
47
|
-
name
|
|
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
|
-
},
|
|
51
|
+
name?: string;
|
|
60
52
|
/** Validation rules */
|
|
61
|
-
rules
|
|
62
|
-
/**
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
|
|
53
|
+
rules?: Rules<string>;
|
|
54
|
+
/** The input's type, either text or tel */
|
|
55
|
+
type?: 'text' | 'tel';
|
|
56
|
+
/** The input's value */
|
|
57
|
+
value?: string;
|
|
58
|
+
}>(),
|
|
59
|
+
{
|
|
60
|
+
autocomplete: undefined,
|
|
61
|
+
dataTest: 'split-input',
|
|
62
|
+
disabled: false,
|
|
63
|
+
inputmode: undefined,
|
|
64
|
+
label: null,
|
|
65
|
+
name: undefined,
|
|
66
|
+
rules: () => [],
|
|
67
|
+
type: 'text',
|
|
68
|
+
value: '',
|
|
69
|
+
}
|
|
70
|
+
);
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
defineSlots<{
|
|
73
|
+
label?: () => VNode[];
|
|
74
|
+
message?: () => VNode[];
|
|
75
|
+
}>();
|
|
71
76
|
|
|
72
|
-
|
|
73
|
-
return fields.value
|
|
74
|
-
.map((field) => `${field.placeholder ?? ''}${field.separator ?? ''}`)
|
|
75
|
-
.join('');
|
|
76
|
-
});
|
|
77
|
+
const maskedValue = ref('');
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
.join('');
|
|
82
|
-
});
|
|
79
|
+
const placeholder = computed(() => {
|
|
80
|
+
return props.fields.map((field) => `${field.placeholder ?? ''}${field.separator ?? ''}`).join('');
|
|
81
|
+
});
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
const mask = computed(() => {
|
|
84
|
+
return props.fields
|
|
85
|
+
.map((field) => `${Array(field.characters).fill('*').join('')}${field.separator ?? ''}`)
|
|
86
|
+
.join('');
|
|
86
87
|
});
|
|
87
88
|
</script>
|
|
88
89
|
|
|
@@ -13,43 +13,53 @@
|
|
|
13
13
|
</div>
|
|
14
14
|
</template>
|
|
15
15
|
|
|
16
|
-
<script lang="ts">
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
16
|
+
<script setup lang="ts">
|
|
17
|
+
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
18
|
+
import { FontAwesomeIcon as FontAwesomeIconComponent } from '@fortawesome/vue-fontawesome';
|
|
19
|
+
import type { Component, VNode } from 'vue';
|
|
20
|
+
import { computed, onMounted } from 'vue';
|
|
19
21
|
|
|
20
22
|
import { useCssColor } from '@propelinc/citrus-ui/src/composables/colors';
|
|
21
|
-
import type { FaIconArray
|
|
23
|
+
import type { FaIconArray } from '@propelinc/citrus-ui/src/types/font-awesome';
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
// FontAwesomeIcon's prop types produce a union too complex for TypeScript to resolve
|
|
26
|
+
const FontAwesomeIcon = FontAwesomeIconComponent as unknown as Component;
|
|
27
|
+
|
|
28
|
+
const props = withDefaults(
|
|
29
|
+
defineProps<{
|
|
28
30
|
/** The background color */
|
|
29
|
-
color
|
|
31
|
+
color?: string;
|
|
32
|
+
/** The Font Awesome icon to display */
|
|
33
|
+
icon?: string | string[] | IconDefinition | null;
|
|
30
34
|
/** Makes the icon and background larger */
|
|
31
|
-
large
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
console.error(
|
|
40
|
-
`We no longer use light Font Awesome icons. Please change ['${prefix}', '${iconName}'] to ['far', '${iconName}'].`
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
});
|
|
35
|
+
large?: boolean;
|
|
36
|
+
}>(),
|
|
37
|
+
{
|
|
38
|
+
color: 'gray-100',
|
|
39
|
+
icon: null,
|
|
40
|
+
large: false,
|
|
41
|
+
}
|
|
42
|
+
);
|
|
45
43
|
|
|
46
|
-
|
|
44
|
+
defineSlots<{
|
|
45
|
+
default?: () => VNode[];
|
|
46
|
+
}>();
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
onMounted(() => {
|
|
49
|
+
const enableCheck = process.env.VUE_APP_DEBUG === 'yes' || process.env.NODE_ENV === 'test';
|
|
50
|
+
if (enableCheck && Array.isArray(props.icon)) {
|
|
51
|
+
const [prefix, iconName] = props.icon as FaIconArray;
|
|
52
|
+
if (prefix === 'fal') {
|
|
53
|
+
console.error(
|
|
54
|
+
`We no longer use light Font Awesome icons. Please change ['${prefix}', '${iconName}'] to ['far', '${iconName}'].`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
52
58
|
});
|
|
59
|
+
|
|
60
|
+
const { cssColor } = useCssColor(() => props.color);
|
|
61
|
+
|
|
62
|
+
const useWhiteIcon = computed(() => props.color === 'black');
|
|
53
63
|
</script>
|
|
54
64
|
|
|
55
65
|
<style lang="scss" scoped>
|
|
@@ -34,10 +34,11 @@
|
|
|
34
34
|
</CMaskedTextField>
|
|
35
35
|
</template>
|
|
36
36
|
|
|
37
|
-
<script lang="ts">
|
|
37
|
+
<script setup lang="ts">
|
|
38
38
|
import { faLock } from '@fortawesome/pro-regular-svg-icons';
|
|
39
39
|
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
|
40
|
-
import
|
|
40
|
+
import type { VNode } from 'vue';
|
|
41
|
+
import { computed } from 'vue';
|
|
41
42
|
|
|
42
43
|
import CMaskedTextField from '@propelinc/citrus-ui/src/components/CMaskedTextField.vue';
|
|
43
44
|
import { useFocusableField } from '@propelinc/citrus-ui/src/composables/fields';
|
|
@@ -45,42 +46,53 @@ import { useTranslation } from '@propelinc/citrus-ui/src/composables/i18n';
|
|
|
45
46
|
import type { Rules } from '@propelinc/citrus-ui/src/composables/validations';
|
|
46
47
|
import { minLengthRule } from '@propelinc/shared-utils';
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
});
|
|
49
|
+
const props = withDefaults(
|
|
50
|
+
defineProps<{
|
|
51
|
+
dataTest?: string;
|
|
52
|
+
id?: string;
|
|
53
|
+
label?: string | null;
|
|
54
|
+
rules?: Rules<string>;
|
|
55
|
+
value?: string;
|
|
56
|
+
fourDigitSsn?: boolean;
|
|
57
|
+
}>(),
|
|
58
|
+
{
|
|
59
|
+
dataTest: 'ssn-field',
|
|
60
|
+
id: undefined,
|
|
61
|
+
label: null,
|
|
62
|
+
rules: (): Rules<string> => [],
|
|
63
|
+
value: '',
|
|
64
|
+
fourDigitSsn: false,
|
|
65
|
+
}
|
|
66
|
+
);
|
|
73
67
|
|
|
74
|
-
|
|
68
|
+
defineEmits<{
|
|
69
|
+
input: [value: string];
|
|
70
|
+
focus: [event: Event];
|
|
71
|
+
blur: [event: Event];
|
|
72
|
+
change: [value: string];
|
|
73
|
+
}>();
|
|
75
74
|
|
|
76
|
-
|
|
75
|
+
defineSlots<{
|
|
76
|
+
label?: () => VNode[];
|
|
77
|
+
message?: () => VNode[];
|
|
78
|
+
append?: () => VNode[];
|
|
79
|
+
}>();
|
|
77
80
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
faLock,
|
|
82
|
-
field,
|
|
83
|
-
};
|
|
84
|
-
},
|
|
81
|
+
const { t } = useTranslation();
|
|
82
|
+
const defaultLabel = computed(() => {
|
|
83
|
+
return props.fourDigitSsn ? t('Last 4 digits of SSN') : t('Social Security number');
|
|
85
84
|
});
|
|
85
|
+
const defaultRules = computed(() => {
|
|
86
|
+
const fourDigitRule = minLengthRule(4, t('Please enter the last four digits of your SSN'));
|
|
87
|
+
const fullSsnRule = minLengthRule(
|
|
88
|
+
9,
|
|
89
|
+
t('Please enter a valid {inputLabel}', { inputLabel: t('Social Security number') })
|
|
90
|
+
);
|
|
91
|
+
return [props.fourDigitSsn ? fourDigitRule : fullSsnRule];
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const computedRules = computed(() => [...defaultRules.value, ...props.rules]);
|
|
95
|
+
|
|
96
|
+
const { field, focus } = useFocusableField();
|
|
97
|
+
defineExpose({ focus });
|
|
86
98
|
</script>
|