nuxt-ui-elements-pro 0.1.6 → 0.1.7
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/module.json +1 -1
- package/dist/module.mjs +103 -3
- package/dist/runtime/components/EventCalendar.d.vue.ts +84 -3
- package/dist/runtime/components/EventCalendar.vue +129 -12
- package/dist/runtime/components/EventCalendar.vue.d.ts +84 -3
- package/dist/runtime/components/OrgChart.d.vue.ts +191 -0
- package/dist/runtime/components/OrgChart.vue +290 -0
- package/dist/runtime/components/OrgChart.vue.d.ts +191 -0
- package/dist/runtime/components/{EventCalendarHeader.d.vue.ts → event-calendar/EventCalendarHeader.d.vue.ts} +20 -1
- package/dist/runtime/components/event-calendar/EventCalendarHeader.vue +55 -0
- package/dist/runtime/components/{EventCalendarHeader.vue.d.ts → event-calendar/EventCalendarHeader.vue.d.ts} +20 -1
- package/dist/runtime/components/{EventCalendarListView.d.vue.ts → event-calendar/EventCalendarListView.d.vue.ts} +1 -1
- package/dist/runtime/components/{EventCalendarListView.vue → event-calendar/EventCalendarListView.vue} +1 -1
- package/dist/runtime/components/{EventCalendarListView.vue.d.ts → event-calendar/EventCalendarListView.vue.d.ts} +1 -1
- package/dist/runtime/components/{EventCalendarMonthView.d.vue.ts → event-calendar/EventCalendarMonthView.d.vue.ts} +1 -1
- package/dist/runtime/components/{EventCalendarMonthView.vue → event-calendar/EventCalendarMonthView.vue} +1 -1
- package/dist/runtime/components/{EventCalendarMonthView.vue.d.ts → event-calendar/EventCalendarMonthView.vue.d.ts} +1 -1
- package/dist/runtime/components/{EventCalendarTimeGrid.d.vue.ts → event-calendar/EventCalendarTimeGrid.d.vue.ts} +1 -1
- package/dist/runtime/components/{EventCalendarTimeGrid.vue → event-calendar/EventCalendarTimeGrid.vue} +1 -1
- package/dist/runtime/components/{EventCalendarTimeGrid.vue.d.ts → event-calendar/EventCalendarTimeGrid.vue.d.ts} +1 -1
- package/dist/runtime/components/org-chart/OrgChartConnectors.d.vue.ts +15 -0
- package/dist/runtime/components/org-chart/OrgChartConnectors.vue +29 -0
- package/dist/runtime/components/org-chart/OrgChartConnectors.vue.d.ts +15 -0
- package/dist/runtime/components/org-chart/OrgChartControls.d.vue.ts +19 -0
- package/dist/runtime/components/org-chart/OrgChartControls.vue +25 -0
- package/dist/runtime/components/org-chart/OrgChartControls.vue.d.ts +19 -0
- package/dist/runtime/components/org-chart/OrgChartNode.d.vue.ts +30 -0
- package/dist/runtime/components/org-chart/OrgChartNode.vue +129 -0
- package/dist/runtime/components/org-chart/OrgChartNode.vue.d.ts +30 -0
- package/dist/runtime/composables/useOrgChart.d.ts +42 -0
- package/dist/runtime/composables/useOrgChart.js +154 -0
- package/dist/runtime/composables/useOrgChartContext.d.ts +8 -0
- package/dist/runtime/composables/useOrgChartContext.js +11 -0
- package/dist/runtime/composables/useOrgChartDragDrop.d.ts +20 -0
- package/dist/runtime/composables/useOrgChartDragDrop.js +67 -0
- package/dist/runtime/composables/useOrgChartKeyboard.d.ts +16 -0
- package/dist/runtime/composables/useOrgChartKeyboard.js +101 -0
- package/dist/runtime/composables/useOrgChartSearch.d.ts +16 -0
- package/dist/runtime/composables/useOrgChartSearch.js +62 -0
- package/dist/runtime/composables/useOrgChartZoom.d.ts +26 -0
- package/dist/runtime/composables/useOrgChartZoom.js +101 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/types/event-calendar.d.ts +1 -0
- package/dist/runtime/types/index.d.ts +2 -4
- package/dist/runtime/types/index.js +2 -4
- package/dist/runtime/types/org-chart.d.ts +181 -0
- package/dist/runtime/types/org-chart.js +0 -0
- package/dist/runtime/utils/org-chart.d.ts +55 -0
- package/dist/runtime/utils/org-chart.js +367 -0
- package/package.json +1 -1
- package/dist/runtime/components/EventCalendarHeader.vue +0 -48
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -119,9 +119,109 @@ const eventCalendar = (options) => ({
|
|
|
119
119
|
}
|
|
120
120
|
});
|
|
121
121
|
|
|
122
|
+
const orgChart = (options) => ({
|
|
123
|
+
slots: {
|
|
124
|
+
// Root container
|
|
125
|
+
root: "relative w-full overflow-auto",
|
|
126
|
+
// Viewport (zoom/pan container)
|
|
127
|
+
viewport: "relative will-change-transform",
|
|
128
|
+
// SVG connector layer
|
|
129
|
+
connectorLayer: "absolute inset-0 pointer-events-none overflow-visible",
|
|
130
|
+
connector: "fill-none text-[var(--ui-border-accented)] stroke-current stroke-2",
|
|
131
|
+
// Non-hierarchical connection
|
|
132
|
+
connection: "fill-none text-[var(--ui-border-accented)] stroke-current stroke-2 pointer-events-auto cursor-pointer",
|
|
133
|
+
connectionLabel: [
|
|
134
|
+
"absolute text-xs px-1.5 py-0.5 rounded bg-elevated border border-default",
|
|
135
|
+
"text-muted whitespace-nowrap pointer-events-auto cursor-pointer",
|
|
136
|
+
"-translate-x-1/2 -translate-y-1/2"
|
|
137
|
+
],
|
|
138
|
+
// Node card
|
|
139
|
+
node: [
|
|
140
|
+
"absolute flex items-center gap-3 rounded-lg border border-default bg-default",
|
|
141
|
+
"px-3 py-2 cursor-pointer select-none",
|
|
142
|
+
"hover:shadow-md"
|
|
143
|
+
],
|
|
144
|
+
nodeAnimated: "transition-all duration-300 ease-in-out",
|
|
145
|
+
nodeSelected: "ring-2",
|
|
146
|
+
nodeFocused: "outline-2 outline-offset-2",
|
|
147
|
+
nodeDimmed: "opacity-30 pointer-events-none",
|
|
148
|
+
nodeMatched: "ring-2 shadow-md",
|
|
149
|
+
// Drag-and-drop
|
|
150
|
+
nodeDragging: "opacity-50 shadow-lg scale-105",
|
|
151
|
+
nodeDropTarget: "ring-2 ring-dashed",
|
|
152
|
+
// Node internals
|
|
153
|
+
nodeAvatar: "size-10 rounded-full shrink-0 object-cover",
|
|
154
|
+
nodeIcon: "size-10 shrink-0 flex items-center justify-center rounded-full bg-elevated",
|
|
155
|
+
nodeContent: "flex flex-col min-w-0",
|
|
156
|
+
nodeName: "text-sm font-semibold text-highlighted truncate",
|
|
157
|
+
nodeTitle: "text-xs text-muted truncate",
|
|
158
|
+
searchHighlight: "text-highlighted rounded-sm px-0.5",
|
|
159
|
+
// Collapse toggle
|
|
160
|
+
collapseToggle: [
|
|
161
|
+
"absolute flex items-center justify-center size-5 rounded-full",
|
|
162
|
+
"bg-elevated border border-default text-muted cursor-pointer",
|
|
163
|
+
"hover:bg-default hover:text-highlighted transition-colors"
|
|
164
|
+
],
|
|
165
|
+
descendantBadge: "text-[10px] font-medium",
|
|
166
|
+
// Zoom controls
|
|
167
|
+
zoomControls: "absolute top-2 right-2 flex flex-col gap-1 z-10",
|
|
168
|
+
// Empty state
|
|
169
|
+
emptyState: "flex flex-col items-center justify-center gap-2 py-14 text-center",
|
|
170
|
+
emptyStateIcon: "size-10 text-muted/50",
|
|
171
|
+
emptyStateText: "text-sm text-muted"
|
|
172
|
+
},
|
|
173
|
+
variants: {
|
|
174
|
+
color: {
|
|
175
|
+
...Object.fromEntries((options.theme.colors || []).map((color) => [color, ""])),
|
|
176
|
+
neutral: ""
|
|
177
|
+
},
|
|
178
|
+
compact: {
|
|
179
|
+
true: "",
|
|
180
|
+
false: ""
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
compoundVariants: [
|
|
184
|
+
...(options.theme.colors || []).map((color) => ({
|
|
185
|
+
color,
|
|
186
|
+
class: {
|
|
187
|
+
nodeSelected: `ring-${color}`,
|
|
188
|
+
nodeFocused: `outline-${color}`,
|
|
189
|
+
nodeDropTarget: `ring-${color} bg-${color}/5`,
|
|
190
|
+
nodeMatched: `ring-${color}`,
|
|
191
|
+
searchHighlight: `bg-${color}/30`
|
|
192
|
+
}
|
|
193
|
+
})),
|
|
194
|
+
{
|
|
195
|
+
color: "neutral",
|
|
196
|
+
class: {
|
|
197
|
+
nodeSelected: "ring-inverted",
|
|
198
|
+
nodeFocused: "outline-inverted",
|
|
199
|
+
nodeDropTarget: "ring-inverted bg-inverted/5",
|
|
200
|
+
nodeMatched: "ring-inverted",
|
|
201
|
+
searchHighlight: "bg-inverted/30"
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
compact: true,
|
|
206
|
+
class: {
|
|
207
|
+
node: "px-2 py-1 gap-2",
|
|
208
|
+
nodeAvatar: "size-6",
|
|
209
|
+
nodeIcon: "size-6",
|
|
210
|
+
nodeName: "text-xs",
|
|
211
|
+
nodeTitle: "hidden"
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
],
|
|
215
|
+
defaultVariants: {
|
|
216
|
+
color: "primary",
|
|
217
|
+
compact: false
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
122
221
|
const theme = {
|
|
123
222
|
__proto__: null,
|
|
124
|
-
eventCalendar: eventCalendar
|
|
223
|
+
eventCalendar: eventCalendar,
|
|
224
|
+
orgChart: orgChart
|
|
125
225
|
};
|
|
126
226
|
|
|
127
227
|
function addTemplates(options, _nuxt) {
|
|
@@ -246,12 +346,12 @@ Add it to your \`.env\` file to build for production.`
|
|
|
246
346
|
}
|
|
247
347
|
};
|
|
248
348
|
addTemplates(optionsWithTheme);
|
|
249
|
-
nuxt.options.css.push(resolver.resolve("./runtime/index.css"));
|
|
250
349
|
addImportsDir(resolver.resolve("./runtime/composables"));
|
|
251
350
|
nuxt.options.alias["#ui-elements-pro"] = resolver.resolve("./runtime");
|
|
252
351
|
addComponentsDir({
|
|
253
352
|
path: resolver.resolve("./runtime/components"),
|
|
254
|
-
prefix: options.prefix
|
|
353
|
+
prefix: options.prefix,
|
|
354
|
+
pattern: "*.vue"
|
|
255
355
|
});
|
|
256
356
|
}
|
|
257
357
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CalendarDate, DateValue } from "@internationalized/date";
|
|
2
2
|
import type { AppConfig } from "@nuxt/schema";
|
|
3
3
|
import type { ComponentConfig } from "nuxt-ui-elements";
|
|
4
|
-
import type { CalendarEvent, CalendarView, MonthViewOptions, WeekViewOptions, DayViewOptions, EventDropPayload, EventResizePayload, SelectPayload, EventCalendarContext } from "../types/event-calendar.js";
|
|
4
|
+
import type { CalendarEvent, CalendarView, CalendarDay, MonthViewOptions, WeekViewOptions, DayViewOptions, EventDropPayload, EventResizePayload, SelectPayload, EventCalendarContext } from "../types/event-calendar.js";
|
|
5
5
|
import { type Component } from "vue";
|
|
6
6
|
import theme from "#build/ui-elements-pro/event-calendar";
|
|
7
7
|
type EventCalendar = ComponentConfig<typeof theme, AppConfig, "eventCalendar">;
|
|
@@ -14,6 +14,8 @@ export interface EventCalendarProps {
|
|
|
14
14
|
modelValue?: Date | string | DateValue;
|
|
15
15
|
/** Calendar view mode @defaultValue 'month' */
|
|
16
16
|
view?: CalendarView;
|
|
17
|
+
/** Which views are available and shown in the view switcher @defaultValue ['month', 'week', 'day', 'list'] */
|
|
18
|
+
views?: CalendarView[];
|
|
17
19
|
/** Locale for day/month names @defaultValue 'en-US' */
|
|
18
20
|
locale?: string;
|
|
19
21
|
/** Day the week starts on (0=Sun, 1=Mon, … 6=Sat) @defaultValue 0 */
|
|
@@ -26,6 +28,8 @@ export interface EventCalendarProps {
|
|
|
26
28
|
selectable?: boolean;
|
|
27
29
|
/** Theme color for calendar chrome @defaultValue 'primary' */
|
|
28
30
|
color?: EventCalendar["variants"]["color"];
|
|
31
|
+
/** Override header title. Pass a string for static text, or a function for dynamic formatting. */
|
|
32
|
+
headerTitle?: string | ((date: CalendarDate, view: CalendarView) => string);
|
|
29
33
|
/** Month view options */
|
|
30
34
|
monthOptions?: MonthViewOptions;
|
|
31
35
|
/** Week view options */
|
|
@@ -60,11 +64,88 @@ export interface EventCalendarEmits {
|
|
|
60
64
|
select: [payload: SelectPayload];
|
|
61
65
|
}
|
|
62
66
|
export interface EventCalendarSlots {
|
|
63
|
-
default
|
|
67
|
+
default?: (props: EventCalendarContext) => any;
|
|
68
|
+
/** Replace the entire header */
|
|
69
|
+
header?: (props: {
|
|
70
|
+
title: string;
|
|
71
|
+
prev: () => void;
|
|
72
|
+
next: () => void;
|
|
73
|
+
today: () => void;
|
|
74
|
+
currentDate: CalendarDate;
|
|
75
|
+
view: CalendarView;
|
|
76
|
+
setView: (v: CalendarView) => void;
|
|
77
|
+
views: CalendarView[];
|
|
78
|
+
}) => any;
|
|
79
|
+
/** Replace just the header title element */
|
|
80
|
+
"header-title"?: (props: {
|
|
81
|
+
title: string;
|
|
82
|
+
date: CalendarDate;
|
|
83
|
+
view: CalendarView;
|
|
84
|
+
}) => any;
|
|
85
|
+
/** Replace just the header nav buttons */
|
|
86
|
+
"header-nav"?: (props: {
|
|
87
|
+
prev: () => void;
|
|
88
|
+
next: () => void;
|
|
89
|
+
today: () => void;
|
|
90
|
+
}) => any;
|
|
91
|
+
/** Replace just the header view switcher */
|
|
92
|
+
"header-view-switcher"?: (props: {
|
|
93
|
+
view: CalendarView;
|
|
94
|
+
setView: (v: CalendarView) => void;
|
|
95
|
+
views: CalendarView[];
|
|
96
|
+
}) => any;
|
|
97
|
+
/** Customize event rendering across all views */
|
|
98
|
+
event?: (props: {
|
|
99
|
+
event: CalendarEvent;
|
|
100
|
+
view: CalendarView;
|
|
101
|
+
}) => any;
|
|
102
|
+
/** Customize weekday header labels (month view) */
|
|
103
|
+
"day-header"?: (props: {
|
|
104
|
+
day: string;
|
|
105
|
+
index: number;
|
|
106
|
+
}) => any;
|
|
107
|
+
/** Customize day cell content (month view) */
|
|
108
|
+
day?: (props: {
|
|
109
|
+
day: CalendarDay;
|
|
110
|
+
}) => any;
|
|
111
|
+
/** Customize "+N more" indicator (month view) */
|
|
112
|
+
"more-events"?: (props: {
|
|
113
|
+
events: CalendarEvent[];
|
|
114
|
+
count: number;
|
|
115
|
+
day: CalendarDay;
|
|
116
|
+
}) => any;
|
|
117
|
+
/** Customize time labels (week/day view) */
|
|
118
|
+
"time-label"?: (props: {
|
|
119
|
+
hour: number;
|
|
120
|
+
label: string;
|
|
121
|
+
}) => any;
|
|
122
|
+
/** Customize all-day event area (week/day view) */
|
|
123
|
+
"all-day"?: (props: {
|
|
124
|
+
events: CalendarEvent[];
|
|
125
|
+
date: CalendarDate;
|
|
126
|
+
}) => any;
|
|
127
|
+
/** Customize date group headers (list view) */
|
|
128
|
+
"date-header"?: (props: {
|
|
129
|
+
day: CalendarDay;
|
|
130
|
+
weekday: string;
|
|
131
|
+
dateLabel: string;
|
|
132
|
+
}) => any;
|
|
133
|
+
/** Customize loading overlay */
|
|
134
|
+
loading?: () => any;
|
|
135
|
+
/** Customize empty state */
|
|
136
|
+
empty?: () => any;
|
|
64
137
|
}
|
|
65
138
|
declare const _default: typeof __VLS_export;
|
|
66
139
|
export default _default;
|
|
67
|
-
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<EventCalendarProps, {
|
|
140
|
+
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<EventCalendarProps, {
|
|
141
|
+
next: () => void;
|
|
142
|
+
prev: () => void;
|
|
143
|
+
today: () => void;
|
|
144
|
+
setView: (v: CalendarView) => void;
|
|
145
|
+
setDate: (date: Date | string | DateValue) => void;
|
|
146
|
+
view: import("vue").ComputedRef<CalendarView>;
|
|
147
|
+
date: import("vue").ComputedRef<CalendarDate>;
|
|
148
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
68
149
|
select: (payload: SelectPayload) => any;
|
|
69
150
|
"update:modelValue": (value: CalendarDate) => any;
|
|
70
151
|
"update:view": (value: CalendarView) => any;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { Primitive } from "reka-ui";
|
|
3
|
-
import { computed, provide } from "vue";
|
|
3
|
+
import { computed, provide, ref, useSlots, watch } from "vue";
|
|
4
|
+
import { asCalendarDate } from "#std/date";
|
|
4
5
|
import { tv } from "../utils/tv";
|
|
5
6
|
import { useEventCalendar } from "../composables/useEventCalendar";
|
|
6
7
|
import { useEventCalendarDragDrop } from "../composables/useEventCalendarDragDrop";
|
|
@@ -8,6 +9,10 @@ import { useEventCalendarKeyboard } from "../composables/useEventCalendarKeyboar
|
|
|
8
9
|
import { useEventCalendarResize } from "../composables/useEventCalendarResize";
|
|
9
10
|
import { useEventCalendarSelect } from "../composables/useEventCalendarSelect";
|
|
10
11
|
import { eventCalendarContextKey } from "../composables/useEventCalendarContext";
|
|
12
|
+
import EventCalendarHeader from "./event-calendar/EventCalendarHeader.vue";
|
|
13
|
+
import EventCalendarMonthView from "./event-calendar/EventCalendarMonthView.vue";
|
|
14
|
+
import EventCalendarTimeGrid from "./event-calendar/EventCalendarTimeGrid.vue";
|
|
15
|
+
import EventCalendarListView from "./event-calendar/EventCalendarListView.vue";
|
|
11
16
|
import theme from "#build/ui-elements-pro/event-calendar";
|
|
12
17
|
</script>
|
|
13
18
|
|
|
@@ -17,12 +22,14 @@ const props = defineProps({
|
|
|
17
22
|
events: { type: Array, required: false },
|
|
18
23
|
modelValue: { type: null, required: false },
|
|
19
24
|
view: { type: String, required: false },
|
|
25
|
+
views: { type: Array, required: false },
|
|
20
26
|
locale: { type: String, required: false },
|
|
21
27
|
weekStartsOn: { type: Number, required: false },
|
|
22
28
|
editable: { type: Boolean, required: false, default: true },
|
|
23
29
|
loading: { type: Boolean, required: false },
|
|
24
30
|
selectable: { type: Boolean, required: false, default: true },
|
|
25
31
|
color: { type: null, required: false },
|
|
32
|
+
headerTitle: { type: [String, Function], required: false },
|
|
26
33
|
monthOptions: { type: Object, required: false },
|
|
27
34
|
weekOptions: { type: Object, required: false },
|
|
28
35
|
dayOptions: { type: Object, required: false },
|
|
@@ -30,6 +37,16 @@ const props = defineProps({
|
|
|
30
37
|
});
|
|
31
38
|
const emit = defineEmits(["update:modelValue", "update:view", "dateClick", "eventClick", "eventDrop", "eventResize", "eventResizeStart", "eventResizeEnd", "select"]);
|
|
32
39
|
defineSlots();
|
|
40
|
+
const slots = useSlots();
|
|
41
|
+
const ALL_VIEWS = ["month", "week", "day", "list"];
|
|
42
|
+
const internalView = ref(props.view ?? "month");
|
|
43
|
+
watch(() => props.view, (v) => {
|
|
44
|
+
if (v !== void 0) internalView.value = v;
|
|
45
|
+
});
|
|
46
|
+
function updateView(v) {
|
|
47
|
+
internalView.value = v;
|
|
48
|
+
emit("update:view", v);
|
|
49
|
+
}
|
|
33
50
|
const ui = computed(
|
|
34
51
|
() => tv({
|
|
35
52
|
extend: tv(theme)
|
|
@@ -40,14 +57,14 @@ const ui = computed(
|
|
|
40
57
|
const calendar = useEventCalendar({
|
|
41
58
|
events: () => props.events ?? [],
|
|
42
59
|
modelValue: () => props.modelValue,
|
|
43
|
-
view: () =>
|
|
60
|
+
view: () => internalView.value,
|
|
44
61
|
locale: () => props.locale ?? "en-US",
|
|
45
62
|
weekStartsOn: () => props.weekStartsOn ?? 0,
|
|
46
63
|
monthOptions: () => props.monthOptions,
|
|
47
64
|
weekOptions: () => props.weekOptions,
|
|
48
65
|
dayOptions: () => props.dayOptions,
|
|
49
66
|
onUpdateModelValue: (date) => emit("update:modelValue", date),
|
|
50
|
-
onUpdateView:
|
|
67
|
+
onUpdateView: updateView
|
|
51
68
|
});
|
|
52
69
|
const dragDrop = useEventCalendarDragDrop({
|
|
53
70
|
editable: () => props.editable ?? true,
|
|
@@ -58,7 +75,7 @@ const resize = useEventCalendarResize({
|
|
|
58
75
|
editable: () => props.editable ?? true,
|
|
59
76
|
normalizedEvents: calendar.normalizedEvents,
|
|
60
77
|
gridConfig: () => {
|
|
61
|
-
const v =
|
|
78
|
+
const v = internalView.value;
|
|
62
79
|
return v === "day" ? calendar.dayConfig.value : calendar.weekConfig.value;
|
|
63
80
|
},
|
|
64
81
|
slotHeight: calendar.SLOT_HEIGHT,
|
|
@@ -68,7 +85,7 @@ const resize = useEventCalendarResize({
|
|
|
68
85
|
});
|
|
69
86
|
const keyboard = useEventCalendarKeyboard({
|
|
70
87
|
displayDate: calendar.displayDate,
|
|
71
|
-
view: () =>
|
|
88
|
+
view: () => internalView.value,
|
|
72
89
|
locale: () => props.locale ?? "en-US",
|
|
73
90
|
weekStartsOn: () => props.weekStartsOn ?? 0,
|
|
74
91
|
goToPrev: calendar.goToPrev,
|
|
@@ -78,17 +95,17 @@ const keyboard = useEventCalendarKeyboard({
|
|
|
78
95
|
});
|
|
79
96
|
const selection = useEventCalendarSelect({
|
|
80
97
|
selectable: () => props.selectable ?? true,
|
|
81
|
-
view: () =>
|
|
98
|
+
view: () => internalView.value,
|
|
82
99
|
slotDuration: () => {
|
|
83
|
-
const v =
|
|
100
|
+
const v = internalView.value;
|
|
84
101
|
return v === "day" ? props.dayOptions?.slotDuration ?? 30 : props.weekOptions?.slotDuration ?? 30;
|
|
85
102
|
},
|
|
86
103
|
startHour: () => {
|
|
87
|
-
const v =
|
|
104
|
+
const v = internalView.value;
|
|
88
105
|
return v === "day" ? props.dayOptions?.startHour ?? 7 : props.weekOptions?.startHour ?? 7;
|
|
89
106
|
},
|
|
90
107
|
endHour: () => {
|
|
91
|
-
const v =
|
|
108
|
+
const v = internalView.value;
|
|
92
109
|
return v === "day" ? props.dayOptions?.endHour ?? 22 : props.weekOptions?.endHour ?? 22;
|
|
93
110
|
},
|
|
94
111
|
onSelect: (payload) => emit("select", payload)
|
|
@@ -105,14 +122,23 @@ function handleEventClick(event, e) {
|
|
|
105
122
|
e.stopPropagation();
|
|
106
123
|
emit("eventClick", event.original);
|
|
107
124
|
}
|
|
125
|
+
const resolvedHeaderTitle = computed(() => {
|
|
126
|
+
if (typeof props.headerTitle === "string") return props.headerTitle;
|
|
127
|
+
if (typeof props.headerTitle === "function") {
|
|
128
|
+
return props.headerTitle(calendar.displayDate.value, internalView.value);
|
|
129
|
+
}
|
|
130
|
+
return calendar.headerTitle.value;
|
|
131
|
+
});
|
|
132
|
+
const resolvedViews = computed(() => props.views ?? ALL_VIEWS);
|
|
108
133
|
const ctx = {
|
|
109
134
|
displayDate: calendar.displayDate,
|
|
110
|
-
view: computed(() =>
|
|
135
|
+
view: computed(() => internalView.value),
|
|
111
136
|
locale: computed(() => props.locale ?? "en-US"),
|
|
112
137
|
weekStartsOn: computed(() => props.weekStartsOn ?? 0),
|
|
113
138
|
editable: computed(() => props.editable ?? true),
|
|
114
139
|
loading: computed(() => props.loading ?? false),
|
|
115
140
|
color: computed(() => props.color ?? "primary"),
|
|
141
|
+
views: resolvedViews,
|
|
116
142
|
monthConfig: calendar.monthConfig,
|
|
117
143
|
weekConfig: calendar.weekConfig,
|
|
118
144
|
dayConfig: calendar.dayConfig,
|
|
@@ -125,7 +151,7 @@ const ctx = {
|
|
|
125
151
|
timeGridDays: calendar.timeGridDays,
|
|
126
152
|
allDayLayout: calendar.allDayLayout,
|
|
127
153
|
timeGridSlots: calendar.timeGridSlots,
|
|
128
|
-
headerTitle:
|
|
154
|
+
headerTitle: resolvedHeaderTitle,
|
|
129
155
|
formatTime: calendar.formatTime,
|
|
130
156
|
formatTimeRange: calendar.formatTimeRange,
|
|
131
157
|
getEventStyle: calendar.getEventStyle,
|
|
@@ -147,10 +173,101 @@ const ctx = {
|
|
|
147
173
|
SLOT_HEIGHT: calendar.SLOT_HEIGHT
|
|
148
174
|
};
|
|
149
175
|
provide(eventCalendarContextKey, ctx);
|
|
176
|
+
function setDate(date) {
|
|
177
|
+
emit("update:modelValue", asCalendarDate(date));
|
|
178
|
+
}
|
|
179
|
+
defineExpose({
|
|
180
|
+
next: ctx.goToNext,
|
|
181
|
+
prev: ctx.goToPrev,
|
|
182
|
+
today: ctx.goToToday,
|
|
183
|
+
setView: ctx.setView,
|
|
184
|
+
setDate,
|
|
185
|
+
view: ctx.view,
|
|
186
|
+
date: ctx.displayDate
|
|
187
|
+
});
|
|
150
188
|
</script>
|
|
151
189
|
|
|
152
190
|
<template>
|
|
153
191
|
<Primitive :as="props.as ?? 'div'" data-slot="root" :class="ui.root({ class: props.ui?.root })">
|
|
154
|
-
|
|
192
|
+
<!-- Compound mode: user provides #default and owns rendering -->
|
|
193
|
+
<slot v-if="slots.default" v-bind="ctx" />
|
|
194
|
+
|
|
195
|
+
<!-- Auto mode: render header + active view with slot forwarding -->
|
|
196
|
+
<template v-else>
|
|
197
|
+
<!-- Header -->
|
|
198
|
+
<slot
|
|
199
|
+
v-if="slots.header"
|
|
200
|
+
name="header"
|
|
201
|
+
:title="resolvedHeaderTitle"
|
|
202
|
+
:prev="ctx.goToPrev"
|
|
203
|
+
:next="ctx.goToNext"
|
|
204
|
+
:today="ctx.goToToday"
|
|
205
|
+
:current-date="ctx.displayDate.value"
|
|
206
|
+
:view="ctx.view.value"
|
|
207
|
+
:set-view="ctx.setView"
|
|
208
|
+
:views="resolvedViews" />
|
|
209
|
+
<EventCalendarHeader v-else>
|
|
210
|
+
<template v-if="slots['header-title']" #title="titleProps">
|
|
211
|
+
<slot name="header-title" v-bind="titleProps" />
|
|
212
|
+
</template>
|
|
213
|
+
<template v-if="slots['header-nav']" #nav="navProps">
|
|
214
|
+
<slot name="header-nav" v-bind="navProps" />
|
|
215
|
+
</template>
|
|
216
|
+
<template v-if="slots['header-view-switcher']" #view-switcher="vsProps">
|
|
217
|
+
<slot name="header-view-switcher" v-bind="vsProps" />
|
|
218
|
+
</template>
|
|
219
|
+
</EventCalendarHeader>
|
|
220
|
+
|
|
221
|
+
<!-- Month view -->
|
|
222
|
+
<EventCalendarMonthView v-if="ctx.view.value === 'month'">
|
|
223
|
+
<template v-if="slots.event" #event="eventProps">
|
|
224
|
+
<slot name="event" v-bind="eventProps" />
|
|
225
|
+
</template>
|
|
226
|
+
<template v-if="slots['day-header']" #day-header="dayHeaderProps">
|
|
227
|
+
<slot name="day-header" v-bind="dayHeaderProps" />
|
|
228
|
+
</template>
|
|
229
|
+
<template v-if="slots.day" #day="dayProps">
|
|
230
|
+
<slot name="day" v-bind="dayProps" />
|
|
231
|
+
</template>
|
|
232
|
+
<template v-if="slots['more-events']" #more-events="moreProps">
|
|
233
|
+
<slot name="more-events" v-bind="moreProps" />
|
|
234
|
+
</template>
|
|
235
|
+
<template v-if="slots.loading" #loading>
|
|
236
|
+
<slot name="loading" />
|
|
237
|
+
</template>
|
|
238
|
+
<template v-if="slots.empty" #empty>
|
|
239
|
+
<slot name="empty" />
|
|
240
|
+
</template>
|
|
241
|
+
</EventCalendarMonthView>
|
|
242
|
+
|
|
243
|
+
<!-- Week/Day time grid view -->
|
|
244
|
+
<EventCalendarTimeGrid v-else-if="ctx.view.value === 'week' || ctx.view.value === 'day'">
|
|
245
|
+
<template v-if="slots.event" #event="eventProps">
|
|
246
|
+
<slot name="event" v-bind="eventProps" />
|
|
247
|
+
</template>
|
|
248
|
+
<template v-if="slots['time-label']" #time-label="timeLabelProps">
|
|
249
|
+
<slot name="time-label" v-bind="timeLabelProps" />
|
|
250
|
+
</template>
|
|
251
|
+
<template v-if="slots['all-day']" #all-day="allDayProps">
|
|
252
|
+
<slot name="all-day" v-bind="allDayProps" />
|
|
253
|
+
</template>
|
|
254
|
+
<template v-if="slots.loading" #loading>
|
|
255
|
+
<slot name="loading" />
|
|
256
|
+
</template>
|
|
257
|
+
<template v-if="slots.empty" #empty>
|
|
258
|
+
<slot name="empty" />
|
|
259
|
+
</template>
|
|
260
|
+
</EventCalendarTimeGrid>
|
|
261
|
+
|
|
262
|
+
<!-- List view -->
|
|
263
|
+
<EventCalendarListView v-else-if="ctx.view.value === 'list'">
|
|
264
|
+
<template v-if="slots.event" #event="eventProps">
|
|
265
|
+
<slot name="event" v-bind="eventProps" />
|
|
266
|
+
</template>
|
|
267
|
+
<template v-if="slots['date-header']" #date-header="dateHeaderProps">
|
|
268
|
+
<slot name="date-header" v-bind="dateHeaderProps" />
|
|
269
|
+
</template>
|
|
270
|
+
</EventCalendarListView>
|
|
271
|
+
</template>
|
|
155
272
|
</Primitive>
|
|
156
273
|
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CalendarDate, DateValue } from "@internationalized/date";
|
|
2
2
|
import type { AppConfig } from "@nuxt/schema";
|
|
3
3
|
import type { ComponentConfig } from "nuxt-ui-elements";
|
|
4
|
-
import type { CalendarEvent, CalendarView, MonthViewOptions, WeekViewOptions, DayViewOptions, EventDropPayload, EventResizePayload, SelectPayload, EventCalendarContext } from "../types/event-calendar.js";
|
|
4
|
+
import type { CalendarEvent, CalendarView, CalendarDay, MonthViewOptions, WeekViewOptions, DayViewOptions, EventDropPayload, EventResizePayload, SelectPayload, EventCalendarContext } from "../types/event-calendar.js";
|
|
5
5
|
import { type Component } from "vue";
|
|
6
6
|
import theme from "#build/ui-elements-pro/event-calendar";
|
|
7
7
|
type EventCalendar = ComponentConfig<typeof theme, AppConfig, "eventCalendar">;
|
|
@@ -14,6 +14,8 @@ export interface EventCalendarProps {
|
|
|
14
14
|
modelValue?: Date | string | DateValue;
|
|
15
15
|
/** Calendar view mode @defaultValue 'month' */
|
|
16
16
|
view?: CalendarView;
|
|
17
|
+
/** Which views are available and shown in the view switcher @defaultValue ['month', 'week', 'day', 'list'] */
|
|
18
|
+
views?: CalendarView[];
|
|
17
19
|
/** Locale for day/month names @defaultValue 'en-US' */
|
|
18
20
|
locale?: string;
|
|
19
21
|
/** Day the week starts on (0=Sun, 1=Mon, … 6=Sat) @defaultValue 0 */
|
|
@@ -26,6 +28,8 @@ export interface EventCalendarProps {
|
|
|
26
28
|
selectable?: boolean;
|
|
27
29
|
/** Theme color for calendar chrome @defaultValue 'primary' */
|
|
28
30
|
color?: EventCalendar["variants"]["color"];
|
|
31
|
+
/** Override header title. Pass a string for static text, or a function for dynamic formatting. */
|
|
32
|
+
headerTitle?: string | ((date: CalendarDate, view: CalendarView) => string);
|
|
29
33
|
/** Month view options */
|
|
30
34
|
monthOptions?: MonthViewOptions;
|
|
31
35
|
/** Week view options */
|
|
@@ -60,11 +64,88 @@ export interface EventCalendarEmits {
|
|
|
60
64
|
select: [payload: SelectPayload];
|
|
61
65
|
}
|
|
62
66
|
export interface EventCalendarSlots {
|
|
63
|
-
default
|
|
67
|
+
default?: (props: EventCalendarContext) => any;
|
|
68
|
+
/** Replace the entire header */
|
|
69
|
+
header?: (props: {
|
|
70
|
+
title: string;
|
|
71
|
+
prev: () => void;
|
|
72
|
+
next: () => void;
|
|
73
|
+
today: () => void;
|
|
74
|
+
currentDate: CalendarDate;
|
|
75
|
+
view: CalendarView;
|
|
76
|
+
setView: (v: CalendarView) => void;
|
|
77
|
+
views: CalendarView[];
|
|
78
|
+
}) => any;
|
|
79
|
+
/** Replace just the header title element */
|
|
80
|
+
"header-title"?: (props: {
|
|
81
|
+
title: string;
|
|
82
|
+
date: CalendarDate;
|
|
83
|
+
view: CalendarView;
|
|
84
|
+
}) => any;
|
|
85
|
+
/** Replace just the header nav buttons */
|
|
86
|
+
"header-nav"?: (props: {
|
|
87
|
+
prev: () => void;
|
|
88
|
+
next: () => void;
|
|
89
|
+
today: () => void;
|
|
90
|
+
}) => any;
|
|
91
|
+
/** Replace just the header view switcher */
|
|
92
|
+
"header-view-switcher"?: (props: {
|
|
93
|
+
view: CalendarView;
|
|
94
|
+
setView: (v: CalendarView) => void;
|
|
95
|
+
views: CalendarView[];
|
|
96
|
+
}) => any;
|
|
97
|
+
/** Customize event rendering across all views */
|
|
98
|
+
event?: (props: {
|
|
99
|
+
event: CalendarEvent;
|
|
100
|
+
view: CalendarView;
|
|
101
|
+
}) => any;
|
|
102
|
+
/** Customize weekday header labels (month view) */
|
|
103
|
+
"day-header"?: (props: {
|
|
104
|
+
day: string;
|
|
105
|
+
index: number;
|
|
106
|
+
}) => any;
|
|
107
|
+
/** Customize day cell content (month view) */
|
|
108
|
+
day?: (props: {
|
|
109
|
+
day: CalendarDay;
|
|
110
|
+
}) => any;
|
|
111
|
+
/** Customize "+N more" indicator (month view) */
|
|
112
|
+
"more-events"?: (props: {
|
|
113
|
+
events: CalendarEvent[];
|
|
114
|
+
count: number;
|
|
115
|
+
day: CalendarDay;
|
|
116
|
+
}) => any;
|
|
117
|
+
/** Customize time labels (week/day view) */
|
|
118
|
+
"time-label"?: (props: {
|
|
119
|
+
hour: number;
|
|
120
|
+
label: string;
|
|
121
|
+
}) => any;
|
|
122
|
+
/** Customize all-day event area (week/day view) */
|
|
123
|
+
"all-day"?: (props: {
|
|
124
|
+
events: CalendarEvent[];
|
|
125
|
+
date: CalendarDate;
|
|
126
|
+
}) => any;
|
|
127
|
+
/** Customize date group headers (list view) */
|
|
128
|
+
"date-header"?: (props: {
|
|
129
|
+
day: CalendarDay;
|
|
130
|
+
weekday: string;
|
|
131
|
+
dateLabel: string;
|
|
132
|
+
}) => any;
|
|
133
|
+
/** Customize loading overlay */
|
|
134
|
+
loading?: () => any;
|
|
135
|
+
/** Customize empty state */
|
|
136
|
+
empty?: () => any;
|
|
64
137
|
}
|
|
65
138
|
declare const _default: typeof __VLS_export;
|
|
66
139
|
export default _default;
|
|
67
|
-
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<EventCalendarProps, {
|
|
140
|
+
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<EventCalendarProps, {
|
|
141
|
+
next: () => void;
|
|
142
|
+
prev: () => void;
|
|
143
|
+
today: () => void;
|
|
144
|
+
setView: (v: CalendarView) => void;
|
|
145
|
+
setDate: (date: Date | string | DateValue) => void;
|
|
146
|
+
view: import("vue").ComputedRef<CalendarView>;
|
|
147
|
+
date: import("vue").ComputedRef<CalendarDate>;
|
|
148
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
68
149
|
select: (payload: SelectPayload) => any;
|
|
69
150
|
"update:modelValue": (value: CalendarDate) => any;
|
|
70
151
|
"update:view": (value: CalendarView) => any;
|