v-calendar-3 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +142 -0
  3. package/dist/cjs/index.css +1133 -0
  4. package/dist/cjs/index.js +10699 -0
  5. package/dist/cjs/index.js.map +1 -0
  6. package/dist/cjs/package.json +1 -0
  7. package/dist/es/index.js +10678 -0
  8. package/dist/es/index.js.map +1 -0
  9. package/dist/es/style.css +1134 -0
  10. package/dist/iife/index.js +2 -0
  11. package/dist/iife/index.js.map +1 -0
  12. package/dist/mjs/index.mjs +10678 -0
  13. package/dist/mjs/index.mjs.map +1 -0
  14. package/dist/mjs/style.css +1134 -0
  15. package/dist/style.css +1134 -0
  16. package/dist/types/components/BaseIcon/BaseIcon.vue.d.ts +41 -0
  17. package/dist/types/components/BaseIcon/icons/IconChevronDown.vue.d.ts +3 -0
  18. package/dist/types/components/BaseIcon/icons/IconChevronLeft.vue.d.ts +3 -0
  19. package/dist/types/components/BaseIcon/icons/IconChevronRight.vue.d.ts +3 -0
  20. package/dist/types/components/BaseIcon/icons/IconClock.vue.d.ts +3 -0
  21. package/dist/types/components/BaseIcon/icons/index.d.ts +4 -0
  22. package/dist/types/components/BaseSelect/BaseSelect.vue.d.ts +26 -0
  23. package/dist/types/components/Calendar/Calendar.vue.d.ts +2526 -0
  24. package/dist/types/components/Calendar/CalendarDay.vue.d.ts +83 -0
  25. package/dist/types/components/Calendar/CalendarDayPopover.vue.d.ts +3 -0
  26. package/dist/types/components/Calendar/CalendarHeader.vue.d.ts +13 -0
  27. package/dist/types/components/Calendar/CalendarNav.vue.d.ts +4 -0
  28. package/dist/types/components/Calendar/CalendarNavPopover.vue.d.ts +3 -0
  29. package/dist/types/components/Calendar/CalendarPage.vue.d.ts +3 -0
  30. package/dist/types/components/Calendar/CalendarPageProvider.vue.d.ts +17 -0
  31. package/dist/types/components/Calendar/CalendarSlot.vue.d.ts +15 -0
  32. package/dist/types/components/Calendar/CalendarTitleSelect.vue.d.ts +15 -0
  33. package/dist/types/components/CalendarGrid/CalendarCell.vue.d.ts +9 -0
  34. package/dist/types/components/CalendarGrid/CalendarCellPopover.vue.d.ts +209 -0
  35. package/dist/types/components/CalendarGrid/CalendarDayCell.vue.d.ts +8 -0
  36. package/dist/types/components/CalendarGrid/CalendarEventDetails.vue.d.ts +15 -0
  37. package/dist/types/components/CalendarGrid/CalendarEventEdit.vue.d.ts +26 -0
  38. package/dist/types/components/CalendarGrid/CalendarGrid.vue.d.ts +134 -0
  39. package/dist/types/components/CalendarGrid/CalendarGridWeek.vue.d.ts +8 -0
  40. package/dist/types/components/CalendarGrid/CalendarViewSelect.vue.d.ts +3 -0
  41. package/dist/types/components/CalendarGrid/CalendarWeekCell.vue.d.ts +10 -0
  42. package/dist/types/components/CalendarGrid/Constraints.d.ts +16 -0
  43. package/dist/types/components/DatePicker/DatePicker.vue.d.ts +15251 -0
  44. package/dist/types/components/DatePicker/DatePickerBase.vue.d.ts +3 -0
  45. package/dist/types/components/DatePicker/DatePickerPopover.vue.d.ts +3 -0
  46. package/dist/types/components/DatePicker/TimePicker.vue.d.ts +10089 -0
  47. package/dist/types/components/Popover/Popover.vue.d.ts +72 -0
  48. package/dist/types/components/Popover/PopoverRow.vue.d.ts +17 -0
  49. package/dist/types/components/index.d.ts +4 -0
  50. package/dist/types/index.d.cts +40981 -0
  51. package/dist/types/index.d.mts +40981 -0
  52. package/dist/types/index.d.ts +40981 -0
  53. package/dist/types/use/base.d.ts +67 -0
  54. package/dist/types/use/calendar.d.ts +2422 -0
  55. package/dist/types/use/calendarGrid.d.ts +9370 -0
  56. package/dist/types/use/datePicker.d.ts +20210 -0
  57. package/dist/types/use/page.d.ts +20 -0
  58. package/dist/types/use/slots.d.ts +5 -0
  59. package/dist/types/use/timePicker.d.ts +10089 -0
  60. package/dist/types/utils/attribute.d.ts +49 -0
  61. package/dist/types/utils/cache.d.ts +10 -0
  62. package/dist/types/utils/calendar/event.d.ts +111 -0
  63. package/dist/types/utils/config/index.d.ts +5 -0
  64. package/dist/types/utils/date/helpers.d.ts +161 -0
  65. package/dist/types/utils/date/range.d.ts +74 -0
  66. package/dist/types/utils/date/repeat.d.ts +34 -0
  67. package/dist/types/utils/date/rules.d.ts +82 -0
  68. package/dist/types/utils/defaults/index.d.ts +30 -0
  69. package/dist/types/utils/defaults/locales.d.ts +9 -0
  70. package/dist/types/utils/glyph.d.ts +58 -0
  71. package/dist/types/utils/helpers.d.ts +49 -0
  72. package/dist/types/utils/locale.d.ts +48 -0
  73. package/dist/types/utils/page.d.ts +95 -0
  74. package/dist/types/utils/plugins/index.d.ts +4 -0
  75. package/dist/types/utils/popovers.d.ts +47 -0
  76. package/dist/types/utils/theme.d.ts +17 -0
  77. package/dist/types/utils/touch.d.ts +8 -0
  78. package/dist/types/utils/useDisplayMode.d.ts +12 -0
  79. package/dist/types/utils/watchers.d.ts +6 -0
  80. package/package.json +115 -0
  81. package/src/components/BaseIcon/BaseIcon.vue +29 -0
  82. package/src/components/BaseIcon/icons/IconChevronDown.vue +5 -0
  83. package/src/components/BaseIcon/icons/IconChevronLeft.vue +5 -0
  84. package/src/components/BaseIcon/icons/IconChevronRight.vue +5 -0
  85. package/src/components/BaseIcon/icons/IconClock.vue +11 -0
  86. package/src/components/BaseIcon/icons/index.ts +4 -0
  87. package/src/components/BaseSelect/BaseSelect.vue +136 -0
  88. package/src/components/Calendar/Calendar.vue +116 -0
  89. package/src/components/Calendar/CalendarDay.vue +422 -0
  90. package/src/components/Calendar/CalendarDayPopover.vue +44 -0
  91. package/src/components/Calendar/CalendarHeader.vue +203 -0
  92. package/src/components/Calendar/CalendarNav.vue +325 -0
  93. package/src/components/Calendar/CalendarNavPopover.vue +24 -0
  94. package/src/components/Calendar/CalendarPage.vue +140 -0
  95. package/src/components/Calendar/CalendarPageProvider.vue +15 -0
  96. package/src/components/Calendar/CalendarSlot.vue +36 -0
  97. package/src/components/Calendar/CalendarTitleSelect.vue +72 -0
  98. package/src/components/CalendarGrid/CalendarCell.vue +112 -0
  99. package/src/components/CalendarGrid/CalendarCellPopover.vue +93 -0
  100. package/src/components/CalendarGrid/CalendarDayCell.vue +57 -0
  101. package/src/components/CalendarGrid/CalendarEventDetails.vue +71 -0
  102. package/src/components/CalendarGrid/CalendarEventEdit.vue +195 -0
  103. package/src/components/CalendarGrid/CalendarGrid.vue +715 -0
  104. package/src/components/CalendarGrid/CalendarGridWeek.vue +60 -0
  105. package/src/components/CalendarGrid/CalendarViewSelect.vue +34 -0
  106. package/src/components/CalendarGrid/CalendarWeekCell.vue +52 -0
  107. package/src/components/CalendarGrid/Constraints.ts +40 -0
  108. package/src/components/DatePicker/DatePicker.vue +27 -0
  109. package/src/components/DatePicker/DatePickerBase.vue +53 -0
  110. package/src/components/DatePicker/DatePickerPopover.vue +37 -0
  111. package/src/components/DatePicker/TimePicker.vue +167 -0
  112. package/src/components/Popover/Popover.vue +572 -0
  113. package/src/components/Popover/PopoverRow.vue +94 -0
  114. package/src/components/index.ts +4 -0
  115. package/src/index.ts +24 -0
  116. package/src/styles/index.css +48 -0
  117. package/src/styles/theme.css +322 -0
  118. package/src/styles/transitions.css +77 -0
  119. package/src/use/base.ts +144 -0
  120. package/src/use/calendar.ts +796 -0
  121. package/src/use/calendarGrid.ts +954 -0
  122. package/src/use/datePicker.ts +909 -0
  123. package/src/use/page.ts +78 -0
  124. package/src/use/slots.ts +17 -0
  125. package/src/use/timePicker.ts +194 -0
  126. package/src/utils/attribute.ts +107 -0
  127. package/src/utils/cache.ts +30 -0
  128. package/src/utils/calendar/event.ts +335 -0
  129. package/src/utils/config/index.ts +11 -0
  130. package/src/utils/date/helpers.ts +1039 -0
  131. package/src/utils/date/range.ts +274 -0
  132. package/src/utils/date/repeat.ts +135 -0
  133. package/src/utils/date/rules.ts +290 -0
  134. package/src/utils/defaults/index.ts +77 -0
  135. package/src/utils/defaults/locales.ts +123 -0
  136. package/src/utils/defaults/masks.json +15 -0
  137. package/src/utils/defaults/touch.json +5 -0
  138. package/src/utils/glyph.ts +305 -0
  139. package/src/utils/helpers.ts +181 -0
  140. package/src/utils/locale.ts +275 -0
  141. package/src/utils/page.ts +608 -0
  142. package/src/utils/plugins/index.ts +24 -0
  143. package/src/utils/popovers.ts +216 -0
  144. package/src/utils/theme.ts +58 -0
  145. package/src/utils/touch.ts +72 -0
  146. package/src/utils/useDisplayMode.ts +198 -0
  147. package/src/utils/watchers.ts +26 -0
@@ -0,0 +1,422 @@
1
+ <template>
2
+ <div :class="dayClasses">
3
+ <!--Highlights-->
4
+ <div v-if="hasHighlights" class="vc-highlights vc-day-layer">
5
+ <div
6
+ v-for="{ key, wrapperClass, class: bgClass, style } in highlights"
7
+ :key="key"
8
+ :class="wrapperClass"
9
+ >
10
+ <div :class="bgClass" :style="style" />
11
+ </div>
12
+ </div>
13
+ <!--Content-->
14
+ <CalendarSlot
15
+ name="day-content"
16
+ :day="day"
17
+ :attributes="attributes"
18
+ :attribute-cells="attributeCells"
19
+ :dayProps="dayContentProps"
20
+ :dayEvents="dayContentEvents"
21
+ :locale="locale"
22
+ >
23
+ <div
24
+ v-bind="dayContentProps"
25
+ v-on="dayContentEvents"
26
+ v-popover="dayPopover"
27
+ >
28
+ {{ day.label }}
29
+ </div>
30
+ </CalendarSlot>
31
+ <!--Dots-->
32
+ <div v-if="hasDots" class="vc-day-layer vc-day-box-center-bottom">
33
+ <div class="vc-dots">
34
+ <span
35
+ v-for="{ key, class: bgClass, style } in dots"
36
+ :key="key"
37
+ :class="bgClass"
38
+ :style="style"
39
+ />
40
+ </div>
41
+ </div>
42
+ <!--Bars-->
43
+ <div v-if="hasBars" class="vc-day-layer vc-day-box-center-bottom">
44
+ <div class="vc-bars">
45
+ <span
46
+ v-for="{ key, class: bgClass, style } in bars"
47
+ :key="key"
48
+ :class="bgClass"
49
+ :style="style"
50
+ />
51
+ </div>
52
+ </div>
53
+ </div>
54
+ </template>
55
+
56
+ <script lang="ts">
57
+ import { type PropType, computed, defineComponent } from 'vue';
58
+ import { useCalendar } from '../../use/calendar';
59
+ import { useSlot } from '../../use/slots';
60
+ import type { Attribute, PopoverConfig } from '../../utils/attribute';
61
+ import type { DateRangeCell } from '../../utils/date/range';
62
+ import { arrayHasItems, defaults, get, last } from '../../utils/helpers';
63
+ import type { CalendarDay } from '../../utils/page';
64
+ import { popoverDirective } from '../../utils/popovers';
65
+ import CalendarSlot from './CalendarSlot.vue';
66
+
67
+ export default defineComponent({
68
+ directives: { popover: popoverDirective },
69
+ components: { CalendarSlot },
70
+ props: {
71
+ day: { type: Object as PropType<CalendarDay>, required: true },
72
+ },
73
+ setup(props) {
74
+ const {
75
+ locale,
76
+ theme,
77
+ attributeContext,
78
+ dayPopoverId,
79
+ onDayClick,
80
+ onDayMouseenter,
81
+ onDayMouseleave,
82
+ onDayFocusin,
83
+ onDayFocusout,
84
+ onDayKeydown,
85
+ } = useCalendar();
86
+
87
+ const day = computed(() => props.day);
88
+ const attributeCells = computed(() => {
89
+ return attributeContext.value.getCells(day.value);
90
+ });
91
+ const attributes = computed(() =>
92
+ attributeCells.value.map(cell => cell.data as Attribute),
93
+ );
94
+ const attributedDay = computed(() => {
95
+ return {
96
+ ...day.value,
97
+ attributes: attributes.value,
98
+ attributeCells: attributeCells.value,
99
+ };
100
+ });
101
+
102
+ function processPopover(
103
+ { data: attribute }: DateRangeCell<Attribute>,
104
+ { popovers }: { popovers: PopoverConfig[] },
105
+ ) {
106
+ const { key, customData, popover } = attribute;
107
+ if (!popover) return;
108
+ const resolvedPopover = defaults(
109
+ {
110
+ key,
111
+ customData,
112
+ attribute,
113
+ },
114
+ { ...popover },
115
+ {
116
+ visibility: popover.label ? 'hover' : 'click',
117
+ placement: 'bottom',
118
+ isInteractive: !popover.label,
119
+ },
120
+ );
121
+ popovers.splice(0, 0, resolvedPopover);
122
+ }
123
+
124
+ const glyphs = computed(() => {
125
+ const result = {
126
+ ...theme.value.prepareRender({}),
127
+ popovers: [],
128
+ };
129
+ attributeCells.value.forEach(cell => {
130
+ theme.value.render(cell, result);
131
+ processPopover(cell, result);
132
+ });
133
+ return result;
134
+ });
135
+
136
+ const highlights = computed(() => glyphs.value.highlights);
137
+ const hasHighlights = computed(() => !!arrayHasItems(highlights.value));
138
+
139
+ const content = computed(() => glyphs.value.content);
140
+
141
+ const dots = computed(() => glyphs.value.dots);
142
+ const hasDots = computed(() => !!arrayHasItems(dots.value));
143
+
144
+ const bars = computed(() => glyphs.value.bars);
145
+ const hasBars = computed(() => !!arrayHasItems(bars.value));
146
+
147
+ const popovers = computed(() => glyphs.value.popovers);
148
+ const popoverAttrs = computed(() =>
149
+ popovers.value.map((p: any) => p.attribute),
150
+ );
151
+
152
+ const dayContentSlot = useSlot('day-content');
153
+ const dayClasses = computed(() => {
154
+ return [
155
+ 'vc-day',
156
+ ...day.value.classes,
157
+ { 'vc-day-box-center-center': !dayContentSlot },
158
+ { 'is-not-in-month': !props.day.inMonth },
159
+ ];
160
+ });
161
+
162
+ const dayContentProps = computed(() => {
163
+ let tabindex;
164
+ if (day.value.isFocusable) {
165
+ tabindex = '0';
166
+ } else {
167
+ tabindex = '-1';
168
+ }
169
+ const classes = [
170
+ 'vc-day-content vc-focusable vc-focus vc-attr',
171
+ { 'vc-disabled': day.value.isDisabled },
172
+ get(last(highlights.value), 'contentClass'),
173
+ get(last(content.value), 'class') || '',
174
+ ];
175
+ const style = {
176
+ ...get(last(highlights.value), 'contentStyle'),
177
+ ...get(last(content.value), 'style'),
178
+ };
179
+ return {
180
+ class: classes,
181
+ style,
182
+ tabindex,
183
+ 'aria-label': day.value.ariaLabel,
184
+ 'aria-disabled': day.value.isDisabled ? true : false,
185
+ role: 'button',
186
+ };
187
+ });
188
+
189
+ const dayContentEvents = computed(() => {
190
+ return {
191
+ click(event: MouseEvent) {
192
+ onDayClick(attributedDay.value, event);
193
+ },
194
+ mouseenter(event: MouseEvent) {
195
+ onDayMouseenter(attributedDay.value, event);
196
+ },
197
+ mouseleave(event: MouseEvent) {
198
+ onDayMouseleave(attributedDay.value, event);
199
+ },
200
+ focusin(event: FocusEvent) {
201
+ onDayFocusin(attributedDay.value, event);
202
+ },
203
+ focusout(event: FocusEvent) {
204
+ onDayFocusout(attributedDay.value, event);
205
+ },
206
+ keydown(event: KeyboardEvent) {
207
+ onDayKeydown(attributedDay.value, event);
208
+ },
209
+ };
210
+ });
211
+
212
+ const dayPopover = computed(() => {
213
+ if (!arrayHasItems(popovers.value)) return null;
214
+ return defaults(
215
+ {
216
+ id: dayPopoverId.value,
217
+ data: { day, attributes: popoverAttrs.value },
218
+ },
219
+ ...popovers.value,
220
+ );
221
+ });
222
+
223
+ return {
224
+ attributes,
225
+ attributeCells,
226
+ bars,
227
+ dayClasses,
228
+ dayContentProps,
229
+ dayContentEvents,
230
+ dayPopover,
231
+ glyphs,
232
+ dots,
233
+ hasDots,
234
+ hasBars,
235
+ highlights,
236
+ hasHighlights,
237
+ locale,
238
+ popovers,
239
+ };
240
+ },
241
+ });
242
+ </script>
243
+
244
+ <style>
245
+ .vc-day {
246
+ position: relative;
247
+ min-height: 32px;
248
+ z-index: 1;
249
+ /* &.is-not-in-month * {
250
+ opacity: 0;
251
+ pointer-events: none;
252
+ } */
253
+ }
254
+
255
+ .vc-monthly .is-not-in-month * {
256
+ opacity: 0;
257
+ pointer-events: none;
258
+ }
259
+
260
+ .vc-day-layer {
261
+ position: absolute;
262
+ left: 0;
263
+ right: 0;
264
+ top: 0;
265
+ bottom: 0;
266
+ pointer-events: none;
267
+ }
268
+
269
+ .vc-day-box-center-center {
270
+ display: flex;
271
+ justify-content: center;
272
+ align-items: center;
273
+ transform-origin: 50% 50%;
274
+ }
275
+
276
+ .vc-day-box-left-center {
277
+ display: flex;
278
+ justify-content: flex-start;
279
+ align-items: center;
280
+ transform-origin: 0% 50%;
281
+ }
282
+
283
+ .vc-day-box-right-center {
284
+ display: flex;
285
+ justify-content: flex-end;
286
+ align-items: center;
287
+ transform-origin: 100% 50%;
288
+ }
289
+
290
+ .vc-day-box-center-bottom {
291
+ display: flex;
292
+ justify-content: center;
293
+ align-items: flex-end;
294
+ }
295
+
296
+ .vc-day-content {
297
+ display: flex;
298
+ justify-content: center;
299
+ align-items: center;
300
+ font-size: var(--vc-text-sm);
301
+ font-weight: var(--vc-font-medium);
302
+ width: 28px;
303
+ height: 28px;
304
+ line-height: 28px;
305
+ border-radius: var(--vc-rounded-full);
306
+ user-select: none;
307
+ cursor: pointer;
308
+ &:hover {
309
+ background-color: var(--vc-day-content-hover-bg);
310
+ }
311
+ &.vc-disabled {
312
+ color: var(--vc-day-content-disabled-color);
313
+ }
314
+ }
315
+
316
+ /* ----Content---- */
317
+
318
+ .vc-content:not(.vc-base) {
319
+ font-weight: var(--vc-font-bold);
320
+ color: var(--vc-content-color);
321
+ }
322
+
323
+ /* ----Highlights---- */
324
+
325
+ .vc-highlights {
326
+ overflow: hidden;
327
+ pointer-events: none;
328
+ z-index: -1;
329
+ }
330
+
331
+ .vc-highlight {
332
+ width: 28px;
333
+ height: 28px;
334
+ &.vc-highlight-base-start {
335
+ width: 50% !important;
336
+ border-radius: 0 !important;
337
+ border-right-width: 0 !important;
338
+ }
339
+ &.vc-highlight-base-end {
340
+ width: 50% !important;
341
+ border-radius: 0 !important;
342
+ border-left-width: 0 !important;
343
+ }
344
+ &.vc-highlight-base-middle {
345
+ width: 100%;
346
+ border-radius: 0 !important;
347
+ border-left-width: 0 !important;
348
+ border-right-width: 0 !important;
349
+ margin: 0 -1px;
350
+ }
351
+ }
352
+
353
+ .vc-highlight-bg-outline,
354
+ .vc-highlight-bg-none {
355
+ background-color: var(--vc-highlight-outline-bg);
356
+ border: 2px solid;
357
+ border-color: var(--vc-highlight-outline-border);
358
+ border-radius: var(--vc-rounded-full);
359
+ }
360
+ .vc-highlight-bg-light {
361
+ background-color: var(--vc-highlight-light-bg);
362
+ border-radius: var(--vc-rounded-full);
363
+ }
364
+ .vc-highlight-bg-solid {
365
+ background-color: var(--vc-highlight-solid-bg);
366
+ border-radius: var(--vc-rounded-full);
367
+ }
368
+
369
+ .vc-highlight-content-outline,
370
+ .vc-highlight-content-none {
371
+ font-weight: var(--vc-font-bold);
372
+ color: var(--vc-highlight-outline-content-color);
373
+ }
374
+ .vc-highlight-content-light {
375
+ font-weight: var(--vc-font-bold);
376
+ color: var(--vc-highlight-light-content-color);
377
+ }
378
+ .vc-highlight-content-solid {
379
+ font-weight: var(--vc-font-bold);
380
+ color: var(--vc-highlight-solid-content-color);
381
+ }
382
+
383
+ /* ----Dots---- */
384
+
385
+ .vc-dots {
386
+ display: flex;
387
+ justify-content: center;
388
+ align-items: center;
389
+ }
390
+
391
+ .vc-dot {
392
+ width: 5px;
393
+ height: 5px;
394
+ border-radius: 9999px;
395
+ transition: var(--vc-day-content-transition);
396
+ &:not(:last-child) {
397
+ margin-right: 3px;
398
+ }
399
+ }
400
+
401
+ /* ----Bars---- */
402
+
403
+ .vc-bars {
404
+ display: flex;
405
+ justify-content: flex-start;
406
+ align-items: center;
407
+ width: 75%;
408
+ }
409
+
410
+ .vc-bar {
411
+ flex-grow: 1;
412
+ height: 3px;
413
+ transition: var(--vc-day-content-transition);
414
+ }
415
+
416
+ .vc-dot {
417
+ background-color: var(--vc-dot-bg);
418
+ }
419
+ .vc-bar {
420
+ background-color: var(--vc-bar-bg);
421
+ }
422
+ </style>
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <Popover :id="dayPopoverId" :class="[`vc-${color}`, `vc-${displayMode}`]">
3
+ <template #default="{ data: { day, attributes }, hide }">
4
+ <CalendarSlot
5
+ name="day-popover"
6
+ :day="day"
7
+ :day-title="dayTitle(day)"
8
+ :attributes="attributes"
9
+ :format="format"
10
+ :masks="masks"
11
+ :hide="hide"
12
+ >
13
+ <div class="vc-day-popover-container">
14
+ <div v-if="masks.dayPopover" class="vc-day-popover-header">
15
+ {{ dayTitle(day) }}
16
+ </div>
17
+ <PopoverRow
18
+ v-for="attribute in attributes"
19
+ :key="attribute.key"
20
+ :attribute="attribute"
21
+ />
22
+ </div>
23
+ </CalendarSlot>
24
+ </template>
25
+ </Popover>
26
+ </template>
27
+
28
+ <script setup lang="ts">
29
+ import { useCalendar } from '../../use/calendar';
30
+ import { CalendarDay } from '../../utils/page';
31
+ import Popover from '../Popover/Popover.vue';
32
+ import PopoverRow from '../Popover/PopoverRow.vue';
33
+ import CalendarSlot from './CalendarSlot.vue';
34
+
35
+ const { dayPopoverId, displayMode, color, masks, locale } = useCalendar();
36
+
37
+ function format(date: Date, mask: string) {
38
+ return locale.value.formatDate(date, mask);
39
+ }
40
+
41
+ function dayTitle(day: CalendarDay) {
42
+ return locale.value.formatDate(day.date, masks.value.dayPopover);
43
+ }
44
+ </script>
@@ -0,0 +1,203 @@
1
+ <template>
2
+ <div
3
+ class="vc-header"
4
+ :class="{ 'is-lg': isLg, 'is-xl': isXl, 'is-2xl': is2xl }"
5
+ :style="gridStyle"
6
+ >
7
+ <button
8
+ v-if="show.prev"
9
+ type="button"
10
+ class="vc-arrow vc-prev vc-focus"
11
+ :disabled="!canMovePrev"
12
+ @click="movePrev"
13
+ @keydown.space.enter="movePrev"
14
+ >
15
+ <CalendarSlot name="header-prev-button" :disabled="!canMovePrev">
16
+ <BaseIcon name="ChevronLeft" size="24" />
17
+ </CalendarSlot>
18
+ </button>
19
+ <div v-if="show.title" class="vc-title-wrapper">
20
+ <CalendarSlot name="header-title-wrapper">
21
+ <button type="button" class="vc-title" v-popover="navPopoverOptions">
22
+ <CalendarSlot name="header-title" :title="page.title">
23
+ <span>{{ page.title }}</span>
24
+ </CalendarSlot>
25
+ </button>
26
+ </CalendarSlot>
27
+ </div>
28
+ <button
29
+ v-if="show.next"
30
+ type="button"
31
+ class="vc-arrow vc-next vc-focus"
32
+ :disabled="!canMoveNext"
33
+ @click="moveNext"
34
+ @keydown.space.enter="moveNext"
35
+ >
36
+ <CalendarSlot name="header-next-button" :disabled="!canMoveNext">
37
+ <BaseIcon name="ChevronRight" size="24" />
38
+ </CalendarSlot>
39
+ </button>
40
+ </div>
41
+ </template>
42
+
43
+ <script setup lang="ts">
44
+ import { computed } from 'vue';
45
+ import { useCalendar } from '../../use/calendar';
46
+ import { Page } from '../../utils/page';
47
+ import { popoverDirective as vPopover } from '../../utils/popovers';
48
+ import BaseIcon from '../BaseIcon/BaseIcon.vue';
49
+ import CalendarSlot from './CalendarSlot.vue';
50
+
51
+ const props = defineProps<{
52
+ page: Page;
53
+ layout?: string;
54
+ isLg?: boolean;
55
+ isXl?: boolean;
56
+ is2xl?: boolean;
57
+ hideTitle?: boolean;
58
+ hideArrows?: boolean;
59
+ }>();
60
+
61
+ const {
62
+ navPopoverId,
63
+ navVisibility,
64
+ canMovePrev,
65
+ movePrev,
66
+ canMoveNext,
67
+ moveNext,
68
+ } = useCalendar();
69
+
70
+ const navPlacement = computed(() => {
71
+ switch (props.page.titlePosition) {
72
+ case 'left':
73
+ return 'bottom-start';
74
+ case 'right':
75
+ return 'bottom-end';
76
+ default:
77
+ return 'bottom';
78
+ }
79
+ });
80
+ const navPopoverOptions = computed(() => {
81
+ const { page } = props;
82
+ return {
83
+ id: navPopoverId.value,
84
+ visibility: navVisibility.value,
85
+ placement: navPlacement.value,
86
+ modifiers: [{ name: 'flip', options: { fallbackPlacements: ['bottom'] } }],
87
+ data: { page },
88
+ isInteractive: true,
89
+ };
90
+ });
91
+ const titleLeft = computed(() => props.page.titlePosition.includes('left'));
92
+ const titleRight = computed(() => props.page.titlePosition.includes('right'));
93
+ const layout_ = computed(() => {
94
+ if (props.layout) return props.layout;
95
+ if (titleLeft.value) return 'tu-pn';
96
+ if (titleRight.value) return 'pn-tu';
97
+ return 'p-tu-n;';
98
+ });
99
+ const show = computed(() => {
100
+ return {
101
+ prev: layout_.value.includes('p') && !props.hideArrows,
102
+ title: layout_.value.includes('t') && !props.hideTitle,
103
+ next: layout_.value.includes('n') && !props.hideArrows,
104
+ };
105
+ });
106
+ const gridStyle = computed(() => {
107
+ const gridTemplateColumns = layout_.value
108
+ .split('')
109
+ .map(l => {
110
+ switch (l) {
111
+ case 'p':
112
+ return '[prev] auto';
113
+ case 'n':
114
+ return '[next] auto';
115
+ case 't':
116
+ return '[title] auto';
117
+ case '-':
118
+ return '1fr';
119
+ default:
120
+ return '';
121
+ }
122
+ })
123
+ .join(' ');
124
+ return { gridTemplateColumns };
125
+ });
126
+ </script>
127
+
128
+ <style lang="css">
129
+ .vc-header {
130
+ display: grid;
131
+ grid-gap: 4px;
132
+ align-items: center;
133
+ height: 30px;
134
+ margin-top: 10px;
135
+ padding-left: 10px;
136
+ padding-right: 10px;
137
+
138
+ &.is-lg {
139
+ font-size: var(--vc-text-lg);
140
+ }
141
+ &.is-xl {
142
+ font-size: var(--vc-text-xl);
143
+ }
144
+ &.is-2xl {
145
+ font-size: var(--vc-text-2xl);
146
+ }
147
+
148
+ .vc-title-wrapper {
149
+ grid-row: 1;
150
+ grid-column: title;
151
+ }
152
+ .vc-prev {
153
+ grid-row: 1;
154
+ grid-column: prev;
155
+ }
156
+ .vc-next {
157
+ grid-row: 1;
158
+ grid-column: next;
159
+ }
160
+
161
+ .vc-title,
162
+ .vc-prev,
163
+ .vc-next {
164
+ display: flex;
165
+ align-items: center;
166
+ border: 0;
167
+ border-radius: var(--vc-rounded);
168
+ pointer-events: auto;
169
+ user-select: none;
170
+ cursor: pointer;
171
+ }
172
+
173
+ .vc-title {
174
+ color: var(--vc-header-title-color);
175
+ font-weight: var(--vc-font-semibold);
176
+ white-space: nowrap;
177
+ padding: 0 8px;
178
+ margin: 0;
179
+ line-height: 30px;
180
+ &:hover {
181
+ opacity: 0.75;
182
+ }
183
+ }
184
+
185
+ .vc-arrow {
186
+ display: flex;
187
+ justify-content: center;
188
+ align-items: center;
189
+ color: var(--vc-header-arrow-color);
190
+ width: 28px;
191
+ height: 30px;
192
+ margin: 0;
193
+ padding: 0;
194
+ &:hover {
195
+ background: var(--vc-header-arrow-hover-bg);
196
+ }
197
+ &:disabled {
198
+ opacity: 0.25;
199
+ pointer-events: none;
200
+ }
201
+ }
202
+ }
203
+ </style>