classcard-ui 0.2.534 → 0.2.537

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 (175) hide show
  1. package/README.md +24 -24
  2. package/dist/classcard-ui.common.js +89 -69
  3. package/dist/classcard-ui.common.js.map +1 -1
  4. package/dist/classcard-ui.umd.js +89 -69
  5. package/dist/classcard-ui.umd.js.map +1 -1
  6. package/dist/classcard-ui.umd.min.js +1 -1
  7. package/dist/classcard-ui.umd.min.js.map +1 -1
  8. package/package.json +81 -81
  9. package/src/App.vue +16 -16
  10. package/src/components/CAlerts/CAlerts.vue +70 -70
  11. package/src/components/CAlerts/index.js +2 -2
  12. package/src/components/CAnchorTabs/CAnchorTabs.vue +104 -104
  13. package/src/components/CAnchorTabs/index.js +2 -2
  14. package/src/components/CAnchorTag/CAnchorTag.vue +62 -62
  15. package/src/components/CAnchorTag/index.js +2 -2
  16. package/src/components/CAvatar/CAvatar.vue +89 -89
  17. package/src/components/CAvatar/index.js +2 -2
  18. package/src/components/CAvatarGroup/CAvatarGroup.vue +145 -145
  19. package/src/components/CAvatarGroup/index.js +2 -2
  20. package/src/components/CBasicTable/CBasicTable.vue +184 -184
  21. package/src/components/CBasicTable/index.js +2 -2
  22. package/src/components/CBreadcrumbs/CBreadcrumbs.vue +38 -38
  23. package/src/components/CBreadcrumbs/index.js +2 -2
  24. package/src/components/CButton/CButton.vue +150 -150
  25. package/src/components/CButton/index.js +2 -2
  26. package/src/components/CButtonGroup/CButtonGroup.vue +116 -116
  27. package/src/components/CButtonGroup/index.js +2 -2
  28. package/src/components/CButtonIcon/CButtonIcon.vue +91 -91
  29. package/src/components/CButtonIcon/index.js +2 -2
  30. package/src/components/CButtonLink/CButtonLink.vue +39 -39
  31. package/src/components/CButtonLink/index.js +2 -2
  32. package/src/components/CButtonSelect/CButtonSelect.vue +103 -103
  33. package/src/components/CButtonSelect/index.js +2 -2
  34. package/src/components/CButtonWithDropdown/CButtonWithDropdown.vue +168 -168
  35. package/src/components/CButtonWithDropdown/index.js +2 -2
  36. package/src/components/CCalendar/CCalendar.vue +373 -369
  37. package/src/components/CCalendar/index.js +3 -3
  38. package/src/components/CCard/CCard.vue +49 -49
  39. package/src/components/CCard/index.js +2 -2
  40. package/src/components/CCheckbox/CCheckbox.vue +70 -70
  41. package/src/components/CCheckbox/index.js +2 -2
  42. package/src/components/CCollapsibleSection/CCollapsibleSection.vue +99 -99
  43. package/src/components/CCollapsibleSection/index.js +2 -2
  44. package/src/components/CColorDots/CColorDots.vue +35 -35
  45. package/src/components/CColorDots/index.js +3 -3
  46. package/src/components/CConfirmActionModal/CConfirmActionModal.vue +120 -120
  47. package/src/components/CConfirmActionModal/index.js +3 -3
  48. package/src/components/CDatepicker/CDatepicker.vue +134 -134
  49. package/src/components/CDatepicker/index.js +2 -2
  50. package/src/components/CDualSelect/CDualSelect.vue +193 -193
  51. package/src/components/CDualSelect/index.js +2 -2
  52. package/src/components/CEditor/CEditor.vue +91 -91
  53. package/src/components/CEditor/index.js +2 -2
  54. package/src/components/CFormSectionHeading/CFormSectionHeading.vue +52 -52
  55. package/src/components/CFormSectionHeading/index.js +2 -2
  56. package/src/components/CGroupedSelect/CGroupedSelect.vue +217 -217
  57. package/src/components/CGroupedSelect/index.js +3 -3
  58. package/src/components/CIcon/CIcon.vue +72 -72
  59. package/src/components/CIcon/index.js +2 -2
  60. package/src/components/CIconDropdown/CIconDropdown.vue +105 -105
  61. package/src/components/CIconDropdown/index.js +2 -2
  62. package/src/components/CInput/CInput.vue +115 -115
  63. package/src/components/CInput/index.js +2 -2
  64. package/src/components/CInputAddon/CInputAddon.vue +202 -202
  65. package/src/components/CInputAddon/index.js +2 -2
  66. package/src/components/CInputEmail/CInputEmail.vue +84 -84
  67. package/src/components/CInputEmail/index.js +2 -2
  68. package/src/components/CModalHeading/CModalHeading.vue +22 -22
  69. package/src/components/CModalHeading/index.js +2 -2
  70. package/src/components/CModuleHelpLinks/CModuleHelpLinks.vue +39 -39
  71. package/src/components/CModuleHelpLinks/index.js +3 -3
  72. package/src/components/CMultiselect/CMultiselect.vue +313 -313
  73. package/src/components/CMultiselect/index.js +2 -2
  74. package/src/components/CMultiselectr/CMultiselectr.vue +44 -44
  75. package/src/components/CMultiselectr/index.js +2 -2
  76. package/src/components/CPageHeading/CPageHeading.vue +56 -56
  77. package/src/components/CPageHeading/index.js +2 -2
  78. package/src/components/CPagination/CPagination.vue +202 -202
  79. package/src/components/CPagination/index.js +2 -2
  80. package/src/components/CPhoneNumber/CPhoneNumber.vue +62 -62
  81. package/src/components/CPhoneNumber/index.js +2 -2
  82. package/src/components/CRadio/CRadio.vue +114 -114
  83. package/src/components/CRadio/index.js +2 -2
  84. package/src/components/CRangeSlider/CRangeSlider.vue +55 -55
  85. package/src/components/CRangeSlider/index.js +2 -2
  86. package/src/components/CReorderableStackedList/CReorderableStackedList.vue +94 -94
  87. package/src/components/CReorderableStackedList/index.js +2 -2
  88. package/src/components/CSelect/CSelect.vue +314 -310
  89. package/src/components/CSelect/index.js +2 -2
  90. package/src/components/CSmallTimeline/CSmallTimeline.vue +40 -40
  91. package/src/components/CSmallTimeline/index.js +2 -2
  92. package/src/components/CStackedList/CStackedList.vue +94 -94
  93. package/src/components/CStackedList/index.js +2 -2
  94. package/src/components/CStats/CStats.vue +88 -88
  95. package/src/components/CStats/index.js +2 -2
  96. package/src/components/CSwitch/CSwitch.vue +132 -132
  97. package/src/components/CSwitch/index.js +2 -2
  98. package/src/components/CTable/CTable.vue +501 -501
  99. package/src/components/CTable/index.js +2 -2
  100. package/src/components/CTabs/CTabs.vue +107 -107
  101. package/src/components/CTabs/index.js +2 -2
  102. package/src/components/CTag/CTag.vue +36 -36
  103. package/src/components/CTag/index.js +2 -2
  104. package/src/components/CTextarea/CTextarea.vue +85 -85
  105. package/src/components/CTextarea/index.js +2 -2
  106. package/src/components/CTimeline/CTimeline.vue +237 -237
  107. package/src/components/CTimeline/index.js +2 -2
  108. package/src/components/CUpload/CUpload.vue +201 -201
  109. package/src/components/CUpload/index.js +2 -2
  110. package/src/components/index.js +48 -48
  111. package/src/icons.js +258 -258
  112. package/src/main.js +22 -22
  113. package/src/stories/CAlerts.stories.js +37 -37
  114. package/src/stories/CAnchorTabs.stories.js +29 -29
  115. package/src/stories/CAnchorTag.stories.js +36 -36
  116. package/src/stories/CAvatar.stories.js +38 -38
  117. package/src/stories/CAvatarGroup.stories.js +100 -100
  118. package/src/stories/CBasicTable.stories.js +316 -316
  119. package/src/stories/CBreadcrumbs.stories.js +24 -24
  120. package/src/stories/CButton.stories.js +46 -46
  121. package/src/stories/CButtonGroup.stories.js +33 -33
  122. package/src/stories/CButtonIcon.stories.js +27 -27
  123. package/src/stories/CButtonLink.stories.js +24 -24
  124. package/src/stories/CButtonSelect.stories.js +32 -32
  125. package/src/stories/CButtonWithDropdown.stories.js +41 -41
  126. package/src/stories/CCalendar.stories.js +16 -16
  127. package/src/stories/CCard.stories.js +30 -30
  128. package/src/stories/CCheckbox.stories.js +29 -29
  129. package/src/stories/CCollapsibleSection.stories.js +28 -28
  130. package/src/stories/CColorDots.stories.js +28 -28
  131. package/src/stories/CConfirmActionModal.stories.js +59 -59
  132. package/src/stories/CDatepicker.stories.js +30 -30
  133. package/src/stories/CDualSelect.stories.js +29 -29
  134. package/src/stories/CEditor.stories.js +30 -30
  135. package/src/stories/CFormSectionHeading.stories.js +34 -34
  136. package/src/stories/CGroupedSelect.stories.js +69 -69
  137. package/src/stories/CIcon.stories.js +26 -26
  138. package/src/stories/CIconDropdown.stories.js +39 -39
  139. package/src/stories/CInput.stories.js +36 -36
  140. package/src/stories/CInputAddon.stories.js +37 -37
  141. package/src/stories/CInputEmail.stories.js +27 -27
  142. package/src/stories/CModalHeading.stories.js +25 -25
  143. package/src/stories/CModuleHelpLinks.stories.js +25 -25
  144. package/src/stories/CMultiselect.stories.js +97 -97
  145. package/src/stories/CMultiselectr.stories.js +23 -23
  146. package/src/stories/CPageHeading.stories.js +32 -32
  147. package/src/stories/CPagination.stories.js +30 -30
  148. package/src/stories/CPhoneNumber.stories.js +29 -29
  149. package/src/stories/CRadio.stories.js +36 -36
  150. package/src/stories/CRangeSlider.stories.js +23 -23
  151. package/src/stories/CReorderableStackedList.stories.js +23 -23
  152. package/src/stories/CSelect.stories.js +50 -50
  153. package/src/stories/CSmallTimeline.stories.js +26 -26
  154. package/src/stories/CStackedList.stories.js +37 -37
  155. package/src/stories/CStats.stories.js +33 -33
  156. package/src/stories/CSwitch.stories.js +28 -28
  157. package/src/stories/CTable.stories.js +77 -77
  158. package/src/stories/CTabs.stories.js +29 -29
  159. package/src/stories/CTag.stories.js +23 -23
  160. package/src/stories/CTextarea.stories.js +32 -32
  161. package/src/stories/CTimeline.stories.js +26 -26
  162. package/src/stories/CUpload.stories.js +36 -36
  163. package/src/stories/Introduction.stories.mdx +207 -207
  164. package/src/stories/Page.vue +88 -88
  165. package/src/stories/assets/code-brackets.svg +0 -0
  166. package/src/stories/assets/colors.svg +0 -0
  167. package/src/stories/assets/comments.svg +0 -0
  168. package/src/stories/assets/direction.svg +0 -0
  169. package/src/stories/assets/flow.svg +0 -0
  170. package/src/stories/assets/plugin.svg +0 -0
  171. package/src/stories/assets/repo.svg +0 -0
  172. package/src/stories/assets/stackalt.svg +0 -0
  173. package/src/stories/header.css +26 -26
  174. package/src/stories/page.css +69 -69
  175. package/src/stories/utils.css +17 -17
@@ -1,369 +1,373 @@
1
- <template>
2
- <!-- This example requires Tailwind CSS v2.0+ -->
3
- <div>
4
- <div class="grid grid-cols-1 md:grid-cols-2 md:gap-8">
5
- <div>
6
- <div
7
- class="relative z-20 flex items-center justify-between border-b border-gray-200 py-4"
8
- >
9
- <h2 class="flex-auto font-semibold text-gray-900">
10
- {{ currentMonthAndYear }}
11
- </h2>
12
- <button
13
- type="button"
14
- @click="handlePreviousMonthClick"
15
- class="-my-1.5 flex flex-none items-center justify-center p-1.5 text-gray-400 hover:text-gray-500"
16
- >
17
- <span class="sr-only">Previous month</span>
18
- <!-- Heroicon name: solid/chevron-left -->
19
- <svg
20
- class="h-5 w-5"
21
- xmlns="http://www.w3.org/2000/svg"
22
- viewBox="0 0 20 20"
23
- fill="currentColor"
24
- aria-hidden="true"
25
- >
26
- <path
27
- fill-rule="evenodd"
28
- d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
29
- clip-rule="evenodd"
30
- />
31
- </svg>
32
- </button>
33
- <button
34
- type="button"
35
- @click="handleNextMonthClick"
36
- class="-my-1.5 -mr-1.5 ml-2 flex flex-none items-center justify-center p-1.5 text-gray-400 hover:text-gray-500"
37
- >
38
- <span class="sr-only">Next month</span>
39
- <!-- Heroicon name: solid/chevron-right -->
40
- <svg
41
- class="h-5 w-5"
42
- xmlns="http://www.w3.org/2000/svg"
43
- viewBox="0 0 20 20"
44
- fill="currentColor"
45
- aria-hidden="true"
46
- >
47
- <path
48
- fill-rule="evenodd"
49
- d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
50
- clip-rule="evenodd"
51
- />
52
- </svg>
53
- </button>
54
- </div>
55
-
56
- <div class="col-span-1 shadow ring-1 ring-gray-200">
57
- <div
58
- class="grid grid-cols-7 gap-px border-b border-gray-300 bg-gray-200 text-center text-xs font-semibold leading-6 text-gray-700"
59
- >
60
- <div class="bg-white py-2">M<span class="sr-only">on</span></div>
61
- <div class="bg-white py-2">T<span class="sr-only">ue</span></div>
62
- <div class="bg-white py-2">W<span class="sr-only">ed</span></div>
63
- <div class="bg-white py-2">T<span class="sr-only">hu</span></div>
64
- <div class="bg-white py-2">F<span class="sr-only">ri</span></div>
65
- <div class="bg-white py-2">S<span class="sr-only">at</span></div>
66
- <div class="bg-white py-2">S<span class="sr-only">un</span></div>
67
- </div>
68
- <div class="flex bg-gray-200 text-xs leading-6 text-gray-700">
69
- <div class="isolate grid w-full grid-cols-7 grid-rows-6 gap-px">
70
- <button
71
- v-for="date in daysArray"
72
- :key="getDateKey(date)"
73
- type="button"
74
- :class="{
75
- 'flex h-14 flex-col py-2 px-3 hover:bg-gray-100 focus:z-10': true,
76
- 'bg-white': isCurrentMonth(date),
77
- 'bg-gray-50': !isCurrentMonth(date),
78
- 'font-semibold': isSelected(date) || isToday(date),
79
- 'text-white': isSelected(date),
80
- 'text-indigo-600': !isSelected(date) && isToday(date),
81
- 'text-gray-900':
82
- !isSelected(date) && isCurrentMonth(date) && !isToday(date),
83
- 'text-gray-500':
84
- !isSelected(date) &&
85
- !isCurrentMonth(date) &&
86
- !isToday(date),
87
- }"
88
- @click="handleDateClick(date)"
89
- >
90
- <time
91
- :datetime="formatForDateTime(date)"
92
- :class="{
93
- 'ml-auto': true,
94
- 'flex h-6 w-6 items-center justify-center rounded-full':
95
- isSelected(date),
96
- 'bg-indigo-600': isSelected(date) && isToday(date),
97
- 'bg-gray-900': isSelected(date) && !isToday(date),
98
- }"
99
- >{{ getDayFromDate(date) }}</time
100
- >
101
- <span v-if="eventsCount" class="sr-only"
102
- >{{ getEventsCountForDate(date) }} events</span
103
- >
104
- <span
105
- v-if="eventsCount && getEventsCountForDate(date) > 0"
106
- class="-mx-0.5 mt-auto flex flex-wrap-reverse"
107
- >
108
- <span
109
- class="mx-0.5 mb-1 h-1.5 w-1.5 rounded-full bg-gray-400"
110
- ></span>
111
- </span>
112
- </button>
113
- </div>
114
- </div>
115
- </div>
116
- </div>
117
- <section
118
- v-if="eventsData && validSelectedDate"
119
- class="col-span-1 mt-8 md:mt-0"
120
- >
121
- <h2 class="py-4 font-semibold text-gray-900">
122
- Schedule for
123
- <time :datetime="selectedDateForDateTime">{{
124
- formattedSelectedDate
125
- }}</time>
126
- </h2>
127
- <p
128
- v-if="getEventsForDate(value).length === 0"
129
- class="text-center text-sm text-gray-400"
130
- >
131
- Sorry, no events found for this date.
132
- </p>
133
- <ol class="space-y-3 leading-6">
134
- <li
135
- class="cursor-pointer rounded border border-gray-100 bg-white py-2 px-4 shadow focus-within:shadow-md hover:shadow-md"
136
- v-for="event in getEventsForDate(value)"
137
- :key="event.id"
138
- >
139
- <div class="text-sm text-gray-900">
140
- {{ formatTimeFromDate(event.start) }} -
141
- {{ formatTimeFromDate(event.end) }}
142
- </div>
143
- <div
144
- class="mt-1 text-sm font-semibold"
145
- :style="{ color: event.color }"
146
- >
147
- {{ event.title }} ({{ event.booked }}/{{ event.seats }})
148
- </div>
149
- <div class="-m-0.5 flex flex-wrap items-center">
150
- <div class="m-0.5 flex items-center space-x-1">
151
- <svg
152
- xmlns="http://www.w3.org/2000/svg"
153
- class="h-4 w-4 text-gray-400"
154
- fill="none"
155
- viewBox="0 0 24 24"
156
- stroke="currentColor"
157
- stroke-width="2"
158
- >
159
- <path
160
- stroke-linecap="round"
161
- stroke-linejoin="round"
162
- d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
163
- />
164
- </svg>
165
- <span class="text-sm text-gray-500"
166
- >{{ event.duration }} mins</span
167
- >
168
- </div>
169
- <div
170
- v-if="event.subject && event.subject.length"
171
- class="m-0.5 flex items-center space-x-1"
172
- >
173
- <svg
174
- xmlns="http://www.w3.org/2000/svg"
175
- class="h-4 w-4 text-gray-400"
176
- fill="none"
177
- viewBox="0 0 24 24"
178
- stroke="currentColor"
179
- stroke-width="2"
180
- >
181
- <path
182
- stroke-linecap="round"
183
- stroke-linejoin="round"
184
- d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"
185
- />
186
- </svg>
187
- <span class="text-sm text-gray-500">{{ event.subject }}</span>
188
- </div>
189
- <div
190
- v-if="event.location && event.location.length"
191
- class="m-0.5 flex items-center space-x-1"
192
- >
193
- <svg
194
- xmlns="http://www.w3.org/2000/svg"
195
- class="h-4 w-4 text-gray-400"
196
- fill="none"
197
- viewBox="0 0 24 24"
198
- stroke="currentColor"
199
- stroke-width="2"
200
- >
201
- <path
202
- stroke-linecap="round"
203
- stroke-linejoin="round"
204
- d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7"
205
- />
206
- </svg>
207
- <span class="text-sm text-gray-500">{{ event.location }}</span>
208
- </div>
209
- <div
210
- v-if="event.staff && event.staff.length"
211
- class="m-0.5 flex items-center space-x-1"
212
- >
213
- <svg
214
- xmlns="http://www.w3.org/2000/svg"
215
- class="h-4 w-4 text-gray-400"
216
- fill="none"
217
- viewBox="0 0 24 24"
218
- stroke="currentColor"
219
- stroke-width="2"
220
- >
221
- <path
222
- stroke-linecap="round"
223
- stroke-linejoin="round"
224
- d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
225
- />
226
- </svg>
227
- <span class="text-sm text-gray-500">{{ event.staff }}</span>
228
- </div>
229
- </div>
230
- </li>
231
- </ol>
232
- </section>
233
- </div>
234
- </div>
235
- </template>
236
-
237
- <script>
238
- import * as dayjs from "dayjs";
239
-
240
- export default {
241
- name: "CCalendar",
242
- props: {
243
- value: {
244
- type: [String, Date, Object],
245
- default: () => null,
246
- },
247
- eventsCount: {
248
- type: Array,
249
- default: () => null,
250
- },
251
- eventsData: {
252
- type: Array,
253
- default: () => null,
254
- },
255
- },
256
- data() {
257
- return {
258
- activeDate: dayjs(),
259
- };
260
- },
261
- methods: {
262
- handlePreviousMonthClick() {
263
- this.activeDate = this.activeDate.subtract(1, "month");
264
- this.$emit("prev-month", this.getActiveStartAndEndDates());
265
- },
266
- handleNextMonthClick() {
267
- this.activeDate = this.activeDate.add(1, "month");
268
- this.$emit("next-month", this.getActiveStartAndEndDates());
269
- },
270
- handleDateClick(date) {
271
- this.$emit("input", date);
272
- },
273
- getDayFromDate(date) {
274
- return dayjs(date).format("D");
275
- },
276
- isSelected(date) {
277
- return dayjs(date).isSame(this.value, "day");
278
- },
279
- isToday(date) {
280
- return dayjs(date).isSame(dayjs(), "day");
281
- },
282
- isCurrentMonth(date) {
283
- return dayjs(date).isSame(this.activeDate, "month");
284
- },
285
- getDateKey(date) {
286
- return dayjs(date).format();
287
- },
288
- formatForDateTime(date) {
289
- return dayjs(date).format("YYYY-MM-DD");
290
- },
291
- formatTimeFromDate(date) {
292
- return dayjs(date).format("hh:mma");
293
- },
294
- getEventsCountForDate(date) {
295
- let eventsCountObj = this.eventsCount.find((event) =>
296
- dayjs(date).isSame(dayjs(event.date), "day")
297
- );
298
- if (eventsCountObj) {
299
- return eventsCountObj.eventsCount;
300
- } else {
301
- return 0;
302
- }
303
- },
304
- getActiveStartAndEndDates() {
305
- return {
306
- startDate: this.daysArray[0],
307
- endDate: this.daysArray[this.daysArray.length - 1],
308
- };
309
- },
310
- getEventsForDate(date) {
311
- return this.eventsData.filter((event) =>
312
- dayjs(date).isSame(dayjs(event.start), "day")
313
- );
314
- },
315
- },
316
- computed: {
317
- currentMonthAndYear() {
318
- return dayjs(this.activeDate).format("MMMM YYYY");
319
- },
320
- daysArray() {
321
- let dates = [];
322
- let firstDayOfmonth = dayjs(this.activeDate).startOf("month");
323
- let lastDayOfmonth = dayjs(this.activeDate).endOf("month");
324
- let firstDayOfMonthInWeek = firstDayOfmonth.day();
325
- let lastDayOfMonthInWeek = lastDayOfmonth.day();
326
- if (firstDayOfMonthInWeek === 0) {
327
- firstDayOfMonthInWeek = 7;
328
- }
329
- if (lastDayOfMonthInWeek === 0) {
330
- lastDayOfMonthInWeek = 7;
331
- }
332
- for (let i = 0; i < firstDayOfMonthInWeek - 1; i++) {
333
- dates.unshift(firstDayOfmonth.subtract(i + 1, "day"));
334
- }
335
- for (let i = 0; i < dayjs(this.activeDate).daysInMonth(); i++) {
336
- dates.push(firstDayOfmonth.add(i, "day"));
337
- }
338
- let cursor = 1;
339
- for (let i = lastDayOfMonthInWeek; i < 7; i++) {
340
- dates.push(lastDayOfmonth.add(cursor, "day"));
341
- cursor++;
342
- }
343
- if (dates.length !== 42) {
344
- let lastDayOfDates = dates[dates.length - 1];
345
- for (let i = 1; i <= 7; i++) {
346
- dates.push(lastDayOfDates.add(i, "day"));
347
- }
348
- }
349
- return dates;
350
- },
351
- formattedSelectedDate() {
352
- return dayjs(this.value ?? dayjs()).format("MMMM D, YYYY");
353
- },
354
- selectedDateForDateTime() {
355
- return dayjs(this.value ?? dayjs()).format("YYYY-MM-DD");
356
- },
357
- validSelectedDate() {
358
- return this.value && dayjs(this.value).isValid();
359
- },
360
- },
361
- mounted() {
362
- if (this.value) {
363
- this.activeDate = dayjs(this.value);
364
- }
365
- },
366
- };
367
- </script>
368
-
369
- <style></style>
1
+ <template>
2
+ <!-- This example requires Tailwind CSS v2.0+ -->
3
+ <div>
4
+ <div class="grid grid-cols-1 md:grid-cols-2 md:gap-8">
5
+ <div>
6
+ <div
7
+ class="relative z-20 flex items-center justify-between border-b border-gray-200 py-4"
8
+ >
9
+ <h2 class="flex-auto font-semibold text-gray-900">
10
+ {{ currentMonthAndYear }}
11
+ </h2>
12
+ <button
13
+ type="button"
14
+ @click="handlePreviousMonthClick"
15
+ class="-my-1.5 flex flex-none items-center justify-center p-1.5 text-gray-400 hover:text-gray-500"
16
+ >
17
+ <span class="sr-only">Previous month</span>
18
+ <!-- Heroicon name: solid/chevron-left -->
19
+ <svg
20
+ class="h-5 w-5"
21
+ xmlns="http://www.w3.org/2000/svg"
22
+ viewBox="0 0 20 20"
23
+ fill="currentColor"
24
+ aria-hidden="true"
25
+ >
26
+ <path
27
+ fill-rule="evenodd"
28
+ d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
29
+ clip-rule="evenodd"
30
+ />
31
+ </svg>
32
+ </button>
33
+ <button
34
+ type="button"
35
+ @click="handleNextMonthClick"
36
+ class="-my-1.5 -mr-1.5 ml-2 flex flex-none items-center justify-center p-1.5 text-gray-400 hover:text-gray-500"
37
+ >
38
+ <span class="sr-only">Next month</span>
39
+ <!-- Heroicon name: solid/chevron-right -->
40
+ <svg
41
+ class="h-5 w-5"
42
+ xmlns="http://www.w3.org/2000/svg"
43
+ viewBox="0 0 20 20"
44
+ fill="currentColor"
45
+ aria-hidden="true"
46
+ >
47
+ <path
48
+ fill-rule="evenodd"
49
+ d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
50
+ clip-rule="evenodd"
51
+ />
52
+ </svg>
53
+ </button>
54
+ </div>
55
+
56
+ <div class="col-span-1 shadow ring-1 ring-gray-200">
57
+ <div
58
+ class="grid grid-cols-7 gap-px border-b border-gray-300 bg-gray-200 text-center text-xs font-semibold leading-6 text-gray-700"
59
+ >
60
+ <div class="bg-white py-2">M<span class="sr-only">on</span></div>
61
+ <div class="bg-white py-2">T<span class="sr-only">ue</span></div>
62
+ <div class="bg-white py-2">W<span class="sr-only">ed</span></div>
63
+ <div class="bg-white py-2">T<span class="sr-only">hu</span></div>
64
+ <div class="bg-white py-2">F<span class="sr-only">ri</span></div>
65
+ <div class="bg-white py-2">S<span class="sr-only">at</span></div>
66
+ <div class="bg-white py-2">S<span class="sr-only">un</span></div>
67
+ </div>
68
+ <div class="flex bg-gray-200 text-xs leading-6 text-gray-700">
69
+ <div class="isolate grid w-full grid-cols-7 grid-rows-6 gap-px">
70
+ <button
71
+ v-for="date in daysArray"
72
+ :key="getDateKey(date)"
73
+ type="button"
74
+ :class="{
75
+ 'flex h-14 flex-col py-2 px-3 hover:bg-gray-100 focus:z-10': true,
76
+ 'bg-white': isCurrentMonth(date),
77
+ 'bg-gray-50': !isCurrentMonth(date),
78
+ 'font-semibold': isSelected(date) || isToday(date),
79
+ 'text-white': isSelected(date),
80
+ 'text-indigo-600': !isSelected(date) && isToday(date),
81
+ 'text-gray-900':
82
+ !isSelected(date) && isCurrentMonth(date) && !isToday(date),
83
+ 'text-gray-500':
84
+ !isSelected(date) &&
85
+ !isCurrentMonth(date) &&
86
+ !isToday(date),
87
+ }"
88
+ @click="handleDateClick(date)"
89
+ >
90
+ <time
91
+ :datetime="formatForDateTime(date)"
92
+ :class="{
93
+ 'ml-auto': true,
94
+ 'flex h-6 w-6 items-center justify-center rounded-full':
95
+ isSelected(date),
96
+ 'bg-indigo-600': isSelected(date) && isToday(date),
97
+ 'bg-gray-900': isSelected(date) && !isToday(date),
98
+ }"
99
+ >{{ getDayFromDate(date) }}</time
100
+ >
101
+ <span v-if="eventsCount" class="sr-only"
102
+ >{{ getEventsCountForDate(date) }} events</span
103
+ >
104
+ <span
105
+ v-if="eventsCount && getEventsCountForDate(date) > 0"
106
+ class="-mx-0.5 mt-auto flex flex-wrap-reverse"
107
+ >
108
+ <span
109
+ class="mx-0.5 mb-1 h-1.5 w-1.5 rounded-full bg-gray-400"
110
+ ></span>
111
+ </span>
112
+ </button>
113
+ </div>
114
+ </div>
115
+ </div>
116
+ </div>
117
+ <section
118
+ v-if="eventsData && validSelectedDate"
119
+ class="col-span-1 mt-8 md:mt-0"
120
+ >
121
+ <h2 class="py-4 font-semibold text-gray-900">
122
+ Schedule for
123
+ <time :datetime="selectedDateForDateTime">{{
124
+ formattedSelectedDate
125
+ }}</time>
126
+ </h2>
127
+ <p
128
+ v-if="getEventsForDate(value).length === 0"
129
+ class="text-center text-sm text-gray-400"
130
+ >
131
+ Sorry, no events found for this date.
132
+ </p>
133
+ <ol class="space-y-3 leading-6">
134
+ <li
135
+ class="cursor-pointer rounded border border-gray-100 bg-white py-2 px-4 shadow focus-within:shadow-md hover:shadow-md"
136
+ v-for="event in getEventsForDate(value)"
137
+ :key="event.id"
138
+ @click="handleEventClick(event)"
139
+ >
140
+ <div class="text-sm text-gray-900">
141
+ {{ formatTimeFromDate(event.start) }} -
142
+ {{ formatTimeFromDate(event.end) }}
143
+ </div>
144
+ <div
145
+ class="mt-1 text-sm font-semibold"
146
+ :style="{ color: event.color }"
147
+ >
148
+ {{ event.title }} ({{ event.booked }}/{{ event.seats }})
149
+ </div>
150
+ <div class="-m-0.5 flex flex-wrap items-center">
151
+ <div class="m-0.5 flex items-center space-x-0.5">
152
+ <svg
153
+ xmlns="http://www.w3.org/2000/svg"
154
+ class="h-4 w-4 text-gray-400"
155
+ fill="none"
156
+ viewBox="0 0 24 24"
157
+ stroke="currentColor"
158
+ stroke-width="2"
159
+ >
160
+ <path
161
+ stroke-linecap="round"
162
+ stroke-linejoin="round"
163
+ d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
164
+ />
165
+ </svg>
166
+ <span class="text-sm text-gray-500"
167
+ >{{ event.duration }} mins</span
168
+ >
169
+ </div>
170
+ <div
171
+ v-if="event.subject && event.subject.length"
172
+ class="m-0.5 flex items-center space-x-0.5"
173
+ >
174
+ <svg
175
+ xmlns="http://www.w3.org/2000/svg"
176
+ class="h-4 w-4 text-gray-400"
177
+ fill="none"
178
+ viewBox="0 0 24 24"
179
+ stroke="currentColor"
180
+ stroke-width="2"
181
+ >
182
+ <path
183
+ stroke-linecap="round"
184
+ stroke-linejoin="round"
185
+ d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"
186
+ />
187
+ </svg>
188
+ <span class="text-sm text-gray-500">{{ event.subject }}</span>
189
+ </div>
190
+ <div
191
+ v-if="event.location && event.location.length"
192
+ class="m-0.5 flex items-center space-x-0.5"
193
+ >
194
+ <svg
195
+ xmlns="http://www.w3.org/2000/svg"
196
+ class="h-4 w-4 text-gray-400"
197
+ fill="none"
198
+ viewBox="0 0 24 24"
199
+ stroke="currentColor"
200
+ stroke-width="2"
201
+ >
202
+ <path
203
+ stroke-linecap="round"
204
+ stroke-linejoin="round"
205
+ d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7"
206
+ />
207
+ </svg>
208
+ <span class="text-sm text-gray-500">{{ event.location }}</span>
209
+ </div>
210
+ <div
211
+ v-if="event.staff && event.staff.length"
212
+ class="m-0.5 flex items-center space-x-0.5"
213
+ >
214
+ <svg
215
+ xmlns="http://www.w3.org/2000/svg"
216
+ class="h-4 w-4 text-gray-400"
217
+ fill="none"
218
+ viewBox="0 0 24 24"
219
+ stroke="currentColor"
220
+ stroke-width="2"
221
+ >
222
+ <path
223
+ stroke-linecap="round"
224
+ stroke-linejoin="round"
225
+ d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
226
+ />
227
+ </svg>
228
+ <span class="text-sm text-gray-500">{{ event.staff }}</span>
229
+ </div>
230
+ </div>
231
+ </li>
232
+ </ol>
233
+ </section>
234
+ </div>
235
+ </div>
236
+ </template>
237
+
238
+ <script>
239
+ import * as dayjs from "dayjs";
240
+
241
+ export default {
242
+ name: "CCalendar",
243
+ props: {
244
+ value: {
245
+ type: [String, Date, Object],
246
+ default: () => null,
247
+ },
248
+ eventsCount: {
249
+ type: Array,
250
+ default: () => null,
251
+ },
252
+ eventsData: {
253
+ type: Array,
254
+ default: () => null,
255
+ },
256
+ },
257
+ data() {
258
+ return {
259
+ activeDate: dayjs(),
260
+ };
261
+ },
262
+ methods: {
263
+ handlePreviousMonthClick() {
264
+ this.activeDate = this.activeDate.subtract(1, "month");
265
+ this.$emit("prev-month", this.getActiveStartAndEndDates());
266
+ },
267
+ handleNextMonthClick() {
268
+ this.activeDate = this.activeDate.add(1, "month");
269
+ this.$emit("next-month", this.getActiveStartAndEndDates());
270
+ },
271
+ handleDateClick(date) {
272
+ this.$emit("input", date);
273
+ },
274
+ getDayFromDate(date) {
275
+ return dayjs(date).format("D");
276
+ },
277
+ isSelected(date) {
278
+ return dayjs(date).isSame(this.value, "day");
279
+ },
280
+ isToday(date) {
281
+ return dayjs(date).isSame(dayjs(), "day");
282
+ },
283
+ isCurrentMonth(date) {
284
+ return dayjs(date).isSame(this.activeDate, "month");
285
+ },
286
+ getDateKey(date) {
287
+ return dayjs(date).format();
288
+ },
289
+ formatForDateTime(date) {
290
+ return dayjs(date).format("YYYY-MM-DD");
291
+ },
292
+ formatTimeFromDate(date) {
293
+ return dayjs(date).format("hh:mma");
294
+ },
295
+ getEventsCountForDate(date) {
296
+ let eventsCountObj = this.eventsCount.find((event) =>
297
+ dayjs(date).isSame(dayjs(event.date), "day")
298
+ );
299
+ if (eventsCountObj) {
300
+ return eventsCountObj.eventsCount;
301
+ } else {
302
+ return 0;
303
+ }
304
+ },
305
+ getActiveStartAndEndDates() {
306
+ return {
307
+ startDate: this.daysArray[0],
308
+ endDate: this.daysArray[this.daysArray.length - 1],
309
+ };
310
+ },
311
+ getEventsForDate(date) {
312
+ return this.eventsData.filter((event) =>
313
+ dayjs(date).isSame(dayjs(event.start), "day")
314
+ );
315
+ },
316
+ handleEventClick(event) {
317
+ this.$emit("event-click", event);
318
+ },
319
+ },
320
+ computed: {
321
+ currentMonthAndYear() {
322
+ return dayjs(this.activeDate).format("MMMM YYYY");
323
+ },
324
+ daysArray() {
325
+ let dates = [];
326
+ let firstDayOfmonth = dayjs(this.activeDate).startOf("month");
327
+ let lastDayOfmonth = dayjs(this.activeDate).endOf("month");
328
+ let firstDayOfMonthInWeek = firstDayOfmonth.day();
329
+ let lastDayOfMonthInWeek = lastDayOfmonth.day();
330
+ if (firstDayOfMonthInWeek === 0) {
331
+ firstDayOfMonthInWeek = 7;
332
+ }
333
+ if (lastDayOfMonthInWeek === 0) {
334
+ lastDayOfMonthInWeek = 7;
335
+ }
336
+ for (let i = 0; i < firstDayOfMonthInWeek - 1; i++) {
337
+ dates.unshift(firstDayOfmonth.subtract(i + 1, "day"));
338
+ }
339
+ for (let i = 0; i < dayjs(this.activeDate).daysInMonth(); i++) {
340
+ dates.push(firstDayOfmonth.add(i, "day"));
341
+ }
342
+ let cursor = 1;
343
+ for (let i = lastDayOfMonthInWeek; i < 7; i++) {
344
+ dates.push(lastDayOfmonth.add(cursor, "day"));
345
+ cursor++;
346
+ }
347
+ if (dates.length !== 42) {
348
+ let lastDayOfDates = dates[dates.length - 1];
349
+ for (let i = 1; i <= 7; i++) {
350
+ dates.push(lastDayOfDates.add(i, "day"));
351
+ }
352
+ }
353
+ return dates;
354
+ },
355
+ formattedSelectedDate() {
356
+ return dayjs(this.value ?? dayjs()).format("MMMM D, YYYY");
357
+ },
358
+ selectedDateForDateTime() {
359
+ return dayjs(this.value ?? dayjs()).format("YYYY-MM-DD");
360
+ },
361
+ validSelectedDate() {
362
+ return this.value && dayjs(this.value).isValid();
363
+ },
364
+ },
365
+ mounted() {
366
+ if (this.value) {
367
+ this.activeDate = dayjs(this.value);
368
+ }
369
+ },
370
+ };
371
+ </script>
372
+
373
+ <style></style>