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
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type App, computed, reactive } from 'vue';
|
|
2
|
+
import type { DarkModeConfig } from '../useDisplayMode';
|
|
3
|
+
import { defaultsDeep, get, has, mapValues } from '../helpers';
|
|
4
|
+
import locales from './locales';
|
|
5
|
+
import masks from './masks.json';
|
|
6
|
+
import touch from './touch.json';
|
|
7
|
+
|
|
8
|
+
declare const window: any;
|
|
9
|
+
|
|
10
|
+
interface DatePickerPopoverDefaults {
|
|
11
|
+
visibility?: string;
|
|
12
|
+
placement?: string;
|
|
13
|
+
isInteractive?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface DatePickerDefaults {
|
|
17
|
+
updateOnInput?: boolean;
|
|
18
|
+
inputDebounce?: number;
|
|
19
|
+
popover?: DatePickerPopoverDefaults;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface Defaults {
|
|
23
|
+
componentPrefix?: string;
|
|
24
|
+
color?: string;
|
|
25
|
+
isDark?: DarkModeConfig;
|
|
26
|
+
navVisibility?: string;
|
|
27
|
+
titlePosition?: string;
|
|
28
|
+
transition?: string;
|
|
29
|
+
touch?: object;
|
|
30
|
+
masks?: object;
|
|
31
|
+
locales?: any;
|
|
32
|
+
datePicker?: DatePickerDefaults;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const defaultConfig: Defaults = {
|
|
36
|
+
componentPrefix: 'V',
|
|
37
|
+
color: 'blue',
|
|
38
|
+
isDark: false,
|
|
39
|
+
navVisibility: 'click',
|
|
40
|
+
titlePosition: 'center',
|
|
41
|
+
transition: 'slide-h',
|
|
42
|
+
touch,
|
|
43
|
+
masks,
|
|
44
|
+
locales,
|
|
45
|
+
datePicker: {
|
|
46
|
+
updateOnInput: true,
|
|
47
|
+
inputDebounce: 1000,
|
|
48
|
+
popover: {
|
|
49
|
+
visibility: 'hover-focus',
|
|
50
|
+
placement: 'bottom-start',
|
|
51
|
+
isInteractive: true,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const state = reactive(defaultConfig);
|
|
57
|
+
|
|
58
|
+
const defaultLocales = computed(() => {
|
|
59
|
+
return mapValues(state.locales, (l: any) => {
|
|
60
|
+
l.masks = defaultsDeep(l.masks, state.masks);
|
|
61
|
+
return l;
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export { defaultLocales };
|
|
66
|
+
|
|
67
|
+
export const getDefault = (path: string) => {
|
|
68
|
+
if (typeof window !== 'undefined' && has(window.__vcalendar__, path)) {
|
|
69
|
+
return get(window.__vcalendar__, path);
|
|
70
|
+
}
|
|
71
|
+
return get(state, path);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const setupDefaults = (app: App, userDefaults: Defaults | undefined) => {
|
|
75
|
+
app.config.globalProperties.$VCalendar = state;
|
|
76
|
+
return Object.assign(state, defaultsDeep(userDefaults, state));
|
|
77
|
+
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
interface LocaleConfig {
|
|
2
|
+
dow: number;
|
|
3
|
+
L: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
interface LocaleSetting {
|
|
7
|
+
id: string;
|
|
8
|
+
firstDayOfWeek: number;
|
|
9
|
+
masks: {
|
|
10
|
+
L: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const locales: Record<string, LocaleConfig> = {
|
|
15
|
+
// Arabic
|
|
16
|
+
ar: { dow: 7, L: 'D/\u200FM/\u200FYYYY' },
|
|
17
|
+
// Bulgarian
|
|
18
|
+
bg: { dow: 2, L: 'D.MM.YYYY' },
|
|
19
|
+
// Catalan
|
|
20
|
+
ca: { dow: 2, L: 'DD/MM/YYYY' },
|
|
21
|
+
// Chinese (China)
|
|
22
|
+
'zh-CN': { dow: 2, L: 'YYYY/MM/DD' },
|
|
23
|
+
// Chinese (Taiwan)
|
|
24
|
+
'zh-TW': { dow: 1, L: 'YYYY/MM/DD' },
|
|
25
|
+
// Croatian
|
|
26
|
+
hr: { dow: 2, L: 'DD.MM.YYYY' },
|
|
27
|
+
// Czech
|
|
28
|
+
cs: { dow: 2, L: 'DD.MM.YYYY' },
|
|
29
|
+
// Danish
|
|
30
|
+
da: { dow: 2, L: 'DD.MM.YYYY' },
|
|
31
|
+
// Dutch
|
|
32
|
+
nl: { dow: 2, L: 'DD-MM-YYYY' },
|
|
33
|
+
// English (US)
|
|
34
|
+
'en-US': { dow: 1, L: 'MM/DD/YYYY' },
|
|
35
|
+
// English (Australia)
|
|
36
|
+
'en-AU': { dow: 2, L: 'DD/MM/YYYY' },
|
|
37
|
+
// English (Canada)
|
|
38
|
+
'en-CA': { dow: 1, L: 'YYYY-MM-DD' },
|
|
39
|
+
// English (Great Britain)
|
|
40
|
+
'en-GB': { dow: 2, L: 'DD/MM/YYYY' },
|
|
41
|
+
// English (Ireland)
|
|
42
|
+
'en-IE': { dow: 2, L: 'DD-MM-YYYY' },
|
|
43
|
+
// English (New Zealand)
|
|
44
|
+
'en-NZ': { dow: 2, L: 'DD/MM/YYYY' },
|
|
45
|
+
// English (South Africa)
|
|
46
|
+
'en-ZA': { dow: 1, L: 'YYYY/MM/DD' },
|
|
47
|
+
// Esperanto
|
|
48
|
+
eo: { dow: 2, L: 'YYYY-MM-DD' },
|
|
49
|
+
// Estonian
|
|
50
|
+
et: { dow: 2, L: 'DD.MM.YYYY' },
|
|
51
|
+
// Finnish
|
|
52
|
+
fi: { dow: 2, L: 'DD.MM.YYYY' },
|
|
53
|
+
// French
|
|
54
|
+
fr: { dow: 2, L: 'DD/MM/YYYY' },
|
|
55
|
+
// French (Canada)
|
|
56
|
+
'fr-CA': { dow: 1, L: 'YYYY-MM-DD' },
|
|
57
|
+
// French (Switzerland)
|
|
58
|
+
'fr-CH': { dow: 2, L: 'DD.MM.YYYY' },
|
|
59
|
+
// German
|
|
60
|
+
de: { dow: 2, L: 'DD.MM.YYYY' },
|
|
61
|
+
// Hebrew
|
|
62
|
+
he: { dow: 1, L: 'DD.MM.YYYY' },
|
|
63
|
+
// Indonesian
|
|
64
|
+
id: { dow: 2, L: 'DD/MM/YYYY' },
|
|
65
|
+
// Italian
|
|
66
|
+
it: { dow: 2, L: 'DD/MM/YYYY' },
|
|
67
|
+
// Japanese
|
|
68
|
+
ja: { dow: 1, L: 'YYYY年M月D日' },
|
|
69
|
+
// Korean
|
|
70
|
+
ko: { dow: 1, L: 'YYYY.MM.DD' },
|
|
71
|
+
// Latvian
|
|
72
|
+
lv: { dow: 2, L: 'DD.MM.YYYY' },
|
|
73
|
+
// Lithuanian
|
|
74
|
+
lt: { dow: 2, L: 'DD.MM.YYYY' },
|
|
75
|
+
// Macedonian
|
|
76
|
+
mk: { dow: 2, L: 'D.MM.YYYY' },
|
|
77
|
+
// Norwegian
|
|
78
|
+
nb: { dow: 2, L: 'D. MMMM YYYY' },
|
|
79
|
+
nn: { dow: 2, L: 'D. MMMM YYYY' },
|
|
80
|
+
// Polish
|
|
81
|
+
pl: { dow: 2, L: 'DD.MM.YYYY' },
|
|
82
|
+
// Portuguese
|
|
83
|
+
pt: { dow: 2, L: 'DD/MM/YYYY' },
|
|
84
|
+
// Romanian
|
|
85
|
+
ro: { dow: 2, L: 'DD.MM.YYYY' },
|
|
86
|
+
// Russian
|
|
87
|
+
ru: { dow: 2, L: 'DD.MM.YYYY' },
|
|
88
|
+
// Slovak
|
|
89
|
+
sk: { dow: 2, L: 'DD.MM.YYYY' },
|
|
90
|
+
// Spanish (Spain)
|
|
91
|
+
'es-ES': { dow: 2, L: 'DD/MM/YYYY' },
|
|
92
|
+
// Spanish (Mexico)
|
|
93
|
+
'es-MX': { dow: 2, L: 'DD/MM/YYYY' },
|
|
94
|
+
// Swedish
|
|
95
|
+
sv: { dow: 2, L: 'YYYY-MM-DD' },
|
|
96
|
+
// Thai
|
|
97
|
+
th: { dow: 1, L: 'DD/MM/YYYY' },
|
|
98
|
+
// Turkish
|
|
99
|
+
tr: { dow: 2, L: 'DD.MM.YYYY' },
|
|
100
|
+
// Ukrainian
|
|
101
|
+
uk: { dow: 2, L: 'DD.MM.YYYY' },
|
|
102
|
+
// Vietnam
|
|
103
|
+
vi: { dow: 2, L: 'DD/MM/YYYY' },
|
|
104
|
+
};
|
|
105
|
+
locales.en = locales['en-US'];
|
|
106
|
+
locales.es = locales['es-ES'];
|
|
107
|
+
locales.no = locales.nb;
|
|
108
|
+
locales.zh = locales['zh-CN'];
|
|
109
|
+
|
|
110
|
+
// Remap from abbr. to intuitive property names
|
|
111
|
+
const localeSettings = Object.entries(locales).reduce(
|
|
112
|
+
(res, [id, { dow, L }]) => {
|
|
113
|
+
res[id] = {
|
|
114
|
+
id,
|
|
115
|
+
firstDayOfWeek: dow,
|
|
116
|
+
masks: { L },
|
|
117
|
+
};
|
|
118
|
+
return res;
|
|
119
|
+
},
|
|
120
|
+
{} as Record<string, LocaleSetting>,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
export default localeSettings;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "MMMM YYYY",
|
|
3
|
+
"weekdays": "W",
|
|
4
|
+
"navMonths": "MMM",
|
|
5
|
+
"hours": "h A",
|
|
6
|
+
"input": ["L", "YYYY-MM-DD", "YYYY/MM/DD"],
|
|
7
|
+
"inputDateTime": ["L h:mm A", "YYYY-MM-DD h:mm A", "YYYY/MM/DD h:mm A"],
|
|
8
|
+
"inputDateTime24hr": ["L HH:mm", "YYYY-MM-DD HH:mm", "YYYY/MM/DD HH:mm"],
|
|
9
|
+
"inputTime": ["h:mm A"],
|
|
10
|
+
"inputTime24hr": ["HH:mm"],
|
|
11
|
+
"dayPopover": "WWW, MMM D, YYYY",
|
|
12
|
+
"data": ["L", "YYYY-MM-DD", "YYYY/MM/DD"],
|
|
13
|
+
"model": "iso",
|
|
14
|
+
"iso": "YYYY-MM-DDTHH:mm:ss.SSSZ"
|
|
15
|
+
}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { Attribute } from './attribute';
|
|
2
|
+
import type { DateRangeCell } from './date/range';
|
|
3
|
+
import { defaultsDeep, hasAny, isObject, isString } from './helpers';
|
|
4
|
+
|
|
5
|
+
type GlyphTarget = 'base' | 'start' | 'end' | 'startEnd';
|
|
6
|
+
type ThemeProp =
|
|
7
|
+
| 'class'
|
|
8
|
+
| 'wrapperClass'
|
|
9
|
+
| 'contentClass'
|
|
10
|
+
| 'style'
|
|
11
|
+
| 'contentStyle'
|
|
12
|
+
| 'color'
|
|
13
|
+
| 'fillMode';
|
|
14
|
+
|
|
15
|
+
const targetProps: GlyphTarget[] = ['base', 'start', 'end', 'startEnd'];
|
|
16
|
+
const displayProps: ThemeProp[] = [
|
|
17
|
+
'class',
|
|
18
|
+
'wrapperClass',
|
|
19
|
+
'contentClass',
|
|
20
|
+
'style',
|
|
21
|
+
'contentStyle',
|
|
22
|
+
'color',
|
|
23
|
+
'fillMode',
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
export interface Glyph {
|
|
27
|
+
key: string | number;
|
|
28
|
+
color: string;
|
|
29
|
+
class: string | any[];
|
|
30
|
+
style: Record<string, any>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface Profile<T> {
|
|
34
|
+
start: T;
|
|
35
|
+
base: T;
|
|
36
|
+
end: T;
|
|
37
|
+
startEnd?: T;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Highlights
|
|
41
|
+
export type HighlightFillMode = 'solid' | 'light' | 'outline';
|
|
42
|
+
export interface Highlight extends Glyph {
|
|
43
|
+
fillMode: HighlightFillMode;
|
|
44
|
+
wrapperClass: string | any[];
|
|
45
|
+
contentClass: string | any[];
|
|
46
|
+
contentStyle: Record<string, any>;
|
|
47
|
+
}
|
|
48
|
+
export type HighlightConfig =
|
|
49
|
+
| boolean
|
|
50
|
+
| string
|
|
51
|
+
| Partial<Highlight | Profile<Partial<Highlight>>>;
|
|
52
|
+
|
|
53
|
+
// Dots
|
|
54
|
+
export type Dot = Glyph;
|
|
55
|
+
export type DotConfig = boolean | string | Partial<Dot | Profile<Partial<Dot>>>;
|
|
56
|
+
|
|
57
|
+
// Bars
|
|
58
|
+
export type Bar = Glyph;
|
|
59
|
+
export type BarConfig = boolean | string | Partial<Bar | Profile<Partial<Bar>>>;
|
|
60
|
+
|
|
61
|
+
// Content
|
|
62
|
+
export type Content = Glyph;
|
|
63
|
+
export type ContentConfig =
|
|
64
|
+
| string
|
|
65
|
+
| Partial<Content | Profile<Partial<Content>>>;
|
|
66
|
+
|
|
67
|
+
const _defaultProfile = { base: {}, start: {}, end: {} };
|
|
68
|
+
|
|
69
|
+
function normalizeConfig(
|
|
70
|
+
color: string,
|
|
71
|
+
config: any,
|
|
72
|
+
defaultProfile: any = _defaultProfile,
|
|
73
|
+
): Profile<Glyph> {
|
|
74
|
+
let rootColor = color;
|
|
75
|
+
let root: any = {};
|
|
76
|
+
// Get the normalized root config
|
|
77
|
+
if (config === true || isString(config)) {
|
|
78
|
+
// Assign default color for booleans or strings
|
|
79
|
+
rootColor = isString(config) ? config : rootColor;
|
|
80
|
+
// Set the default root
|
|
81
|
+
root = { ...defaultProfile };
|
|
82
|
+
} else if (isObject(config)) {
|
|
83
|
+
if (hasAny(config as Record<string, any>, targetProps)) {
|
|
84
|
+
// Mixin target configs
|
|
85
|
+
root = { ...config };
|
|
86
|
+
} else {
|
|
87
|
+
// Mixin display configs
|
|
88
|
+
root = {
|
|
89
|
+
base: { ...(config as Record<string, any>) },
|
|
90
|
+
start: { ...(config as Record<string, any>) },
|
|
91
|
+
end: { ...(config as Record<string, any>) },
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Fill in missing targets
|
|
96
|
+
const result = defaultsDeep(
|
|
97
|
+
root,
|
|
98
|
+
{ start: root.startEnd, end: root.startEnd },
|
|
99
|
+
defaultProfile,
|
|
100
|
+
) as Profile<any>;
|
|
101
|
+
// Normalize each target
|
|
102
|
+
Object.entries(result).forEach(([targetType, targetConfig]) => {
|
|
103
|
+
let targetColor = rootColor;
|
|
104
|
+
if (targetConfig === true || isString(targetConfig)) {
|
|
105
|
+
targetColor = isString(targetConfig) ? targetConfig : targetColor;
|
|
106
|
+
// @ts-ignore
|
|
107
|
+
result[targetType] = { color: targetColor };
|
|
108
|
+
} else if (isObject(targetConfig)) {
|
|
109
|
+
if (hasAny(targetConfig, displayProps)) {
|
|
110
|
+
// @ts-ignore
|
|
111
|
+
result[targetType] = { ...targetConfig };
|
|
112
|
+
} else {
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
result[targetType] = {};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Set the theme color if it is missing
|
|
118
|
+
// @ts-ignore
|
|
119
|
+
defaultsDeep(result[targetType], { color: targetColor });
|
|
120
|
+
});
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface GlyphRenderer<P extends Partial<Glyph>> {
|
|
125
|
+
type: string;
|
|
126
|
+
normalizeConfig(color: string, config: any): Profile<P>;
|
|
127
|
+
prepareRender(glyphs: Record<string, P[]>): void;
|
|
128
|
+
render(attr: DateRangeCell<Attribute>, glyphs: Record<string, P[]>): void;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export class HighlightRenderer implements GlyphRenderer<Highlight> {
|
|
132
|
+
type = 'highlight';
|
|
133
|
+
|
|
134
|
+
normalizeConfig(color: string, config: any) {
|
|
135
|
+
return normalizeConfig(color, config, {
|
|
136
|
+
base: { fillMode: 'light' },
|
|
137
|
+
start: { fillMode: 'solid' },
|
|
138
|
+
end: { fillMode: 'solid' },
|
|
139
|
+
}) as Profile<Highlight>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
prepareRender(glyphs: Record<string, Glyph[]>) {
|
|
143
|
+
glyphs.highlights = [];
|
|
144
|
+
if (!glyphs.content) glyphs.content = [];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
render(
|
|
148
|
+
{ data, onStart, onEnd }: DateRangeCell<Attribute>,
|
|
149
|
+
glyphs: Record<string, Highlight[]>,
|
|
150
|
+
) {
|
|
151
|
+
const { key, highlight } = data;
|
|
152
|
+
if (!highlight) return;
|
|
153
|
+
const { highlights } = glyphs;
|
|
154
|
+
const { base, start, end } = highlight;
|
|
155
|
+
if (onStart && onEnd) {
|
|
156
|
+
highlights.push({
|
|
157
|
+
...start,
|
|
158
|
+
key,
|
|
159
|
+
wrapperClass: `vc-day-layer vc-day-box-center-center vc-attr vc-${start.color}`,
|
|
160
|
+
class: [`vc-highlight vc-highlight-bg-${start.fillMode}`, start.class],
|
|
161
|
+
contentClass: [
|
|
162
|
+
`vc-attr vc-highlight-content-${start.fillMode} vc-${start.color}`,
|
|
163
|
+
start.contentClass,
|
|
164
|
+
],
|
|
165
|
+
});
|
|
166
|
+
} else if (onStart) {
|
|
167
|
+
highlights.push({
|
|
168
|
+
...base,
|
|
169
|
+
key: `${key}-base`,
|
|
170
|
+
wrapperClass: `vc-day-layer vc-day-box-right-center vc-attr vc-${base.color}`,
|
|
171
|
+
class: [
|
|
172
|
+
`vc-highlight vc-highlight-base-start vc-highlight-bg-${base.fillMode}`,
|
|
173
|
+
base.class,
|
|
174
|
+
],
|
|
175
|
+
});
|
|
176
|
+
highlights.push({
|
|
177
|
+
...start,
|
|
178
|
+
key,
|
|
179
|
+
wrapperClass: `vc-day-layer vc-day-box-center-center vc-attr vc-${start.color}`,
|
|
180
|
+
class: [`vc-highlight vc-highlight-bg-${start.fillMode}`, start.class],
|
|
181
|
+
contentClass: [
|
|
182
|
+
`vc-attr vc-highlight-content-${start.fillMode} vc-${start.color}`,
|
|
183
|
+
start.contentClass,
|
|
184
|
+
],
|
|
185
|
+
});
|
|
186
|
+
} else if (onEnd) {
|
|
187
|
+
highlights.push({
|
|
188
|
+
...base,
|
|
189
|
+
key: `${key}-base`,
|
|
190
|
+
wrapperClass: `vc-day-layer vc-day-box-left-center vc-attr vc-${base.color}`,
|
|
191
|
+
class: [
|
|
192
|
+
`vc-highlight vc-highlight-base-end vc-highlight-bg-${base.fillMode}`,
|
|
193
|
+
base.class,
|
|
194
|
+
],
|
|
195
|
+
});
|
|
196
|
+
highlights.push({
|
|
197
|
+
...end,
|
|
198
|
+
key,
|
|
199
|
+
wrapperClass: `vc-day-layer vc-day-box-center-center vc-attr vc-${end.color}`,
|
|
200
|
+
class: [`vc-highlight vc-highlight-bg-${end.fillMode}`, end.class],
|
|
201
|
+
contentClass: [
|
|
202
|
+
`vc-attr vc-highlight-content-${end.fillMode} vc-${end.color}`,
|
|
203
|
+
end.contentClass,
|
|
204
|
+
],
|
|
205
|
+
});
|
|
206
|
+
} else {
|
|
207
|
+
highlights.push({
|
|
208
|
+
...base,
|
|
209
|
+
key: `${key}-middle`,
|
|
210
|
+
wrapperClass: `vc-day-layer vc-day-box-center-center vc-attr vc-${base.color}`,
|
|
211
|
+
class: [
|
|
212
|
+
`vc-highlight vc-highlight-base-middle vc-highlight-bg-${base.fillMode}`,
|
|
213
|
+
base.class,
|
|
214
|
+
],
|
|
215
|
+
contentClass: [
|
|
216
|
+
`vc-attr vc-highlight-content-${base.fillMode} vc-${base.color}`,
|
|
217
|
+
base.contentClass,
|
|
218
|
+
],
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export class BaseRenderer<T extends Partial<Glyph>>
|
|
225
|
+
implements GlyphRenderer<T>
|
|
226
|
+
{
|
|
227
|
+
type = '';
|
|
228
|
+
collectionType = '';
|
|
229
|
+
|
|
230
|
+
constructor(type: string, collectionType: string) {
|
|
231
|
+
this.type = type;
|
|
232
|
+
this.collectionType = collectionType;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
normalizeConfig(color: string, config: any) {
|
|
236
|
+
return normalizeConfig(color, config) as Profile<T>;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
prepareRender(glyphs: Record<string, T[]>) {
|
|
240
|
+
glyphs[this.collectionType] = [];
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
render(
|
|
244
|
+
{ data, onStart, onEnd }: DateRangeCell<Attribute>,
|
|
245
|
+
glyphs: Record<string, T[]>,
|
|
246
|
+
) {
|
|
247
|
+
const { key } = data;
|
|
248
|
+
const item = data[this.type as keyof Attribute];
|
|
249
|
+
if (!key || !item) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const collection = glyphs[this.collectionType];
|
|
253
|
+
const { base, start, end } = item;
|
|
254
|
+
if (onStart) {
|
|
255
|
+
collection.push({
|
|
256
|
+
...start,
|
|
257
|
+
key,
|
|
258
|
+
class: [
|
|
259
|
+
`vc-${this.type} vc-${this.type}-start vc-${start.color} vc-attr`,
|
|
260
|
+
start.class,
|
|
261
|
+
],
|
|
262
|
+
});
|
|
263
|
+
} else if (onEnd) {
|
|
264
|
+
collection.push({
|
|
265
|
+
...end,
|
|
266
|
+
key,
|
|
267
|
+
class: [
|
|
268
|
+
`vc-${this.type} vc-${this.type}-end vc-${end.color} vc-attr`,
|
|
269
|
+
end.class,
|
|
270
|
+
],
|
|
271
|
+
});
|
|
272
|
+
} else {
|
|
273
|
+
collection.push({
|
|
274
|
+
...base,
|
|
275
|
+
key,
|
|
276
|
+
class: [
|
|
277
|
+
`vc-${this.type} vc-${this.type}-base vc-${base.color} vc-attr`,
|
|
278
|
+
base.class,
|
|
279
|
+
],
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export class ContentRenderer extends BaseRenderer<Content> {
|
|
286
|
+
constructor() {
|
|
287
|
+
super('content', 'content');
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
normalizeConfig(_: string, config: any) {
|
|
291
|
+
return normalizeConfig('base', config) as Profile<Content>;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export class DotRenderer extends BaseRenderer<Dot> {
|
|
296
|
+
constructor() {
|
|
297
|
+
super('dot', 'dots');
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export class BarRenderer extends BaseRenderer<Dot> {
|
|
302
|
+
constructor() {
|
|
303
|
+
super('bar', 'bars');
|
|
304
|
+
}
|
|
305
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import _has from 'lodash/has';
|
|
2
|
+
import _isDate from 'lodash/isDate';
|
|
3
|
+
import isFunction from 'lodash/isFunction';
|
|
4
|
+
import isString from 'lodash/isString';
|
|
5
|
+
import _some from 'lodash/some';
|
|
6
|
+
import type { ComponentPublicInstance } from 'vue';
|
|
7
|
+
|
|
8
|
+
export { isFunction, isString };
|
|
9
|
+
export { default as isBoolean } from 'lodash/isBoolean';
|
|
10
|
+
export { default as isNumber } from 'lodash/isNumber';
|
|
11
|
+
export { default as isUndefined } from 'lodash/isUndefined';
|
|
12
|
+
export { default as get } from 'lodash/get';
|
|
13
|
+
export { default as set } from 'lodash/set';
|
|
14
|
+
export { default as mapValues } from 'lodash/mapValues';
|
|
15
|
+
export { default as defaults } from 'lodash/defaults';
|
|
16
|
+
export { default as defaultsDeep } from 'lodash/defaultsDeep';
|
|
17
|
+
export { default as map } from 'lodash/map';
|
|
18
|
+
export { default as head } from 'lodash/head';
|
|
19
|
+
export { default as last } from 'lodash/last';
|
|
20
|
+
|
|
21
|
+
// Type checkers
|
|
22
|
+
export const getType = (value: any) =>
|
|
23
|
+
Object.prototype.toString.call(value).slice(8, -1);
|
|
24
|
+
export const isDate = (value: unknown): value is Date =>
|
|
25
|
+
_isDate(value) && !isNaN(value.getTime());
|
|
26
|
+
export const isObject = (value: unknown): value is object =>
|
|
27
|
+
getType(value) === 'Object';
|
|
28
|
+
|
|
29
|
+
// Object utils
|
|
30
|
+
const hasObj: any = _has;
|
|
31
|
+
export { hasObj as has };
|
|
32
|
+
export const hasAny = (obj: object, props: string[]) =>
|
|
33
|
+
_some(props, p => _has(obj, p));
|
|
34
|
+
|
|
35
|
+
// Collection utils
|
|
36
|
+
export const some = _some;
|
|
37
|
+
|
|
38
|
+
export const pad = (val: string | number, len: number, char = '0') => {
|
|
39
|
+
val = val !== null && val !== undefined ? String(val) : '';
|
|
40
|
+
len = len || 2;
|
|
41
|
+
while (val.length < len) {
|
|
42
|
+
val = `${char}${val}`;
|
|
43
|
+
}
|
|
44
|
+
return val;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const roundTenth = (n: number) => {
|
|
48
|
+
return Math.round(n * 100) / 100;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const isArray = (val: any): val is any[] => Array.isArray(val);
|
|
52
|
+
|
|
53
|
+
export const arrayHasItems = (array: any): boolean =>
|
|
54
|
+
isArray(array) && array.length > 0;
|
|
55
|
+
|
|
56
|
+
export const resolveEl = (target: unknown): Node | null => {
|
|
57
|
+
if (target == null) return null;
|
|
58
|
+
if (isString(target)) {
|
|
59
|
+
return typeof document === 'undefined'
|
|
60
|
+
? null
|
|
61
|
+
: document.querySelector(target);
|
|
62
|
+
}
|
|
63
|
+
return (target as ComponentPublicInstance).$el ?? target;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const resolveDocument = (target?: unknown): Document | null => {
|
|
67
|
+
if ((target as Document | undefined)?.nodeType === 9) {
|
|
68
|
+
return target as Document;
|
|
69
|
+
}
|
|
70
|
+
const element = resolveEl(target);
|
|
71
|
+
return (
|
|
72
|
+
element?.ownerDocument ??
|
|
73
|
+
(typeof document === 'undefined' ? null : document)
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export interface ElementPosition {
|
|
78
|
+
top: number;
|
|
79
|
+
left: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface CustomElement {
|
|
83
|
+
addEventListener: Function;
|
|
84
|
+
removeEventListener: Function;
|
|
85
|
+
dispatchEvent: Function;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const off = (
|
|
89
|
+
element: CustomElement,
|
|
90
|
+
event: string,
|
|
91
|
+
handler: (e: any) => void,
|
|
92
|
+
opts: boolean | EventListenerOptions | undefined = undefined,
|
|
93
|
+
) => {
|
|
94
|
+
element.removeEventListener(event, handler, opts);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export const on = (
|
|
98
|
+
element: CustomElement,
|
|
99
|
+
event: string,
|
|
100
|
+
handler: (e: any) => void,
|
|
101
|
+
opts: boolean | AddEventListenerOptions | undefined = undefined,
|
|
102
|
+
) => {
|
|
103
|
+
element.addEventListener(event, handler, opts);
|
|
104
|
+
return () => off(element, event, handler, opts);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export const elementContains = (element: Node, child: Node) =>
|
|
108
|
+
!!element && !!child && (element === child || element.contains(child));
|
|
109
|
+
|
|
110
|
+
export const onSpaceOrEnter = (
|
|
111
|
+
event: KeyboardEvent,
|
|
112
|
+
handler: (e: KeyboardEvent) => void,
|
|
113
|
+
) => {
|
|
114
|
+
if (event.key === ' ' || event.key === 'Enter') {
|
|
115
|
+
handler(event);
|
|
116
|
+
event.preventDefault();
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export const capitalize = (str: string) => {
|
|
121
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export const omit = <T extends object, K extends [...(keyof T)[]]>(
|
|
125
|
+
obj: T,
|
|
126
|
+
...keys: K
|
|
127
|
+
) => {
|
|
128
|
+
const ret = {} as {
|
|
129
|
+
[K in keyof typeof obj]: (typeof obj)[K];
|
|
130
|
+
};
|
|
131
|
+
let key: keyof typeof obj;
|
|
132
|
+
for (key in obj) {
|
|
133
|
+
if (!keys.includes(key)) {
|
|
134
|
+
ret[key] = obj[key];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return ret;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export const pick = <T extends object, K extends keyof T>(
|
|
141
|
+
obj: T,
|
|
142
|
+
keys: K[],
|
|
143
|
+
): Pick<T, K> => {
|
|
144
|
+
const ret: any = {};
|
|
145
|
+
keys.forEach(key => {
|
|
146
|
+
if (key in obj) ret[key] = obj[key];
|
|
147
|
+
});
|
|
148
|
+
return ret;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export function extend<T extends object, E extends object>(
|
|
152
|
+
value: T,
|
|
153
|
+
ext: E,
|
|
154
|
+
): T & E {
|
|
155
|
+
const handler = {
|
|
156
|
+
get(target: T, prop: keyof (T | E)) {
|
|
157
|
+
if ((prop as string) in target) {
|
|
158
|
+
return target[prop];
|
|
159
|
+
}
|
|
160
|
+
return ext[prop];
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
// @ts-ignore
|
|
164
|
+
return new Proxy(value, handler) as T & E;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function clamp(num: number, min: number, max: number) {
|
|
168
|
+
return Math.min(Math.max(num, min), max);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function hash(str: string): number {
|
|
172
|
+
let hashcode = 0;
|
|
173
|
+
let chr;
|
|
174
|
+
if (str.length === 0) return hashcode;
|
|
175
|
+
for (let i = 0; i < str.length; i++) {
|
|
176
|
+
chr = str.charCodeAt(i);
|
|
177
|
+
hashcode = (hashcode << 5) - hashcode + chr;
|
|
178
|
+
hashcode |= 0; // Convert to 32bit integer
|
|
179
|
+
}
|
|
180
|
+
return hashcode;
|
|
181
|
+
}
|