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
@@ -1,24 +1,35 @@
1
1
  import type { CalendarDate, DateValue } from "@internationalized/date";
2
2
  import type { AppConfig } from "@nuxt/schema";
3
- import theme from "#build/ui-elements-pro/event-calendar";
4
3
  import type { ComponentConfig } from "nuxt-ui-elements";
5
- import type { CalendarEvent, CalendarDay, MonthViewOptions, WeekViewOptions, DayViewOptions, EventDropPayload } from "../types/event-calendar.js";
4
+ import type { CalendarEvent, CalendarView, CalendarDay, MonthViewOptions, WeekViewOptions, DayViewOptions, EventDropPayload, EventResizePayload, SelectPayload, EventCalendarContext } from "../types/event-calendar.js";
5
+ import { type Component } from "vue";
6
+ import theme from "#build/ui-elements-pro/event-calendar";
6
7
  type EventCalendar = ComponentConfig<typeof theme, AppConfig, "eventCalendar">;
7
8
  export interface EventCalendarProps {
9
+ /** Rendered element type @defaultValue 'div' */
10
+ as?: string | Component;
8
11
  /** Array of events to display */
9
12
  events?: CalendarEvent[];
10
13
  /** Currently displayed date. Controls which month/week/day is shown. Supports v-model. */
11
14
  modelValue?: Date | string | DateValue;
12
15
  /** Calendar view mode @defaultValue 'month' */
13
- view?: "month" | "week" | "day";
16
+ view?: CalendarView;
17
+ /** Which views are available and shown in the view switcher @defaultValue ['month', 'week', 'day', 'list'] */
18
+ views?: CalendarView[];
14
19
  /** Locale for day/month names @defaultValue 'en-US' */
15
20
  locale?: string;
16
- /** Day the week starts on @defaultValue 0 */
17
- weekStartsOn?: 0 | 1;
21
+ /** Day the week starts on (0=Sun, 1=Mon, … 6=Sat) @defaultValue 0 */
22
+ weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
18
23
  /** Enable drag-and-drop globally @defaultValue true */
19
24
  editable?: boolean;
25
+ /** Show loading overlay @defaultValue false */
26
+ loading?: boolean;
27
+ /** Enable click/drag date range selection @defaultValue true */
28
+ selectable?: boolean;
20
29
  /** Theme color for calendar chrome @defaultValue 'primary' */
21
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);
22
33
  /** Month view options */
23
34
  monthOptions?: MonthViewOptions;
24
35
  /** Week view options */
@@ -32,64 +43,140 @@ export interface EventCalendarEmits {
32
43
  /** Fires when the displayed date changes */
33
44
  "update:modelValue": [value: CalendarDate];
34
45
  /** Fires when the view changes */
35
- "update:view": [value: "month" | "week" | "day"];
46
+ "update:view": [value: CalendarView];
36
47
  /** Fires when a date cell is clicked */
37
48
  dateClick: [date: CalendarDate];
38
49
  /** Fires when an event is clicked */
39
50
  eventClick: [event: CalendarEvent];
40
51
  /** Fires after drag-and-drop */
41
52
  eventDrop: [payload: EventDropPayload];
53
+ /** Fires after resize */
54
+ eventResize: [payload: EventResizePayload];
55
+ /** Fires when resize starts */
56
+ eventResizeStart: [payload: {
57
+ event: CalendarEvent;
58
+ }];
59
+ /** Fires when resize ends */
60
+ eventResizeEnd: [payload: {
61
+ event: CalendarEvent;
62
+ }];
63
+ /** Fires after a click or drag date range selection */
64
+ select: [payload: SelectPayload];
42
65
  }
43
66
  export interface EventCalendarSlots {
44
- header: (props: {
67
+ default?: (props: EventCalendarContext) => any;
68
+ /** Replace the entire header */
69
+ header?: (props: {
45
70
  title: string;
46
71
  prev: () => void;
47
72
  next: () => void;
48
73
  today: () => void;
49
74
  currentDate: CalendarDate;
50
- view: "month" | "week" | "day";
51
- setView: (v: "month" | "week" | "day") => void;
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[];
52
96
  }) => any;
53
- "day-header": (props: {
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: {
54
104
  day: string;
55
105
  index: number;
56
106
  }) => any;
57
- day: (props: {
107
+ /** Customize day cell content (month view) */
108
+ day?: (props: {
58
109
  day: CalendarDay;
59
110
  }) => any;
60
- event: (props: {
61
- event: CalendarEvent;
62
- view: "month" | "week" | "day";
63
- }) => any;
64
- "more-events": (props: {
111
+ /** Customize "+N more" indicator (month view) */
112
+ "more-events"?: (props: {
65
113
  events: CalendarEvent[];
66
114
  count: number;
67
115
  day: CalendarDay;
68
116
  }) => any;
69
- "time-label": (props: {
117
+ /** Customize time labels (week/day view) */
118
+ "time-label"?: (props: {
70
119
  hour: number;
71
120
  label: string;
72
121
  }) => any;
73
- "all-day": (props: {
122
+ /** Customize all-day event area (week/day view) */
123
+ "all-day"?: (props: {
74
124
  events: CalendarEvent[];
75
125
  date: CalendarDate;
76
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;
77
137
  }
78
138
  declare const _default: typeof __VLS_export;
79
139
  export default _default;
80
- declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<EventCalendarProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
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, {
149
+ select: (payload: SelectPayload) => any;
81
150
  "update:modelValue": (value: CalendarDate) => any;
82
- "update:view": (value: "day" | "month" | "week") => any;
151
+ "update:view": (value: CalendarView) => any;
83
152
  dateClick: (date: CalendarDate) => any;
84
153
  eventClick: (event: CalendarEvent) => any;
85
154
  eventDrop: (payload: EventDropPayload) => any;
155
+ eventResize: (payload: EventResizePayload) => any;
156
+ eventResizeStart: (payload: {
157
+ event: CalendarEvent;
158
+ }) => any;
159
+ eventResizeEnd: (payload: {
160
+ event: CalendarEvent;
161
+ }) => any;
86
162
  }, string, import("vue").PublicProps, Readonly<EventCalendarProps> & Readonly<{
163
+ onSelect?: ((payload: SelectPayload) => any) | undefined;
87
164
  "onUpdate:modelValue"?: ((value: CalendarDate) => any) | undefined;
88
- "onUpdate:view"?: ((value: "day" | "month" | "week") => any) | undefined;
165
+ "onUpdate:view"?: ((value: CalendarView) => any) | undefined;
89
166
  onDateClick?: ((date: CalendarDate) => any) | undefined;
90
167
  onEventClick?: ((event: CalendarEvent) => any) | undefined;
91
168
  onEventDrop?: ((payload: EventDropPayload) => any) | undefined;
92
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, EventCalendarSlots>;
169
+ onEventResize?: ((payload: EventResizePayload) => any) | undefined;
170
+ onEventResizeStart?: ((payload: {
171
+ event: CalendarEvent;
172
+ }) => any) | undefined;
173
+ onEventResizeEnd?: ((payload: {
174
+ event: CalendarEvent;
175
+ }) => any) | undefined;
176
+ }>, {
177
+ editable: boolean;
178
+ selectable: boolean;
179
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, EventCalendarSlots>;
93
180
  type __VLS_WithSlots<T, S> = T & {
94
181
  new (): {
95
182
  $slots: S;
@@ -0,0 +1,191 @@
1
+ import type { AppConfig } from "@nuxt/schema";
2
+ import type { ComponentConfig } from "nuxt-ui-elements";
3
+ import type { OrgChartNode, OrgChartTreeNode, OrgChartConnection, OrgChartConnectionPath, OrgChartDirection, OrgChartConnectorStyle, OrgChartSelectionMode, OrgChartLayoutConfig, OrgChartZoomConfig, OrgChartConnector, OrgChartContext } from "../types/org-chart.js";
4
+ import { type Component } from "vue";
5
+ import theme from "#build/ui-elements-pro/org-chart";
6
+ type OrgChartTheme = ComponentConfig<typeof theme, AppConfig, "orgChart">;
7
+ export interface OrgChartProps {
8
+ /** Rendered element type @defaultValue 'div' */
9
+ as?: string | Component;
10
+ /** Flat array of org chart nodes */
11
+ nodes?: OrgChartNode[];
12
+ /** Non-hierarchical connections between nodes */
13
+ connections?: OrgChartConnection[];
14
+ /** Layout direction @defaultValue 'vertical' */
15
+ direction?: OrgChartDirection;
16
+ /** Connector style @defaultValue 'right-angle' */
17
+ connectorStyle?: OrgChartConnectorStyle;
18
+ /** Selection mode @defaultValue 'none' */
19
+ selectionMode?: OrgChartSelectionMode;
20
+ /** Compact mode with reduced spacing @defaultValue false */
21
+ compact?: boolean;
22
+ /** Theme color @defaultValue 'primary' */
23
+ color?: OrgChartTheme["variants"]["color"];
24
+ /** Two-way binding for expanded node IDs */
25
+ expanded?: (string | number)[];
26
+ /** Two-way binding for selected node IDs */
27
+ selected?: (string | number)[];
28
+ /** Search query to filter and highlight nodes */
29
+ searchQuery?: string;
30
+ /** Enable drag-and-drop rearrangement @defaultValue false */
31
+ draggable?: boolean;
32
+ /** Enable animations @defaultValue true */
33
+ animated?: boolean;
34
+ /** Layout configuration overrides */
35
+ layoutConfig?: OrgChartLayoutConfig;
36
+ /** Zoom/pan configuration */
37
+ zoomConfig?: OrgChartZoomConfig;
38
+ /** Slot class overrides */
39
+ ui?: OrgChartTheme["slots"];
40
+ }
41
+ export interface OrgChartEmits {
42
+ /** Fires when expanded node IDs change */
43
+ "update:expanded": [value: (string | number)[]];
44
+ /** Fires when selected node IDs change */
45
+ "update:selected": [value: (string | number)[]];
46
+ /** Fires when any node is clicked */
47
+ "node-click": [node: OrgChartNode];
48
+ /** Fires when a node is expanded or collapsed */
49
+ "node-expand": [payload: {
50
+ node: OrgChartNode;
51
+ expanded: boolean;
52
+ }];
53
+ /** Fires when a node is selected or deselected */
54
+ "node-select": [payload: {
55
+ node: OrgChartNode;
56
+ selected: boolean;
57
+ }];
58
+ /** Fires when a node is dropped onto a new parent via drag-and-drop */
59
+ "node-drop": [payload: {
60
+ node: OrgChartNode;
61
+ oldParentId: string | number | null;
62
+ newParentId: string | number;
63
+ }];
64
+ /** Fires when a non-hierarchical connection is clicked */
65
+ "connection-click": [connection: OrgChartConnection];
66
+ }
67
+ export interface OrgChartSlots {
68
+ /** Compound mode: full rendering control */
69
+ default?: (props: OrgChartContext) => any;
70
+ /** Custom node rendering (replaces entire node card content) */
71
+ node?: (props: {
72
+ node: OrgChartNode;
73
+ treeNode: OrgChartTreeNode;
74
+ selected: boolean;
75
+ expanded: boolean;
76
+ focused: boolean;
77
+ matched: boolean;
78
+ dimmed: boolean;
79
+ }) => any;
80
+ /** Custom avatar area */
81
+ avatar?: (props: {
82
+ node: OrgChartNode;
83
+ }) => any;
84
+ /** Custom label */
85
+ label?: (props: {
86
+ node: OrgChartNode;
87
+ highlight?: string;
88
+ }) => any;
89
+ /** Custom description / title */
90
+ description?: (props: {
91
+ node: OrgChartNode;
92
+ highlight?: string;
93
+ }) => any;
94
+ /** Custom connector rendering */
95
+ connector?: (props: {
96
+ connectors: OrgChartConnector[];
97
+ }) => any;
98
+ /** Custom non-hierarchical connection rendering */
99
+ connection?: (props: {
100
+ connections: OrgChartConnectionPath[];
101
+ }) => any;
102
+ /** Custom connection label */
103
+ "connection-label"?: (props: {
104
+ connection: OrgChartConnection;
105
+ x: number;
106
+ y: number;
107
+ }) => any;
108
+ /** Custom collapse toggle */
109
+ "collapse-toggle"?: (props: {
110
+ expanded: boolean;
111
+ count: number;
112
+ node: OrgChartNode;
113
+ }) => any;
114
+ /** Custom zoom controls */
115
+ "zoom-controls"?: (props: {
116
+ zoomIn: () => void;
117
+ zoomOut: () => void;
118
+ zoomReset: () => void;
119
+ fitToView: () => void;
120
+ scale: number;
121
+ }) => any;
122
+ /** Custom drop indicator */
123
+ "drop-indicator"?: (props: {
124
+ targetNode: OrgChartNode;
125
+ }) => any;
126
+ /** Empty state (no nodes) */
127
+ empty?: () => any;
128
+ }
129
+ declare const _default: typeof __VLS_export;
130
+ export default _default;
131
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<OrgChartProps, {
132
+ expandAll: () => void;
133
+ collapseAll: () => void;
134
+ toggleNode: (id: string | number) => void;
135
+ selectNode: (id: string | number) => void;
136
+ deselectNode: (id: string | number) => void;
137
+ scrollToNode: (id: string | number) => void;
138
+ fitToView: () => void;
139
+ getChildren: (id: string | number) => OrgChartTreeNode[];
140
+ getAncestors: (id: string | number) => OrgChartTreeNode[];
141
+ tree: import("vue").ComputedRef<OrgChartTreeNode | null>;
142
+ layout: import("vue").ComputedRef<import("../types/org-chart.js").OrgChartLayout>;
143
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
144
+ "update:expanded": (value: (string | number)[]) => any;
145
+ "update:selected": (value: (string | number)[]) => any;
146
+ "node-click": (node: OrgChartNode) => any;
147
+ "node-expand": (payload: {
148
+ node: OrgChartNode;
149
+ expanded: boolean;
150
+ }) => any;
151
+ "node-select": (payload: {
152
+ node: OrgChartNode;
153
+ selected: boolean;
154
+ }) => any;
155
+ "node-drop": (payload: {
156
+ node: OrgChartNode;
157
+ oldParentId: string | number | null;
158
+ newParentId: string | number;
159
+ }) => any;
160
+ "connection-click": (connection: OrgChartConnection) => any;
161
+ }, string, import("vue").PublicProps, Readonly<OrgChartProps> & Readonly<{
162
+ "onUpdate:expanded"?: ((value: (string | number)[]) => any) | undefined;
163
+ "onUpdate:selected"?: ((value: (string | number)[]) => any) | undefined;
164
+ "onNode-click"?: ((node: OrgChartNode) => any) | undefined;
165
+ "onNode-expand"?: ((payload: {
166
+ node: OrgChartNode;
167
+ expanded: boolean;
168
+ }) => any) | undefined;
169
+ "onNode-select"?: ((payload: {
170
+ node: OrgChartNode;
171
+ selected: boolean;
172
+ }) => any) | undefined;
173
+ "onNode-drop"?: ((payload: {
174
+ node: OrgChartNode;
175
+ oldParentId: string | number | null;
176
+ newParentId: string | number;
177
+ }) => any) | undefined;
178
+ "onConnection-click"?: ((connection: OrgChartConnection) => any) | undefined;
179
+ }>, {
180
+ draggable: boolean;
181
+ compact: boolean;
182
+ direction: OrgChartDirection;
183
+ connectorStyle: OrgChartConnectorStyle;
184
+ selectionMode: OrgChartSelectionMode;
185
+ animated: boolean;
186
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, OrgChartSlots>;
187
+ type __VLS_WithSlots<T, S> = T & {
188
+ new (): {
189
+ $slots: S;
190
+ };
191
+ };
@@ -0,0 +1,290 @@
1
+ <script>
2
+ import { Primitive } from "reka-ui";
3
+ import { computed, provide, ref, useSlots, watch } from "vue";
4
+ import { tv } from "../utils/tv";
5
+ import { useOrgChart } from "../composables/useOrgChart";
6
+ import { useOrgChartKeyboard } from "../composables/useOrgChartKeyboard";
7
+ import { useOrgChartZoom } from "../composables/useOrgChartZoom";
8
+ import { useOrgChartSearch } from "../composables/useOrgChartSearch";
9
+ import { useOrgChartDragDrop } from "../composables/useOrgChartDragDrop";
10
+ import { orgChartContextKey } from "../composables/useOrgChartContext";
11
+ import { DEFAULT_LAYOUT_CONFIG, DEFAULT_ZOOM_CONFIG } from "../utils/org-chart";
12
+ import OrgChartNodeVue from "./org-chart/OrgChartNode.vue";
13
+ import OrgChartConnectors from "./org-chart/OrgChartConnectors.vue";
14
+ import OrgChartControls from "./org-chart/OrgChartControls.vue";
15
+ import theme from "#build/ui-elements-pro/org-chart";
16
+ </script>
17
+
18
+ <script setup>
19
+ const props = defineProps({
20
+ as: { type: null, required: false },
21
+ nodes: { type: Array, required: false },
22
+ connections: { type: Array, required: false },
23
+ direction: { type: String, required: false, default: "vertical" },
24
+ connectorStyle: { type: String, required: false, default: "right-angle" },
25
+ selectionMode: { type: String, required: false, default: "none" },
26
+ compact: { type: Boolean, required: false, default: false },
27
+ color: { type: null, required: false },
28
+ expanded: { type: Array, required: false },
29
+ selected: { type: Array, required: false },
30
+ searchQuery: { type: String, required: false },
31
+ draggable: { type: Boolean, required: false, default: false },
32
+ animated: { type: Boolean, required: false, default: true },
33
+ layoutConfig: { type: Object, required: false },
34
+ zoomConfig: { type: Object, required: false },
35
+ ui: { type: Object, required: false }
36
+ });
37
+ const emit = defineEmits(["update:expanded", "update:selected", "node-click", "node-expand", "node-select", "node-drop", "connection-click"]);
38
+ defineSlots();
39
+ const slots = useSlots();
40
+ const ui = computed(
41
+ () => tv({
42
+ extend: tv(theme)
43
+ })({
44
+ color: props.color ?? "primary",
45
+ compact: props.compact
46
+ })
47
+ );
48
+ const resolvedLayoutConfig = computed(() => ({
49
+ ...DEFAULT_LAYOUT_CONFIG,
50
+ ...props.compact ? { nodeWidth: 160, nodeHeight: 48, siblingGap: 24, levelGap: 40 } : {},
51
+ ...props.layoutConfig
52
+ }));
53
+ const resolvedZoomConfig = computed(() => ({
54
+ ...DEFAULT_ZOOM_CONFIG,
55
+ ...props.zoomConfig
56
+ }));
57
+ const orgChart = useOrgChart({
58
+ nodes: () => props.nodes ?? [],
59
+ connections: () => props.connections ?? [],
60
+ direction: () => props.direction,
61
+ connectorStyle: () => props.connectorStyle,
62
+ selectionMode: () => props.selectionMode,
63
+ layoutConfig: () => resolvedLayoutConfig.value,
64
+ expanded: () => props.expanded,
65
+ selected: () => props.selected,
66
+ onUpdateExpanded: (ids) => emit("update:expanded", ids),
67
+ onUpdateSelected: (ids) => emit("update:selected", ids),
68
+ onNodeClick: (node) => emit("node-click", node),
69
+ onNodeExpand: (payload) => emit("node-expand", payload),
70
+ onNodeSelect: (payload) => emit("node-select", payload)
71
+ });
72
+ const search = useOrgChartSearch({
73
+ searchQuery: () => props.searchQuery ?? "",
74
+ nodes: () => props.nodes ?? [],
75
+ nodeMap: orgChart.nodeMap,
76
+ expandedIds: orgChart.expandedIds,
77
+ onUpdateExpanded: (ids) => emit("update:expanded", ids)
78
+ });
79
+ watch(() => props.searchQuery, () => {
80
+ search.checkAndExpand();
81
+ });
82
+ const dragDrop = useOrgChartDragDrop({
83
+ draggable: () => props.draggable,
84
+ nodeMap: orgChart.nodeMap,
85
+ onNodeDrop: (payload) => emit("node-drop", payload)
86
+ });
87
+ const viewportRef = ref(null);
88
+ const zoom = useOrgChartZoom({
89
+ config: () => resolvedZoomConfig.value,
90
+ containerRef: viewportRef,
91
+ layoutWidth: computed(() => orgChart.layout.value.width),
92
+ layoutHeight: computed(() => orgChart.layout.value.height),
93
+ nodeMap: orgChart.nodeMap,
94
+ layoutConfig: () => resolvedLayoutConfig.value
95
+ });
96
+ const keyboard = useOrgChartKeyboard({
97
+ flatVisibleNodes: orgChart.flatVisibleNodes,
98
+ nodeMap: orgChart.nodeMap,
99
+ expandedIds: orgChart.expandedIds,
100
+ selectionMode: () => props.selectionMode,
101
+ toggleExpand: orgChart.toggleExpand,
102
+ selectNode: orgChart.selectNode,
103
+ scrollToNode: zoom.scrollToNode
104
+ });
105
+ function handleConnectionClick(connection, _e) {
106
+ emit("connection-click", connection);
107
+ }
108
+ const connectionPaths = computed(() => orgChart.layout.value.connectionPaths);
109
+ const ctx = {
110
+ tree: orgChart.tree,
111
+ layout: orgChart.layout,
112
+ flatVisibleNodes: orgChart.flatVisibleNodes,
113
+ nodeMap: orgChart.nodeMap,
114
+ direction: computed(() => props.direction),
115
+ connectorStyle: computed(() => props.connectorStyle),
116
+ selectionMode: computed(() => props.selectionMode),
117
+ compact: computed(() => props.compact),
118
+ animated: computed(() => props.animated),
119
+ draggable: computed(() => props.draggable),
120
+ layoutConfig: resolvedLayoutConfig,
121
+ zoomConfig: resolvedZoomConfig,
122
+ expandedIds: orgChart.expandedIds,
123
+ selectedIds: orgChart.selectedIds,
124
+ focusedId: keyboard.focusedId,
125
+ // Search
126
+ searchQuery: computed(() => props.searchQuery ?? ""),
127
+ matchedIds: search.matchedIds,
128
+ isMatched: search.isMatched,
129
+ isDimmed: search.isDimmed,
130
+ isExpanded: orgChart.isExpanded,
131
+ isSelected: orgChart.isSelected,
132
+ isFocused: keyboard.isFocused,
133
+ getDescendantCount: orgChart.getDescendantCount,
134
+ getNode: orgChart.getNode,
135
+ getChildren: orgChart.getChildren,
136
+ getAncestors: orgChart.getAncestors,
137
+ toggleExpand: orgChart.toggleExpand,
138
+ expandAll: orgChart.expandAll,
139
+ collapseAll: orgChart.collapseAll,
140
+ selectNode: orgChart.selectNode,
141
+ deselectNode: orgChart.deselectNode,
142
+ scrollToNode: zoom.scrollToNode,
143
+ fitToView: zoom.fitToView,
144
+ handleNodeClick: orgChart.handleNodeClick,
145
+ onKeydown: keyboard.onKeydown,
146
+ // Drag-and-drop
147
+ draggedNodeId: dragDrop.draggedNodeId,
148
+ dropTargetId: dragDrop.dropTargetId,
149
+ onDragStart: dragDrop.onDragStart,
150
+ onDragOver: dragDrop.onDragOver,
151
+ onDragLeave: dragDrop.onDragLeave,
152
+ onDrop: dragDrop.onDrop,
153
+ onDragEnd: dragDrop.onDragEnd,
154
+ // Non-hierarchical connections
155
+ connectionPaths,
156
+ handleConnectionClick,
157
+ ui,
158
+ propUi: computed(() => props.ui),
159
+ scale: zoom.scale,
160
+ translateX: zoom.translateX,
161
+ translateY: zoom.translateY,
162
+ transformStyle: zoom.transformStyle,
163
+ zoomIn: zoom.zoomIn,
164
+ zoomOut: zoom.zoomOut,
165
+ zoomReset: zoom.zoomReset,
166
+ onWheel: zoom.onWheel,
167
+ onPointerDown: zoom.onPointerDown
168
+ };
169
+ provide(orgChartContextKey, ctx);
170
+ defineExpose({
171
+ expandAll: orgChart.expandAll,
172
+ collapseAll: orgChart.collapseAll,
173
+ toggleNode: orgChart.toggleExpand,
174
+ selectNode: orgChart.selectNode,
175
+ deselectNode: orgChart.deselectNode,
176
+ scrollToNode: zoom.scrollToNode,
177
+ fitToView: zoom.fitToView,
178
+ getChildren: orgChart.getChildren,
179
+ getAncestors: orgChart.getAncestors,
180
+ tree: orgChart.tree,
181
+ layout: orgChart.layout
182
+ });
183
+ </script>
184
+
185
+ <template>
186
+ <Primitive :as="props.as ?? 'div'" data-slot="root" :class="ui.root({ class: props.ui?.root })" role="tree" aria-label="Organization chart">
187
+ <!-- Compound mode: user provides #default and owns rendering -->
188
+ <slot v-if="slots.default" v-bind="ctx" />
189
+
190
+ <!-- Auto mode: render everything with slot forwarding -->
191
+ <template v-else>
192
+ <OrgChartControls v-if="resolvedZoomConfig.enabled && resolvedZoomConfig.controls">
193
+ <template v-if="slots['zoom-controls']" #default="controlProps">
194
+ <slot name="zoom-controls" v-bind="controlProps" />
195
+ </template>
196
+ </OrgChartControls>
197
+
198
+ <div
199
+ v-if="orgChart.layout.value.nodes.length > 0"
200
+ ref="viewportRef"
201
+ data-slot="viewport"
202
+ :class="ui.viewport({ class: props.ui?.viewport })"
203
+ :style="[
204
+ resolvedZoomConfig.enabled ? zoom.transformStyle.value : void 0,
205
+ { width: `${orgChart.layout.value.width}px`, height: `${orgChart.layout.value.height}px` }
206
+ ]"
207
+ @wheel="zoom.onWheel"
208
+ @pointerdown="zoom.onPointerDown"
209
+ >
210
+ <OrgChartConnectors>
211
+ <template v-if="slots.connector" #default="connProps">
212
+ <slot name="connector" v-bind="connProps" />
213
+ </template>
214
+ </OrgChartConnectors>
215
+
216
+ <template v-for="treeNode in orgChart.flatVisibleNodes.value" :key="treeNode.data.id">
217
+ <slot
218
+ v-if="slots.node"
219
+ name="node"
220
+ :node="treeNode.data"
221
+ :tree-node="treeNode"
222
+ :selected="orgChart.isSelected(treeNode.data.id)"
223
+ :expanded="orgChart.isExpanded(treeNode.data.id)"
224
+ :focused="keyboard.isFocused(treeNode.data.id)"
225
+ :matched="search.isMatched(treeNode.data.id)"
226
+ :dimmed="search.isDimmed(treeNode.data.id)"
227
+ />
228
+ <OrgChartNodeVue v-else :node="treeNode">
229
+ <template v-if="slots.avatar" #avatar="avatarProps">
230
+ <slot name="avatar" v-bind="avatarProps" />
231
+ </template>
232
+ <template v-if="slots.label" #label="labelProps">
233
+ <slot name="label" v-bind="{ ...labelProps, highlight: props.searchQuery }" />
234
+ </template>
235
+ <template v-if="slots.description" #description="descProps">
236
+ <slot name="description" v-bind="{ ...descProps, highlight: props.searchQuery }" />
237
+ </template>
238
+ <template v-if="slots['collapse-toggle']" #collapse-toggle="toggleProps">
239
+ <slot name="collapse-toggle" v-bind="toggleProps" />
240
+ </template>
241
+ </OrgChartNodeVue>
242
+ </template>
243
+
244
+ <!-- Non-hierarchical connections (rendered after nodes so they appear on top) -->
245
+ <svg
246
+ v-if="connectionPaths.length > 0"
247
+ :class="ui.connectorLayer({ class: props.ui?.connectorLayer })"
248
+ :width="orgChart.layout.value.width"
249
+ :height="orgChart.layout.value.height"
250
+ :viewBox="`0 0 ${orgChart.layout.value.width} ${orgChart.layout.value.height}`"
251
+ aria-hidden="true"
252
+ >
253
+ <path
254
+ v-for="cp in connectionPaths"
255
+ :key="`conn-${cp.connection.id}`"
256
+ data-slot="connection"
257
+ :d="cp.path"
258
+ :class="ui.connection({ class: props.ui?.connection })"
259
+ :stroke="cp.connection.color ? cp.connection.color === 'neutral' ? 'var(--ui-bg-inverted)' : `var(--ui-${cp.connection.color})` : void 0"
260
+ :stroke-dasharray="cp.connection.style === 'dotted' ? '2 4' : cp.connection.style === 'solid' ? void 0 : '6 4'"
261
+ @click.stop="handleConnectionClick(cp.connection, $event)"
262
+ />
263
+ </svg>
264
+
265
+ <!-- Connection labels -->
266
+ <div
267
+ v-for="cp in connectionPaths"
268
+ :key="`conn-label-${cp.connection.id}`"
269
+ :data-slot="'connectionLabel'"
270
+ :class="ui.connectionLabel({ class: props.ui?.connectionLabel })"
271
+ :style="{
272
+ left: `${cp.labelX}px`,
273
+ top: `${cp.labelY}px`,
274
+ display: cp.connection.label ? void 0 : 'none'
275
+ }"
276
+ @click.stop="handleConnectionClick(cp.connection, $event)"
277
+ >
278
+ {{ cp.connection.label }}
279
+ </div>
280
+ </div>
281
+
282
+ <slot v-else name="empty">
283
+ <div data-slot="emptyState" :class="ui.emptyState({ class: props.ui?.emptyState })">
284
+ <UIcon name="i-lucide-network" :class="ui.emptyStateIcon({ class: props.ui?.emptyStateIcon })" />
285
+ <p :class="ui.emptyStateText({ class: props.ui?.emptyStateText })">No data to display</p>
286
+ </div>
287
+ </slot>
288
+ </template>
289
+ </Primitive>
290
+ </template>