@propelinc/citrus-ui 1.0.5 → 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.
Files changed (201) hide show
  1. package/README.md +39 -14
  2. package/dist/citrus-ui.cdn.css +1 -0
  3. package/dist/citrus-ui.css +1 -0
  4. package/dist/colors/colors.d.ts +31 -0
  5. package/dist/colors/theme.d.ts +3 -0
  6. package/dist/colors/util-classes.d.ts +11 -0
  7. package/dist/components/CAccordion.vue.d.ts +34 -0
  8. package/dist/components/CAccordionItem.vue.d.ts +39 -0
  9. package/dist/components/CAppBar.vue.d.ts +59 -0
  10. package/dist/components/CBadge.vue.d.ts +35 -0
  11. package/dist/components/CBottomSheet.vue.d.ts +90 -0
  12. package/dist/components/CButton/CButton.vue.d.ts +97 -0
  13. package/dist/components/CButton/types.d.ts +5 -0
  14. package/dist/components/CButtonStack.vue.d.ts +27 -0
  15. package/dist/components/CCard.vue.d.ts +53 -0
  16. package/dist/components/CCardFooter.vue.d.ts +20 -0
  17. package/dist/components/CCardHeader.vue.d.ts +22 -0
  18. package/dist/components/CCardSection.vue.d.ts +26 -0
  19. package/dist/components/CCheckbox.vue.d.ts +62 -0
  20. package/dist/components/CCol.vue.d.ts +30 -0
  21. package/dist/components/CDivider.vue.d.ts +9 -0
  22. package/dist/components/CDobField.vue.d.ts +60 -0
  23. package/dist/components/CDobSelect.vue.d.ts +50 -0
  24. package/dist/components/CEmailField.vue.d.ts +48 -0
  25. package/dist/components/CExpandTransition.vue.d.ts +29 -0
  26. package/dist/components/CFadeTransition.vue.d.ts +20 -0
  27. package/dist/components/CFileInput.vue.d.ts +50 -0
  28. package/dist/components/CFixedPageFooter.vue.d.ts +153 -0
  29. package/dist/components/CForm.vue.d.ts +44 -0
  30. package/dist/components/CFormFieldCounter.vue.d.ts +15 -0
  31. package/dist/components/CIconButton.vue.d.ts +97 -0
  32. package/dist/components/CLabel.vue.d.ts +36 -0
  33. package/dist/components/CListItem.vue.d.ts +56 -0
  34. package/dist/components/CListItemContent.vue.d.ts +27 -0
  35. package/dist/components/CListItemIcon.vue.d.ts +28 -0
  36. package/dist/components/CLoader.vue.d.ts +23 -0
  37. package/dist/components/CLogo.vue.d.ts +9 -0
  38. package/dist/components/CMaskedTextField.vue.d.ts +511 -0
  39. package/dist/components/CMenu.vue.d.ts +17 -0
  40. package/dist/components/CMenuItem.vue.d.ts +37 -0
  41. package/dist/components/CMenuLabel.vue.d.ts +20 -0
  42. package/dist/components/CModal.vue.d.ts +59 -0
  43. package/dist/components/CModalLoading.vue.d.ts +36 -0
  44. package/dist/components/CNotification.vue.d.ts +64 -0
  45. package/dist/components/CPhoneField.vue.d.ts +792 -0
  46. package/dist/components/CPill.vue.d.ts +41 -0
  47. package/dist/components/CPillGroup.vue.d.ts +39 -0
  48. package/dist/components/CPopup.vue.d.ts +37 -0
  49. package/dist/components/CProgressLinear.vue.d.ts +21 -0
  50. package/dist/components/CProgressRing.vue.d.ts +48 -0
  51. package/dist/components/CRadio.vue.d.ts +40 -0
  52. package/dist/components/CRadioGroup.vue.d.ts +54 -0
  53. package/dist/components/CRebrand.vue.d.ts +28 -0
  54. package/dist/components/CRow.vue.d.ts +41 -0
  55. package/dist/components/CSafeArea.vue.d.ts +18 -0
  56. package/dist/components/CSectionHeader.vue.d.ts +29 -0
  57. package/dist/components/CSelect.vue.d.ts +96 -0
  58. package/dist/components/CSkeleton.vue.d.ts +3 -0
  59. package/dist/components/CSkeletonLoaderCard.vue.d.ts +9 -0
  60. package/dist/components/CSkeletonLoaderCircle.vue.d.ts +3 -0
  61. package/dist/components/CSkeletonLoaderText.vue.d.ts +16 -0
  62. package/dist/components/CSlideFadeTransition.vue.d.ts +36 -0
  63. package/dist/components/CSplitInput.vue.d.ts +56 -0
  64. package/dist/components/CSquaredIcon.vue.d.ts +33 -0
  65. package/dist/components/CSsnField.vue.d.ts +798 -0
  66. package/dist/components/CStatusDot.vue.d.ts +10 -0
  67. package/dist/components/CSwitch.vue.d.ts +39 -0
  68. package/dist/components/CSwitchListItem.vue.d.ts +48 -0
  69. package/dist/components/CTextArea.vue.d.ts +96 -0
  70. package/dist/components/CTextField.vue.d.ts +129 -0
  71. package/dist/components/CTextLink.vue.d.ts +36 -0
  72. package/dist/components/CThirdPartyLogo.vue.d.ts +22 -0
  73. package/dist/components/CTimeago.vue.d.ts +12 -0
  74. package/dist/components/CToast.vue.d.ts +69 -0
  75. package/dist/components/CToastsList.vue.d.ts +3 -0
  76. package/dist/components/CValidationMessage.vue.d.ts +37 -0
  77. package/dist/components/CZipcodeField.vue.d.ts +796 -0
  78. package/dist/components/index.d.ts +66 -0
  79. package/dist/components/internal/CCloseButton.vue.d.ts +14 -0
  80. package/dist/composables/accessibility.d.ts +1 -0
  81. package/dist/composables/animation.d.ts +12 -0
  82. package/dist/composables/binding.d.ts +19 -0
  83. package/dist/composables/colors.d.ts +13 -0
  84. package/dist/composables/elements.d.ts +3 -0
  85. package/dist/composables/fields.d.ts +10 -0
  86. package/dist/composables/gestures.d.ts +53 -0
  87. package/dist/composables/i18n.d.ts +3 -0
  88. package/dist/composables/id.d.ts +11 -0
  89. package/dist/composables/input-mask.d.ts +18 -0
  90. package/dist/composables/router.d.ts +30 -0
  91. package/dist/composables/slots.d.ts +2 -0
  92. package/dist/composables/toast.d.ts +21 -0
  93. package/dist/composables/validations.d.ts +77 -0
  94. package/dist/icons.cdn.mjs +3 -0
  95. package/dist/icons.cdn.mjs.map +1 -0
  96. package/dist/icons.d.ts +1 -0
  97. package/dist/icons.mjs +6 -0
  98. package/dist/icons.mjs.map +1 -0
  99. package/dist/index.cdn.mjs +9328 -12875
  100. package/dist/index.cdn.mjs.map +1 -1
  101. package/dist/index.cdn2.mjs +55255 -0
  102. package/dist/index.cdn2.mjs.map +1 -0
  103. package/dist/index.d.ts +8 -0
  104. package/dist/index.mjs +3946 -0
  105. package/dist/index.mjs.map +1 -0
  106. package/dist/plugin.d.ts +3 -0
  107. package/dist/services/animation.d.ts +17 -0
  108. package/dist/services/directives/index.d.ts +2 -0
  109. package/dist/services/directives/scroll-into-view.d.ts +7 -0
  110. package/dist/services/directives/tap-animation.d.ts +6 -0
  111. package/dist/services/id.d.ts +22 -0
  112. package/dist/services/injections/accordions.d.ts +3 -0
  113. package/dist/services/injections/animations.d.ts +2 -0
  114. package/dist/services/injections/buttons.d.ts +4 -0
  115. package/dist/services/injections/forms.d.ts +6 -0
  116. package/dist/services/injections/icon-buttons.d.ts +3 -0
  117. package/dist/services/injections/pills.d.ts +4 -0
  118. package/dist/services/injections/radio.d.ts +10 -0
  119. package/dist/{styles/main.css → styles.css} +8 -6
  120. package/dist/theme/icons.d.ts +36 -0
  121. package/dist/types/CForm.d.ts +12 -0
  122. package/dist/types/font-awesome.d.ts +5 -0
  123. package/dist/types.d.ts +13 -0
  124. package/package.json +8 -3
  125. package/src/colors/colors.ts +8 -3
  126. package/src/components/CAccordion.vue +31 -24
  127. package/src/components/CAccordionItem.vue +46 -45
  128. package/src/components/CAppBar.vue +108 -101
  129. package/src/components/CBadge.vue +33 -25
  130. package/src/components/CBottomSheet.vue +212 -199
  131. package/src/components/CButton/CButton.vue +135 -147
  132. package/src/components/CButtonStack.vue +21 -13
  133. package/src/components/CCard.vue +72 -69
  134. package/src/components/CCardFooter.vue +5 -5
  135. package/src/components/CCardHeader.vue +9 -7
  136. package/src/components/CCardSection.vue +15 -8
  137. package/src/components/CCheckbox.vue +68 -69
  138. package/src/components/CCol.vue +21 -22
  139. package/src/components/CDivider.vue +9 -8
  140. package/src/components/CDobField.vue +114 -105
  141. package/src/components/CDobSelect.vue +162 -164
  142. package/src/components/CEmailField.vue +39 -27
  143. package/src/components/CExpandTransition.vue +14 -17
  144. package/src/components/CFadeTransition.vue +3 -3
  145. package/src/components/CFileInput.vue +57 -50
  146. package/src/components/CFixedPageFooter.vue +23 -17
  147. package/src/components/CForm.vue +67 -60
  148. package/src/components/CFormFieldCounter.vue +25 -28
  149. package/src/components/CIconButton.vue +84 -65
  150. package/src/components/CLabel.vue +19 -13
  151. package/src/components/CListItem.vue +67 -66
  152. package/src/components/CListItemContent.vue +14 -16
  153. package/src/components/CListItemIcon.vue +18 -14
  154. package/src/components/CLoader.vue +47 -56
  155. package/src/components/CLogo.vue +13 -12
  156. package/src/components/CMaskedTextField.vue +80 -64
  157. package/src/components/CMenu.vue +14 -6
  158. package/src/components/CMenuItem.vue +28 -22
  159. package/src/components/CMenuLabel.vue +6 -5
  160. package/src/components/CModal.vue +76 -71
  161. package/src/components/CModalLoading.vue +24 -15
  162. package/src/components/CNotification.vue +77 -28
  163. package/src/components/CPhoneField.vue +34 -25
  164. package/src/components/CPill.vue +92 -88
  165. package/src/components/CPillGroup.vue +30 -21
  166. package/src/components/CPopup.vue +46 -37
  167. package/src/components/CProgressLinear.vue +17 -11
  168. package/src/components/CProgressRing.vue +33 -33
  169. package/src/components/CRadio.vue +57 -57
  170. package/src/components/CRadioGroup.vue +85 -72
  171. package/src/components/CRow.vue +22 -20
  172. package/src/components/CSectionHeader.vue +20 -12
  173. package/src/components/CSelect.vue +89 -73
  174. package/src/components/CSkeletonLoaderCard.vue +9 -15
  175. package/src/components/CSkeletonLoaderCircle.vue +1 -9
  176. package/src/components/CSkeletonLoaderText.vue +17 -18
  177. package/src/components/CSlideFadeTransition.vue +12 -34
  178. package/src/components/CSplitInput.vue +46 -45
  179. package/src/components/CSquaredIcon.vue +39 -29
  180. package/src/components/CSsnField.vue +48 -36
  181. package/src/components/CStatusDot.vue +16 -16
  182. package/src/components/CSwitch.vue +31 -22
  183. package/src/components/CSwitchListItem.vue +27 -28
  184. package/src/components/CTextArea.vue +116 -83
  185. package/src/components/CTextField.vue +194 -198
  186. package/src/components/CTextLink.vue +28 -25
  187. package/src/components/CThirdPartyLogo.vue +30 -59
  188. package/src/components/CToast.vue +135 -132
  189. package/src/components/CToastsList.vue +2 -15
  190. package/src/components/CValidationMessage.vue +31 -24
  191. package/src/components/CZipcodeField.vue +40 -27
  192. package/src/composables/elements.ts +1 -1
  193. package/src/composables/fields.ts +4 -4
  194. package/src/composables/router.ts +6 -5
  195. package/src/icons.ts +6 -0
  196. package/src/services/injections/buttons.ts +1 -1
  197. package/src/styles/_core.scss +1 -2
  198. package/src/styles/_reset.scss +1 -1
  199. package/src/types.ts +2 -0
  200. package/dist/index.cdn.css +0 -1
  201. package/dist/styles/utils.css +0 -2709
@@ -12,23 +12,32 @@
12
12
  </CModal>
13
13
  </template>
14
14
 
15
- <script lang="ts">
16
- import type { PropType } from 'vue';
17
- import { defineComponent } from 'vue';
15
+ <script setup lang="ts">
16
+ import type { VNode } from 'vue';
18
17
 
19
18
  import CModal from '@propelinc/citrus-ui/src/components/CModal.vue';
20
19
 
21
- export default defineComponent({
22
- name: 'CModalLoading',
23
- components: { CModal },
24
- props: {
25
- /** Controls whether or not the modal is showing */
26
- value: { type: Boolean, default: false },
27
- /** Controls the message shown below the Modal Loading icon */
28
- message: { type: String as PropType<string | null>, default: null },
20
+ withDefaults(
21
+ defineProps<{
29
22
  /** Prefix for test selectors */
30
- dataTest: { type: String, default: 'loading-modal' },
31
- },
32
- emits: ['input'],
33
- });
23
+ dataTest?: string;
24
+ /** Controls the message shown below the Modal Loading icon */
25
+ message?: string | null;
26
+ /** Controls whether or not the modal is showing */
27
+ value?: boolean;
28
+ }>(),
29
+ {
30
+ dataTest: 'loading-modal',
31
+ message: null,
32
+ value: false,
33
+ }
34
+ );
35
+
36
+ defineEmits<{
37
+ input: [value: boolean];
38
+ }>();
39
+
40
+ defineSlots<{
41
+ loading?: () => VNode[];
42
+ }>();
34
43
  </script>
@@ -2,10 +2,7 @@
2
2
  <div
3
3
  data-test="notification"
4
4
  class="c-notification"
5
- :class="{
6
- 'c-notification--alert': alert,
7
- 'c-notification--warning': warning,
8
- }"
5
+ :class="`c-notification--${computedVariant}`"
9
6
  >
10
7
  <CIconButton
11
8
  v-if="dismissible"
@@ -49,35 +46,83 @@
49
46
  </div>
50
47
  </template>
51
48
 
52
- <script lang="ts">
49
+ <script setup lang="ts">
53
50
  import { faXmark as farXmark } from '@fortawesome/pro-regular-svg-icons';
54
- import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
55
- import { computed, defineComponent } from 'vue';
51
+ import { FontAwesomeIcon as FontAwesomeIconComponent } from '@fortawesome/vue-fontawesome';
52
+ import type { Component, VNode } from 'vue';
53
+ import { computed } from 'vue';
54
+ import type { RouteLocationRaw } from 'vue-router';
56
55
 
57
56
  import CButton from '@propelinc/citrus-ui/src/components/CButton/CButton.vue';
58
57
  import CIconButton from '@propelinc/citrus-ui/src/components/CIconButton.vue';
59
58
 
60
- export default defineComponent({
61
- components: { CButton, CIconButton, FontAwesomeIcon },
62
- props: {
63
- // TODO(mohan): Make this prop accessible.
64
- alert: { type: Boolean, default: false },
65
- warning: { type: Boolean, default: false },
66
- dismissible: { type: Boolean, default: false },
67
- title: { type: String, default: '' },
68
- titleIcon: { type: [String, Array, Object], default: undefined },
69
- buttonText: { type: String, default: undefined },
70
- buttonTo: { type: [Object, String], default: undefined },
71
- buttonHref: { type: String, default: undefined },
72
- buttonTarget: { type: String, default: undefined },
73
- buttonLoading: { type: Boolean, default: false },
74
- },
75
- emits: ['click:button', 'dismiss'],
76
- setup(props) {
77
- const hasButton = computed(() => !!props.buttonText);
78
-
79
- return { hasButton, farXmark };
80
- },
59
+ import type { NotificationVariant } from '../types';
60
+
61
+ // FontAwesomeIcon's prop types produce a union too complex for TypeScript to resolve
62
+ const FontAwesomeIcon = FontAwesomeIconComponent as unknown as Component;
63
+
64
+ const props = withDefaults(
65
+ defineProps<{
66
+ /**
67
+ * @deprecated use `variant` prop instead
68
+ * Renders the error state
69
+ */
70
+ // TODO(mohan): Make alert prop accessible.
71
+ alert?: boolean;
72
+ /**
73
+ * @deprecated use `variant` prop instead
74
+ * Renders the warning state
75
+ */
76
+ warning?: boolean;
77
+ /** The variant of the notification */
78
+ variant?: NotificationVariant;
79
+ dismissible?: boolean;
80
+ title?: string;
81
+ titleIcon?: object;
82
+ buttonText?: string;
83
+ buttonTo?: RouteLocationRaw;
84
+ buttonHref?: string;
85
+ buttonTarget?: string;
86
+ buttonLoading?: boolean;
87
+ }>(),
88
+ {
89
+ alert: false,
90
+ warning: false,
91
+ variant: 'info',
92
+ dismissible: false,
93
+ title: '',
94
+ titleIcon: undefined,
95
+ buttonText: undefined,
96
+ buttonTo: undefined,
97
+ buttonHref: undefined,
98
+ buttonTarget: undefined,
99
+ buttonLoading: false,
100
+ }
101
+ );
102
+
103
+ defineEmits<{
104
+ 'click:button': [];
105
+ 'dismiss': [];
106
+ }>();
107
+
108
+ defineSlots<{
109
+ title?: () => VNode[];
110
+ default?: () => VNode[];
111
+ }>();
112
+
113
+ const hasButton = computed(() => !!props.buttonText);
114
+
115
+ /**
116
+ * Handle merging the deprecated `alert` and `warning` props
117
+ * with the `variant` prop.
118
+ */
119
+ const computedVariant = computed(() => {
120
+ if (props.alert) {
121
+ return 'alert';
122
+ } else if (props.warning) {
123
+ return 'warning';
124
+ }
125
+ return props.variant;
81
126
  });
82
127
  </script>
83
128
 
@@ -91,6 +136,10 @@ export default defineComponent({
91
136
  position: relative;
92
137
  }
93
138
 
139
+ .c-notification--success {
140
+ background-color: $color-green-100;
141
+ }
142
+
94
143
  .c-notification--alert {
95
144
  background-color: $color-red-100;
96
145
  }
@@ -24,9 +24,9 @@
24
24
  </CMaskedTextField>
25
25
  </template>
26
26
 
27
- <script lang="ts">
28
- import { computed, defineComponent } from 'vue';
29
- import type { PropType } from 'vue';
27
+ <script setup lang="ts">
28
+ import type { VNode } from 'vue';
29
+ import { computed } from 'vue';
30
30
 
31
31
  import CMaskedTextField from '@propelinc/citrus-ui/src/components/CMaskedTextField.vue';
32
32
  import { useFocusableField } from '@propelinc/citrus-ui/src/composables/fields';
@@ -34,36 +34,45 @@ import { useTranslation } from '@propelinc/citrus-ui/src/composables/i18n';
34
34
  import type { Rules } from '@propelinc/citrus-ui/src/composables/validations';
35
35
  import { minLengthRule } from '@propelinc/shared-utils';
36
36
 
37
- export default defineComponent({
38
- name: 'CPhoneField',
39
- components: { CMaskedTextField },
40
- props: {
37
+ withDefaults(
38
+ defineProps<{
41
39
  /** A custom data-test attribute for the input. */
42
- dataTest: { type: String, default: 'phone-field' },
40
+ dataTest?: string;
43
41
  /** A unique id for the input. */
44
- id: { type: String as PropType<string | undefined>, default: undefined },
42
+ id?: string;
45
43
  /** The input's label. */
46
- label: { type: String as PropType<string | null>, default: null },
44
+ label?: string | null;
47
45
  /** The input's placeholder. */
48
- placeholder: { type: String, default: '' },
46
+ placeholder?: string;
49
47
  /** Additional validation rules. */
50
- rules: { type: Array as PropType<Rules<string>>, default: () => [] },
48
+ rules?: Rules<string>;
51
49
  /** The value of the input. */
52
- value: { type: String, default: '' },
53
- },
54
- setup(_, { expose }) {
55
- const { t } = useTranslation();
50
+ value?: string;
51
+ }>(),
52
+ {
53
+ dataTest: 'phone-field',
54
+ id: undefined,
55
+ label: null,
56
+ placeholder: '',
57
+ rules: () => [],
58
+ value: '',
59
+ }
60
+ );
56
61
 
57
- const defaultRules = computed(() => {
58
- const errorMessage = t('Please enter a valid {inputLabel}', {
59
- inputLabel: t('phone number'),
60
- });
61
- return [minLengthRule(10, errorMessage)];
62
- });
62
+ defineSlots<{
63
+ label?: () => VNode[];
64
+ message?: () => VNode[];
65
+ }>();
63
66
 
64
- const { field } = useFocusableField(expose);
67
+ const { t } = useTranslation();
65
68
 
66
- return { defaultRules, field };
67
- },
69
+ const defaultRules = computed(() => {
70
+ const errorMessage = t('Please enter a valid {inputLabel}', {
71
+ inputLabel: t('phone number'),
72
+ });
73
+ return [minLengthRule(10, errorMessage)];
68
74
  });
75
+
76
+ const { field, focus } = useFocusableField();
77
+ defineExpose({ focus });
69
78
  </script>
@@ -22,105 +22,109 @@
22
22
  </span>
23
23
  </template>
24
24
 
25
- <script lang="ts">
26
- import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
27
- import type { PropType } from 'vue';
28
- import { computed, defineComponent, inject } from 'vue';
25
+ <script setup lang="ts">
26
+ import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
27
+ import { FontAwesomeIcon as FontAwesomeIconComponent } from '@fortawesome/vue-fontawesome';
28
+ import type { Component, VNode } from 'vue';
29
+ import { computed, inject } from 'vue';
29
30
 
30
31
  import {
31
32
  ROLE,
32
33
  SELECTED_VALUE,
33
34
  TOGGLE_VALUE,
34
35
  } from '@propelinc/citrus-ui/src/services/injections/pills';
35
- import type { FaPropType } from '@propelinc/citrus-ui/src/types/font-awesome';
36
+
37
+ // FontAwesomeIcon's prop types produce a union too complex for TypeScript to resolve
38
+ const FontAwesomeIcon = FontAwesomeIconComponent as unknown as Component;
36
39
 
37
40
  type ToggleVariant = 'standalone' | 'group' | 'none';
38
41
 
39
- export default defineComponent({
40
- components: { FontAwesomeIcon },
41
- props: {
42
- /** By default, this is a boolean that determines if the pill is selected or
43
- not. If in a pill group, this is a string that identifies this pill. */
44
- value: {
45
- type: [Boolean, String] as PropType<boolean | string | undefined>,
46
- default: undefined,
47
- },
42
+ const props = withDefaults(
43
+ defineProps<{
48
44
  /** The icon to display. */
49
- icon: { type: [String, Array, Object] as FaPropType, default: undefined },
50
- },
51
- emits: ['click', 'input'],
52
- setup(props, { emit }) {
53
- const injectedRole = inject(ROLE, undefined);
54
- const injectedSelectedValue = inject(SELECTED_VALUE, undefined);
55
- const toggleValue = inject(TOGGLE_VALUE, undefined);
56
-
57
- const toggleVariant = computed<ToggleVariant>(() => {
58
- if (toggleValue) {
59
- return 'group';
60
- }
61
-
62
- if (props.value !== undefined) {
63
- return 'standalone';
64
- }
65
-
66
- return 'none';
67
- });
68
-
69
- const isSelected = computed(() => {
70
- if (toggleVariant.value === 'standalone') {
71
- // @ts-expect-error - "Expression produces a union type that is too complex to represent" error
72
- // unclear why this is occurring, ignoring for now
73
- return props.value;
74
- }
75
-
76
- if (injectedSelectedValue?.value) {
77
- return injectedSelectedValue.value === props.value;
78
- }
79
-
80
- return undefined;
81
- });
82
-
83
- const ariaChecked = computed((): 'true' | 'false' | undefined => {
84
- if (isSelected.value === undefined) {
85
- return undefined;
86
- }
87
-
88
- return isSelected.value ? 'true' : 'false';
89
- });
90
-
91
- const role = computed(() => {
92
- if (toggleVariant.value === 'standalone') {
93
- return 'radio';
94
- }
95
-
96
- if (toggleVariant.value === 'group') {
97
- return injectedRole?.value ?? undefined;
98
- }
99
-
100
- return undefined;
101
- });
102
-
103
- const onClick = (): void => {
104
- if (toggleVariant.value === 'standalone') {
105
- emit('input', !props.value);
106
- }
107
-
108
- if (toggleVariant.value === 'group' && toggleValue) {
109
- const nextValue = isSelected.value ? undefined : (props.value as string);
110
- toggleValue(nextValue);
111
- }
112
-
113
- emit('click');
114
- };
115
-
116
- return {
117
- ariaChecked,
118
- isSelected,
119
- onClick,
120
- role,
121
- };
122
- },
45
+ icon?: string | string[] | IconDefinition;
46
+ /**
47
+ * By default, this is a boolean that determines if the pill is selected or
48
+ * not. If in a pill group, this is a string that identifies this pill.
49
+ */
50
+ value?: boolean | string;
51
+ }>(),
52
+ {
53
+ icon: undefined,
54
+ value: undefined,
55
+ }
56
+ );
57
+
58
+ const emit = defineEmits<{
59
+ click: [];
60
+ input: [value: boolean];
61
+ }>();
62
+
63
+ defineSlots<{
64
+ default?: () => VNode[];
65
+ icon?: () => VNode[];
66
+ }>();
67
+
68
+ const injectedRole = inject(ROLE, undefined);
69
+ const injectedSelectedValue = inject(SELECTED_VALUE, undefined);
70
+ const toggleValue = inject(TOGGLE_VALUE, undefined);
71
+
72
+ const toggleVariant = computed<ToggleVariant>(() => {
73
+ if (toggleValue) {
74
+ return 'group';
75
+ }
76
+
77
+ if (props.value !== undefined) {
78
+ return 'standalone';
79
+ }
80
+
81
+ return 'none';
82
+ });
83
+
84
+ const isSelected = computed(() => {
85
+ if (toggleVariant.value === 'standalone') {
86
+ return props.value;
87
+ }
88
+
89
+ if (injectedSelectedValue?.value) {
90
+ return injectedSelectedValue.value === props.value;
91
+ }
92
+
93
+ return undefined;
94
+ });
95
+
96
+ const ariaChecked = computed((): 'true' | 'false' | undefined => {
97
+ if (isSelected.value === undefined) {
98
+ return undefined;
99
+ }
100
+
101
+ return isSelected.value ? 'true' : 'false';
123
102
  });
103
+
104
+ const role = computed(() => {
105
+ if (toggleVariant.value === 'standalone') {
106
+ return 'radio';
107
+ }
108
+
109
+ if (toggleVariant.value === 'group') {
110
+ return injectedRole?.value ?? undefined;
111
+ }
112
+
113
+ return undefined;
114
+ });
115
+
116
+ const onClick = (): void => {
117
+ if (toggleVariant.value === 'standalone') {
118
+ emit('input', !props.value);
119
+ }
120
+
121
+ if (toggleVariant.value === 'group' && toggleValue) {
122
+ const nextValue = isSelected.value ? undefined : (props.value as string);
123
+ toggleValue(nextValue);
124
+ }
125
+
126
+ emit('click');
127
+ };
124
128
  </script>
125
129
 
126
130
  <style lang="scss" scoped>
@@ -15,9 +15,9 @@
15
15
  </div>
16
16
  </template>
17
17
 
18
- <script lang="ts">
19
- import type { PropType } from 'vue';
20
- import { computed, defineComponent, provide, ref } from 'vue';
18
+ <script setup lang="ts">
19
+ import type { VNode } from 'vue';
20
+ import { computed, provide, ref } from 'vue';
21
21
 
22
22
  import CPill from '@propelinc/citrus-ui/src/components/CPill.vue';
23
23
  import {
@@ -33,25 +33,34 @@ interface PillConfig {
33
33
  icon?: FaIcon;
34
34
  }
35
35
 
36
- export default defineComponent({
37
- components: { CPill },
38
- props: {
39
- /** Specifies which pill is selected. */
40
- value: { type: String as PropType<string>, default: () => '' },
36
+ const props = withDefaults(
37
+ defineProps<{
41
38
  /** A list of pills to display. This is overwritten by the default slot. */
42
- options: { type: Array as PropType<PillConfig[]>, default: () => [] },
43
- },
44
- emits: ['input'],
45
- setup(props, { emit }) {
46
- provide(ROLE, ref('radio'));
47
- provide(
48
- SELECTED_VALUE,
49
- computed(() => props.value)
50
- );
51
- provide(TOGGLE_VALUE, (value) => {
52
- emit('input', value);
53
- });
54
- },
39
+ options?: PillConfig[];
40
+ /** Specifies which pill is selected. */
41
+ value?: string;
42
+ }>(),
43
+ {
44
+ options: () => [],
45
+ value: '',
46
+ }
47
+ );
48
+
49
+ const emit = defineEmits<{
50
+ input: [value: string | undefined];
51
+ }>();
52
+
53
+ defineSlots<{
54
+ default?: () => VNode[];
55
+ }>();
56
+
57
+ provide(ROLE, ref('radio'));
58
+ provide(
59
+ SELECTED_VALUE,
60
+ computed(() => props.value)
61
+ );
62
+ provide(TOGGLE_VALUE, (value) => {
63
+ emit('input', value);
55
64
  });
56
65
  </script>
57
66
 
@@ -7,51 +7,60 @@
7
7
  </sl-popup>
8
8
  </template>
9
9
 
10
- <script lang="ts">
11
- import { type SlPopup } from '@shoelace-style/shoelace';
10
+ <script setup lang="ts">
11
+ import type { SlPopup } from '@shoelace-style/shoelace';
12
12
  import '@shoelace-style/shoelace/dist/components/popup/popup.js';
13
- import { defineComponent, onMounted, onUnmounted, ref, watchEffect } from 'vue';
13
+ import type { VNode } from 'vue';
14
+ import { onMounted, onUnmounted, ref, watchEffect } from 'vue';
14
15
 
15
- export default defineComponent({
16
- name: 'CPopup',
17
- props: {
18
- value: { type: Boolean, default: false },
19
- },
20
- emits: ['mouseleave', 'outside-click'],
21
- setup(props, { emit }) {
22
- const popup = ref<SlPopup | null>(null);
16
+ const props = withDefaults(
17
+ defineProps<{
18
+ value?: boolean;
19
+ }>(),
20
+ {
21
+ value: false,
22
+ }
23
+ );
23
24
 
24
- const handleMouseLeave = (): void => {
25
- if (props.value) {
26
- emit('mouseleave');
27
- }
28
- };
25
+ const emit = defineEmits<{
26
+ 'mouseleave': [];
27
+ 'outside-click': [];
28
+ }>();
29
29
 
30
- const handleOutsideClick = ({ target }: MouseEvent): void => {
31
- if (target instanceof HTMLElement && !popup.value?.contains(target)) {
32
- emit('outside-click');
33
- }
34
- };
30
+ defineSlots<{
31
+ default?: () => VNode[];
32
+ content?: () => VNode[];
33
+ }>();
35
34
 
36
- watchEffect(async () => {
37
- if (props.value) {
38
- document.addEventListener('click', handleOutsideClick);
39
- } else {
40
- document.removeEventListener('click', handleOutsideClick);
41
- }
42
- });
35
+ const popup = ref<SlPopup | null>(null);
43
36
 
44
- onMounted(() => {
45
- popup.value?.addEventListener('mouseleave', handleMouseLeave);
46
- });
37
+ const handleMouseLeave = (): void => {
38
+ if (props.value) {
39
+ emit('mouseleave');
40
+ }
41
+ };
47
42
 
48
- onUnmounted(() => {
49
- document.removeEventListener('click', handleOutsideClick);
50
- popup.value?.removeEventListener('mouseleave', handleMouseLeave);
51
- });
43
+ const handleOutsideClick = ({ target }: MouseEvent): void => {
44
+ if (target instanceof HTMLElement && !popup.value?.contains(target)) {
45
+ emit('outside-click');
46
+ }
47
+ };
52
48
 
53
- return { popup };
54
- },
49
+ watchEffect(async () => {
50
+ if (props.value) {
51
+ document.addEventListener('click', handleOutsideClick);
52
+ } else {
53
+ document.removeEventListener('click', handleOutsideClick);
54
+ }
55
+ });
56
+
57
+ onMounted(() => {
58
+ popup.value?.addEventListener('mouseleave', handleMouseLeave);
59
+ });
60
+
61
+ onUnmounted(() => {
62
+ document.removeEventListener('click', handleOutsideClick);
63
+ popup.value?.removeEventListener('mouseleave', handleMouseLeave);
55
64
  });
56
65
  </script>
57
66
 
@@ -9,24 +9,30 @@
9
9
  />
10
10
  </template>
11
11
 
12
- <script lang="ts">
13
- import { defineComponent } from 'vue';
12
+ <script setup lang="ts">
14
13
  import '@shoelace-style/shoelace/dist/components/progress-bar/progress-bar.js';
15
14
 
16
- export default defineComponent({
17
- props: {
15
+ withDefaults(
16
+ defineProps<{
18
17
  /** Customizes screen reader only text alternative, should be translated */
19
- accessibleText: { type: String, default: undefined },
18
+ accessibleText?: string;
20
19
  /** Selector for testing */
21
- dataTest: { type: String, default: 'c-progress-linear' },
20
+ dataTest?: string;
22
21
  /** Renders an indefinite loading state */
23
- indeterminate: { type: Boolean, default: false },
22
+ indeterminate?: boolean;
24
23
  /** Rounds the progress bar */
25
- rounded: { type: Boolean, default: true },
24
+ rounded?: boolean;
26
25
  /** The current progress from 0 to 100 */
27
- value: { type: [Number, String], default: 0 },
28
- },
29
- });
26
+ value?: number | string;
27
+ }>(),
28
+ {
29
+ accessibleText: undefined,
30
+ dataTest: 'c-progress-linear',
31
+ indeterminate: false,
32
+ rounded: true,
33
+ value: 0,
34
+ }
35
+ );
30
36
  </script>
31
37
 
32
38
  <style lang="scss" scoped>