nuxt-ui-elements-pro 0.1.5 → 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.
Files changed (67) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +153 -18
  3. package/dist/runtime/components/EventCalendar.d.vue.ts +109 -22
  4. package/dist/runtime/components/EventCalendar.vue +225 -602
  5. package/dist/runtime/components/EventCalendar.vue.d.ts +109 -22
  6. package/dist/runtime/components/OrgChart.d.vue.ts +191 -0
  7. package/dist/runtime/components/OrgChart.vue +290 -0
  8. package/dist/runtime/components/OrgChart.vue.d.ts +191 -0
  9. package/dist/runtime/components/event-calendar/EventCalendarHeader.d.vue.ts +45 -0
  10. package/dist/runtime/components/event-calendar/EventCalendarHeader.vue +55 -0
  11. package/dist/runtime/components/event-calendar/EventCalendarHeader.vue.d.ts +45 -0
  12. package/dist/runtime/components/event-calendar/EventCalendarListView.d.vue.ts +25 -0
  13. package/dist/runtime/components/event-calendar/EventCalendarListView.vue +95 -0
  14. package/dist/runtime/components/event-calendar/EventCalendarListView.vue.d.ts +25 -0
  15. package/dist/runtime/components/event-calendar/EventCalendarMonthView.d.vue.ts +34 -0
  16. package/dist/runtime/components/event-calendar/EventCalendarMonthView.vue +336 -0
  17. package/dist/runtime/components/event-calendar/EventCalendarMonthView.vue.d.ts +34 -0
  18. package/dist/runtime/components/event-calendar/EventCalendarTimeGrid.d.vue.ts +31 -0
  19. package/dist/runtime/components/event-calendar/EventCalendarTimeGrid.vue +306 -0
  20. package/dist/runtime/components/event-calendar/EventCalendarTimeGrid.vue.d.ts +31 -0
  21. package/dist/runtime/components/org-chart/OrgChartConnectors.d.vue.ts +15 -0
  22. package/dist/runtime/components/org-chart/OrgChartConnectors.vue +29 -0
  23. package/dist/runtime/components/org-chart/OrgChartConnectors.vue.d.ts +15 -0
  24. package/dist/runtime/components/org-chart/OrgChartControls.d.vue.ts +19 -0
  25. package/dist/runtime/components/org-chart/OrgChartControls.vue +25 -0
  26. package/dist/runtime/components/org-chart/OrgChartControls.vue.d.ts +19 -0
  27. package/dist/runtime/components/org-chart/OrgChartNode.d.vue.ts +30 -0
  28. package/dist/runtime/components/org-chart/OrgChartNode.vue +129 -0
  29. package/dist/runtime/components/org-chart/OrgChartNode.vue.d.ts +30 -0
  30. package/dist/runtime/composables/useEventCalendar.d.ts +52 -0
  31. package/dist/runtime/composables/useEventCalendar.js +362 -0
  32. package/dist/runtime/composables/useEventCalendarContext.d.ts +8 -0
  33. package/dist/runtime/composables/useEventCalendarContext.js +11 -0
  34. package/dist/runtime/composables/useEventCalendarDragDrop.d.ts +1 -1
  35. package/dist/runtime/composables/useEventCalendarDragDrop.js +11 -9
  36. package/dist/runtime/composables/useEventCalendarKeyboard.d.ts +20 -0
  37. package/dist/runtime/composables/useEventCalendarKeyboard.js +128 -0
  38. package/dist/runtime/composables/useEventCalendarResize.d.ts +31 -0
  39. package/dist/runtime/composables/useEventCalendarResize.js +87 -0
  40. package/dist/runtime/composables/useEventCalendarSelect.d.ts +21 -0
  41. package/dist/runtime/composables/useEventCalendarSelect.js +119 -0
  42. package/dist/runtime/composables/useOrgChart.d.ts +42 -0
  43. package/dist/runtime/composables/useOrgChart.js +154 -0
  44. package/dist/runtime/composables/useOrgChartContext.d.ts +8 -0
  45. package/dist/runtime/composables/useOrgChartContext.js +11 -0
  46. package/dist/runtime/composables/useOrgChartDragDrop.d.ts +20 -0
  47. package/dist/runtime/composables/useOrgChartDragDrop.js +67 -0
  48. package/dist/runtime/composables/useOrgChartKeyboard.d.ts +16 -0
  49. package/dist/runtime/composables/useOrgChartKeyboard.js +101 -0
  50. package/dist/runtime/composables/useOrgChartSearch.d.ts +16 -0
  51. package/dist/runtime/composables/useOrgChartSearch.js +62 -0
  52. package/dist/runtime/composables/useOrgChartZoom.d.ts +26 -0
  53. package/dist/runtime/composables/useOrgChartZoom.js +101 -0
  54. package/dist/runtime/index.d.ts +3 -0
  55. package/dist/runtime/index.js +2 -0
  56. package/dist/runtime/types/event-calendar.d.ts +170 -0
  57. package/dist/runtime/types/index.d.ts +2 -0
  58. package/dist/runtime/types/index.js +2 -0
  59. package/dist/runtime/types/org-chart.d.ts +181 -0
  60. package/dist/runtime/types/org-chart.js +0 -0
  61. package/dist/runtime/utils/event-calendar.d.ts +22 -1
  62. package/dist/runtime/utils/event-calendar.js +199 -1
  63. package/dist/runtime/utils/org-chart.d.ts +55 -0
  64. package/dist/runtime/utils/org-chart.js +367 -0
  65. package/dist/runtime/utils/recurrence.d.ts +30 -0
  66. package/dist/runtime/utils/recurrence.js +150 -0
  67. package/package.json +15 -6
@@ -0,0 +1,87 @@
1
+ import { toCalendarDate, toCalendarDateTime } from "@internationalized/date";
2
+ import { onUnmounted, ref } from "vue";
3
+ export function useEventCalendarResize(options) {
4
+ const { editable, normalizedEvents, gridConfig, slotHeight, onEventResize, onResizeStart, onResizeEnd } = options;
5
+ const resizingEventId = ref(null);
6
+ const resizePreviewHeightPx = ref(null);
7
+ let activeEvent = null;
8
+ let originalHeightPx = 0;
9
+ function onPointerMove(e) {
10
+ if (!activeEvent) return;
11
+ const config = gridConfig();
12
+ const deltaY = e.clientY - pointerStartY;
13
+ const rawHeight = originalHeightPx + deltaY;
14
+ const snappedHeight = Math.round(rawHeight / slotHeight) * slotHeight;
15
+ const minHeightPx = 15 / config.slotDuration * slotHeight;
16
+ const maxDurationMinutes = config.endHour * 60 - activeEvent.startMinutes;
17
+ const maxHeightPx = maxDurationMinutes / config.slotDuration * slotHeight;
18
+ resizePreviewHeightPx.value = Math.max(minHeightPx, Math.min(snappedHeight, maxHeightPx));
19
+ }
20
+ function onPointerUp(_e) {
21
+ document.removeEventListener("pointermove", onPointerMove);
22
+ document.removeEventListener("pointerup", onPointerUp);
23
+ if (activeEvent) {
24
+ const event2 = normalizedEvents.value.find((ev) => ev.id === activeEvent.id);
25
+ if (event2) {
26
+ onResizeEnd({ event: event2.original });
27
+ }
28
+ }
29
+ if (!activeEvent || resizePreviewHeightPx.value == null) {
30
+ cleanup();
31
+ return;
32
+ }
33
+ if (resizePreviewHeightPx.value === originalHeightPx) {
34
+ cleanup();
35
+ return;
36
+ }
37
+ const config = gridConfig();
38
+ const newDurationMinutes = resizePreviewHeightPx.value / slotHeight * config.slotDuration;
39
+ const newEndMinutes = activeEvent.startMinutes + newDurationMinutes;
40
+ const newEndHour = Math.floor(newEndMinutes / 60);
41
+ const newEndMinute = Math.round(newEndMinutes % 60);
42
+ const startDate = toCalendarDate(activeEvent.start);
43
+ const newEnd = toCalendarDateTime(startDate).set({ hour: newEndHour, minute: newEndMinute });
44
+ const event = normalizedEvents.value.find((ev) => ev.id === activeEvent.id);
45
+ if (event) {
46
+ onEventResize({
47
+ event: event.original,
48
+ oldStart: event.start,
49
+ oldEnd: event.end,
50
+ newStart: event.start,
51
+ newEnd
52
+ });
53
+ }
54
+ cleanup();
55
+ }
56
+ let pointerStartY = 0;
57
+ function onResizePointerDown(event, e) {
58
+ if (!editable() || !event.resizable) return;
59
+ e.preventDefault();
60
+ e.stopPropagation();
61
+ resizingEventId.value = event.id;
62
+ activeEvent = event;
63
+ originalHeightPx = event.heightPx;
64
+ resizePreviewHeightPx.value = event.heightPx;
65
+ pointerStartY = e.clientY;
66
+ const normalized = normalizedEvents.value.find((ev) => ev.id === event.id);
67
+ if (normalized) {
68
+ onResizeStart({ event: normalized.original });
69
+ }
70
+ document.addEventListener("pointermove", onPointerMove);
71
+ document.addEventListener("pointerup", onPointerUp);
72
+ }
73
+ function cleanup() {
74
+ resizingEventId.value = null;
75
+ resizePreviewHeightPx.value = null;
76
+ activeEvent = null;
77
+ }
78
+ onUnmounted(() => {
79
+ document.removeEventListener("pointermove", onPointerMove);
80
+ document.removeEventListener("pointerup", onPointerUp);
81
+ });
82
+ return {
83
+ resizingEventId,
84
+ resizePreviewHeightPx,
85
+ onResizePointerDown
86
+ };
87
+ }
@@ -0,0 +1,21 @@
1
+ import type { CalendarDate } from "@internationalized/date";
2
+ import type { CalendarView, SelectPayload } from "../types/event-calendar.js";
3
+ export interface UseEventCalendarSelectOptions {
4
+ selectable: () => boolean;
5
+ view: () => CalendarView;
6
+ slotDuration: () => number;
7
+ startHour: () => number;
8
+ endHour: () => number;
9
+ onSelect: (payload: SelectPayload) => void;
10
+ }
11
+ export declare function useEventCalendarSelect(options: UseEventCalendarSelectOptions): {
12
+ isSelecting: import("vue").Ref<boolean, boolean>;
13
+ preventNextClick: import("vue").Ref<boolean, boolean>;
14
+ isSlotInSelection: (date: CalendarDate, hour: number, minute: number) => boolean;
15
+ isDateInSelection: (date: CalendarDate) => boolean;
16
+ onSlotPointerDown: (date: CalendarDate, hour: number, minute: number, e: PointerEvent) => void;
17
+ onSlotPointerMove: (date: CalendarDate, hour: number, minute: number) => void;
18
+ onDayCellPointerDown: (date: CalendarDate, e: PointerEvent) => void;
19
+ onDayCellPointerMove: (date: CalendarDate) => void;
20
+ onSelectionPointerUp: () => void;
21
+ };
@@ -0,0 +1,119 @@
1
+ import { toCalendarDateTime } from "@internationalized/date";
2
+ import { ref, shallowRef } from "vue";
3
+ export function useEventCalendarSelect(options) {
4
+ const { selectable, slotDuration, onSelect } = options;
5
+ const isSelecting = ref(false);
6
+ const selectionAnchor = shallowRef(null);
7
+ const selectionEnd = shallowRef(null);
8
+ const preventNextClick = ref(false);
9
+ const didMove = ref(false);
10
+ function isEventTarget(e) {
11
+ const el = e.target;
12
+ if (!el) return false;
13
+ return !!el.closest("[data-slot='timeEvent'], [data-slot='eventChip']");
14
+ }
15
+ function toMinutes(point) {
16
+ return (point.hour ?? 0) * 60 + (point.minute ?? 0);
17
+ }
18
+ function clearState() {
19
+ isSelecting.value = false;
20
+ selectionAnchor.value = null;
21
+ selectionEnd.value = null;
22
+ didMove.value = false;
23
+ }
24
+ function onSlotPointerDown(date, hour, minute, e) {
25
+ if (!selectable() || e.button !== 0 || isEventTarget(e)) return;
26
+ selectionAnchor.value = { date, hour, minute };
27
+ selectionEnd.value = { date, hour, minute };
28
+ isSelecting.value = true;
29
+ didMove.value = false;
30
+ }
31
+ function onSlotPointerMove(date, hour, minute) {
32
+ if (!isSelecting.value || !selectionAnchor.value) return;
33
+ if (date.toString() !== selectionAnchor.value.date.toString()) return;
34
+ selectionEnd.value = { date, hour, minute };
35
+ didMove.value = true;
36
+ }
37
+ function onDayCellPointerDown(date, e) {
38
+ if (!selectable() || e.button !== 0 || isEventTarget(e)) return;
39
+ selectionAnchor.value = { date };
40
+ selectionEnd.value = { date };
41
+ isSelecting.value = true;
42
+ didMove.value = false;
43
+ }
44
+ function onDayCellPointerMove(date) {
45
+ if (!isSelecting.value || !selectionAnchor.value) return;
46
+ selectionEnd.value = { date };
47
+ didMove.value = true;
48
+ }
49
+ function onSelectionPointerUp() {
50
+ if (!isSelecting.value || !selectionAnchor.value || !selectionEnd.value) {
51
+ clearState();
52
+ return;
53
+ }
54
+ const anchor = selectionAnchor.value;
55
+ const end = selectionEnd.value;
56
+ const isTimeGrid = anchor.hour !== void 0;
57
+ if (isTimeGrid) {
58
+ const anchorMinutes = toMinutes(anchor);
59
+ const endMinutes = toMinutes(end);
60
+ const duration = slotDuration();
61
+ let startMinutes;
62
+ let finalEndMinutes;
63
+ if (anchorMinutes <= endMinutes) {
64
+ startMinutes = anchorMinutes;
65
+ finalEndMinutes = endMinutes + duration;
66
+ } else {
67
+ startMinutes = endMinutes;
68
+ finalEndMinutes = anchorMinutes + duration;
69
+ }
70
+ const startDt = toCalendarDateTime(anchor.date).set({
71
+ hour: Math.floor(startMinutes / 60),
72
+ minute: startMinutes % 60
73
+ });
74
+ const endDt = toCalendarDateTime(anchor.date).set({
75
+ hour: Math.floor(finalEndMinutes / 60),
76
+ minute: finalEndMinutes % 60
77
+ });
78
+ onSelect({ start: startDt, end: endDt, allDay: false });
79
+ } else {
80
+ const cmp = anchor.date.compare(end.date);
81
+ const startDate = cmp <= 0 ? anchor.date : end.date;
82
+ const endDate = cmp <= 0 ? end.date : anchor.date;
83
+ onSelect({ start: startDate, end: endDate, allDay: true });
84
+ }
85
+ if (didMove.value) {
86
+ preventNextClick.value = true;
87
+ }
88
+ clearState();
89
+ }
90
+ function isSlotInSelection(date, hour, minute) {
91
+ if (!isSelecting.value || !selectionAnchor.value || !selectionEnd.value) return false;
92
+ if (selectionAnchor.value.hour === void 0) return false;
93
+ if (date.toString() !== selectionAnchor.value.date.toString()) return false;
94
+ const anchorMin = toMinutes(selectionAnchor.value);
95
+ const endMin = toMinutes(selectionEnd.value);
96
+ const slotMin = hour * 60 + minute;
97
+ const lo = Math.min(anchorMin, endMin);
98
+ const hi = Math.max(anchorMin, endMin);
99
+ return slotMin >= lo && slotMin <= hi;
100
+ }
101
+ function isDateInSelection(date) {
102
+ if (!isSelecting.value || !selectionAnchor.value || !selectionEnd.value) return false;
103
+ if (selectionAnchor.value.hour !== void 0) return false;
104
+ const anchorCmp = date.compare(selectionAnchor.value.date);
105
+ const endCmp = date.compare(selectionEnd.value.date);
106
+ return anchorCmp >= 0 && endCmp <= 0 || anchorCmp <= 0 && endCmp >= 0;
107
+ }
108
+ return {
109
+ isSelecting,
110
+ preventNextClick,
111
+ isSlotInSelection,
112
+ isDateInSelection,
113
+ onSlotPointerDown,
114
+ onSlotPointerMove,
115
+ onDayCellPointerDown,
116
+ onDayCellPointerMove,
117
+ onSelectionPointerUp
118
+ };
119
+ }
@@ -0,0 +1,42 @@
1
+ import type { OrgChartNode, OrgChartTreeNode, OrgChartConnection, OrgChartDirection, OrgChartConnectorStyle, OrgChartSelectionMode, OrgChartLayout, ResolvedLayoutConfig } from "../types/org-chart.js";
2
+ export interface UseOrgChartOptions {
3
+ nodes: () => OrgChartNode[];
4
+ connections: () => OrgChartConnection[];
5
+ direction: () => OrgChartDirection;
6
+ connectorStyle: () => OrgChartConnectorStyle;
7
+ selectionMode: () => OrgChartSelectionMode;
8
+ layoutConfig: () => ResolvedLayoutConfig;
9
+ expanded: () => (string | number)[] | undefined;
10
+ selected: () => (string | number)[] | undefined;
11
+ onUpdateExpanded: (ids: (string | number)[]) => void;
12
+ onUpdateSelected: (ids: (string | number)[]) => void;
13
+ onNodeClick: (node: OrgChartNode) => void;
14
+ onNodeExpand: (payload: {
15
+ node: OrgChartNode;
16
+ expanded: boolean;
17
+ }) => void;
18
+ onNodeSelect: (payload: {
19
+ node: OrgChartNode;
20
+ selected: boolean;
21
+ }) => void;
22
+ }
23
+ export declare function useOrgChart(options: UseOrgChartOptions): {
24
+ tree: import("vue").ComputedRef<OrgChartTreeNode | null>;
25
+ nodeMap: import("vue").ComputedRef<Map<string | number, OrgChartTreeNode>>;
26
+ layout: import("vue").ComputedRef<OrgChartLayout>;
27
+ flatVisibleNodes: import("vue").ComputedRef<OrgChartTreeNode[]>;
28
+ expandedIds: import("vue").Ref<Set<string | number> & Omit<Set<string | number>, keyof Set<any>>, Set<string | number> | (Set<string | number> & Omit<Set<string | number>, keyof Set<any>>)>;
29
+ selectedIds: import("vue").Ref<Set<string | number> & Omit<Set<string | number>, keyof Set<any>>, Set<string | number> | (Set<string | number> & Omit<Set<string | number>, keyof Set<any>>)>;
30
+ toggleExpand: (id: string | number) => void;
31
+ expandAll: () => void;
32
+ collapseAll: () => void;
33
+ selectNode: (id: string | number) => void;
34
+ deselectNode: (id: string | number) => void;
35
+ isExpanded: (id: string | number) => boolean;
36
+ isSelected: (id: string | number) => boolean;
37
+ getDescendantCount: (id: string | number) => number;
38
+ getNode: (id: string | number) => OrgChartTreeNode | undefined;
39
+ getChildren: (id: string | number) => OrgChartTreeNode[];
40
+ getAncestors: (id: string | number) => OrgChartTreeNode[];
41
+ handleNodeClick: (treeNode: OrgChartTreeNode, _e: Event) => void;
42
+ };
@@ -0,0 +1,154 @@
1
+ import { computed, ref, watch } from "vue";
2
+ import {
3
+ buildTree,
4
+ buildNodeMap,
5
+ computeFullLayout,
6
+ flattenVisibleTree,
7
+ getAllNodeIds,
8
+ getAncestors as getAncestorsUtil
9
+ } from "../utils/org-chart.js";
10
+ export function useOrgChart(options) {
11
+ const tree = computed(() => buildTree(options.nodes()));
12
+ const nodeMap = computed(() => {
13
+ if (!tree.value) return /* @__PURE__ */ new Map();
14
+ return buildNodeMap(tree.value);
15
+ });
16
+ const expandedIds = ref(/* @__PURE__ */ new Set());
17
+ watch(tree, (t) => {
18
+ if (!t) return;
19
+ const externalExpanded = options.expanded();
20
+ if (externalExpanded !== void 0) {
21
+ expandedIds.value = new Set(externalExpanded);
22
+ } else {
23
+ expandedIds.value = getAllNodeIds(t);
24
+ }
25
+ }, { immediate: true });
26
+ watch(() => options.expanded(), (ext) => {
27
+ if (ext !== void 0) {
28
+ expandedIds.value = new Set(ext);
29
+ }
30
+ });
31
+ function emitExpanded() {
32
+ options.onUpdateExpanded([...expandedIds.value]);
33
+ }
34
+ function toggleExpand(id) {
35
+ const next = new Set(expandedIds.value);
36
+ const node = nodeMap.value.get(id);
37
+ if (!node || node.children.length === 0) return;
38
+ const wasExpanded = next.has(id);
39
+ if (wasExpanded) {
40
+ next.delete(id);
41
+ } else {
42
+ next.add(id);
43
+ }
44
+ expandedIds.value = next;
45
+ emitExpanded();
46
+ if (node) {
47
+ options.onNodeExpand({ node: node.data, expanded: !wasExpanded });
48
+ }
49
+ }
50
+ function expandAll() {
51
+ if (!tree.value) return;
52
+ expandedIds.value = getAllNodeIds(tree.value);
53
+ emitExpanded();
54
+ }
55
+ function collapseAll() {
56
+ if (!tree.value) return;
57
+ expandedIds.value = /* @__PURE__ */ new Set([tree.value.data.id]);
58
+ emitExpanded();
59
+ }
60
+ const selectedIds = ref(/* @__PURE__ */ new Set());
61
+ watch(() => options.selected(), (ext) => {
62
+ if (ext !== void 0) {
63
+ selectedIds.value = new Set(ext);
64
+ }
65
+ }, { immediate: true });
66
+ function emitSelected() {
67
+ options.onUpdateSelected([...selectedIds.value]);
68
+ }
69
+ function selectNode(id) {
70
+ const mode = options.selectionMode();
71
+ if (mode === "none") return;
72
+ const node = nodeMap.value.get(id);
73
+ if (!node) return;
74
+ const next = new Set(mode === "single" ? [] : [...selectedIds.value]);
75
+ const wasSelected = selectedIds.value.has(id);
76
+ if (wasSelected) {
77
+ next.delete(id);
78
+ } else {
79
+ next.add(id);
80
+ }
81
+ selectedIds.value = next;
82
+ emitSelected();
83
+ options.onNodeSelect({ node: node.data, selected: !wasSelected });
84
+ }
85
+ function deselectNode(id) {
86
+ const next = new Set(selectedIds.value);
87
+ next.delete(id);
88
+ selectedIds.value = next;
89
+ emitSelected();
90
+ }
91
+ const layout = computed(() => {
92
+ if (!tree.value) {
93
+ return { nodes: [], connectors: [], connectionPaths: [], width: 0, height: 0 };
94
+ }
95
+ return computeFullLayout(
96
+ tree.value,
97
+ options.layoutConfig(),
98
+ options.direction(),
99
+ options.connectorStyle(),
100
+ expandedIds.value,
101
+ options.connections()
102
+ );
103
+ });
104
+ const flatVisibleNodes = computed(() => {
105
+ if (!tree.value) return [];
106
+ return flattenVisibleTree(tree.value, expandedIds.value);
107
+ });
108
+ function isExpanded(id) {
109
+ return expandedIds.value.has(id);
110
+ }
111
+ function isSelected(id) {
112
+ return selectedIds.value.has(id);
113
+ }
114
+ function getDescendantCount(id) {
115
+ const node = nodeMap.value.get(id);
116
+ return node ? node.descendantCount : 0;
117
+ }
118
+ function getNode(id) {
119
+ return nodeMap.value.get(id);
120
+ }
121
+ function getChildren(id) {
122
+ const node = nodeMap.value.get(id);
123
+ return node ? node.children : [];
124
+ }
125
+ function getAncestors(id) {
126
+ return getAncestorsUtil(id, nodeMap.value);
127
+ }
128
+ function handleNodeClick(treeNode, _e) {
129
+ options.onNodeClick(treeNode.data);
130
+ if (options.selectionMode() !== "none") {
131
+ selectNode(treeNode.data.id);
132
+ }
133
+ }
134
+ return {
135
+ tree,
136
+ nodeMap,
137
+ layout,
138
+ flatVisibleNodes,
139
+ expandedIds,
140
+ selectedIds,
141
+ toggleExpand,
142
+ expandAll,
143
+ collapseAll,
144
+ selectNode,
145
+ deselectNode,
146
+ isExpanded,
147
+ isSelected,
148
+ getDescendantCount,
149
+ getNode,
150
+ getChildren,
151
+ getAncestors,
152
+ handleNodeClick
153
+ };
154
+ }
@@ -0,0 +1,8 @@
1
+ import type { InjectionKey } from "vue";
2
+ import type { OrgChartContext } from "../types/org-chart.js";
3
+ export declare const orgChartContextKey: InjectionKey<OrgChartContext>;
4
+ /**
5
+ * Inject the OrgChart context in a sub-component.
6
+ * Throws if called outside an <UEOrgChart> root.
7
+ */
8
+ export declare function useOrgChartContext(): OrgChartContext;
@@ -0,0 +1,11 @@
1
+ import { inject } from "vue";
2
+ export const orgChartContextKey = Symbol("nuxt-ui-elements-pro.org-chart");
3
+ export function useOrgChartContext() {
4
+ const ctx = inject(orgChartContextKey);
5
+ if (!ctx) {
6
+ throw new Error(
7
+ "[OrgChart] useOrgChartContext() was called outside of an <UEOrgChart> root. Sub-components must be used as children of <UEOrgChart>."
8
+ );
9
+ }
10
+ return ctx;
11
+ }
@@ -0,0 +1,20 @@
1
+ import type { ComputedRef } from "vue";
2
+ import type { OrgChartNode, OrgChartTreeNode } from "../types/org-chart.js";
3
+ export interface UseOrgChartDragDropOptions {
4
+ draggable: () => boolean;
5
+ nodeMap: ComputedRef<Map<string | number, OrgChartTreeNode>>;
6
+ onNodeDrop: (payload: {
7
+ node: OrgChartNode;
8
+ oldParentId: string | number | null;
9
+ newParentId: string | number;
10
+ }) => void;
11
+ }
12
+ export declare function useOrgChartDragDrop(options: UseOrgChartDragDropOptions): {
13
+ draggedNodeId: import("vue").Ref<string | number | null, string | number | null>;
14
+ dropTargetId: import("vue").Ref<string | number | null, string | number | null>;
15
+ onDragStart: (nodeId: string | number, e: DragEvent) => void;
16
+ onDragOver: (nodeId: string | number, e: DragEvent) => void;
17
+ onDragLeave: (_e: DragEvent) => void;
18
+ onDrop: (nodeId: string | number, e: DragEvent) => void;
19
+ onDragEnd: (_e: DragEvent) => void;
20
+ };
@@ -0,0 +1,67 @@
1
+ import { ref } from "vue";
2
+ import { getDescendants } from "../utils/org-chart.js";
3
+ export function useOrgChartDragDrop(options) {
4
+ const draggedNodeId = ref(null);
5
+ const dropTargetId = ref(null);
6
+ function onDragStart(nodeId, e) {
7
+ if (!options.draggable()) return;
8
+ const node = options.nodeMap.value.get(nodeId);
9
+ if (!node) return;
10
+ if (!node.parent) {
11
+ e.preventDefault();
12
+ return;
13
+ }
14
+ draggedNodeId.value = nodeId;
15
+ if (e.dataTransfer) {
16
+ e.dataTransfer.effectAllowed = "move";
17
+ e.dataTransfer.setData("text/plain", String(nodeId));
18
+ }
19
+ }
20
+ function onDragOver(nodeId, e) {
21
+ if (!options.draggable() || draggedNodeId.value === null) return;
22
+ if (nodeId === draggedNodeId.value) return;
23
+ const draggedNode = options.nodeMap.value.get(draggedNodeId.value);
24
+ if (draggedNode) {
25
+ const descendants = getDescendants(draggedNode);
26
+ if (descendants.some((d) => d.data.id === nodeId)) return;
27
+ }
28
+ e.preventDefault();
29
+ if (e.dataTransfer) {
30
+ e.dataTransfer.dropEffect = "move";
31
+ }
32
+ dropTargetId.value = nodeId;
33
+ }
34
+ function onDragLeave(_e) {
35
+ dropTargetId.value = null;
36
+ }
37
+ function onDrop(nodeId, e) {
38
+ if (!options.draggable() || draggedNodeId.value === null) return;
39
+ e.preventDefault();
40
+ const draggedNode = options.nodeMap.value.get(draggedNodeId.value);
41
+ if (!draggedNode) return;
42
+ if (nodeId === draggedNodeId.value) return;
43
+ const descendants = getDescendants(draggedNode);
44
+ if (descendants.some((d) => d.data.id === nodeId)) return;
45
+ const oldParentId = draggedNode.data.parentId;
46
+ options.onNodeDrop({
47
+ node: draggedNode.data,
48
+ oldParentId,
49
+ newParentId: nodeId
50
+ });
51
+ draggedNodeId.value = null;
52
+ dropTargetId.value = null;
53
+ }
54
+ function onDragEnd(_e) {
55
+ draggedNodeId.value = null;
56
+ dropTargetId.value = null;
57
+ }
58
+ return {
59
+ draggedNodeId,
60
+ dropTargetId,
61
+ onDragStart,
62
+ onDragOver,
63
+ onDragLeave,
64
+ onDrop,
65
+ onDragEnd
66
+ };
67
+ }
@@ -0,0 +1,16 @@
1
+ import type { ComputedRef, Ref } from "vue";
2
+ import type { OrgChartTreeNode, OrgChartSelectionMode } from "../types/org-chart.js";
3
+ export interface UseOrgChartKeyboardOptions {
4
+ flatVisibleNodes: ComputedRef<OrgChartTreeNode[]>;
5
+ nodeMap: ComputedRef<Map<string | number, OrgChartTreeNode>>;
6
+ expandedIds: Ref<Set<string | number>>;
7
+ selectionMode: () => OrgChartSelectionMode;
8
+ toggleExpand: (id: string | number) => void;
9
+ selectNode: (id: string | number) => void;
10
+ scrollToNode: (id: string | number) => void;
11
+ }
12
+ export declare function useOrgChartKeyboard(options: UseOrgChartKeyboardOptions): {
13
+ focusedId: Ref<string | number | null, string | number | null>;
14
+ isFocused: (id: string | number) => boolean;
15
+ onKeydown: (e: KeyboardEvent) => void;
16
+ };
@@ -0,0 +1,101 @@
1
+ import { ref } from "vue";
2
+ export function useOrgChartKeyboard(options) {
3
+ const focusedId = ref(null);
4
+ function isFocused(id) {
5
+ return focusedId.value === id;
6
+ }
7
+ function focusNode(id) {
8
+ focusedId.value = id;
9
+ options.scrollToNode(id);
10
+ }
11
+ function onKeydown(e) {
12
+ const nodes = options.flatVisibleNodes.value;
13
+ if (nodes.length === 0) return;
14
+ if (focusedId.value === null) {
15
+ focusNode(nodes[0].data.id);
16
+ return;
17
+ }
18
+ const currentIndex = nodes.findIndex((n) => n.data.id === focusedId.value);
19
+ if (currentIndex === -1) {
20
+ focusNode(nodes[0].data.id);
21
+ return;
22
+ }
23
+ const current = nodes[currentIndex];
24
+ switch (e.key) {
25
+ case "ArrowUp": {
26
+ e.preventDefault();
27
+ if (current.parent) {
28
+ focusNode(current.parent.data.id);
29
+ }
30
+ break;
31
+ }
32
+ case "ArrowDown": {
33
+ e.preventDefault();
34
+ if (current.children.length > 0 && options.expandedIds.value.has(current.data.id)) {
35
+ focusNode(current.children[0].data.id);
36
+ }
37
+ break;
38
+ }
39
+ case "ArrowLeft": {
40
+ e.preventDefault();
41
+ if (current.children.length > 0 && options.expandedIds.value.has(current.data.id)) {
42
+ options.toggleExpand(current.data.id);
43
+ } else if (current.parent) {
44
+ focusNode(current.parent.data.id);
45
+ }
46
+ break;
47
+ }
48
+ case "ArrowRight": {
49
+ e.preventDefault();
50
+ if (current.children.length > 0) {
51
+ if (!options.expandedIds.value.has(current.data.id)) {
52
+ options.toggleExpand(current.data.id);
53
+ } else {
54
+ focusNode(current.children[0].data.id);
55
+ }
56
+ }
57
+ break;
58
+ }
59
+ case "Enter": {
60
+ e.preventDefault();
61
+ if (current.children.length > 0) {
62
+ options.toggleExpand(current.data.id);
63
+ }
64
+ break;
65
+ }
66
+ case " ": {
67
+ e.preventDefault();
68
+ if (options.selectionMode() !== "none") {
69
+ options.selectNode(current.data.id);
70
+ }
71
+ break;
72
+ }
73
+ case "Home": {
74
+ e.preventDefault();
75
+ focusNode(nodes[0].data.id);
76
+ break;
77
+ }
78
+ case "End": {
79
+ e.preventDefault();
80
+ focusNode(nodes[nodes.length - 1].data.id);
81
+ break;
82
+ }
83
+ case "*": {
84
+ e.preventDefault();
85
+ if (current.parent) {
86
+ for (const sibling of current.parent.children) {
87
+ if (sibling.children.length > 0 && !options.expandedIds.value.has(sibling.data.id)) {
88
+ options.toggleExpand(sibling.data.id);
89
+ }
90
+ }
91
+ }
92
+ break;
93
+ }
94
+ }
95
+ }
96
+ return {
97
+ focusedId,
98
+ isFocused,
99
+ onKeydown
100
+ };
101
+ }
@@ -0,0 +1,16 @@
1
+ import type { ComputedRef, Ref } from "vue";
2
+ import type { OrgChartNode, OrgChartTreeNode } from "../types/org-chart.js";
3
+ export interface UseOrgChartSearchOptions {
4
+ searchQuery: () => string;
5
+ nodes: () => OrgChartNode[];
6
+ nodeMap: ComputedRef<Map<string | number, OrgChartTreeNode>>;
7
+ expandedIds: Ref<Set<string | number>>;
8
+ onUpdateExpanded: (ids: (string | number)[]) => void;
9
+ }
10
+ export declare function useOrgChartSearch(options: UseOrgChartSearchOptions): {
11
+ matchedIds: ComputedRef<Set<string | number>>;
12
+ isSearchActive: ComputedRef<boolean>;
13
+ isMatched: (id: string | number) => boolean;
14
+ isDimmed: (id: string | number) => boolean;
15
+ checkAndExpand: () => void;
16
+ };