@svar-ui/svelte-calendar 2.6.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/dist/Demo.svelte +7 -0
- package/dist/Demo.svelte.d.ts +26 -0
- package/dist/components/AddEventButton.svelte +12 -0
- package/dist/components/AddEventButton.svelte.d.ts +18 -0
- package/dist/components/Calendar.svelte +110 -0
- package/dist/components/Calendar.svelte.d.ts +153 -0
- package/dist/components/CalendarPanel.svelte +147 -0
- package/dist/components/CalendarPanel.svelte.d.ts +18 -0
- package/dist/components/ContextMenu.svelte +87 -0
- package/dist/components/ContextMenu.svelte.d.ts +17 -0
- package/dist/components/DateLabel.svelte +13 -0
- package/dist/components/DateLabel.svelte.d.ts +18 -0
- package/dist/components/DateNav.svelte +31 -0
- package/dist/components/DateNav.svelte.d.ts +18 -0
- package/dist/components/DateTimePicker.svelte +30 -0
- package/dist/components/DateTimePicker.svelte.d.ts +8 -0
- package/dist/components/Editor.svelte +123 -0
- package/dist/components/Editor.svelte.d.ts +10 -0
- package/dist/components/Layout.svelte +76 -0
- package/dist/components/Layout.svelte.d.ts +21 -0
- package/dist/components/MenuButton.svelte +9 -0
- package/dist/components/MenuButton.svelte.d.ts +18 -0
- package/dist/components/Navigation.svelte +59 -0
- package/dist/components/Navigation.svelte.d.ts +12 -0
- package/dist/components/Render/BarSection.svelte +89 -0
- package/dist/components/Render/BarSection.svelte.d.ts +13 -0
- package/dist/components/Render/BoxSection.svelte +94 -0
- package/dist/components/Render/BoxSection.svelte.d.ts +15 -0
- package/dist/components/Render/Grid.svelte +16 -0
- package/dist/components/Render/Grid.svelte.d.ts +14 -0
- package/dist/components/Render/GridCells.svelte +98 -0
- package/dist/components/Render/GridCells.svelte.d.ts +14 -0
- package/dist/components/Render/GridLines.svelte +45 -0
- package/dist/components/Render/GridLines.svelte.d.ts +10 -0
- package/dist/components/Render/GridSection.svelte +348 -0
- package/dist/components/Render/GridSection.svelte.d.ts +16 -0
- package/dist/components/Render/Headers.svelte +86 -0
- package/dist/components/Render/Headers.svelte.d.ts +8 -0
- package/dist/components/Render/ListSection.svelte +110 -0
- package/dist/components/Render/ListSection.svelte.d.ts +8 -0
- package/dist/components/Render/NowLine.svelte +68 -0
- package/dist/components/Render/NowLine.svelte.d.ts +8 -0
- package/dist/components/Render/ScrollableSection.svelte +207 -0
- package/dist/components/Render/ScrollableSection.svelte.d.ts +14 -0
- package/dist/components/Render/SectionContent.svelte +83 -0
- package/dist/components/Render/SectionContent.svelte.d.ts +17 -0
- package/dist/components/Render/Sections.svelte +340 -0
- package/dist/components/Render/Sections.svelte.d.ts +14 -0
- package/dist/components/Render/YearSection.svelte +265 -0
- package/dist/components/Render/YearSection.svelte.d.ts +9 -0
- package/dist/components/Render/useEventOverlay.svelte.d.ts +21 -0
- package/dist/components/Render/useEventOverlay.svelte.js +60 -0
- package/dist/components/TodayButton.svelte +11 -0
- package/dist/components/TodayButton.svelte.d.ts +18 -0
- package/dist/components/editorItems.d.ts +15 -0
- package/dist/components/editorItems.js +20 -0
- package/dist/components/types.d.ts +29 -0
- package/dist/components/types.js +1 -0
- package/dist/directives/clickdate.d.ts +8 -0
- package/dist/directives/clickdate.js +45 -0
- package/dist/directives/clickevent.d.ts +15 -0
- package/dist/directives/clickevent.js +54 -0
- package/dist/directives/drag.d.ts +19 -0
- package/dist/directives/drag.js +494 -0
- package/dist/directives/dragresize.d.ts +10 -0
- package/dist/directives/dragresize.js +58 -0
- package/dist/directives/resize.d.ts +5 -0
- package/dist/directives/resize.js +11 -0
- package/dist/dom.d.ts +1 -0
- package/dist/dom.js +12 -0
- package/dist/env.d.ts +9 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +12 -0
- package/dist/init.d.ts +1 -0
- package/dist/init.js +5 -0
- package/dist/themes/Willow.svelte +16 -0
- package/dist/themes/Willow.svelte.d.ts +7 -0
- package/dist/themes/WillowDark.svelte +16 -0
- package/dist/themes/WillowDark.svelte.d.ts +7 -0
- package/license.txt +21 -0
- package/package.json +60 -0
- package/readme.md +107 -0
package/dist/Demo.svelte
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export default Demo;
|
|
2
|
+
type Demo = SvelteComponent<{
|
|
3
|
+
[x: string]: never;
|
|
4
|
+
}, {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
}, {}> & {
|
|
7
|
+
$$bindings?: string | undefined;
|
|
8
|
+
};
|
|
9
|
+
declare const Demo: $$__sveltets_2_IsomorphicComponent<{
|
|
10
|
+
[x: string]: never;
|
|
11
|
+
}, {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
}, {}, {}, string>;
|
|
14
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
15
|
+
new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
|
|
16
|
+
$$bindings?: Bindings;
|
|
17
|
+
} & Exports;
|
|
18
|
+
(internal: unknown, props: {
|
|
19
|
+
$$events?: Events;
|
|
20
|
+
$$slots?: Slots;
|
|
21
|
+
}): Exports & {
|
|
22
|
+
$set?: any;
|
|
23
|
+
$on?: any;
|
|
24
|
+
};
|
|
25
|
+
z_$$bindings?: Bindings;
|
|
26
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script lang="ts">import { getContext } from "svelte";
|
|
2
|
+
import { Button } from "@svar-ui/svelte-core";
|
|
3
|
+
const store = getContext("calendar-api");
|
|
4
|
+
function addEvent() {
|
|
5
|
+
store.exec("add-event", {
|
|
6
|
+
event: {},
|
|
7
|
+
edit: true
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<Button icon="wxi-plus" type="primary" onclick={addEvent}></Button>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const AddEventButton: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type AddEventButton = InstanceType<typeof AddEventButton>;
|
|
18
|
+
export default AddEventButton;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<script lang="ts">import { setContext, getContext } from "svelte";
|
|
2
|
+
import { writable } from "svelte/store";
|
|
3
|
+
// locales
|
|
4
|
+
import { locale as l, dateToString } from "@svar-ui/lib-dom";
|
|
5
|
+
import { en } from "@svar-ui/calendar-locales";
|
|
6
|
+
import { en as coreEn } from "@svar-ui/core-locales";
|
|
7
|
+
// stores
|
|
8
|
+
import { EventBusRouter } from "@svar-ui/lib-state";
|
|
9
|
+
import { CalendarStore } from "@svar-ui/calendar-store";
|
|
10
|
+
// ui
|
|
11
|
+
import Layout from "./Layout.svelte";
|
|
12
|
+
let { events, init, view = "day", date, views = [
|
|
13
|
+
"day",
|
|
14
|
+
"week",
|
|
15
|
+
"month"
|
|
16
|
+
], toolbar, cellCss, eventCss, eventContent, recurring = false, readonly = false, children, tooltip, eventPopup, ...restProps } = $props();
|
|
17
|
+
// uses same logic as the Locale component
|
|
18
|
+
const words = {
|
|
19
|
+
...coreEn,
|
|
20
|
+
...en
|
|
21
|
+
};
|
|
22
|
+
let locale = getContext("wx-i18n");
|
|
23
|
+
if (!locale) locale = l(words);
|
|
24
|
+
else locale = locale.extend(words, true);
|
|
25
|
+
setContext("wx-i18n", locale);
|
|
26
|
+
// create date format helper that resolves format names and format strings
|
|
27
|
+
const rawLocale = locale.getRaw();
|
|
28
|
+
const fmt = (format) => {
|
|
29
|
+
const resolved = rawLocale?.eventCalendar?.[format] ?? format;
|
|
30
|
+
return dateToString(resolved, rawLocale?.calendar);
|
|
31
|
+
};
|
|
32
|
+
// init stores
|
|
33
|
+
// svelte-ignore state_referenced_locally
|
|
34
|
+
const dataStore = new CalendarStore(writable, {
|
|
35
|
+
recurring,
|
|
36
|
+
weekStart: rawLocale?.calendar?.weekStart ?? 1,
|
|
37
|
+
dateFormat: fmt
|
|
38
|
+
});
|
|
39
|
+
// define event route
|
|
40
|
+
let firstInRoute = dataStore.in;
|
|
41
|
+
const dash = /-/g;
|
|
42
|
+
let lastInRoute = new EventBusRouter((a, b) => {
|
|
43
|
+
const name = "on" + a.replace(dash, "");
|
|
44
|
+
const handler = restProps[name];
|
|
45
|
+
if (handler) {
|
|
46
|
+
handler(b);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
firstInRoute.setNext(lastInRoute);
|
|
50
|
+
// public API
|
|
51
|
+
export const getState = dataStore.getState.bind(dataStore), getReactiveState = dataStore.getReactive.bind(dataStore), getStores = () => ({ data: dataStore }), getEvents = dataStore.getEvents.bind(dataStore), getEvent = dataStore.getEvent.bind(dataStore), exec = firstInRoute.exec, setNext = (ev) => lastInRoute = lastInRoute.setNext(ev), intercept = firstInRoute.intercept.bind(firstInRoute), on = firstInRoute.on.bind(firstInRoute), detach = firstInRoute.detach.bind(firstInRoute);
|
|
52
|
+
// extra api
|
|
53
|
+
const api = {
|
|
54
|
+
exec,
|
|
55
|
+
setNext,
|
|
56
|
+
intercept,
|
|
57
|
+
on,
|
|
58
|
+
detach,
|
|
59
|
+
getState,
|
|
60
|
+
getReactiveState,
|
|
61
|
+
getStores,
|
|
62
|
+
getEvents,
|
|
63
|
+
getEvent,
|
|
64
|
+
fmt
|
|
65
|
+
};
|
|
66
|
+
const viewOptions = $derived(views.map((v) => {
|
|
67
|
+
if (typeof v === "string") {
|
|
68
|
+
return { id: v };
|
|
69
|
+
}
|
|
70
|
+
return { ...v };
|
|
71
|
+
}));
|
|
72
|
+
// common API available in components
|
|
73
|
+
const stateStore = {
|
|
74
|
+
getState,
|
|
75
|
+
getReactiveState,
|
|
76
|
+
exec,
|
|
77
|
+
getEvent,
|
|
78
|
+
fmt
|
|
79
|
+
};
|
|
80
|
+
setContext("calendar-api", stateStore);
|
|
81
|
+
let init_once = true;
|
|
82
|
+
const reinitStore = () => {
|
|
83
|
+
dataStore.configureViews(viewOptions);
|
|
84
|
+
dataStore.init({
|
|
85
|
+
currentView: view,
|
|
86
|
+
currentDate: date,
|
|
87
|
+
events
|
|
88
|
+
});
|
|
89
|
+
if (init_once && init) {
|
|
90
|
+
init(api);
|
|
91
|
+
init_once = false;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
reinitStore();
|
|
95
|
+
$effect(reinitStore);
|
|
96
|
+
</script>
|
|
97
|
+
|
|
98
|
+
<Layout
|
|
99
|
+
store={stateStore}
|
|
100
|
+
views={viewOptions}
|
|
101
|
+
brandmark={dataStore.getBrandmark() ?? undefined}
|
|
102
|
+
{toolbar}
|
|
103
|
+
{cellCss}
|
|
104
|
+
{eventCss}
|
|
105
|
+
{eventContent}
|
|
106
|
+
{children}
|
|
107
|
+
{tooltip}
|
|
108
|
+
{eventPopup}
|
|
109
|
+
{readonly}
|
|
110
|
+
/>
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import { CalendarStore } from "@svar-ui/calendar-store";
|
|
3
|
+
import type { ViewConfig } from "@svar-ui/calendar-store";
|
|
4
|
+
import type { CalendarInstanceApi } from "./types.js";
|
|
5
|
+
import type { ToolbarItem, CellCss, EventCss } from "@svar-ui/calendar-store";
|
|
6
|
+
type Props = {
|
|
7
|
+
events: any;
|
|
8
|
+
init?: (api: CalendarInstanceApi) => void;
|
|
9
|
+
readonly?: boolean;
|
|
10
|
+
view?: string;
|
|
11
|
+
views?: (string | ViewConfig)[];
|
|
12
|
+
toolbar?: {
|
|
13
|
+
items?: ToolbarItem[];
|
|
14
|
+
css?: string;
|
|
15
|
+
} | null;
|
|
16
|
+
cellCss?: CellCss;
|
|
17
|
+
eventCss?: EventCss;
|
|
18
|
+
eventContent?: any;
|
|
19
|
+
date?: Date;
|
|
20
|
+
recurring?: boolean;
|
|
21
|
+
children?: Snippet;
|
|
22
|
+
tooltip?: any;
|
|
23
|
+
eventPopup?: any;
|
|
24
|
+
};
|
|
25
|
+
declare const Calendar: import("svelte").Component<Props, {
|
|
26
|
+
getState: () => import("@svar-ui/calendar-store").State;
|
|
27
|
+
getReactiveState: () => {
|
|
28
|
+
currentDate: import("@svar-ui/lib-state").IPublicWritable<Date>;
|
|
29
|
+
currentView: import("@svar-ui/lib-state").IPublicWritable<string>;
|
|
30
|
+
rangeLabel: import("@svar-ui/lib-state").IPublicWritable<string>;
|
|
31
|
+
visibleDateRange: import("@svar-ui/lib-state").IPublicWritable<{
|
|
32
|
+
start: Date;
|
|
33
|
+
end: Date;
|
|
34
|
+
}>;
|
|
35
|
+
events: import("@svar-ui/lib-state").IPublicWritable<import("@svar-ui/calendar-store").EventsStore>;
|
|
36
|
+
viewData: import("@svar-ui/lib-state").IPublicWritable<any>;
|
|
37
|
+
filters: import("@svar-ui/lib-state").IPublicWritable<Map<string, (obj: any) => boolean>>;
|
|
38
|
+
editorData: import("@svar-ui/lib-state").IPublicWritable<import("@svar-ui/calendar-store").CalendarEvent | null>;
|
|
39
|
+
_view: import("@svar-ui/lib-state").IPublicWritable<import("@svar-ui/calendar-store").ViewModel>;
|
|
40
|
+
};
|
|
41
|
+
getStores: () => {
|
|
42
|
+
data: CalendarStore;
|
|
43
|
+
};
|
|
44
|
+
getEvents: (start?: Date, end?: Date) => import("@svar-ui/calendar-store").CalendarEvent[];
|
|
45
|
+
getEvent: (id: string | number) => import("@svar-ui/calendar-store").CalendarEvent | undefined;
|
|
46
|
+
exec: (name: keyof import("@svar-ui/calendar-store").StoreActions, ev: {
|
|
47
|
+
date?: Date;
|
|
48
|
+
view?: string;
|
|
49
|
+
} | {
|
|
50
|
+
direction: "next" | "previous" | "now";
|
|
51
|
+
} | {
|
|
52
|
+
event: Partial<import("@svar-ui/calendar-store").CalendarEvent>;
|
|
53
|
+
edit?: boolean;
|
|
54
|
+
id?: import("@svar-ui/calendar-store").EventID;
|
|
55
|
+
} | {
|
|
56
|
+
id: import("@svar-ui/calendar-store").EventID;
|
|
57
|
+
event: Partial<import("@svar-ui/calendar-store").CalendarEvent>;
|
|
58
|
+
mode?: "single" | "following";
|
|
59
|
+
originalDate?: string;
|
|
60
|
+
} | {
|
|
61
|
+
id: import("@svar-ui/calendar-store").EventID;
|
|
62
|
+
} | {
|
|
63
|
+
id: import("@svar-ui/calendar-store").EventID | null;
|
|
64
|
+
} | {
|
|
65
|
+
id: import("@svar-ui/calendar-store").EventID;
|
|
66
|
+
x: number;
|
|
67
|
+
y: number;
|
|
68
|
+
} | {
|
|
69
|
+
filter?: ((obj: any) => boolean) | null;
|
|
70
|
+
tag?: string;
|
|
71
|
+
}) => Promise<{
|
|
72
|
+
date?: Date;
|
|
73
|
+
view?: string;
|
|
74
|
+
} | {
|
|
75
|
+
direction: "next" | "previous" | "now";
|
|
76
|
+
} | {
|
|
77
|
+
event: Partial<import("@svar-ui/calendar-store").CalendarEvent>;
|
|
78
|
+
edit?: boolean;
|
|
79
|
+
id?: import("@svar-ui/calendar-store").EventID;
|
|
80
|
+
} | {
|
|
81
|
+
id: import("@svar-ui/calendar-store").EventID;
|
|
82
|
+
event: Partial<import("@svar-ui/calendar-store").CalendarEvent>;
|
|
83
|
+
mode?: "single" | "following";
|
|
84
|
+
originalDate?: string;
|
|
85
|
+
} | {
|
|
86
|
+
id: import("@svar-ui/calendar-store").EventID;
|
|
87
|
+
} | {
|
|
88
|
+
id: import("@svar-ui/calendar-store").EventID | null;
|
|
89
|
+
} | {
|
|
90
|
+
id: import("@svar-ui/calendar-store").EventID;
|
|
91
|
+
x: number;
|
|
92
|
+
y: number;
|
|
93
|
+
} | {
|
|
94
|
+
filter?: ((obj: any) => boolean) | null;
|
|
95
|
+
tag?: string;
|
|
96
|
+
}>;
|
|
97
|
+
setNext: (ev: any) => any;
|
|
98
|
+
intercept: (name: keyof import("@svar-ui/calendar-store").StoreActions, handler: (v: {
|
|
99
|
+
date?: Date;
|
|
100
|
+
view?: string;
|
|
101
|
+
} | {
|
|
102
|
+
direction: "next" | "previous" | "now";
|
|
103
|
+
} | {
|
|
104
|
+
event: Partial<import("@svar-ui/calendar-store").CalendarEvent>;
|
|
105
|
+
edit?: boolean;
|
|
106
|
+
id?: import("@svar-ui/calendar-store").EventID;
|
|
107
|
+
} | {
|
|
108
|
+
id: import("@svar-ui/calendar-store").EventID;
|
|
109
|
+
event: Partial<import("@svar-ui/calendar-store").CalendarEvent>;
|
|
110
|
+
mode?: "single" | "following";
|
|
111
|
+
originalDate?: string;
|
|
112
|
+
} | {
|
|
113
|
+
id: import("@svar-ui/calendar-store").EventID;
|
|
114
|
+
} | {
|
|
115
|
+
id: import("@svar-ui/calendar-store").EventID | null;
|
|
116
|
+
} | {
|
|
117
|
+
id: import("@svar-ui/calendar-store").EventID;
|
|
118
|
+
x: number;
|
|
119
|
+
y: number;
|
|
120
|
+
} | {
|
|
121
|
+
filter?: ((obj: any) => boolean) | null;
|
|
122
|
+
tag?: string;
|
|
123
|
+
}) => void | boolean | Promise<boolean>, config?: import("@svar-ui/lib-state").IEventConfig) => void;
|
|
124
|
+
on: (name: keyof import("@svar-ui/calendar-store").StoreActions, handler: (v: {
|
|
125
|
+
date?: Date;
|
|
126
|
+
view?: string;
|
|
127
|
+
} | {
|
|
128
|
+
direction: "next" | "previous" | "now";
|
|
129
|
+
} | {
|
|
130
|
+
event: Partial<import("@svar-ui/calendar-store").CalendarEvent>;
|
|
131
|
+
edit?: boolean;
|
|
132
|
+
id?: import("@svar-ui/calendar-store").EventID;
|
|
133
|
+
} | {
|
|
134
|
+
id: import("@svar-ui/calendar-store").EventID;
|
|
135
|
+
event: Partial<import("@svar-ui/calendar-store").CalendarEvent>;
|
|
136
|
+
mode?: "single" | "following";
|
|
137
|
+
originalDate?: string;
|
|
138
|
+
} | {
|
|
139
|
+
id: import("@svar-ui/calendar-store").EventID;
|
|
140
|
+
} | {
|
|
141
|
+
id: import("@svar-ui/calendar-store").EventID | null;
|
|
142
|
+
} | {
|
|
143
|
+
id: import("@svar-ui/calendar-store").EventID;
|
|
144
|
+
x: number;
|
|
145
|
+
y: number;
|
|
146
|
+
} | {
|
|
147
|
+
filter?: ((obj: any) => boolean) | null;
|
|
148
|
+
tag?: string;
|
|
149
|
+
}) => void | boolean | Promise<boolean>, config?: import("@svar-ui/lib-state").IEventConfig) => void;
|
|
150
|
+
detach: (tag: number | string | symbol) => void;
|
|
151
|
+
}, "">;
|
|
152
|
+
type Calendar = ReturnType<typeof Calendar>;
|
|
153
|
+
export default Calendar;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
<script lang="ts">import { getContext } from "svelte";
|
|
2
|
+
import { writable } from "svelte/store";
|
|
3
|
+
import { Calendar, Checkbox } from "@svar-ui/svelte-core";
|
|
4
|
+
let { calendars, accessor = "calendarId", open = true, onchange } = $props();
|
|
5
|
+
// i18n support with fallback
|
|
6
|
+
const i18n = getContext("wx-i18n");
|
|
7
|
+
const _ = i18n?.getGroup("eventCalendar");
|
|
8
|
+
// Calendar API from context (available when placed inside Calendar widget)
|
|
9
|
+
const calendarApi = getContext("calendar-api");
|
|
10
|
+
const reactiveState = calendarApi?.getReactiveState();
|
|
11
|
+
const currentDate = reactiveState?.currentDate ?? writable(new Date());
|
|
12
|
+
const visibleDateRange = reactiveState?.visibleDateRange ?? writable({
|
|
13
|
+
start: new Date(),
|
|
14
|
+
end: new Date()
|
|
15
|
+
});
|
|
16
|
+
const rangeMarkers = $derived.by(() => {
|
|
17
|
+
const range = $visibleDateRange;
|
|
18
|
+
const startTime = range.start.getTime();
|
|
19
|
+
const endTime = range.end.getTime();
|
|
20
|
+
return (date) => {
|
|
21
|
+
const t = date.getTime();
|
|
22
|
+
return t >= startTime && t < endTime ? "wx-view-range" : "";
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
let active = $derived.by(() => {
|
|
26
|
+
return calendars.reduce((acc, cal) => {
|
|
27
|
+
acc[cal.id] = cal.active !== false;
|
|
28
|
+
return acc;
|
|
29
|
+
}, {});
|
|
30
|
+
});
|
|
31
|
+
function applyFilter() {
|
|
32
|
+
const value = [];
|
|
33
|
+
for (const a in active) {
|
|
34
|
+
if (active[a]) value.push(a);
|
|
35
|
+
}
|
|
36
|
+
const filter = value.length === calendars.length ? null : (event) => active[event[accessor]];
|
|
37
|
+
if (calendarApi) {
|
|
38
|
+
calendarApi.exec("filter-events", {
|
|
39
|
+
filter,
|
|
40
|
+
tag: "calendar-panel"
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
onchange?.({
|
|
44
|
+
value,
|
|
45
|
+
filter
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function toggle(id) {
|
|
49
|
+
active[id] = !active[id];
|
|
50
|
+
applyFilter();
|
|
51
|
+
}
|
|
52
|
+
$effect(() => {
|
|
53
|
+
if (calendars.some((c) => c.active === false)) applyFilter();
|
|
54
|
+
});
|
|
55
|
+
function onDateChange({ value }) {
|
|
56
|
+
if (value && calendarApi) {
|
|
57
|
+
calendarApi.exec("navigate-to", { date: value });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
{#if open}
|
|
63
|
+
<div class="wx-calendar-panel">
|
|
64
|
+
<div role="group" aria-label={_("Calendar filters")}>
|
|
65
|
+
{#each calendars as cal (cal.id)}
|
|
66
|
+
<div class="wx-calendar-name {cal.css}">
|
|
67
|
+
<Checkbox
|
|
68
|
+
value={active[cal.id] ?? true}
|
|
69
|
+
onchange={() => toggle(cal.id)}
|
|
70
|
+
/* css={cal.css}
|
|
71
|
+
ariaLabel={cal.label} */
|
|
72
|
+
label={cal.label}
|
|
73
|
+
/>
|
|
74
|
+
</div>
|
|
75
|
+
{/each}
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<div class="wx-calendar-panel-bottom">
|
|
79
|
+
<Calendar
|
|
80
|
+
buttons={false}
|
|
81
|
+
value={$currentDate}
|
|
82
|
+
onchange={onDateChange}
|
|
83
|
+
markers={rangeMarkers}
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
{/if}
|
|
88
|
+
|
|
89
|
+
<style>
|
|
90
|
+
.wx-calendar-panel {
|
|
91
|
+
display: flex;
|
|
92
|
+
flex-direction: column;
|
|
93
|
+
gap: 4px;
|
|
94
|
+
padding: var(--wx-padding);
|
|
95
|
+
overflow: hidden;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.wx-calendar-panel-toggle {
|
|
99
|
+
background: none;
|
|
100
|
+
border: var(--wx-border);
|
|
101
|
+
cursor: pointer;
|
|
102
|
+
padding: 4px 3px;
|
|
103
|
+
font-size: var(--wx-icon-size);
|
|
104
|
+
line-height: 16px;
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
justify-content: center;
|
|
108
|
+
color: var(--wx-color-font);
|
|
109
|
+
flex-shrink: 0;
|
|
110
|
+
border-radius: var(--wx-border-radius);
|
|
111
|
+
outline: none;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.wx-calendar-panel-toggle:hover {
|
|
115
|
+
background: var(--wx-background-hover);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.wx-calendar-name {
|
|
119
|
+
margin-top: 4px;
|
|
120
|
+
border: none !important;
|
|
121
|
+
border-radius: var(--wx-border-radius);
|
|
122
|
+
padding: 4px;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.wx-calendar-panel-color {
|
|
126
|
+
display: inline-block;
|
|
127
|
+
width: 12px;
|
|
128
|
+
height: 12px;
|
|
129
|
+
border-radius: var(--wx-icon-border-radius);
|
|
130
|
+
flex-shrink: 0;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.wx-calendar-panel-label {
|
|
134
|
+
white-space: nowrap;
|
|
135
|
+
overflow: hidden;
|
|
136
|
+
opacity: 1;
|
|
137
|
+
max-width: 200px;
|
|
138
|
+
transition:
|
|
139
|
+
opacity 0.3s ease,
|
|
140
|
+
max-width 0.3s ease;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.wx-calendar-panel-bottom :global(.wx-view-range:not(.wx-selected):not(.wx-out)) {
|
|
144
|
+
background: var(--wx-color-primary-selected);
|
|
145
|
+
border-radius: 0;
|
|
146
|
+
}
|
|
147
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type CalendarGroup = {
|
|
2
|
+
id: string | number;
|
|
3
|
+
label: string;
|
|
4
|
+
active?: boolean;
|
|
5
|
+
css?: string;
|
|
6
|
+
};
|
|
7
|
+
type Props = {
|
|
8
|
+
calendars: CalendarGroup[];
|
|
9
|
+
accessor?: string;
|
|
10
|
+
open?: boolean;
|
|
11
|
+
onchange?: (detail: {
|
|
12
|
+
value: (string | number)[];
|
|
13
|
+
filter: ((event: Record<string, any>) => boolean) | null;
|
|
14
|
+
}) => void;
|
|
15
|
+
};
|
|
16
|
+
declare const CalendarPanel: import("svelte").Component<Props, {}, "">;
|
|
17
|
+
type CalendarPanel = ReturnType<typeof CalendarPanel>;
|
|
18
|
+
export default CalendarPanel;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<script lang="ts">import { getContext, setContext } from "svelte";
|
|
2
|
+
import { ContextMenu } from "@svar-ui/svelte-menu";
|
|
3
|
+
import { locale } from "@svar-ui/lib-dom";
|
|
4
|
+
import { en } from "@svar-ui/calendar-locales";
|
|
5
|
+
import { en as coreEn } from "@svar-ui/core-locales";
|
|
6
|
+
import { getMenuOptions } from "@svar-ui/calendar-store";
|
|
7
|
+
let { options = [], api = null, resolver = null, filter = null, at = "point", children, onclick, css } = $props();
|
|
8
|
+
let activeId = null;
|
|
9
|
+
// set locale
|
|
10
|
+
let l = getContext("wx-i18n");
|
|
11
|
+
if (!l) {
|
|
12
|
+
l = locale({
|
|
13
|
+
...en,
|
|
14
|
+
...coreEn
|
|
15
|
+
});
|
|
16
|
+
setContext("wx-i18n", l);
|
|
17
|
+
}
|
|
18
|
+
const _ = l.getGroup("eventCalendar");
|
|
19
|
+
function applyLocale(opts) {
|
|
20
|
+
return opts.map((op) => {
|
|
21
|
+
op = { ...op };
|
|
22
|
+
if (op.text) op.text = _(op.text);
|
|
23
|
+
if (op.subtext) op.subtext = _(op.subtext);
|
|
24
|
+
if (op.data) op.data = applyLocale(op.data);
|
|
25
|
+
return op;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function getOptions() {
|
|
29
|
+
const base = options.length ? options : getMenuOptions();
|
|
30
|
+
return applyLocale(base);
|
|
31
|
+
}
|
|
32
|
+
function itemResolver(rawId, ev) {
|
|
33
|
+
if (!rawId || !api) return null;
|
|
34
|
+
const event = api.getEvent(rawId);
|
|
35
|
+
if (!event) return null;
|
|
36
|
+
if (resolver) {
|
|
37
|
+
const result = resolver(event, ev);
|
|
38
|
+
if (!result) return null;
|
|
39
|
+
}
|
|
40
|
+
activeId = event.id;
|
|
41
|
+
return event;
|
|
42
|
+
}
|
|
43
|
+
function menuAction(ev) {
|
|
44
|
+
const action = ev?.action;
|
|
45
|
+
if (!action) return;
|
|
46
|
+
const id = typeof activeId === "object" ? activeId.id : activeId;
|
|
47
|
+
if (action.id === "edit-event") {
|
|
48
|
+
api.exec("select-event", { id });
|
|
49
|
+
} else if (action.id === "delete-event") {
|
|
50
|
+
api.exec("delete-event", { id });
|
|
51
|
+
}
|
|
52
|
+
onclick?.(ev);
|
|
53
|
+
}
|
|
54
|
+
function filterMenu(item, event) {
|
|
55
|
+
return filter ? filter(item, event) : true;
|
|
56
|
+
}
|
|
57
|
+
const cOptions = $derived(getOptions());
|
|
58
|
+
let menu = $state();
|
|
59
|
+
export function show(ev, obj) {
|
|
60
|
+
menu.show(ev, obj);
|
|
61
|
+
}
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<ContextMenu
|
|
65
|
+
filter={filterMenu}
|
|
66
|
+
options={cOptions}
|
|
67
|
+
dataKey="id"
|
|
68
|
+
resolver={itemResolver}
|
|
69
|
+
onclick={menuAction}
|
|
70
|
+
{css}
|
|
71
|
+
{at}
|
|
72
|
+
bind:this={menu}
|
|
73
|
+
/>
|
|
74
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
75
|
+
<span oncontextmenu={menu.show} data-menu-ignore="true">
|
|
76
|
+
{@render children?.()}
|
|
77
|
+
</span>
|
|
78
|
+
|
|
79
|
+
<style>
|
|
80
|
+
:global(.wx-menu .wx-option.wx-disabled) {
|
|
81
|
+
pointer-events: none;
|
|
82
|
+
}
|
|
83
|
+
:global(.wx-menu .wx-option.wx-disabled .wx-value),
|
|
84
|
+
:global(.wx-menu .wx-option.wx-disabled .wx-icon) {
|
|
85
|
+
color: var(--wx-color-font-disabled);
|
|
86
|
+
}
|
|
87
|
+
</style>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import { ContextMenu } from "@svar-ui/svelte-menu";
|
|
3
|
+
type Props = {
|
|
4
|
+
options?: any[];
|
|
5
|
+
api?: any;
|
|
6
|
+
resolver?: ((event: any, ev: MouseEvent) => any) | null;
|
|
7
|
+
filter?: ((item: any, event: any) => boolean) | null;
|
|
8
|
+
at?: string;
|
|
9
|
+
children?: Snippet;
|
|
10
|
+
onclick?: (e: any) => void;
|
|
11
|
+
css?: string;
|
|
12
|
+
};
|
|
13
|
+
declare const ContextMenu: import("svelte").Component<Props, {
|
|
14
|
+
show: (ev: any, obj?: any) => void;
|
|
15
|
+
}, "">;
|
|
16
|
+
type ContextMenu = ReturnType<typeof ContextMenu>;
|
|
17
|
+
export default ContextMenu;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script lang="ts">import { getContext } from "svelte";
|
|
2
|
+
const store = getContext("calendar-api");
|
|
3
|
+
const { rangeLabel } = store.getReactiveState();
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<span class="wx-date-label" role="heading" aria-level="2" aria-live="polite" aria-atomic="true">{$rangeLabel}</span>
|
|
7
|
+
|
|
8
|
+
<style>
|
|
9
|
+
.wx-date-label {
|
|
10
|
+
font-size: var(--wx-font-size-hd);
|
|
11
|
+
flex-grow: 1;
|
|
12
|
+
}
|
|
13
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const DateLabel: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type DateLabel = InstanceType<typeof DateLabel>;
|
|
18
|
+
export default DateLabel;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script lang="ts">import { getContext } from "svelte";
|
|
2
|
+
import { Button } from "@svar-ui/svelte-core";
|
|
3
|
+
const store = getContext("calendar-api");
|
|
4
|
+
const _ = getContext("wx-i18n").getGroup("eventCalendar");
|
|
5
|
+
function next() {
|
|
6
|
+
store.exec("navigate-time", { direction: "next" });
|
|
7
|
+
}
|
|
8
|
+
function prev() {
|
|
9
|
+
store.exec("navigate-time", { direction: "previous" });
|
|
10
|
+
}
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<div class="wx-date-nav" role="group" aria-label={_("Date navigation")}>
|
|
14
|
+
<Button icon="wxi-angle-left" onclick={prev} /*ariaLabel={_("Previous period")}*/ />
|
|
15
|
+
<Button icon="wxi-angle-right" onclick={next} /*ariaLabel={_("Next period")}*/ />
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<style>
|
|
19
|
+
.wx-date-nav {
|
|
20
|
+
display: flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
}
|
|
23
|
+
.wx-date-nav :global(button:first-child) {
|
|
24
|
+
border-top-right-radius: 0;
|
|
25
|
+
border-bottom-right-radius: 0;
|
|
26
|
+
}
|
|
27
|
+
.wx-date-nav :global(button:last-child) {
|
|
28
|
+
border-top-left-radius: 0;
|
|
29
|
+
border-bottom-left-radius: 0;
|
|
30
|
+
}
|
|
31
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const DateNav: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type DateNav = InstanceType<typeof DateNav>;
|
|
18
|
+
export default DateNav;
|