@citizenplane/pimp 8.26.1 → 8.28.1

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 (187) hide show
  1. package/dist/{IconAccompaniedMinorEach-CUq3oXbX.js → IconAccompaniedMinorEach-MkIJAypb.js} +1 -1
  2. package/dist/{IconAccompaniedMinorNone-nZ4eSfTj.js → IconAccompaniedMinorNone-DMb-bSCG.js} +1 -1
  3. package/dist/{IconAccompaniedMinorOne-CDMqq14b.js → IconAccompaniedMinorOne-C9ORHm66.js} +1 -1
  4. package/dist/{IconAddReceipt-DRpGiWBU.js → IconAddReceipt-CeJlKuX2.js} +1 -1
  5. package/dist/{IconAirportTerminal-8k-3lKjb.js → IconAirportTerminal-D3p4CRpN.js} +1 -1
  6. package/dist/{IconArrival-m6HnOVje.js → IconArrival-C3oPAqgQ.js} +1 -1
  7. package/dist/IconBaggageCabinNone-valcCKfd.js +22 -0
  8. package/dist/IconBaggageCheckedNone-oq4yx5cO.js +22 -0
  9. package/dist/IconBaggagePersonalNone-BovIoK0M.js +20 -0
  10. package/dist/{IconBroadcast-B13UworG.js → IconBroadcast-CqdgVQaO.js} +1 -1
  11. package/dist/{IconCabinBag-CNnzHz2B.js → IconCabinBag-CMrtn-s6.js} +1 -1
  12. package/dist/IconCalendar-DmUZ-Du1.js +30 -0
  13. package/dist/IconCalendarDelay-DHaiharm.js +22 -0
  14. package/dist/{IconCheckedBaggage-CkxUDHe9.js → IconCheckedBaggage-OeOjHxe7.js} +1 -1
  15. package/dist/{IconCheckedBaggage20-DEtphLSa.js → IconCheckedBaggage20-CXeWuJgc.js} +1 -1
  16. package/dist/{IconCheckedBaggage30-CmAddx5h.js → IconCheckedBaggage30-Cartaaei.js} +1 -1
  17. package/dist/{IconChild-OReHyUco.js → IconChild-ChjkS7Gd.js} +1 -1
  18. package/dist/{IconContact-D2N23RZ5.js → IconContact-CtOxYQIs.js} +1 -1
  19. package/dist/{IconDeparture-D10LaXRX.js → IconDeparture-DJxClL94.js} +1 -1
  20. package/dist/{IconDistribution-SpPiru9I.js → IconDistribution-BmCLzb9p.js} +1 -1
  21. package/dist/{IconDistributionClosed-Bzqe7nju.js → IconDistributionClosed-BMjqoyt9.js} +1 -1
  22. package/dist/{IconDistributionExclusivePair-CjPM-_R1.js → IconDistributionExclusivePair-D71kgwyk.js} +1 -1
  23. package/dist/{IconDistributionSided-DehjCN0D.js → IconDistributionSided-Du56cPXR.js} +1 -1
  24. package/dist/{IconDistributionSupplySided-DWCyXqd1.js → IconDistributionSupplySided-BY9ACIGQ.js} +1 -1
  25. package/dist/{IconDynamicContent-BvzbgXvW.js → IconDynamicContent-DoYbB86x.js} +1 -1
  26. package/dist/IconEndDate-CVABdl-P.js +22 -0
  27. package/dist/{IconFares-zARDpPNl.js → IconFares-BXnx8WJa.js} +1 -1
  28. package/dist/{IconFaresOutlined-DLFV8nwg.js → IconFaresOutlined-CjJhZUKX.js} +1 -1
  29. package/dist/{IconFemale-Ba4uoI-S.js → IconFemale-D4lMoNKt.js} +1 -1
  30. package/dist/{IconFindConversation-d0pP3wG9.js → IconFindConversation-CYdB5hW8.js} +1 -1
  31. package/dist/{IconFire-CXzWKoMB.js → IconFire-Bh3vQ1A3.js} +1 -1
  32. package/dist/{IconFlight-Cof8M5dO.js → IconFlight-RyDIRwoI.js} +1 -1
  33. package/dist/{IconFlightReturn-CA9iGMcW.js → IconFlightReturn-DN7K5zxX.js} +1 -1
  34. package/dist/IconFlightSchedule-DAX_cnvF.js +28 -0
  35. package/dist/{IconHandHeart-CCLKnMOm.js → IconHandHeart-C5jxr29k.js} +1 -1
  36. package/dist/{IconHistory-DI6WD_3J.js → IconHistory-CuJwcjfY.js} +1 -1
  37. package/dist/{IconHourGlass-BorNLEca.js → IconHourGlass-DyrZPbXz.js} +1 -1
  38. package/dist/{IconIdCard-DhbhBkul.js → IconIdCard-lBDLYRPq.js} +1 -1
  39. package/dist/{IconInfant-D4EztT9g.js → IconInfant-E19ozPuk.js} +1 -1
  40. package/dist/{IconItinerary-Bhj_lgG2.js → IconItinerary-5AEG0f9f.js} +1 -1
  41. package/dist/{IconLeave-BvpY7gdD.js → IconLeave-XuFJRd-0.js} +1 -1
  42. package/dist/{IconMale-RMd_9ZSg.js → IconMale-R2ZgQj0s.js} +1 -1
  43. package/dist/{IconMultiSegments-DROUj0t5.js → IconMultiSegments-DfiqdUEm.js} +1 -1
  44. package/dist/IconNoPassport-h-6DjTcc.js +22 -0
  45. package/dist/{IconNoRefund-yNAZr7uX.js → IconNoRefund-C5R_Zxke.js} +1 -1
  46. package/dist/IconNoSeat-C-XnWQk8.js +23 -0
  47. package/dist/{IconNotion-CpZhGILz.js → IconNotion-pdx45QBU.js} +1 -1
  48. package/dist/{IconOffline-Bf1mw_1N.js → IconOffline-EG6mJ-Fs.js} +1 -1
  49. package/dist/{IconOneWay-6oGoLo57.js → IconOneWay-CX6CckSB.js} +2 -2
  50. package/dist/{IconPaid-B3dvioAR.js → IconPaid-BJhBGPy9.js} +1 -1
  51. package/dist/IconPassport-C6THdLYf.js +37 -0
  52. package/dist/{IconPayout-b3TcXwjA.js → IconPayout-MS-qRRR0.js} +1 -1
  53. package/dist/IconPlug-yYpQdJgj.js +22 -0
  54. package/dist/IconPlugOff-DSGcBog-.js +23 -0
  55. package/dist/{IconReceipt-Dh454941.js → IconReceipt-ChU6nBry.js} +1 -1
  56. package/dist/IconRecurrence-DtwCmoXo.js +22 -0
  57. package/dist/{IconRefund-D-FNjukU.js → IconRefund-D1wQXsZj.js} +1 -1
  58. package/dist/{IconRoundTrip-BqVPrNwg.js → IconRoundTrip-DhPU15r6.js} +1 -1
  59. package/dist/{IconRouteNoStop-CZ_QeOIY.js → IconRouteNoStop-C5b0NI9V.js} +1 -1
  60. package/dist/{IconRouteOneStop-DGpLAQmQ.js → IconRouteOneStop-CDL4AJoN.js} +1 -1
  61. package/dist/IconScheduleChange-CasvbB9p.js +22 -0
  62. package/dist/{IconSeatEmpty-BwyVwYQZ.js → IconSeatEmpty-CUDMQzqk.js} +1 -1
  63. package/dist/{IconSeatSold-B_SNoTs-.js → IconSeatSold-mwtkmlhT.js} +1 -1
  64. package/dist/{IconSeatTotal-DUEF7k6I.js → IconSeatTotal-BPegCOjA.js} +1 -1
  65. package/dist/IconStartDate-DoPJpEly.js +22 -0
  66. package/dist/{IconTemplate-D1ACYaHI.js → IconTemplate-CQH8r3U7.js} +1 -1
  67. package/dist/{IconTicket-5Z4b83BP.js → IconTicket-mONYGHBg.js} +1 -1
  68. package/dist/{IconTimer-DbcddAPo.js → IconTimer-BxR1ymxu.js} +1 -1
  69. package/dist/{IconTrafficControl-CEzhRpZt.js → IconTrafficControl-AcQHu-Dm.js} +1 -1
  70. package/dist/{index-DbgX3-2I.js → index-CjeXy6n3.js} +17600 -18506
  71. package/dist/pimp.es.js +1 -1
  72. package/dist/pimp.umd.js +23 -23
  73. package/dist/style.css +1 -1
  74. package/package.json +2 -1
  75. package/src/components/{core/BaseInputLabel.vue → BaseInputLabel.vue} +9 -15
  76. package/src/components/{core/BaseSelectClearButton.vue → BaseSelectClearButton.vue} +2 -2
  77. package/src/components/{atomic-elements/CpAirlineLogo.vue → CpAirlineLogo.vue} +9 -10
  78. package/src/components/{feedback-indicators/CpAlert.vue → CpAlert.vue} +16 -27
  79. package/src/components/{atomic-elements/CpBadge.vue → CpBadge.vue} +27 -44
  80. package/src/components/{buttons/CpButton.vue → CpButton.vue} +63 -104
  81. package/src/components/{date-pickers/CpCalendar.vue → CpCalendar.vue} +157 -156
  82. package/src/components/{toggles/CpCheckbox.vue → CpCheckbox.vue} +45 -54
  83. package/src/components/{date-pickers/CpDate.vue → CpDate.vue} +202 -212
  84. package/src/components/CpDatepicker.vue +203 -0
  85. package/src/components/{atomic-elements/CpDialog.vue → CpDialog.vue} +14 -9
  86. package/src/components/{typography/CpHeading.vue → CpHeading.vue} +11 -31
  87. package/src/components/{visual/CpIcon.vue → CpIcon.vue} +2 -1
  88. package/src/components/{inputs/CpInput.vue → CpInput.vue} +41 -58
  89. package/src/components/{feedback-indicators/CpLoader.vue → CpLoader.vue} +7 -8
  90. package/src/components/{selects/CpMultiselect.vue → CpMultiselect.vue} +60 -91
  91. package/src/components/{atomic-elements/CpPartnerBadge.vue → CpPartnerBadge.vue} +12 -20
  92. package/src/components/{toggles/CpRadio.vue → CpRadio.vue} +47 -58
  93. package/src/components/{selects/CpSelect.vue → CpSelect.vue} +74 -94
  94. package/src/components/{selects/CpSelectMenu.vue → CpSelectMenu.vue} +94 -96
  95. package/src/components/{toggles/CpSwitch.vue → CpSwitch.vue} +51 -67
  96. package/src/components/{lists-and-table/CpTable.vue → CpTable.vue} +159 -113
  97. package/src/components/{lists-and-table/CpTableEmptyState.vue → CpTableEmptyState.vue} +5 -8
  98. package/src/components/{inputs/CpTextarea.vue → CpTextarea.vue} +32 -52
  99. package/src/components/CpToaster.vue +377 -0
  100. package/src/components/{atomic-elements/CpTooltip.vue → CpTooltip.vue} +12 -11
  101. package/src/components/TransitionExpand.vue +70 -0
  102. package/src/components/icons/IconBaggageCabinNone.vue +24 -0
  103. package/src/components/icons/IconBaggageCheckedNone.vue +25 -0
  104. package/src/components/icons/IconBaggagePersonalNone.vue +33 -0
  105. package/src/components/icons/IconCalendar.vue +17 -0
  106. package/src/components/icons/IconCalendarDelay.vue +21 -0
  107. package/src/components/icons/IconEndDate.vue +19 -0
  108. package/src/components/icons/IconFlightSchedule.vue +23 -0
  109. package/src/components/icons/IconNoPassport.vue +23 -24
  110. package/src/components/icons/IconNoSeat.vue +18 -0
  111. package/src/components/icons/IconOneWay.vue +1 -1
  112. package/src/components/icons/IconPassport.vue +15 -22
  113. package/src/components/icons/IconPlug.vue +17 -0
  114. package/src/components/icons/IconPlugOff.vue +18 -0
  115. package/src/components/icons/IconRecurrence.vue +17 -8
  116. package/src/components/icons/IconScheduleChange.vue +17 -26
  117. package/src/components/icons/IconStartDate.vue +19 -0
  118. package/src/components/index.ts +43 -55
  119. package/src/constants/{src/CpCustomIcons.ts → CpCustomIcons.ts} +13 -2
  120. package/src/constants/CpTableConfig.ts +12 -0
  121. package/src/constants/Heading.ts +8 -0
  122. package/src/{utils/constants/src/Intent.js → constants/Intent.ts} +1 -1
  123. package/src/constants/PartnerTypes.ts +6 -0
  124. package/src/constants/Position.ts +10 -0
  125. package/src/constants/Sizes.ts +5 -0
  126. package/src/constants/colors/Colors.ts +10 -0
  127. package/src/constants/colors/ToggleColors.ts +6 -0
  128. package/src/constants/index.ts +10 -5
  129. package/src/directives/ClickOutside.ts +17 -0
  130. package/src/directives/{ResizeSelect.js → ResizeSelect.ts} +3 -3
  131. package/src/helpers/{dom.js → dom.ts} +13 -9
  132. package/src/helpers/{index.js → index.ts} +13 -3
  133. package/src/helpers/object.ts +9 -0
  134. package/src/helpers/string/src/camelize.ts +6 -0
  135. package/src/helpers/string/src/{decamelize.js → decamelize.ts} +1 -1
  136. package/src/libs/CoreDatepicker.vue +4 -4
  137. package/src/plugins/toaster.ts +71 -0
  138. package/src/stories/BaseInputLabel.stories.ts +2 -1
  139. package/src/stories/CpAirlineLogo.stories.ts +1 -1
  140. package/src/stories/CpAlert.stories.ts +2 -1
  141. package/src/stories/CpBadge.stories.ts +1 -1
  142. package/src/stories/CpButton.stories.ts +1 -1
  143. package/src/stories/CpCheckbox.stories.ts +4 -2
  144. package/src/stories/CpDate.stories.ts +4 -2
  145. package/src/stories/CpDatepicker.stories.ts +4 -2
  146. package/src/stories/CpDialog.stories.ts +3 -2
  147. package/src/stories/CpHeading.stories.ts +2 -1
  148. package/src/stories/CpIcon.stories.ts +3 -1
  149. package/src/stories/CpInput.stories.ts +4 -2
  150. package/src/stories/CpLoader.stories.ts +2 -1
  151. package/src/stories/CpMultiselect.stories.ts +3 -2
  152. package/src/stories/CpPartnerBadge.stories.ts +2 -2
  153. package/src/stories/CpRadio.stories.ts +4 -2
  154. package/src/stories/CpSelect.stories.ts +4 -2
  155. package/src/stories/CpSelectMenu.stories.ts +4 -2
  156. package/src/stories/CpSwitch.stories.ts +4 -2
  157. package/src/stories/CpTable.stories.ts +9 -2
  158. package/src/stories/CpTableEmptyState.stories.ts +2 -1
  159. package/src/stories/CpTextarea.stories.ts +4 -2
  160. package/src/stories/CpToaster.stories.ts +2 -1
  161. package/src/stories/CpTooltip.stories.ts +2 -1
  162. package/src/stories/TransitionExpand.stories.ts +4 -2
  163. package/src/types/luxon.d.ts +1 -0
  164. package/src/vendors/ff-polyfill.ts +38 -0
  165. package/vitest.workspace.js +1 -3
  166. package/dist/IconNoPassport-DBmaQH_g.js +0 -18
  167. package/dist/IconPassport-5SwUf6_R.js +0 -20
  168. package/dist/IconRecurrence-CXVkBJ3i.js +0 -24
  169. package/dist/IconScheduleChange-CEIGEhU4.js +0 -19
  170. package/src/components/date-pickers/CpDatepicker.vue +0 -229
  171. package/src/components/feedback-indicators/CpToaster.vue +0 -372
  172. package/src/components/helpers-utilities/TransitionExpand.vue +0 -72
  173. package/src/constants/src/CpTableConfig.ts +0 -14
  174. package/src/constants/src/Position.ts +0 -10
  175. package/src/constants/src/colors/Colors.ts +0 -10
  176. package/src/constants/src/colors/ToggleColors.ts +0 -6
  177. package/src/directives/ClickOutside.js +0 -13
  178. package/src/helpers/object.js +0 -9
  179. package/src/helpers/string/src/camelize.js +0 -6
  180. package/src/plugins/toaster.js +0 -61
  181. package/src/utils/constants/index.js +0 -3
  182. package/src/utils/constants/src/PartnerTypes.js +0 -6
  183. package/src/utils/constants/src/Sizes.js +0 -5
  184. package/src/vendors/ff-polyfill.js +0 -36
  185. /package/src/components/{atomic-elements/CpDialogWrapper.vue → CpDialogWrapper.vue} +0 -0
  186. /package/src/components/{logo/Pimp.vue → Pimp.vue} +0 -0
  187. /package/src/helpers/string/{index.js → index.ts} +0 -0
@@ -8,7 +8,6 @@
8
8
  class="cpButton"
9
9
  role="button"
10
10
  tabindex="0"
11
- @click="handleClick"
12
11
  >
13
12
  <span class="cpButton__body">
14
13
  <span v-if="isLoading" class="cpButton__loader"><cp-loader color="#B2B2BD" /></span>
@@ -23,120 +22,80 @@
23
22
  </component>
24
23
  </template>
25
24
 
26
- <script>
27
- import { capitalizeFirstLetter } from '@/helpers'
25
+ <script setup lang="ts">
26
+ import { computed, useSlots } from 'vue'
27
+
28
+ import CpLoader from '@/components/CpLoader.vue'
29
+
28
30
  import { Colors } from '@/constants'
31
+ import { capitalizeFirstLetter } from '@/helpers'
29
32
 
30
- import CpLoader from '@/components/feedback-indicators/CpLoader.vue'
33
+ enum ButtonAppearances {
34
+ DEFAULT = 'default',
35
+ PRIMARY = 'primary',
36
+ MINIMAL = 'minimal',
37
+ }
31
38
 
32
- const ButtonAppearances = {
33
- default: 'default',
34
- primary: 'primary',
35
- minimal: 'minimal',
39
+ enum ButtonTags {
40
+ BUTTON = 'button',
41
+ A = 'a',
36
42
  }
37
43
 
38
- const ButtonTags = {
39
- button: 'button',
40
- a: 'a',
44
+ enum ButtonTypes {
45
+ BUTTON = 'button',
46
+ SUBMIT = 'submit',
47
+ RESET = 'reset',
41
48
  }
42
49
 
43
- const ButtonTypes = {
44
- button: 'button',
45
- submit: 'submit',
46
- reset: 'reset',
50
+ interface Props {
51
+ appearance?: ButtonAppearances
52
+ color?: Colors
53
+ disabled?: boolean
54
+ isLarge?: boolean
55
+ isLoading?: boolean
56
+ isSquare?: boolean
57
+ tag?: ButtonTags
58
+ type?: ButtonTypes
47
59
  }
48
60
 
49
- export default {
50
- components: {
51
- CpLoader,
52
- },
53
- props: {
54
- appearance: {
55
- type: String,
56
- default: ButtonAppearances.default,
57
- validator: (value) => {
58
- return {}.propertyIsEnumerable.call(ButtonAppearances, value)
59
- },
60
- },
61
- color: {
62
- type: String,
63
- default: '',
64
- validator: (value) => Object.values(Colors).includes(value) || value === '',
65
- },
66
- disabled: {
67
- type: Boolean,
68
- default: false,
69
- },
70
- tag: {
71
- type: String,
72
- default: ButtonTags.button,
73
- validator: (value) => {
74
- return {}.propertyIsEnumerable.call(ButtonTags, value)
75
- },
76
- },
77
- type: {
78
- type: String,
79
- default: ButtonTypes.button,
80
- validator: (value) => {
81
- return {}.propertyIsEnumerable.call(ButtonTypes, value)
82
- },
83
- },
84
- isLoading: {
85
- type: Boolean,
86
- default: false,
87
- },
88
- isSquare: {
89
- type: Boolean,
90
- default: false,
91
- },
92
- isLarge: {
93
- type: Boolean,
94
- default: false,
95
- },
96
- },
97
- emits: ['click'],
98
- computed: {
99
- capitalizedAppearance() {
100
- return capitalizeFirstLetter(this.appearance)
101
- },
102
- capitalizedColor() {
103
- return capitalizeFirstLetter(this.color)
104
- },
105
- dynamicClasses() {
106
- return [
107
- `cpButton--is${this.capitalizedAppearance}`,
108
- this.capitalizedColor && `cpButton--is${this.capitalizedColor}`,
109
- {
110
- 'cpButton--isDisabled': this.isButtonDisabled,
111
- 'cpButton--isIcon': !this.hasLabel,
112
- 'cpButton--isLoading': this.isLoading,
113
- 'cpButton--isSquare': this.isSquare,
114
- 'cpButton--isLarge': this.isLarge,
115
- },
116
- ]
117
- },
118
- hasLabel() {
119
- return !!this.$slots['default']
120
- },
121
- hasIconBefore() {
122
- return !!this.$slots['icon-before']
123
- },
124
- hasIconAfter() {
125
- return !!this.$slots['icon-after']
126
- },
127
- isButtonDisabled() {
128
- if (this.disabled || this.isLoading) return true
129
- return null
130
- },
131
- },
132
- methods: {
133
- handleClick($event) {
134
- if (this.isButtonDisabled) return
61
+ const props = withDefaults(defineProps<Props>(), {
62
+ appearance: ButtonAppearances.DEFAULT,
63
+ color: undefined,
64
+ disabled: false,
65
+ tag: ButtonTags.BUTTON,
66
+ type: ButtonTypes.BUTTON,
67
+ isLoading: false,
68
+ isSquare: false,
69
+ isLarge: false,
70
+ })
71
+
72
+ const slots = useSlots()
135
73
 
136
- this.$emit('click', $event)
74
+ const capitalizedAppearance = computed(() => capitalizeFirstLetter(props.appearance))
75
+
76
+ const capitalizedColor = computed(() => capitalizeFirstLetter(props.color))
77
+
78
+ const hasLabel = computed(() => !!slots.default)
79
+
80
+ const hasIconBefore = computed(() => !!slots['icon-before'])
81
+
82
+ const hasIconAfter = computed(() => !!slots['icon-after'])
83
+
84
+ const isButtonDisabled = computed(() => props.disabled || props.isLoading)
85
+
86
+ const dynamicClasses = computed(() => {
87
+ return [
88
+ `cpButton--is${capitalizedAppearance.value}`,
89
+ {
90
+ [`cpButton--is${capitalizedColor.value}`]: !!capitalizedColor.value,
91
+ 'cpButton--isDisabled': isButtonDisabled.value,
92
+ 'cpButton--isIcon': !hasLabel.value,
93
+ 'cpButton--isLoading': props.isLoading,
94
+ 'cpButton--isSquare': props.isSquare,
95
+ 'cpButton--isLarge': props.isLarge,
137
96
  },
138
- },
139
- }
97
+ ]
98
+ })
140
99
  </script>
141
100
 
142
101
  <style lang="scss">
@@ -23,9 +23,9 @@
23
23
  :locale="locale"
24
24
  class="cpCalendar__datepicker"
25
25
  :class="dynamicClasses"
26
- @date-one-selected="(date) => selectDate('dateOne', date)"
27
- @date-two-selected="(date) => selectDate('dateTwo', date)"
28
- @is-inline="(value) => (isInline = value)"
26
+ @date-one-selected="onDateSelected('dateOne', $event)"
27
+ @date-two-selected="onDateSelected('dateTwo', $event)"
28
+ @is-inline="onIsInline"
29
29
  @opened="() => (isDisabled = true)"
30
30
  @closed="() => (isDisabled = false)"
31
31
  >
@@ -86,172 +86,173 @@
86
86
  </div>
87
87
  </template>
88
88
 
89
- <script>
89
+ <script setup lang="ts">
90
90
  import { DateTime, Info, Interval } from 'luxon'
91
+ import { ref, computed, watch } from 'vue'
91
92
 
92
- import CpButton from '@/components/buttons/CpButton.vue'
93
- import CpInput from '@/components/inputs/CpInput.vue'
94
- import CpIcon from '@/components/visual/CpIcon.vue'
95
- import CoreDatepicker from '@/libs/CoreDatepicker.vue'
93
+ import CpButton from '@/components/CpButton.vue'
94
+ import CpIcon from '@/components/CpIcon.vue'
95
+ import CpInput from '@/components/CpInput.vue'
96
96
 
97
97
  import { randomString, formatDates } from '@/helpers'
98
+ import CoreDatepicker from '@/libs/CoreDatepicker.vue'
98
99
 
99
- export default {
100
- name: 'CpCalendar',
101
- components: {
102
- CoreDatepicker,
103
- CpInput,
104
- CpIcon,
105
- CpButton,
106
- },
107
- props: {
108
- triggerElementId: {
109
- type: String,
110
- default: 'calendar-trigger-' + randomString(5),
111
- },
112
- closeAfterSelect: {
113
- type: Boolean,
114
- default: false,
115
- },
116
- label: {
117
- type: String,
118
- default: '',
119
- },
120
- isError: {
121
- type: Boolean,
122
- default: false,
123
- },
124
- errorMessage: {
125
- type: String,
126
- default: '',
127
- },
128
- initDateOne: {
129
- type: String,
130
- default: '',
131
- validator: (value) => {
132
- return value === '' || value.length === 10
133
- },
134
- },
135
- locale: {
136
- type: String,
137
- default: () => {
138
- return navigator.language
139
- },
140
- },
141
- },
142
- emits: ['dates'],
143
- data() {
144
- return {
145
- humanFormat: 'EEE DD',
146
- dateOne: this.initDateOne || '',
147
- dateTwo: '',
148
- days: Info.weekdays('short', { locale: 'en-EN' }).map((day, value) => {
149
- return { day, selected: false, value }
150
- }),
151
- recurenceDates: [],
152
- mode: 'single',
153
- triggerCalendar: false,
154
- isInline: false,
155
- isDisabled: null,
156
- }
157
- },
158
- computed: {
159
- selectedDays() {
160
- return this.days.filter((day) => day.selected === true).map((day) => day.value + 1)
161
- },
162
- summary() {
163
- const start = DateTime.fromISO(this.dateOne).toFormat(this.humanFormat)
164
- const end = DateTime.fromISO(this.dateTwo).toFormat(this.humanFormat)
165
-
166
- return {
167
- start,
168
- end,
169
- }
170
- },
171
- isDaysDisplayed() {
172
- return this.mode === 'range'
173
- },
174
- dynamicClasses() {
175
- return { 'cpCalendar__datepicker--isInline': this.isInline }
176
- },
177
- },
178
- watch: {
179
- isInline(value) {
180
- if (value) this.removeRecurency()
181
- },
182
- },
183
- methods: {
184
- done() {
185
- this.emitToParent()
186
- this.closeCalendar()
187
- },
188
- closeCalendar() {
189
- this.triggerCalendar = !this.triggerCalendar
190
- },
191
- humanDateFormat(dateOne, dateTwo) {
192
- return formatDates({ dateOne, dateTwo, format: this.humanFormat, locale: this.locale })
193
- },
194
- toggleDay(index) {
195
- this.days[index].selected = !this.days[index].selected
196
- this.recurenceDates = this.generateDates(this.dateOne, this.dateTwo, this.selectedDays)
197
- this.emitToParent()
198
- },
199
- addRecurency() {
200
- const dt = DateTime.local()
201
- this.mode = 'range'
202
-
203
- if (!this.dateOne) this.dateOne = dt.plus({ days: 1 }).toISODate()
204
- if (!this.dateTwo) this.dateTwo = DateTime.fromISO(this.dateOne).plus({ days: 7 }).toISODate()
205
- },
206
- removeRecurency() {
207
- this.mode = 'single'
208
- this.recurenceDates = []
209
- this.dateTwo = ''
210
- this.days = Info.weekdays('short', { locale: 'en-EN' }).map((day, value) => {
211
- return { day, selected: false, value }
212
- })
213
- },
214
- emitToParent() {
215
- let dates = [this.dateOne]
216
- if (this.isDaysDisplayed) {
217
- dates = this.recurenceDates.length ? this.datesToStringArray(this.recurenceDates) : []
218
- }
219
- return this.$emit('dates', dates)
220
- },
221
- generateDates(startDate, endDate, selectedWeekDaysIndex) {
222
- const isoStartDate = DateTime.fromISO(startDate)
223
- const isoEndDate = DateTime.fromISO(endDate)
100
+ interface DayOption {
101
+ day: string
102
+ selected: boolean
103
+ value: number
104
+ }
224
105
 
225
- let selectedDaysFinalList = []
106
+ interface Props {
107
+ closeAfterSelect?: boolean
108
+ errorMessage?: string
109
+ initDateOne?: string
110
+ isError?: boolean
111
+ label?: string
112
+ locale?: string
113
+ triggerElementId?: string
114
+ }
226
115
 
227
- const daysIntervalBetweenTwoDates = Interval.fromDateTimes(isoStartDate.startOf('day'), isoEndDate.endOf('day'))
228
- .splitBy({ days: 1 })
229
- .map((day) => day.start)
116
+ interface Emits {
117
+ (e: 'dates', dates: string[]): void
118
+ }
230
119
 
231
- daysIntervalBetweenTwoDates.forEach((day) => {
232
- const dayOfWeekAsNumber = Number(DateTime.fromISO(day).toFormat('c'))
120
+ const props = withDefaults(defineProps<Props>(), {
121
+ triggerElementId: () => `calendar-trigger-${randomString()}`,
122
+ closeAfterSelect: false,
123
+ label: '',
124
+ isError: false,
125
+ errorMessage: '',
126
+ initDateOne: '',
127
+ locale: () => navigator.language,
128
+ })
129
+
130
+ const emit = defineEmits<Emits>()
131
+
132
+ const humanFormat = 'EEE DD'
133
+ const dateOne = ref(props.initDateOne || '')
134
+ const dateTwo = ref('')
135
+ const days = ref<DayOption[]>(
136
+ Info.weekdays('short', { locale: 'en-EN' }).map((day: string, value: number) => ({ day, selected: false, value })),
137
+ )
138
+ const recurenceDates = ref<string[]>([])
139
+ const mode = ref<'single' | 'range'>('single')
140
+ const triggerCalendar = ref(false)
141
+ const isInline = ref(false)
142
+ const isDisabled = ref(false)
143
+
144
+ const selectedDays = computed(() => {
145
+ return days.value.filter((day) => day.selected === true).map((day) => day.value + 1)
146
+ })
147
+
148
+ const summary = computed(() => {
149
+ const start = DateTime.fromISO(dateOne.value).toFormat(humanFormat)
150
+ const end = DateTime.fromISO(dateTwo.value).toFormat(humanFormat)
151
+
152
+ return {
153
+ start,
154
+ end,
155
+ }
156
+ })
233
157
 
234
- if (selectedWeekDaysIndex.includes(dayOfWeekAsNumber)) {
235
- selectedDaysFinalList.push(day)
236
- }
237
- })
158
+ const isDaysDisplayed = computed(() => {
159
+ return mode.value === 'range'
160
+ })
238
161
 
239
- return selectedDaysFinalList
240
- },
241
- selectDate(key, value) {
242
- this[key] = value
162
+ const dynamicClasses = computed(() => {
163
+ return { 'cpCalendar__datepicker--isInline': isInline.value }
164
+ })
243
165
 
244
- if (this.isDaysDisplayed) {
245
- this.recurenceDates = this.generateDates(this.dateOne, this.dateTwo, this.selectedDays)
246
- }
166
+ const done = (): void => {
167
+ emitToParent()
168
+ closeCalendar()
169
+ }
170
+
171
+ const onDateSelected = (dateSelector: 'dateOne' | 'dateTwo', date: string) => selectDate(dateSelector, date)
172
+
173
+ const onIsInline = (value: boolean) => (isInline.value = value)
247
174
 
248
- return this.emitToParent()
249
- },
250
- datesToStringArray(dates) {
251
- return dates.map((date) => date.toISODate())
252
- },
253
- },
175
+ const closeCalendar = (): void => {
176
+ triggerCalendar.value = !triggerCalendar.value
254
177
  }
178
+
179
+ const humanDateFormat = (dateOne: string, dateTwo: string): string => {
180
+ return formatDates({ dateOne, dateTwo, format: humanFormat, locale: props.locale })
181
+ }
182
+
183
+ const toggleDay = (index: number): void => {
184
+ days.value[index].selected = !days.value[index].selected
185
+ recurenceDates.value = generateDates(dateOne.value, dateTwo.value, selectedDays.value)
186
+ emitToParent()
187
+ }
188
+
189
+ const addRecurency = (): void => {
190
+ const dt = DateTime.local()
191
+ mode.value = 'range'
192
+
193
+ if (!dateOne.value) dateOne.value = dt.plus({ days: 1 }).toISODate()
194
+ if (!dateTwo.value) dateTwo.value = DateTime.fromISO(dateOne.value).plus({ days: 7 }).toISODate()
195
+ }
196
+
197
+ const removeRecurency = (): void => {
198
+ mode.value = 'single'
199
+ recurenceDates.value = []
200
+ dateTwo.value = ''
201
+ days.value = Info.weekdays('short', { locale: 'en-EN' }).map((day: string, value: number) => {
202
+ return { day, selected: false, value }
203
+ })
204
+ }
205
+
206
+ const emitToParent = (): void => {
207
+ let dates = [dateOne.value]
208
+ if (isDaysDisplayed.value) {
209
+ dates = recurenceDates.value.length ? datesToStringArray(recurenceDates.value) : []
210
+ }
211
+ return emit('dates', dates)
212
+ }
213
+
214
+ const generateDates = (startDate: string, endDate: string, selectedWeekDaysIndex: number[]): string[] => {
215
+ const isoStartDate = DateTime.fromISO(startDate)
216
+ const isoEndDate = DateTime.fromISO(endDate)
217
+
218
+ let selectedDaysFinalList: string[] = []
219
+
220
+ const daysIntervalBetweenTwoDates = Interval.fromDateTimes(isoStartDate.startOf('day'), isoEndDate.endOf('day'))
221
+ .splitBy({ days: 1 })
222
+ .map((day: typeof Interval) => day.start)
223
+
224
+ daysIntervalBetweenTwoDates.forEach((day: string) => {
225
+ const dayOfWeekAsNumber = Number(DateTime.fromISO(day).toFormat('c'))
226
+
227
+ if (selectedWeekDaysIndex.includes(dayOfWeekAsNumber)) {
228
+ selectedDaysFinalList.push(day)
229
+ }
230
+ })
231
+
232
+ return selectedDaysFinalList
233
+ }
234
+
235
+ const selectDate = (key: 'dateOne' | 'dateTwo', value: string): void => {
236
+ if (key === 'dateOne') {
237
+ dateOne.value = value
238
+ } else {
239
+ dateTwo.value = value
240
+ }
241
+
242
+ if (isDaysDisplayed.value) {
243
+ recurenceDates.value = generateDates(dateOne.value, dateTwo.value, selectedDays.value)
244
+ }
245
+
246
+ return emitToParent()
247
+ }
248
+
249
+ const datesToStringArray = (dates: string[]): string[] => {
250
+ return dates.map((date) => DateTime.fromISO(date).toISODate() || '')
251
+ }
252
+
253
+ watch(isInline, (value) => {
254
+ if (value) removeRecurency()
255
+ })
255
256
  </script>
256
257
 
257
258
  <style lang="scss">
@@ -26,63 +26,36 @@
26
26
  </label>
27
27
  </template>
28
28
 
29
- <script setup>
29
+ <script setup lang="ts">
30
30
  import { computed, ref, onMounted, useSlots } from 'vue'
31
31
 
32
- import { capitalizeFirstLetter, randomString } from '@/helpers'
33
32
  import { ToggleColors } from '@/constants'
33
+ import { capitalizeFirstLetter, randomString } from '@/helpers'
34
34
 
35
- const props = defineProps({
36
- modelValue: {
37
- type: [Array, Boolean],
38
- default: () => [],
39
- required: false,
40
- },
41
- checkboxValue: {
42
- type: [String, Number],
43
- default: '',
44
- required: false,
45
- },
46
- checkboxLabel: {
47
- type: String,
48
- required: false,
49
- default: '',
50
- },
51
- isDisabled: {
52
- type: Boolean,
53
- default: false,
54
- required: false,
55
- },
56
- groupName: {
57
- type: String,
58
- default: '',
59
- required: false,
60
- },
61
- capitalizeLabel: {
62
- type: Boolean,
63
- default: true,
64
- },
65
- color: {
66
- type: String,
67
- required: false,
68
- default: ToggleColors.BLUE,
69
- validator: (value) => Object.values(ToggleColors).includes(value),
70
- },
71
- reverseLabel: {
72
- type: Boolean,
73
- required: false,
74
- default: false,
75
- },
76
- autofocus: {
77
- type: Boolean,
78
- required: false,
79
- default: false,
80
- },
81
- helper: {
82
- type: String,
83
- required: false,
84
- default: '',
85
- },
35
+ interface Props {
36
+ autofocus?: boolean
37
+ capitalizeLabel?: boolean
38
+ checkboxLabel?: string
39
+ checkboxValue?: string | number
40
+ color?: string
41
+ groupName?: string
42
+ helper?: string
43
+ isDisabled?: boolean
44
+ modelValue?: boolean | unknown[]
45
+ reverseLabel?: boolean
46
+ }
47
+
48
+ const props = withDefaults(defineProps<Props>(), {
49
+ modelValue: false,
50
+ checkboxValue: '',
51
+ checkboxLabel: '',
52
+ isDisabled: false,
53
+ groupName: '',
54
+ capitalizeLabel: true,
55
+ color: ToggleColors.BLUE,
56
+ reverseLabel: false,
57
+ autofocus: false,
58
+ helper: '',
86
59
  })
87
60
 
88
61
  const emit = defineEmits(['update:modelValue'])
@@ -92,6 +65,9 @@ const checkboxUniqueId = ref('')
92
65
 
93
66
  const isChecked = computed({
94
67
  get() {
68
+ if (Array.isArray(props.modelValue)) {
69
+ return props.modelValue.includes(props.checkboxValue)
70
+ }
95
71
  return props.modelValue
96
72
  },
97
73
  set(newValue) {
@@ -123,7 +99,22 @@ const labelComputedClasses = computed(() => {
123
99
 
124
100
  onMounted(() => (checkboxUniqueId.value = randomString()))
125
101
 
126
- const onChange = () => emit('update:modelValue', checkedProxy.value)
102
+ const onChange = (value: string | number) => {
103
+ if (Array.isArray(props.modelValue)) {
104
+ const currentValues = [...props.modelValue]
105
+ const valueIndex = currentValues.indexOf(value)
106
+
107
+ if (valueIndex > -1) {
108
+ currentValues.splice(valueIndex, 1)
109
+ } else {
110
+ currentValues.push(value)
111
+ }
112
+
113
+ emit('update:modelValue', currentValues)
114
+ } else {
115
+ emit('update:modelValue', !props.modelValue)
116
+ }
117
+ }
127
118
  </script>
128
119
 
129
120
  <style lang="scss">