nuxt-ui-elements-pro 0.1.9 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/module.d.mts +5 -0
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +243 -3
  4. package/dist/runtime/components/EventCalendar.d.vue.ts +4 -0
  5. package/dist/runtime/components/EventCalendar.vue +5 -2
  6. package/dist/runtime/components/EventCalendar.vue.d.ts +4 -0
  7. package/dist/runtime/components/FeedbackWidget.d.vue.ts +118 -0
  8. package/dist/runtime/components/FeedbackWidget.vue +141 -0
  9. package/dist/runtime/components/FeedbackWidget.vue.d.ts +118 -0
  10. package/dist/runtime/components/GanttChart.d.vue.ts +138 -0
  11. package/dist/runtime/components/GanttChart.vue +206 -0
  12. package/dist/runtime/components/GanttChart.vue.d.ts +138 -0
  13. package/dist/runtime/components/event-calendar/EventCalendarMonthView.d.vue.ts +3 -0
  14. package/dist/runtime/components/event-calendar/EventCalendarMonthView.vue +15 -6
  15. package/dist/runtime/components/event-calendar/EventCalendarMonthView.vue.d.ts +3 -0
  16. package/dist/runtime/components/event-calendar/EventCalendarTimeGrid.vue +23 -3
  17. package/dist/runtime/components/feedback-widget/FeedbackWidgetButton.d.vue.ts +22 -0
  18. package/dist/runtime/components/feedback-widget/FeedbackWidgetButton.vue +27 -0
  19. package/dist/runtime/components/feedback-widget/FeedbackWidgetButton.vue.d.ts +22 -0
  20. package/dist/runtime/components/feedback-widget/FeedbackWidgetPanel.d.vue.ts +42 -0
  21. package/dist/runtime/components/feedback-widget/FeedbackWidgetPanel.vue +288 -0
  22. package/dist/runtime/components/feedback-widget/FeedbackWidgetPanel.vue.d.ts +42 -0
  23. package/dist/runtime/components/gantt-chart/GanttChartDependencies.d.vue.ts +16 -0
  24. package/dist/runtime/components/gantt-chart/GanttChartDependencies.vue +70 -0
  25. package/dist/runtime/components/gantt-chart/GanttChartDependencies.vue.d.ts +16 -0
  26. package/dist/runtime/components/gantt-chart/GanttChartHeader.d.vue.ts +41 -0
  27. package/dist/runtime/components/gantt-chart/GanttChartHeader.vue +56 -0
  28. package/dist/runtime/components/gantt-chart/GanttChartHeader.vue.d.ts +41 -0
  29. package/dist/runtime/components/gantt-chart/GanttChartTimeline.d.vue.ts +34 -0
  30. package/dist/runtime/components/gantt-chart/GanttChartTimeline.vue +193 -0
  31. package/dist/runtime/components/gantt-chart/GanttChartTimeline.vue.d.ts +34 -0
  32. package/dist/runtime/composables/useEventCalendar.d.ts +2 -0
  33. package/dist/runtime/composables/useEventCalendar.js +8 -6
  34. package/dist/runtime/composables/useEventCalendarContext.d.ts +2 -7
  35. package/dist/runtime/composables/useEventCalendarContext.js +4 -11
  36. package/dist/runtime/composables/useFeedbackWidget.d.ts +46 -0
  37. package/dist/runtime/composables/useFeedbackWidget.js +137 -0
  38. package/dist/runtime/composables/useFeedbackWidgetContext.d.ts +3 -0
  39. package/dist/runtime/composables/useFeedbackWidgetContext.js +4 -0
  40. package/dist/runtime/composables/useGanttChart.d.ts +52 -0
  41. package/dist/runtime/composables/useGanttChart.js +224 -0
  42. package/dist/runtime/composables/useGanttChartContext.d.ts +3 -0
  43. package/dist/runtime/composables/useGanttChartContext.js +4 -0
  44. package/dist/runtime/composables/useGanttChartDragDrop.d.ts +28 -0
  45. package/dist/runtime/composables/useGanttChartDragDrop.js +68 -0
  46. package/dist/runtime/composables/useGanttChartKeyboard.d.ts +14 -0
  47. package/dist/runtime/composables/useGanttChartKeyboard.js +92 -0
  48. package/dist/runtime/composables/useGanttChartResize.d.ts +26 -0
  49. package/dist/runtime/composables/useGanttChartResize.js +89 -0
  50. package/dist/runtime/composables/useOrgChartContext.d.ts +2 -7
  51. package/dist/runtime/composables/useOrgChartContext.js +4 -11
  52. package/dist/runtime/index.d.ts +1 -0
  53. package/dist/runtime/index.js +1 -0
  54. package/dist/runtime/server/api/_feedback.post.d.ts +3 -0
  55. package/dist/runtime/server/api/_feedback.post.js +115 -0
  56. package/dist/runtime/server/nodemailer.d.ts +29 -0
  57. package/dist/runtime/server/utils/feedback-captcha.d.ts +1 -0
  58. package/dist/runtime/server/utils/feedback-captcha.js +27 -0
  59. package/dist/runtime/server/utils/feedback-rate-limit.d.ts +4 -0
  60. package/dist/runtime/server/utils/feedback-rate-limit.js +26 -0
  61. package/dist/runtime/types/event-calendar.d.ts +10 -4
  62. package/dist/runtime/types/feedback-widget.d.ts +110 -0
  63. package/dist/runtime/types/feedback-widget.js +0 -0
  64. package/dist/runtime/types/gantt-chart.d.ts +223 -0
  65. package/dist/runtime/types/gantt-chart.js +0 -0
  66. package/dist/runtime/types/index.d.ts +4 -0
  67. package/dist/runtime/types/index.js +4 -0
  68. package/dist/runtime/utils/createComponentContext.d.ts +15 -0
  69. package/dist/runtime/utils/createComponentContext.js +17 -0
  70. package/dist/runtime/utils/date.d.ts +10 -0
  71. package/dist/runtime/utils/date.js +9 -0
  72. package/dist/runtime/utils/event-calendar.d.ts +1 -9
  73. package/dist/runtime/utils/event-calendar.js +2 -9
  74. package/dist/runtime/utils/gantt-chart.d.ts +85 -0
  75. package/dist/runtime/utils/gantt-chart.js +549 -0
  76. package/dist/runtime/utils/recurrence.js +2 -1
  77. package/package.json +17 -8
@@ -0,0 +1,118 @@
1
+ import type { AppConfig } from "@nuxt/schema";
2
+ import type { ComponentConfig } from "nuxt-ui-elements";
3
+ import type { FeedbackType, FeedbackTypeId, FeedbackSubmission, FeedbackSubmitResult, FeedbackWidgetPosition, FeedbackWidgetContext } from "../types/feedback-widget.js";
4
+ import { type Component } from "vue";
5
+ import theme from "#build/ui-elements-pro/feedback-widget";
6
+ type FeedbackWidgetTheme = ComponentConfig<typeof theme, AppConfig, "feedbackWidget">;
7
+ export interface FeedbackWidgetProps {
8
+ /** Rendered element type @defaultValue 'div' */
9
+ as?: string | Component;
10
+ /** Configurable feedback type options @defaultValue bug/feature/general */
11
+ feedbackTypes?: FeedbackType[];
12
+ /** Widget position @defaultValue 'bottom-right' */
13
+ position?: FeedbackWidgetPosition;
14
+ /** Theme color @defaultValue 'primary' */
15
+ color?: FeedbackWidgetTheme["variants"]["color"];
16
+ /** Show screenshot capture button @defaultValue false */
17
+ showScreenshot?: boolean;
18
+ /** Custom button icon @defaultValue 'i-lucide-message-square-plus' */
19
+ buttonIcon?: string;
20
+ /** Button label (screen reader) @defaultValue 'Send feedback' */
21
+ buttonLabel?: string;
22
+ /** Panel title @defaultValue 'Send Feedback' */
23
+ title?: string;
24
+ /** Email field placeholder @defaultValue 'your@email.com' */
25
+ emailPlaceholder?: string;
26
+ /** Message field placeholder @defaultValue 'Tell us what you think...' */
27
+ messagePlaceholder?: string;
28
+ /** Custom submit handler. If provided, bypasses built-in server route. */
29
+ onSubmit?: (submission: FeedbackSubmission) => Promise<FeedbackSubmitResult> | FeedbackSubmitResult;
30
+ /** Built-in endpoint path @defaultValue '/api/_feedback' */
31
+ submitEndpoint?: string;
32
+ /** Slot class overrides */
33
+ ui?: FeedbackWidgetTheme["slots"];
34
+ }
35
+ export interface FeedbackWidgetEmits {
36
+ /** Fires when the panel opens */
37
+ open: [];
38
+ /** Fires when the panel closes */
39
+ close: [];
40
+ /** Fires after successful submission */
41
+ success: [submission: FeedbackSubmission];
42
+ /** Fires on submission error */
43
+ error: [message: string];
44
+ }
45
+ export interface FeedbackWidgetSlots {
46
+ /** Compound mode: full rendering control */
47
+ default?: (props: FeedbackWidgetContext) => any;
48
+ /** Custom trigger button */
49
+ button?: (props: {
50
+ open: () => void;
51
+ close: () => void;
52
+ toggle: () => void;
53
+ isOpen: boolean;
54
+ }) => any;
55
+ /** Custom panel header */
56
+ "panel-header"?: (props: {
57
+ title: string;
58
+ close: () => void;
59
+ }) => any;
60
+ /** Custom type selector */
61
+ "type-selector"?: (props: {
62
+ types: FeedbackType[];
63
+ selected: FeedbackTypeId | null;
64
+ select: (id: FeedbackTypeId) => void;
65
+ }) => any;
66
+ /** Custom form fields */
67
+ form?: (props: {
68
+ email: string;
69
+ message: string;
70
+ screenshot: string | null;
71
+ }) => any;
72
+ /** Custom success state */
73
+ success?: (props: {
74
+ reset: () => void;
75
+ close: () => void;
76
+ }) => any;
77
+ /** Custom submit button area */
78
+ "submit-area"?: (props: {
79
+ submit: () => void;
80
+ isValid: boolean;
81
+ isSubmitting: boolean;
82
+ }) => any;
83
+ }
84
+ declare const _default: typeof __VLS_export;
85
+ export default _default;
86
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<FeedbackWidgetProps, {
87
+ open: () => void;
88
+ close: () => void;
89
+ toggle: () => void;
90
+ reset: () => void;
91
+ submit: () => Promise<void>;
92
+ isOpen: import("vue").Ref<boolean, boolean>;
93
+ isSubmitted: import("vue").Ref<boolean, boolean>;
94
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
95
+ success: (submission: FeedbackSubmission) => any;
96
+ error: (message: string) => any;
97
+ close: () => any;
98
+ open: () => any;
99
+ }, string, import("vue").PublicProps, Readonly<FeedbackWidgetProps> & Readonly<{
100
+ onSuccess?: ((submission: FeedbackSubmission) => any) | undefined;
101
+ onError?: ((message: string) => any) | undefined;
102
+ onClose?: (() => any) | undefined;
103
+ onOpen?: (() => any) | undefined;
104
+ }>, {
105
+ title: string;
106
+ position: FeedbackWidgetPosition;
107
+ buttonIcon: string;
108
+ showScreenshot: boolean;
109
+ buttonLabel: string;
110
+ emailPlaceholder: string;
111
+ messagePlaceholder: string;
112
+ submitEndpoint: string;
113
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, FeedbackWidgetSlots>;
114
+ type __VLS_WithSlots<T, S> = T & {
115
+ new (): {
116
+ $slots: S;
117
+ };
118
+ };
@@ -0,0 +1,138 @@
1
+ import type { AppConfig } from "@nuxt/schema";
2
+ import type { ComponentConfig } from "nuxt-ui-elements";
3
+ import type { DateValue } from "@internationalized/date";
4
+ import type { GanttTask, GanttDependency, GanttZoomLevel, GanttTaskBar, GanttTaskDropPayload, GanttTaskResizePayload, GanttChartContext } from "../types/gantt-chart.js";
5
+ import { type Component } from "vue";
6
+ import theme from "#build/ui-elements-pro/gantt-chart";
7
+ type GanttChartTheme = ComponentConfig<typeof theme, AppConfig, "ganttChart">;
8
+ export interface GanttChartProps {
9
+ /** Rendered element type @defaultValue 'div' */
10
+ as?: string | Component;
11
+ /** Array of tasks to display */
12
+ tasks?: GanttTask[];
13
+ /** Array of task dependencies */
14
+ dependencies?: GanttDependency[];
15
+ /** Displayed date (v-model) */
16
+ modelValue?: Date | string | DateValue;
17
+ /** Current zoom level (v-model:zoomLevel) @defaultValue 'month' */
18
+ zoomLevel?: GanttZoomLevel;
19
+ /** Available zoom levels @defaultValue all levels */
20
+ zoomLevels?: GanttZoomLevel[];
21
+ /** Locale for formatting @defaultValue 'en-US' */
22
+ locale?: string;
23
+ /** Enable drag/drop and resize @defaultValue true */
24
+ editable?: boolean;
25
+ /** Show loading state @defaultValue false */
26
+ loading?: boolean;
27
+ /** Theme color @defaultValue 'primary' */
28
+ color?: GanttChartTheme["variants"]["color"];
29
+ /** Row height in pixels @defaultValue 40 */
30
+ rowHeight?: number;
31
+ /** Two-way binding for expanded group IDs */
32
+ expanded?: (string | number)[];
33
+ /** Slot class overrides */
34
+ ui?: GanttChartTheme["slots"];
35
+ }
36
+ export interface GanttChartEmits {
37
+ /** Fires when displayed date changes */
38
+ "update:modelValue": [value: import("@internationalized/date").CalendarDate];
39
+ /** Fires when zoom level changes */
40
+ "update:zoomLevel": [value: GanttZoomLevel];
41
+ /** Fires when expanded group IDs change */
42
+ "update:expanded": [value: (string | number)[]];
43
+ /** Fires when a task is clicked */
44
+ "taskClick": [task: GanttTask];
45
+ /** Fires when a task is moved via drag */
46
+ "taskDrop": [payload: GanttTaskDropPayload];
47
+ /** Fires when a task is resized */
48
+ "taskResize": [payload: GanttTaskResizePayload];
49
+ }
50
+ export interface GanttChartSlots {
51
+ /** Compound mode: full rendering control */
52
+ default?: (props: GanttChartContext) => any;
53
+ /** Custom header rendering */
54
+ header?: (props: {
55
+ title: string;
56
+ zoomLevel: GanttZoomLevel;
57
+ setZoomLevel: (l: GanttZoomLevel) => void;
58
+ }) => any;
59
+ /** Custom header title */
60
+ "header-title"?: (props: {
61
+ title: string;
62
+ }) => any;
63
+ /** Custom navigation buttons */
64
+ "header-nav"?: (props: {
65
+ prev: () => void;
66
+ next: () => void;
67
+ today: () => void;
68
+ }) => any;
69
+ /** Custom zoom level switcher */
70
+ "zoom-switcher"?: (props: {
71
+ zoomLevel: GanttZoomLevel;
72
+ setZoomLevel: (l: GanttZoomLevel) => void;
73
+ zoomLevels: GanttZoomLevel[];
74
+ }) => any;
75
+ /** Custom task bar rendering */
76
+ "task-bar"?: (props: {
77
+ task: GanttTask;
78
+ bar: GanttTaskBar;
79
+ }) => any;
80
+ /** Custom milestone rendering */
81
+ milestone?: (props: {
82
+ task: GanttTask;
83
+ bar: GanttTaskBar;
84
+ }) => any;
85
+ /** Custom group header rendering */
86
+ "group-header"?: (props: {
87
+ task: GanttTask;
88
+ bar: GanttTaskBar;
89
+ expanded: boolean;
90
+ toggle: () => void;
91
+ }) => any;
92
+ /** Custom today marker */
93
+ "today-marker"?: () => any;
94
+ /** Custom dependency arrow rendering */
95
+ dependency?: (props: {
96
+ paths: import("../types/gantt-chart.js").GanttDependencyPath[];
97
+ }) => any;
98
+ /** Custom loading state */
99
+ loading?: () => any;
100
+ /** Custom empty state */
101
+ empty?: () => any;
102
+ }
103
+ declare const _default: typeof __VLS_export;
104
+ export default _default;
105
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<GanttChartProps, {
106
+ expandAll: () => void;
107
+ collapseAll: () => void;
108
+ toggleExpand: (id: string | number) => void;
109
+ scrollToDate: (date: import("@internationalized/date").CalendarDate) => void;
110
+ scrollToTask: (taskId: string | number) => void;
111
+ layout: import("vue").ComputedRef<import("../types/gantt-chart.js").GanttLayout>;
112
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
113
+ "update:modelValue": (value: import("@internationalized/date").CalendarDate) => any;
114
+ "update:zoomLevel": (value: GanttZoomLevel) => any;
115
+ "update:expanded": (value: (string | number)[]) => any;
116
+ taskClick: (task: GanttTask) => any;
117
+ taskDrop: (payload: GanttTaskDropPayload) => any;
118
+ taskResize: (payload: GanttTaskResizePayload) => any;
119
+ }, string, import("vue").PublicProps, Readonly<GanttChartProps> & Readonly<{
120
+ "onUpdate:modelValue"?: ((value: import("@internationalized/date").CalendarDate) => any) | undefined;
121
+ "onUpdate:zoomLevel"?: ((value: GanttZoomLevel) => any) | undefined;
122
+ "onUpdate:expanded"?: ((value: (string | number)[]) => any) | undefined;
123
+ onTaskClick?: ((task: GanttTask) => any) | undefined;
124
+ onTaskDrop?: ((payload: GanttTaskDropPayload) => any) | undefined;
125
+ onTaskResize?: ((payload: GanttTaskResizePayload) => any) | undefined;
126
+ }>, {
127
+ editable: boolean;
128
+ loading: boolean;
129
+ locale: string;
130
+ zoomLevel: GanttZoomLevel;
131
+ zoomLevels: GanttZoomLevel[];
132
+ rowHeight: number;
133
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, GanttChartSlots>;
134
+ type __VLS_WithSlots<T, S> = T & {
135
+ new (): {
136
+ $slots: S;
137
+ };
138
+ };
@@ -0,0 +1,206 @@
1
+ <script>
2
+ import { Primitive } from "reka-ui";
3
+ import { computed, provide, useSlots } from "vue";
4
+ import { tv } from "../utils/tv";
5
+ import { useGanttChart } from "../composables/useGanttChart";
6
+ import { useGanttChartDragDrop } from "../composables/useGanttChartDragDrop";
7
+ import { useGanttChartResize } from "../composables/useGanttChartResize";
8
+ import { useGanttChartKeyboard } from "../composables/useGanttChartKeyboard";
9
+ import { ganttChartContextKey } from "../composables/useGanttChartContext";
10
+ import { DEFAULT_ROW_HEIGHT } from "../utils/gantt-chart";
11
+ import GanttChartHeader from "./gantt-chart/GanttChartHeader.vue";
12
+ import GanttChartTimeline from "./gantt-chart/GanttChartTimeline.vue";
13
+ import theme from "#build/ui-elements-pro/gantt-chart";
14
+ </script>
15
+
16
+ <script setup>
17
+ const props = defineProps({
18
+ as: { type: null, required: false },
19
+ tasks: { type: Array, required: false },
20
+ dependencies: { type: Array, required: false },
21
+ modelValue: { type: null, required: false },
22
+ zoomLevel: { type: String, required: false, default: "month" },
23
+ zoomLevels: { type: Array, required: false, default: () => ["day", "week", "month", "quarter", "year"] },
24
+ locale: { type: String, required: false, default: "en-US" },
25
+ editable: { type: Boolean, required: false, default: true },
26
+ loading: { type: Boolean, required: false, default: false },
27
+ color: { type: null, required: false },
28
+ rowHeight: { type: Number, required: false, default: DEFAULT_ROW_HEIGHT },
29
+ expanded: { type: Array, required: false },
30
+ ui: { type: Object, required: false }
31
+ });
32
+ const emit = defineEmits(["update:modelValue", "update:zoomLevel", "update:expanded", "taskClick", "taskDrop", "taskResize"]);
33
+ defineSlots();
34
+ const slots = useSlots();
35
+ const ui = computed(
36
+ () => tv({
37
+ extend: tv(theme)
38
+ })({
39
+ color: props.color ?? "primary"
40
+ })
41
+ );
42
+ const ganttChart = useGanttChart({
43
+ tasks: () => props.tasks ?? [],
44
+ dependencies: () => props.dependencies ?? [],
45
+ modelValue: () => props.modelValue,
46
+ zoomLevel: () => props.zoomLevel,
47
+ zoomLevels: () => props.zoomLevels,
48
+ locale: () => props.locale,
49
+ rowHeight: () => props.rowHeight,
50
+ expanded: () => props.expanded,
51
+ onUpdateModelValue: (date) => emit("update:modelValue", date),
52
+ onUpdateZoomLevel: (level) => emit("update:zoomLevel", level),
53
+ onUpdateExpanded: (ids) => emit("update:expanded", ids)
54
+ });
55
+ const dragDrop = useGanttChartDragDrop({
56
+ editable: () => props.editable,
57
+ layout: ganttChart.layout,
58
+ zoomLevel: ganttChart.zoomLevel,
59
+ unitWidth: ganttChart.unitWidth,
60
+ dateToPixel: ganttChart.dateToPixel,
61
+ pixelToDate: ganttChart.pixelToDate,
62
+ onTaskDrop: (payload) => emit("taskDrop", payload)
63
+ });
64
+ const resize = useGanttChartResize({
65
+ editable: () => props.editable,
66
+ zoomLevel: ganttChart.zoomLevel,
67
+ unitWidth: ganttChart.unitWidth,
68
+ dateToPixel: ganttChart.dateToPixel,
69
+ pixelToDate: ganttChart.pixelToDate,
70
+ onTaskResize: (payload) => emit("taskResize", payload)
71
+ });
72
+ const flatVisibleTaskBars = computed(() => ganttChart.layout.value.taskBars);
73
+ const keyboard = useGanttChartKeyboard({
74
+ flatVisibleTasks: flatVisibleTaskBars,
75
+ expandedIds: ganttChart.expandedIds,
76
+ toggleExpand: ganttChart.toggleExpand,
77
+ scrollToTask: ganttChart.scrollToTask
78
+ });
79
+ function handleTaskClick(task, _e) {
80
+ emit("taskClick", task.original);
81
+ }
82
+ const ctx = {
83
+ zoomLevel: ganttChart.zoomLevel,
84
+ locale: computed(() => props.locale),
85
+ editable: computed(() => props.editable),
86
+ loading: computed(() => props.loading),
87
+ color: computed(() => props.color ?? "primary"),
88
+ layout: ganttChart.layout,
89
+ rowHeight: ganttChart.rowHeight,
90
+ timelineStart: ganttChart.timelineStart,
91
+ timelineEnd: ganttChart.timelineEnd,
92
+ headerTitle: ganttChart.headerTitle,
93
+ goToPrev: ganttChart.goToPrev,
94
+ goToNext: ganttChart.goToNext,
95
+ goToToday: ganttChart.goToToday,
96
+ setZoomLevel: ganttChart.setZoomLevel,
97
+ scrollToDate: ganttChart.scrollToDate,
98
+ scrollToTask: ganttChart.scrollToTask,
99
+ zoomLevels: ganttChart.zoomLevels,
100
+ expandedIds: ganttChart.expandedIds,
101
+ toggleExpand: ganttChart.toggleExpand,
102
+ expandAll: ganttChart.expandAll,
103
+ collapseAll: ganttChart.collapseAll,
104
+ isExpanded: ganttChart.isExpanded,
105
+ handleTaskClick,
106
+ getTaskStyle: ganttChart.getTaskStyle,
107
+ draggedTaskId: dragDrop.draggedTaskId,
108
+ dragPreview: dragDrop.dragPreview,
109
+ onDragStart: dragDrop.onDragStart,
110
+ resizingTaskId: resize.resizingTaskId,
111
+ resizeEdge: resize.resizeEdge,
112
+ resizePreview: resize.resizePreview,
113
+ onResizePointerDown: resize.onResizePointerDown,
114
+ focusedTaskId: keyboard.focusedTaskId,
115
+ onKeydown: keyboard.onKeydown,
116
+ dateToPixel: ganttChart.dateToPixel,
117
+ pixelToDate: ganttChart.pixelToDate,
118
+ ui,
119
+ propUi: computed(() => props.ui)
120
+ };
121
+ provide(ganttChartContextKey, ctx);
122
+ defineExpose({
123
+ expandAll: ganttChart.expandAll,
124
+ collapseAll: ganttChart.collapseAll,
125
+ toggleExpand: ganttChart.toggleExpand,
126
+ scrollToDate: ganttChart.scrollToDate,
127
+ scrollToTask: ganttChart.scrollToTask,
128
+ layout: ganttChart.layout
129
+ });
130
+ </script>
131
+
132
+ <template>
133
+ <Primitive
134
+ :as="props.as ?? 'div'"
135
+ data-slot="root"
136
+ :class="ui.root({ class: props.ui?.root })"
137
+ role="treegrid"
138
+ aria-label="Gantt chart"
139
+ tabindex="0"
140
+ @keydown="ctx.onKeydown"
141
+ >
142
+ <!-- Compound mode: user provides #default and owns rendering -->
143
+ <slot v-if="slots.default" v-bind="ctx" />
144
+
145
+ <!-- Auto mode: render everything with slot forwarding -->
146
+ <template v-else>
147
+ <slot name="header" :title="ctx.headerTitle.value" :zoom-level="ctx.zoomLevel.value" :set-zoom-level="ctx.setZoomLevel">
148
+ <GanttChartHeader>
149
+ <template v-if="slots['header-title']" #title="titleProps">
150
+ <slot name="header-title" v-bind="titleProps" />
151
+ </template>
152
+ <template v-if="slots['zoom-switcher']" #zoom-switcher="zoomProps">
153
+ <slot name="zoom-switcher" v-bind="zoomProps" />
154
+ </template>
155
+ <template v-if="slots['header-nav']" #nav="navProps">
156
+ <slot name="header-nav" v-bind="navProps" />
157
+ </template>
158
+ </GanttChartHeader>
159
+ </slot>
160
+
161
+ <div
162
+ v-if="ganttChart.layout.value.taskBars.length > 0"
163
+ :ref="(el) => {
164
+ ganttChart.bodyEl.value = el;
165
+ }"
166
+ data-slot="body"
167
+ :class="ui.body({ class: props.ui?.body })"
168
+ >
169
+ <GanttChartTimeline>
170
+ <template v-if="slots['task-bar']" #task-bar="barProps">
171
+ <slot name="task-bar" v-bind="barProps" />
172
+ </template>
173
+ <template v-if="slots.milestone" #milestone="msProps">
174
+ <slot name="milestone" v-bind="msProps" />
175
+ </template>
176
+ <template v-if="slots['group-header']" #group-header="ghProps">
177
+ <slot name="group-header" v-bind="ghProps" />
178
+ </template>
179
+ <template v-if="slots['today-marker']" #today-marker>
180
+ <slot name="today-marker" />
181
+ </template>
182
+ <template v-if="slots.dependency" #dependency="depProps">
183
+ <slot name="dependency" v-bind="depProps" />
184
+ </template>
185
+ </GanttChartTimeline>
186
+ </div>
187
+
188
+ <slot v-else name="empty">
189
+ <div data-slot="emptyState" :class="ui.emptyState({ class: props.ui?.emptyState })">
190
+ <p :class="ui.emptyStateText({ class: props.ui?.emptyStateText })">No tasks to display</p>
191
+ </div>
192
+ </slot>
193
+
194
+ <!-- Loading overlay -->
195
+ <div
196
+ v-if="props.loading"
197
+ data-slot="loadingOverlay"
198
+ :class="ui.loadingOverlay({ class: props.ui?.loadingOverlay })"
199
+ >
200
+ <slot name="loading">
201
+ <UIcon name="i-lucide-loader-2" class="size-8 text-muted animate-spin" />
202
+ </slot>
203
+ </div>
204
+ </template>
205
+ </Primitive>
206
+ </template>
@@ -0,0 +1,138 @@
1
+ import type { AppConfig } from "@nuxt/schema";
2
+ import type { ComponentConfig } from "nuxt-ui-elements";
3
+ import type { DateValue } from "@internationalized/date";
4
+ import type { GanttTask, GanttDependency, GanttZoomLevel, GanttTaskBar, GanttTaskDropPayload, GanttTaskResizePayload, GanttChartContext } from "../types/gantt-chart.js";
5
+ import { type Component } from "vue";
6
+ import theme from "#build/ui-elements-pro/gantt-chart";
7
+ type GanttChartTheme = ComponentConfig<typeof theme, AppConfig, "ganttChart">;
8
+ export interface GanttChartProps {
9
+ /** Rendered element type @defaultValue 'div' */
10
+ as?: string | Component;
11
+ /** Array of tasks to display */
12
+ tasks?: GanttTask[];
13
+ /** Array of task dependencies */
14
+ dependencies?: GanttDependency[];
15
+ /** Displayed date (v-model) */
16
+ modelValue?: Date | string | DateValue;
17
+ /** Current zoom level (v-model:zoomLevel) @defaultValue 'month' */
18
+ zoomLevel?: GanttZoomLevel;
19
+ /** Available zoom levels @defaultValue all levels */
20
+ zoomLevels?: GanttZoomLevel[];
21
+ /** Locale for formatting @defaultValue 'en-US' */
22
+ locale?: string;
23
+ /** Enable drag/drop and resize @defaultValue true */
24
+ editable?: boolean;
25
+ /** Show loading state @defaultValue false */
26
+ loading?: boolean;
27
+ /** Theme color @defaultValue 'primary' */
28
+ color?: GanttChartTheme["variants"]["color"];
29
+ /** Row height in pixels @defaultValue 40 */
30
+ rowHeight?: number;
31
+ /** Two-way binding for expanded group IDs */
32
+ expanded?: (string | number)[];
33
+ /** Slot class overrides */
34
+ ui?: GanttChartTheme["slots"];
35
+ }
36
+ export interface GanttChartEmits {
37
+ /** Fires when displayed date changes */
38
+ "update:modelValue": [value: import("@internationalized/date").CalendarDate];
39
+ /** Fires when zoom level changes */
40
+ "update:zoomLevel": [value: GanttZoomLevel];
41
+ /** Fires when expanded group IDs change */
42
+ "update:expanded": [value: (string | number)[]];
43
+ /** Fires when a task is clicked */
44
+ "taskClick": [task: GanttTask];
45
+ /** Fires when a task is moved via drag */
46
+ "taskDrop": [payload: GanttTaskDropPayload];
47
+ /** Fires when a task is resized */
48
+ "taskResize": [payload: GanttTaskResizePayload];
49
+ }
50
+ export interface GanttChartSlots {
51
+ /** Compound mode: full rendering control */
52
+ default?: (props: GanttChartContext) => any;
53
+ /** Custom header rendering */
54
+ header?: (props: {
55
+ title: string;
56
+ zoomLevel: GanttZoomLevel;
57
+ setZoomLevel: (l: GanttZoomLevel) => void;
58
+ }) => any;
59
+ /** Custom header title */
60
+ "header-title"?: (props: {
61
+ title: string;
62
+ }) => any;
63
+ /** Custom navigation buttons */
64
+ "header-nav"?: (props: {
65
+ prev: () => void;
66
+ next: () => void;
67
+ today: () => void;
68
+ }) => any;
69
+ /** Custom zoom level switcher */
70
+ "zoom-switcher"?: (props: {
71
+ zoomLevel: GanttZoomLevel;
72
+ setZoomLevel: (l: GanttZoomLevel) => void;
73
+ zoomLevels: GanttZoomLevel[];
74
+ }) => any;
75
+ /** Custom task bar rendering */
76
+ "task-bar"?: (props: {
77
+ task: GanttTask;
78
+ bar: GanttTaskBar;
79
+ }) => any;
80
+ /** Custom milestone rendering */
81
+ milestone?: (props: {
82
+ task: GanttTask;
83
+ bar: GanttTaskBar;
84
+ }) => any;
85
+ /** Custom group header rendering */
86
+ "group-header"?: (props: {
87
+ task: GanttTask;
88
+ bar: GanttTaskBar;
89
+ expanded: boolean;
90
+ toggle: () => void;
91
+ }) => any;
92
+ /** Custom today marker */
93
+ "today-marker"?: () => any;
94
+ /** Custom dependency arrow rendering */
95
+ dependency?: (props: {
96
+ paths: import("../types/gantt-chart.js").GanttDependencyPath[];
97
+ }) => any;
98
+ /** Custom loading state */
99
+ loading?: () => any;
100
+ /** Custom empty state */
101
+ empty?: () => any;
102
+ }
103
+ declare const _default: typeof __VLS_export;
104
+ export default _default;
105
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<GanttChartProps, {
106
+ expandAll: () => void;
107
+ collapseAll: () => void;
108
+ toggleExpand: (id: string | number) => void;
109
+ scrollToDate: (date: import("@internationalized/date").CalendarDate) => void;
110
+ scrollToTask: (taskId: string | number) => void;
111
+ layout: import("vue").ComputedRef<import("../types/gantt-chart.js").GanttLayout>;
112
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
113
+ "update:modelValue": (value: import("@internationalized/date").CalendarDate) => any;
114
+ "update:zoomLevel": (value: GanttZoomLevel) => any;
115
+ "update:expanded": (value: (string | number)[]) => any;
116
+ taskClick: (task: GanttTask) => any;
117
+ taskDrop: (payload: GanttTaskDropPayload) => any;
118
+ taskResize: (payload: GanttTaskResizePayload) => any;
119
+ }, string, import("vue").PublicProps, Readonly<GanttChartProps> & Readonly<{
120
+ "onUpdate:modelValue"?: ((value: import("@internationalized/date").CalendarDate) => any) | undefined;
121
+ "onUpdate:zoomLevel"?: ((value: GanttZoomLevel) => any) | undefined;
122
+ "onUpdate:expanded"?: ((value: (string | number)[]) => any) | undefined;
123
+ onTaskClick?: ((task: GanttTask) => any) | undefined;
124
+ onTaskDrop?: ((payload: GanttTaskDropPayload) => any) | undefined;
125
+ onTaskResize?: ((payload: GanttTaskResizePayload) => any) | undefined;
126
+ }>, {
127
+ editable: boolean;
128
+ loading: boolean;
129
+ locale: string;
130
+ zoomLevel: GanttZoomLevel;
131
+ zoomLevels: GanttZoomLevel[];
132
+ rowHeight: number;
133
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, GanttChartSlots>;
134
+ type __VLS_WithSlots<T, S> = T & {
135
+ new (): {
136
+ $slots: S;
137
+ };
138
+ };
@@ -12,6 +12,9 @@ export interface EventCalendarMonthViewSlots {
12
12
  "month-day-header": (props: {
13
13
  day: CalendarDay;
14
14
  }) => any;
15
+ "month-day-cell": (props: {
16
+ day: CalendarDay;
17
+ }) => any;
15
18
  event: (props: {
16
19
  event: CalendarEvent;
17
20
  view: CalendarView;
@@ -78,6 +78,7 @@ onKeyStroke("Escape", () => {
78
78
  :aria-current="day.isToday ? 'date' : void 0"
79
79
  :data-date="day.date.toString()"
80
80
  :class="[
81
+ 'group/cell',
81
82
  ctx.ui.value.dayCell({ class: ctx.propUi.value?.dayCell }),
82
83
  !day.isCurrentMonth && ctx.ui.value.dayCellOutside({ class: ctx.propUi.value?.dayCellOutside }),
83
84
  ctx.dropTargetKey.value === `month-${day.date.toString()}` && ctx.ui.value.dropTarget({ class: ctx.propUi.value?.dropTarget }),
@@ -96,6 +97,12 @@ onKeyStroke("Escape", () => {
96
97
  @dragover="ctx.onDragOver(`month-${day.date.toString()}`, $event)"
97
98
  @dragleave="ctx.onDragLeave"
98
99
  @drop="ctx.onDropMonthCell(day.date, $event)">
100
+ <div
101
+ v-if="$slots['month-day-cell']"
102
+ data-slot="monthDayCell"
103
+ :class="ctx.ui.value.monthDayCell({ class: ctx.propUi.value?.monthDayCell })">
104
+ <slot name="month-day-cell" :day="day" />
105
+ </div>
99
106
  </div>
100
107
 
101
108
  <!-- Layer 2: Day numbers (row 1) -->
@@ -108,16 +115,18 @@ onKeyStroke("Escape", () => {
108
115
  gridColumn: `${colIdx + 1}`,
109
116
  gridRow: '1'
110
117
  }">
111
- <slot name="month-day-header" :day="day">
112
- <div
113
- :class="[
118
+ <div class="pointer-events-auto w-fit">
119
+ <slot name="month-day-header" :day="day">
120
+ <div
121
+ :class="[
114
122
  !day.isToday && ctx.ui.value.dayNumber({ class: ctx.propUi.value?.dayNumber }),
115
123
  day.isToday && ctx.ui.value.dayNumberToday({ class: ctx.propUi.value?.dayNumberToday }),
116
124
  !day.isCurrentMonth && !day.isToday && ctx.ui.value.dayNumberOutside({ class: ctx.propUi.value?.dayNumberOutside })
117
125
  ]">
118
- {{ day.date.day }}
119
- </div>
120
- </slot>
126
+ {{ day.date.day }}
127
+ </div>
128
+ </slot>
129
+ </div>
121
130
  </div>
122
131
 
123
132
  <!-- Layer 3: Spanning event bars -->
@@ -12,6 +12,9 @@ export interface EventCalendarMonthViewSlots {
12
12
  "month-day-header": (props: {
13
13
  day: CalendarDay;
14
14
  }) => any;
15
+ "month-day-cell": (props: {
16
+ day: CalendarDay;
17
+ }) => any;
15
18
  event: (props: {
16
19
  event: CalendarEvent;
17
20
  view: CalendarView;