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.
- package/LICENSE +9 -0
- package/README.md +142 -0
- package/dist/cjs/index.css +1133 -0
- package/dist/cjs/index.js +10699 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/es/index.js +10678 -0
- package/dist/es/index.js.map +1 -0
- package/dist/es/style.css +1134 -0
- package/dist/iife/index.js +2 -0
- package/dist/iife/index.js.map +1 -0
- package/dist/mjs/index.mjs +10678 -0
- package/dist/mjs/index.mjs.map +1 -0
- package/dist/mjs/style.css +1134 -0
- package/dist/style.css +1134 -0
- package/dist/types/components/BaseIcon/BaseIcon.vue.d.ts +41 -0
- package/dist/types/components/BaseIcon/icons/IconChevronDown.vue.d.ts +3 -0
- package/dist/types/components/BaseIcon/icons/IconChevronLeft.vue.d.ts +3 -0
- package/dist/types/components/BaseIcon/icons/IconChevronRight.vue.d.ts +3 -0
- package/dist/types/components/BaseIcon/icons/IconClock.vue.d.ts +3 -0
- package/dist/types/components/BaseIcon/icons/index.d.ts +4 -0
- package/dist/types/components/BaseSelect/BaseSelect.vue.d.ts +26 -0
- package/dist/types/components/Calendar/Calendar.vue.d.ts +2526 -0
- package/dist/types/components/Calendar/CalendarDay.vue.d.ts +83 -0
- package/dist/types/components/Calendar/CalendarDayPopover.vue.d.ts +3 -0
- package/dist/types/components/Calendar/CalendarHeader.vue.d.ts +13 -0
- package/dist/types/components/Calendar/CalendarNav.vue.d.ts +4 -0
- package/dist/types/components/Calendar/CalendarNavPopover.vue.d.ts +3 -0
- package/dist/types/components/Calendar/CalendarPage.vue.d.ts +3 -0
- package/dist/types/components/Calendar/CalendarPageProvider.vue.d.ts +17 -0
- package/dist/types/components/Calendar/CalendarSlot.vue.d.ts +15 -0
- package/dist/types/components/Calendar/CalendarTitleSelect.vue.d.ts +15 -0
- package/dist/types/components/CalendarGrid/CalendarCell.vue.d.ts +9 -0
- package/dist/types/components/CalendarGrid/CalendarCellPopover.vue.d.ts +209 -0
- package/dist/types/components/CalendarGrid/CalendarDayCell.vue.d.ts +8 -0
- package/dist/types/components/CalendarGrid/CalendarEventDetails.vue.d.ts +15 -0
- package/dist/types/components/CalendarGrid/CalendarEventEdit.vue.d.ts +26 -0
- package/dist/types/components/CalendarGrid/CalendarGrid.vue.d.ts +134 -0
- package/dist/types/components/CalendarGrid/CalendarGridWeek.vue.d.ts +8 -0
- package/dist/types/components/CalendarGrid/CalendarViewSelect.vue.d.ts +3 -0
- package/dist/types/components/CalendarGrid/CalendarWeekCell.vue.d.ts +10 -0
- package/dist/types/components/CalendarGrid/Constraints.d.ts +16 -0
- package/dist/types/components/DatePicker/DatePicker.vue.d.ts +15251 -0
- package/dist/types/components/DatePicker/DatePickerBase.vue.d.ts +3 -0
- package/dist/types/components/DatePicker/DatePickerPopover.vue.d.ts +3 -0
- package/dist/types/components/DatePicker/TimePicker.vue.d.ts +10089 -0
- package/dist/types/components/Popover/Popover.vue.d.ts +72 -0
- package/dist/types/components/Popover/PopoverRow.vue.d.ts +17 -0
- package/dist/types/components/index.d.ts +4 -0
- package/dist/types/index.d.cts +40981 -0
- package/dist/types/index.d.mts +40981 -0
- package/dist/types/index.d.ts +40981 -0
- package/dist/types/use/base.d.ts +67 -0
- package/dist/types/use/calendar.d.ts +2422 -0
- package/dist/types/use/calendarGrid.d.ts +9370 -0
- package/dist/types/use/datePicker.d.ts +20210 -0
- package/dist/types/use/page.d.ts +20 -0
- package/dist/types/use/slots.d.ts +5 -0
- package/dist/types/use/timePicker.d.ts +10089 -0
- package/dist/types/utils/attribute.d.ts +49 -0
- package/dist/types/utils/cache.d.ts +10 -0
- package/dist/types/utils/calendar/event.d.ts +111 -0
- package/dist/types/utils/config/index.d.ts +5 -0
- package/dist/types/utils/date/helpers.d.ts +161 -0
- package/dist/types/utils/date/range.d.ts +74 -0
- package/dist/types/utils/date/repeat.d.ts +34 -0
- package/dist/types/utils/date/rules.d.ts +82 -0
- package/dist/types/utils/defaults/index.d.ts +30 -0
- package/dist/types/utils/defaults/locales.d.ts +9 -0
- package/dist/types/utils/glyph.d.ts +58 -0
- package/dist/types/utils/helpers.d.ts +49 -0
- package/dist/types/utils/locale.d.ts +48 -0
- package/dist/types/utils/page.d.ts +95 -0
- package/dist/types/utils/plugins/index.d.ts +4 -0
- package/dist/types/utils/popovers.d.ts +47 -0
- package/dist/types/utils/theme.d.ts +17 -0
- package/dist/types/utils/touch.d.ts +8 -0
- package/dist/types/utils/useDisplayMode.d.ts +12 -0
- package/dist/types/utils/watchers.d.ts +6 -0
- package/package.json +115 -0
- package/src/components/BaseIcon/BaseIcon.vue +29 -0
- package/src/components/BaseIcon/icons/IconChevronDown.vue +5 -0
- package/src/components/BaseIcon/icons/IconChevronLeft.vue +5 -0
- package/src/components/BaseIcon/icons/IconChevronRight.vue +5 -0
- package/src/components/BaseIcon/icons/IconClock.vue +11 -0
- package/src/components/BaseIcon/icons/index.ts +4 -0
- package/src/components/BaseSelect/BaseSelect.vue +136 -0
- package/src/components/Calendar/Calendar.vue +116 -0
- package/src/components/Calendar/CalendarDay.vue +422 -0
- package/src/components/Calendar/CalendarDayPopover.vue +44 -0
- package/src/components/Calendar/CalendarHeader.vue +203 -0
- package/src/components/Calendar/CalendarNav.vue +325 -0
- package/src/components/Calendar/CalendarNavPopover.vue +24 -0
- package/src/components/Calendar/CalendarPage.vue +140 -0
- package/src/components/Calendar/CalendarPageProvider.vue +15 -0
- package/src/components/Calendar/CalendarSlot.vue +36 -0
- package/src/components/Calendar/CalendarTitleSelect.vue +72 -0
- package/src/components/CalendarGrid/CalendarCell.vue +112 -0
- package/src/components/CalendarGrid/CalendarCellPopover.vue +93 -0
- package/src/components/CalendarGrid/CalendarDayCell.vue +57 -0
- package/src/components/CalendarGrid/CalendarEventDetails.vue +71 -0
- package/src/components/CalendarGrid/CalendarEventEdit.vue +195 -0
- package/src/components/CalendarGrid/CalendarGrid.vue +715 -0
- package/src/components/CalendarGrid/CalendarGridWeek.vue +60 -0
- package/src/components/CalendarGrid/CalendarViewSelect.vue +34 -0
- package/src/components/CalendarGrid/CalendarWeekCell.vue +52 -0
- package/src/components/CalendarGrid/Constraints.ts +40 -0
- package/src/components/DatePicker/DatePicker.vue +27 -0
- package/src/components/DatePicker/DatePickerBase.vue +53 -0
- package/src/components/DatePicker/DatePickerPopover.vue +37 -0
- package/src/components/DatePicker/TimePicker.vue +167 -0
- package/src/components/Popover/Popover.vue +572 -0
- package/src/components/Popover/PopoverRow.vue +94 -0
- package/src/components/index.ts +4 -0
- package/src/index.ts +24 -0
- package/src/styles/index.css +48 -0
- package/src/styles/theme.css +322 -0
- package/src/styles/transitions.css +77 -0
- package/src/use/base.ts +144 -0
- package/src/use/calendar.ts +796 -0
- package/src/use/calendarGrid.ts +954 -0
- package/src/use/datePicker.ts +909 -0
- package/src/use/page.ts +78 -0
- package/src/use/slots.ts +17 -0
- package/src/use/timePicker.ts +194 -0
- package/src/utils/attribute.ts +107 -0
- package/src/utils/cache.ts +30 -0
- package/src/utils/calendar/event.ts +335 -0
- package/src/utils/config/index.ts +11 -0
- package/src/utils/date/helpers.ts +1039 -0
- package/src/utils/date/range.ts +274 -0
- package/src/utils/date/repeat.ts +135 -0
- package/src/utils/date/rules.ts +290 -0
- package/src/utils/defaults/index.ts +77 -0
- package/src/utils/defaults/locales.ts +123 -0
- package/src/utils/defaults/masks.json +15 -0
- package/src/utils/defaults/touch.json +5 -0
- package/src/utils/glyph.ts +305 -0
- package/src/utils/helpers.ts +181 -0
- package/src/utils/locale.ts +275 -0
- package/src/utils/page.ts +608 -0
- package/src/utils/plugins/index.ts +24 -0
- package/src/utils/popovers.ts +216 -0
- package/src/utils/theme.ts +58 -0
- package/src/utils/touch.ts +72 -0
- package/src/utils/useDisplayMode.ts +198 -0
- package/src/utils/watchers.ts +26 -0
package/src/use/page.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { type Ref, inject, provide } from 'vue';
|
|
2
|
+
import { useCalendar } from '..';
|
|
3
|
+
import { getMonthDates } from '../utils/date/helpers';
|
|
4
|
+
import { type Page, getPageId } from '../utils/page';
|
|
5
|
+
|
|
6
|
+
export interface MonthNavItem {
|
|
7
|
+
month: number;
|
|
8
|
+
year: number;
|
|
9
|
+
id: string;
|
|
10
|
+
label: string;
|
|
11
|
+
ariaLabel: string;
|
|
12
|
+
isActive: boolean;
|
|
13
|
+
isCurrent: boolean;
|
|
14
|
+
isDisabled: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type YearNavItem = Omit<MonthNavItem, 'month'>;
|
|
18
|
+
|
|
19
|
+
export type CalendarPageContext = ReturnType<typeof createPage>;
|
|
20
|
+
|
|
21
|
+
const contextKey = Symbol('__vc_page_context__');
|
|
22
|
+
|
|
23
|
+
export function createPage(page: Ref<Page>) {
|
|
24
|
+
const { locale, getDateAddress, canMove } = useCalendar();
|
|
25
|
+
|
|
26
|
+
function getMonthItems(year: number, mask: string): MonthNavItem[] {
|
|
27
|
+
const { month: thisMonth, year: thisYear } = getDateAddress(new Date());
|
|
28
|
+
return getMonthDates().map((d, i: number) => {
|
|
29
|
+
const month = i + 1;
|
|
30
|
+
return {
|
|
31
|
+
month,
|
|
32
|
+
year,
|
|
33
|
+
id: getPageId(month, year),
|
|
34
|
+
label: locale.value.formatDate(d, mask),
|
|
35
|
+
ariaLabel: locale.value.formatDate(d, 'MMMM'),
|
|
36
|
+
isActive: month === page.value.month && year === page.value.year,
|
|
37
|
+
isCurrent: month === thisMonth && year === thisYear,
|
|
38
|
+
isDisabled: !canMove(
|
|
39
|
+
{ month, year },
|
|
40
|
+
{ position: page.value.position },
|
|
41
|
+
),
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function getYearItems(startYear: number, endYear: number): YearNavItem[] {
|
|
47
|
+
const { year: thisYear } = getDateAddress(new Date());
|
|
48
|
+
const { position } = page.value;
|
|
49
|
+
const items = [];
|
|
50
|
+
for (let year = startYear; year <= endYear; year += 1) {
|
|
51
|
+
const enabled = [...Array(12).keys()].some(m =>
|
|
52
|
+
canMove({ month: m + 1, year }, { position }),
|
|
53
|
+
);
|
|
54
|
+
items.push({
|
|
55
|
+
year,
|
|
56
|
+
id: year.toString(),
|
|
57
|
+
label: year.toString(),
|
|
58
|
+
ariaLabel: year.toString(),
|
|
59
|
+
isActive: year === page.value.year,
|
|
60
|
+
isCurrent: year === thisYear,
|
|
61
|
+
isDisabled: !enabled,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return items;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const context = { page, getMonthItems, getYearItems };
|
|
68
|
+
provide(contextKey, context);
|
|
69
|
+
return context;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function usePage(): CalendarPageContext {
|
|
73
|
+
const context = inject<CalendarPageContext>(contextKey);
|
|
74
|
+
if (context) return context;
|
|
75
|
+
throw new Error(
|
|
76
|
+
'Page context missing. Please verify this component is nested within a valid context provider.',
|
|
77
|
+
);
|
|
78
|
+
}
|
package/src/use/slots.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type SetupContext, inject, provide } from 'vue';
|
|
2
|
+
|
|
3
|
+
type Slots = SetupContext['slots'];
|
|
4
|
+
|
|
5
|
+
function contextKey(slotKey: string) {
|
|
6
|
+
return `__vc_slot_${slotKey}__`;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function provideSlots(slots: Slots, remap: Record<string, string> = {}) {
|
|
10
|
+
Object.keys(slots).forEach(slotKey => {
|
|
11
|
+
provide(contextKey(remap[slotKey] ?? slotKey), slots[slotKey]);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function useSlot(slotKey: string) {
|
|
16
|
+
return inject(contextKey(slotKey), null);
|
|
17
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { computed } from 'vue';
|
|
2
|
+
import { useDatePicker } from '../use/datePicker';
|
|
3
|
+
import {
|
|
4
|
+
type DateParts,
|
|
5
|
+
type SimpleDateParts,
|
|
6
|
+
getDatePartsOptions,
|
|
7
|
+
isDateParts,
|
|
8
|
+
} from '../utils/date/helpers';
|
|
9
|
+
import { arrayHasItems } from '../utils/helpers';
|
|
10
|
+
|
|
11
|
+
const _amOptions = [
|
|
12
|
+
{ value: 0, label: '12' },
|
|
13
|
+
{ value: 1, label: '1' },
|
|
14
|
+
{ value: 2, label: '2' },
|
|
15
|
+
{ value: 3, label: '3' },
|
|
16
|
+
{ value: 4, label: '4' },
|
|
17
|
+
{ value: 5, label: '5' },
|
|
18
|
+
{ value: 6, label: '6' },
|
|
19
|
+
{ value: 7, label: '7' },
|
|
20
|
+
{ value: 8, label: '8' },
|
|
21
|
+
{ value: 9, label: '9' },
|
|
22
|
+
{ value: 10, label: '10' },
|
|
23
|
+
{ value: 11, label: '11' },
|
|
24
|
+
];
|
|
25
|
+
const _pmOptions = [
|
|
26
|
+
{ value: 12, label: '12' },
|
|
27
|
+
{ value: 13, label: '1' },
|
|
28
|
+
{ value: 14, label: '2' },
|
|
29
|
+
{ value: 15, label: '3' },
|
|
30
|
+
{ value: 16, label: '4' },
|
|
31
|
+
{ value: 17, label: '5' },
|
|
32
|
+
{ value: 18, label: '6' },
|
|
33
|
+
{ value: 19, label: '7' },
|
|
34
|
+
{ value: 20, label: '8' },
|
|
35
|
+
{ value: 21, label: '9' },
|
|
36
|
+
{ value: 22, label: '10' },
|
|
37
|
+
{ value: 23, label: '11' },
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
export interface TimePickerProps {
|
|
41
|
+
position: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type TimePickerContext = ReturnType<typeof createTimePicker>;
|
|
45
|
+
|
|
46
|
+
export function createTimePicker(props: TimePickerProps) {
|
|
47
|
+
const ctx = useDatePicker();
|
|
48
|
+
const {
|
|
49
|
+
locale,
|
|
50
|
+
isRange,
|
|
51
|
+
isTimeMode,
|
|
52
|
+
dateParts,
|
|
53
|
+
rules,
|
|
54
|
+
is24hr,
|
|
55
|
+
hideTimeHeader,
|
|
56
|
+
timeAccuracy,
|
|
57
|
+
updateValue: updateDpValue,
|
|
58
|
+
} = ctx;
|
|
59
|
+
|
|
60
|
+
function updateParts(newParts: Partial<DateParts>) {
|
|
61
|
+
newParts = Object.assign(parts.value, newParts);
|
|
62
|
+
const newValue = isRange.value
|
|
63
|
+
? {
|
|
64
|
+
start: isStart.value ? newParts : dateParts.value[0],
|
|
65
|
+
end: isStart.value ? dateParts.value[1] : newParts,
|
|
66
|
+
}
|
|
67
|
+
: newParts;
|
|
68
|
+
updateDpValue(newValue, {
|
|
69
|
+
patch: 'time',
|
|
70
|
+
targetPriority: isStart.value ? 'start' : 'end',
|
|
71
|
+
moveToValue: true,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const isStart = computed(() => props.position === 0);
|
|
76
|
+
const parts = computed(
|
|
77
|
+
() => dateParts.value[props.position] || { isValid: false },
|
|
78
|
+
);
|
|
79
|
+
const partsValid = computed(() => isDateParts(parts.value));
|
|
80
|
+
const isValid = computed(() => !!parts.value.isValid);
|
|
81
|
+
const showHeader = computed(() => {
|
|
82
|
+
return !hideTimeHeader.value && isValid.value;
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const date = computed(() => {
|
|
86
|
+
if (!partsValid.value) return null;
|
|
87
|
+
let date = locale.value.toDate(parts.value as Partial<SimpleDateParts>);
|
|
88
|
+
if ((parts.value as DateParts).hours === 24) {
|
|
89
|
+
date = new Date(date.getTime() - 1);
|
|
90
|
+
}
|
|
91
|
+
return date;
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const hours = computed({
|
|
95
|
+
get() {
|
|
96
|
+
return (parts.value as DateParts).hours;
|
|
97
|
+
},
|
|
98
|
+
set(val) {
|
|
99
|
+
updateParts({ hours: val });
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const minutes = computed({
|
|
104
|
+
get() {
|
|
105
|
+
return (parts.value as DateParts).minutes;
|
|
106
|
+
},
|
|
107
|
+
set(val) {
|
|
108
|
+
updateParts({ minutes: val });
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const seconds = computed({
|
|
113
|
+
get() {
|
|
114
|
+
return (parts.value as DateParts).seconds;
|
|
115
|
+
},
|
|
116
|
+
set(val) {
|
|
117
|
+
updateParts({ seconds: val });
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const milliseconds = computed({
|
|
122
|
+
get() {
|
|
123
|
+
return (parts.value as DateParts).milliseconds;
|
|
124
|
+
},
|
|
125
|
+
set(val) {
|
|
126
|
+
updateParts({ milliseconds: val });
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const isAM = computed({
|
|
131
|
+
get() {
|
|
132
|
+
return (parts.value as DateParts).hours < 12;
|
|
133
|
+
},
|
|
134
|
+
set(value) {
|
|
135
|
+
value = String(value).toLowerCase() == 'true';
|
|
136
|
+
let hValue = hours.value;
|
|
137
|
+
if (value && hValue >= 12) {
|
|
138
|
+
hValue -= 12;
|
|
139
|
+
} else if (!value && hValue < 12) {
|
|
140
|
+
hValue += 12;
|
|
141
|
+
}
|
|
142
|
+
updateParts({ hours: hValue });
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const options = computed(() =>
|
|
147
|
+
getDatePartsOptions(parts.value as DateParts, rules.value[props.position]),
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
const amHourOptions = computed(() => {
|
|
151
|
+
return _amOptions.filter(opt =>
|
|
152
|
+
options.value.hours.some(ho => ho.value === opt.value),
|
|
153
|
+
);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const pmHourOptions = computed(() => {
|
|
157
|
+
return _pmOptions.filter(opt =>
|
|
158
|
+
options.value.hours.some(ho => ho.value === opt.value),
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const hourOptions = computed(() => {
|
|
163
|
+
if (is24hr.value) return options.value.hours;
|
|
164
|
+
if (isAM.value) return amHourOptions.value;
|
|
165
|
+
return pmHourOptions.value;
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const isAMOptions = computed(() => {
|
|
169
|
+
const result = [];
|
|
170
|
+
if (arrayHasItems(amHourOptions.value))
|
|
171
|
+
result.push({ value: true, label: 'AM' });
|
|
172
|
+
if (arrayHasItems(pmHourOptions.value))
|
|
173
|
+
result.push({ value: false, label: 'PM' });
|
|
174
|
+
return result;
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
...ctx,
|
|
179
|
+
showHeader,
|
|
180
|
+
timeAccuracy,
|
|
181
|
+
parts,
|
|
182
|
+
isValid,
|
|
183
|
+
date,
|
|
184
|
+
hours,
|
|
185
|
+
minutes,
|
|
186
|
+
seconds,
|
|
187
|
+
milliseconds,
|
|
188
|
+
options,
|
|
189
|
+
hourOptions,
|
|
190
|
+
isAM,
|
|
191
|
+
isAMOptions,
|
|
192
|
+
is24hr,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { Placement } from '@popperjs/core';
|
|
2
|
+
import { addDays } from './date/helpers';
|
|
3
|
+
import { DateRange, type DateRangeSource } from './date/range';
|
|
4
|
+
import {
|
|
5
|
+
Bar,
|
|
6
|
+
BarConfig,
|
|
7
|
+
Content,
|
|
8
|
+
ContentConfig,
|
|
9
|
+
Dot,
|
|
10
|
+
DotConfig,
|
|
11
|
+
Highlight,
|
|
12
|
+
HighlightConfig,
|
|
13
|
+
Profile,
|
|
14
|
+
} from './glyph';
|
|
15
|
+
import { arrayHasItems } from './helpers';
|
|
16
|
+
import Locale from './locale';
|
|
17
|
+
import type { PopoverVisibility } from './popovers';
|
|
18
|
+
import { Theme } from './theme';
|
|
19
|
+
|
|
20
|
+
export type PopoverConfig = Partial<{
|
|
21
|
+
label: string;
|
|
22
|
+
visibility: PopoverVisibility;
|
|
23
|
+
placement: Placement;
|
|
24
|
+
hideIndicator: boolean;
|
|
25
|
+
isInteractive: boolean;
|
|
26
|
+
}>;
|
|
27
|
+
|
|
28
|
+
export type EventConfig = Partial<{
|
|
29
|
+
label: string;
|
|
30
|
+
}>;
|
|
31
|
+
|
|
32
|
+
export type AttributeConfig = Partial<{
|
|
33
|
+
key: string | number;
|
|
34
|
+
hashcode: string;
|
|
35
|
+
content: ContentConfig;
|
|
36
|
+
highlight: HighlightConfig;
|
|
37
|
+
dot: DotConfig;
|
|
38
|
+
bar: BarConfig;
|
|
39
|
+
popover: PopoverConfig;
|
|
40
|
+
event: EventConfig;
|
|
41
|
+
dates: DateRangeSource[];
|
|
42
|
+
customData: any;
|
|
43
|
+
order: number;
|
|
44
|
+
pinPage: boolean;
|
|
45
|
+
}>;
|
|
46
|
+
|
|
47
|
+
let attrKey = 0;
|
|
48
|
+
|
|
49
|
+
export class Attribute {
|
|
50
|
+
key: string | number = '';
|
|
51
|
+
hashcode = '';
|
|
52
|
+
highlight: Profile<Highlight> | null = null;
|
|
53
|
+
content: Profile<Content> | null = null;
|
|
54
|
+
dot: Profile<Dot> | null = null;
|
|
55
|
+
bar: Profile<Bar> | null = null;
|
|
56
|
+
event: EventConfig | null = null;
|
|
57
|
+
popover: PopoverConfig | null = null;
|
|
58
|
+
customData: any = null;
|
|
59
|
+
ranges: DateRange[];
|
|
60
|
+
hasRanges = false;
|
|
61
|
+
order = 0;
|
|
62
|
+
pinPage = false;
|
|
63
|
+
maxRepeatSpan = 0;
|
|
64
|
+
locale: Locale;
|
|
65
|
+
|
|
66
|
+
constructor(config: Partial<AttributeConfig>, theme: Theme, locale: Locale) {
|
|
67
|
+
const { dates } = Object.assign(
|
|
68
|
+
this,
|
|
69
|
+
{ hashcode: '', order: 0, pinPage: false },
|
|
70
|
+
config,
|
|
71
|
+
);
|
|
72
|
+
this.key ||= ++attrKey;
|
|
73
|
+
this.locale = locale;
|
|
74
|
+
// Normalize attribute
|
|
75
|
+
theme.normalizeGlyphs(this);
|
|
76
|
+
// Assign dates
|
|
77
|
+
this.ranges = locale.ranges(dates ?? []);
|
|
78
|
+
this.hasRanges = !!arrayHasItems(this.ranges);
|
|
79
|
+
this.maxRepeatSpan = this.ranges
|
|
80
|
+
.filter(r => r.hasRepeat)
|
|
81
|
+
.map(r => r.daySpan)
|
|
82
|
+
.reduce((res, curr) => Math.max(res, curr), 0);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
intersectsRange({ start, end }: DateRange) {
|
|
86
|
+
if (start == null || end == null) return false;
|
|
87
|
+
const simpleRanges = this.ranges.filter(r => !r.hasRepeat);
|
|
88
|
+
for (const range of simpleRanges) {
|
|
89
|
+
if (range.intersectsDayRange(start.dayIndex, end.dayIndex)) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const repeatRanges = this.ranges.filter(r => r.hasRepeat);
|
|
94
|
+
if (!repeatRanges.length) return false;
|
|
95
|
+
let day = start;
|
|
96
|
+
if (this.maxRepeatSpan > 1) {
|
|
97
|
+
day = this.locale.getDateParts(addDays(day.date, -this.maxRepeatSpan));
|
|
98
|
+
}
|
|
99
|
+
while (day.dayIndex <= end.dayIndex) {
|
|
100
|
+
for (const range of repeatRanges) {
|
|
101
|
+
if (range.startsOnDay(day)) return true;
|
|
102
|
+
}
|
|
103
|
+
day = this.locale.getDateParts(addDays(day.date, 1));
|
|
104
|
+
}
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export default class Cache<T> {
|
|
2
|
+
keys: string[] = [];
|
|
3
|
+
store: Record<string, T> = {};
|
|
4
|
+
|
|
5
|
+
constructor(
|
|
6
|
+
public size: number,
|
|
7
|
+
public createKey: (...args: any[]) => string,
|
|
8
|
+
public createItem: (...args: any[]) => T,
|
|
9
|
+
) {}
|
|
10
|
+
|
|
11
|
+
get(...args: any[]) {
|
|
12
|
+
const key = this.createKey(...args);
|
|
13
|
+
return this.store[key];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
getOrSet(...args: any[]): T {
|
|
17
|
+
const key = this.createKey(...args);
|
|
18
|
+
if (this.store[key]) return this.store[key];
|
|
19
|
+
const item = this.createItem(...args);
|
|
20
|
+
if (this.keys.length >= this.size) {
|
|
21
|
+
const removeKey = this.keys.shift();
|
|
22
|
+
if (removeKey != null) {
|
|
23
|
+
delete this.store[removeKey];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
this.keys.push(key);
|
|
27
|
+
this.store[key] = item;
|
|
28
|
+
return item;
|
|
29
|
+
}
|
|
30
|
+
}
|