@appcorp/shadcn 1.0.10

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 (78) hide show
  1. package/README.md +138 -0
  2. package/app/layout.d.ts +7 -0
  3. package/app/layout.js +18 -0
  4. package/app/page.d.ts +2 -0
  5. package/app/page.js +16 -0
  6. package/components/badge.d.ts +9 -0
  7. package/components/badge.js +82 -0
  8. package/components/button.d.ts +10 -0
  9. package/components/button.js +91 -0
  10. package/components/card.d.ts +9 -0
  11. package/components/card.js +94 -0
  12. package/components/carousel.d.ts +19 -0
  13. package/components/carousel.js +168 -0
  14. package/components/checkbox.d.ts +9 -0
  15. package/components/checkbox.js +87 -0
  16. package/components/combobox.d.ts +70 -0
  17. package/components/combobox.js +315 -0
  18. package/components/command.d.ts +18 -0
  19. package/components/command.js +115 -0
  20. package/components/context-menu.d.ts +25 -0
  21. package/components/context-menu.js +148 -0
  22. package/components/dialog.d.ts +15 -0
  23. package/components/dialog.js +118 -0
  24. package/components/drawer.d.ts +13 -0
  25. package/components/drawer.js +115 -0
  26. package/components/dropdown-menu.d.ts +25 -0
  27. package/components/dropdown-menu.js +148 -0
  28. package/components/enhanced-dropzone.d.ts +21 -0
  29. package/components/enhanced-dropzone.js +187 -0
  30. package/components/enhanced-table-footer-action.d.ts +35 -0
  31. package/components/enhanced-table-footer-action.js +110 -0
  32. package/components/enhanced-table-footer-page.d.ts +34 -0
  33. package/components/enhanced-table-footer-page.js +132 -0
  34. package/components/enhanced-table-footer-pagination.d.ts +38 -0
  35. package/components/enhanced-table-footer-pagination.js +116 -0
  36. package/components/enhanced-table-header-action.d.ts +7 -0
  37. package/components/enhanced-table-header-action.js +21 -0
  38. package/components/enhanced-table-header-search.d.ts +12 -0
  39. package/components/enhanced-table-header-search.js +17 -0
  40. package/components/enhanced-table.d.ts +87 -0
  41. package/components/enhanced-table.js +221 -0
  42. package/components/form.d.ts +24 -0
  43. package/components/form.js +125 -0
  44. package/components/input.d.ts +8 -0
  45. package/components/input.js +86 -0
  46. package/components/label.d.ts +7 -0
  47. package/components/label.js +68 -0
  48. package/components/popover.d.ts +7 -0
  49. package/components/popover.js +82 -0
  50. package/components/select.d.ts +15 -0
  51. package/components/select.js +127 -0
  52. package/components/separator.d.ts +4 -0
  53. package/components/separator.js +66 -0
  54. package/components/shadcn-io/color-picker/index.d.ts +43 -0
  55. package/components/shadcn-io/color-picker/index.js +304 -0
  56. package/components/shadcn-io/copy-button/index.d.ts +16 -0
  57. package/components/shadcn-io/copy-button/index.js +121 -0
  58. package/components/shadcn-io/dropzone/index.d.ts +19 -0
  59. package/components/shadcn-io/dropzone/index.js +131 -0
  60. package/components/shadcn-io/gantt/index.d.ts +145 -0
  61. package/components/shadcn-io/gantt/index.js +767 -0
  62. package/components/shadcn-io/table/index.d.ts +60 -0
  63. package/components/shadcn-io/table/index.js +138 -0
  64. package/components/sonner.d.ts +4 -0
  65. package/components/sonner.js +54 -0
  66. package/components/switch.d.ts +9 -0
  67. package/components/switch.js +89 -0
  68. package/components/table.d.ts +10 -0
  69. package/components/table.js +101 -0
  70. package/components/textarea.d.ts +8 -0
  71. package/components/textarea.js +86 -0
  72. package/lib/themes.d.ts +147 -0
  73. package/lib/themes.js +150 -0
  74. package/lib/toast-utils.d.ts +44 -0
  75. package/lib/toast-utils.js +212 -0
  76. package/lib/utils.d.ts +2 -0
  77. package/lib/utils.js +12 -0
  78. package/package.json +101 -0
@@ -0,0 +1,767 @@
1
+ "use client";
2
+ "use strict";
3
+ var __assign = (this && this.__assign) || function () {
4
+ __assign = Object.assign || function(t) {
5
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
6
+ s = arguments[i];
7
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
8
+ t[p] = s[p];
9
+ }
10
+ return t;
11
+ };
12
+ return __assign.apply(this, arguments);
13
+ };
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ var __rest = (this && this.__rest) || function (s, e) {
48
+ var t = {};
49
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
50
+ t[p] = s[p];
51
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
52
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
53
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
54
+ t[p[i]] = s[p[i]];
55
+ }
56
+ return t;
57
+ };
58
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
59
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
60
+ if (ar || !(i in from)) {
61
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
62
+ ar[i] = from[i];
63
+ }
64
+ }
65
+ return to.concat(ar || Array.prototype.slice.call(from));
66
+ };
67
+ var __importDefault = (this && this.__importDefault) || function (mod) {
68
+ return (mod && mod.__esModule) ? mod : { "default": mod };
69
+ };
70
+ Object.defineProperty(exports, "__esModule", { value: true });
71
+ exports.GanttToday = exports.GanttTimeline = exports.GanttProvider = exports.GanttMarker = exports.GanttFeatureList = exports.GanttFeatureRow = exports.GanttFeatureListGroup = exports.GanttFeatureItem = exports.GanttFeatureItemCard = exports.GanttFeatureDragHelper = exports.GanttCreateMarkerTrigger = exports.GanttColumns = exports.GanttColumn = exports.GanttAddFeatureHelper = exports.GanttSidebar = exports.GanttSidebarGroup = exports.GanttSidebarHeader = exports.GanttSidebarItem = exports.GanttHeader = exports.GanttContentHeader = exports.useGanttScrollX = exports.useGanttDragging = void 0;
72
+ var core_1 = require("@dnd-kit/core");
73
+ var modifiers_1 = require("@dnd-kit/modifiers");
74
+ var usehooks_1 = require("@uidotdev/usehooks");
75
+ var date_fns_1 = require("date-fns");
76
+ var jotai_1 = require("jotai");
77
+ var lodash_throttle_1 = __importDefault(require("lodash.throttle"));
78
+ var lucide_react_1 = require("lucide-react");
79
+ var react_1 = __importStar(require("react"));
80
+ var card_1 = require("../../card");
81
+ var context_menu_1 = require("../../context-menu");
82
+ var utils_1 = require("../../../lib/utils");
83
+ var draggingAtom = (0, jotai_1.atom)(false);
84
+ var scrollXAtom = (0, jotai_1.atom)(0);
85
+ var useGanttDragging = function () { return (0, jotai_1.useAtom)(draggingAtom); };
86
+ exports.useGanttDragging = useGanttDragging;
87
+ var useGanttScrollX = function () { return (0, jotai_1.useAtom)(scrollXAtom); };
88
+ exports.useGanttScrollX = useGanttScrollX;
89
+ var getsDaysIn = function (range) {
90
+ // For when range is daily
91
+ var fn = function (_date) { return 1; }; // eslint-disable-line @typescript-eslint/no-unused-vars
92
+ if (range === "monthly" || range === "quarterly") {
93
+ fn = date_fns_1.getDaysInMonth;
94
+ }
95
+ return fn;
96
+ };
97
+ var getDifferenceIn = function (range) {
98
+ var fn = date_fns_1.differenceInDays;
99
+ if (range === "monthly" || range === "quarterly") {
100
+ fn = date_fns_1.differenceInMonths;
101
+ }
102
+ return fn;
103
+ };
104
+ var getInnerDifferenceIn = function (range) {
105
+ var fn = date_fns_1.differenceInHours;
106
+ if (range === "monthly" || range === "quarterly") {
107
+ fn = date_fns_1.differenceInDays;
108
+ }
109
+ return fn;
110
+ };
111
+ var getStartOf = function (range) {
112
+ var fn = date_fns_1.startOfDay;
113
+ if (range === "monthly" || range === "quarterly") {
114
+ fn = date_fns_1.startOfMonth;
115
+ }
116
+ return fn;
117
+ };
118
+ var getEndOf = function (range) {
119
+ var fn = date_fns_1.endOfDay;
120
+ if (range === "monthly" || range === "quarterly") {
121
+ fn = date_fns_1.endOfMonth;
122
+ }
123
+ return fn;
124
+ };
125
+ var getAddRange = function (range) {
126
+ var fn = date_fns_1.addDays;
127
+ if (range === "monthly" || range === "quarterly") {
128
+ fn = date_fns_1.addMonths;
129
+ }
130
+ return fn;
131
+ };
132
+ var getDateByMousePosition = function (context, mouseX) {
133
+ var timelineStartDate = new Date(context.timelineData[0].year, 0, 1);
134
+ var columnWidth = (context.columnWidth * context.zoom) / 100;
135
+ var offset = Math.floor(mouseX / columnWidth);
136
+ var daysIn = getsDaysIn(context.range);
137
+ var addRange = getAddRange(context.range);
138
+ var month = addRange(timelineStartDate, offset);
139
+ var daysInMonth = daysIn(month);
140
+ var pixelsPerDay = Math.round(columnWidth / daysInMonth);
141
+ var dayOffset = Math.floor((mouseX % columnWidth) / pixelsPerDay);
142
+ var actualDate = (0, date_fns_1.addDays)(month, dayOffset);
143
+ return actualDate;
144
+ };
145
+ var createInitialTimelineData = function (today) {
146
+ var data = [];
147
+ data.push({ year: today.getFullYear() - 1, quarters: new Array(4).fill(null) }, { year: today.getFullYear(), quarters: new Array(4).fill(null) }, { year: today.getFullYear() + 1, quarters: new Array(4).fill(null) });
148
+ var _loop_1 = function (yearObj) {
149
+ yearObj.quarters = new Array(4).fill(null).map(function (_, quarterIndex) { return ({
150
+ months: new Array(3).fill(null).map(function (_, monthIndex) {
151
+ var month = quarterIndex * 3 + monthIndex;
152
+ return {
153
+ days: (0, date_fns_1.getDaysInMonth)(new Date(yearObj.year, month, 1)),
154
+ };
155
+ }),
156
+ }); });
157
+ };
158
+ for (var _i = 0, data_1 = data; _i < data_1.length; _i++) {
159
+ var yearObj = data_1[_i];
160
+ _loop_1(yearObj);
161
+ }
162
+ return data;
163
+ };
164
+ var getOffset = function (date, timelineStartDate, context) {
165
+ var parsedColumnWidth = (context.columnWidth * context.zoom) / 100;
166
+ var differenceIn = getDifferenceIn(context.range);
167
+ var startOf = getStartOf(context.range);
168
+ var fullColumns = differenceIn(startOf(date), timelineStartDate);
169
+ if (context.range === "daily") {
170
+ return parsedColumnWidth * fullColumns;
171
+ }
172
+ var partialColumns = date.getDate();
173
+ var daysInMonth = (0, date_fns_1.getDaysInMonth)(date);
174
+ var pixelsPerDay = parsedColumnWidth / daysInMonth;
175
+ return fullColumns * parsedColumnWidth + partialColumns * pixelsPerDay;
176
+ };
177
+ var getWidth = function (startAt, endAt, context) {
178
+ var parsedColumnWidth = (context.columnWidth * context.zoom) / 100;
179
+ if (!endAt) {
180
+ return parsedColumnWidth * 2;
181
+ }
182
+ var differenceIn = getDifferenceIn(context.range);
183
+ if (context.range === "daily") {
184
+ var delta = differenceIn(endAt, startAt);
185
+ return parsedColumnWidth * (delta ? delta : 1);
186
+ }
187
+ var daysInStartMonth = (0, date_fns_1.getDaysInMonth)(startAt);
188
+ var pixelsPerDayInStartMonth = parsedColumnWidth / daysInStartMonth;
189
+ if ((0, date_fns_1.isSameDay)(startAt, endAt)) {
190
+ return pixelsPerDayInStartMonth;
191
+ }
192
+ var innerDifferenceIn = getInnerDifferenceIn(context.range);
193
+ var startOf = getStartOf(context.range);
194
+ if ((0, date_fns_1.isSameDay)(startOf(startAt), startOf(endAt))) {
195
+ return innerDifferenceIn(endAt, startAt) * pixelsPerDayInStartMonth;
196
+ }
197
+ var startRangeOffset = daysInStartMonth - (0, date_fns_1.getDate)(startAt);
198
+ var endRangeOffset = (0, date_fns_1.getDate)(endAt);
199
+ var fullRangeOffset = differenceIn(startOf(endAt), startOf(startAt));
200
+ var daysInEndMonth = (0, date_fns_1.getDaysInMonth)(endAt);
201
+ var pixelsPerDayInEndMonth = parsedColumnWidth / daysInEndMonth;
202
+ return ((fullRangeOffset - 1) * parsedColumnWidth +
203
+ startRangeOffset * pixelsPerDayInStartMonth +
204
+ endRangeOffset * pixelsPerDayInEndMonth);
205
+ };
206
+ var calculateInnerOffset = function (date, range, columnWidth) {
207
+ var startOf = getStartOf(range);
208
+ var endOf = getEndOf(range);
209
+ var differenceIn = getInnerDifferenceIn(range);
210
+ var startOfRange = startOf(date);
211
+ var endOfRange = endOf(date);
212
+ var totalRangeDays = differenceIn(endOfRange, startOfRange);
213
+ var dayOfMonth = date.getDate();
214
+ return (dayOfMonth / totalRangeDays) * columnWidth;
215
+ };
216
+ var GanttContext = (0, react_1.createContext)({
217
+ zoom: 100,
218
+ range: "monthly",
219
+ columnWidth: 50,
220
+ headerHeight: 60,
221
+ sidebarWidth: 300,
222
+ rowHeight: 36,
223
+ onAddItem: undefined,
224
+ placeholderLength: 2,
225
+ timelineData: [],
226
+ ref: null,
227
+ scrollToFeature: undefined,
228
+ });
229
+ var GanttContentHeader = function (_a) {
230
+ var title = _a.title, columns = _a.columns, renderHeaderItem = _a.renderHeaderItem;
231
+ var id = (0, react_1.useId)();
232
+ return (react_1.default.createElement("div", { className: "sticky top-0 z-20 grid w-full shrink-0 bg-backdrop/90 backdrop-blur-sm", style: { height: "var(--gantt-header-height)" } },
233
+ react_1.default.createElement("div", null,
234
+ react_1.default.createElement("div", { className: "sticky inline-flex whitespace-nowrap px-3 py-2 text-muted-foreground text-xs", style: {
235
+ left: "var(--gantt-sidebar-width)",
236
+ } },
237
+ react_1.default.createElement("p", null, title))),
238
+ react_1.default.createElement("div", { className: "grid w-full", style: {
239
+ gridTemplateColumns: "repeat(".concat(columns, ", var(--gantt-column-width))"),
240
+ } }, Array.from({ length: columns }).map(function (_, index) { return (react_1.default.createElement("div", { className: "shrink-0 border-border/50 border-b py-1 text-center text-xs", key: "".concat(id, "-").concat(index) }, renderHeaderItem(index))); }))));
241
+ };
242
+ exports.GanttContentHeader = GanttContentHeader;
243
+ var DailyHeader = function () {
244
+ var gantt = (0, react_1.useContext)(GanttContext);
245
+ return gantt.timelineData.map(function (year) {
246
+ return year.quarters
247
+ .flatMap(function (quarter) { return quarter.months; })
248
+ .map(function (month, index) { return (react_1.default.createElement("div", { className: "relative flex flex-col", key: "".concat(year.year, "-").concat(index) },
249
+ react_1.default.createElement(exports.GanttContentHeader, { columns: month.days, renderHeaderItem: function (item) { return (react_1.default.createElement("div", { className: "flex items-center justify-center gap-1" },
250
+ react_1.default.createElement("p", null, (0, date_fns_1.format)((0, date_fns_1.addDays)(new Date(year.year, index, 1), item), "d")),
251
+ react_1.default.createElement("p", { className: "text-muted-foreground" }, (0, date_fns_1.format)((0, date_fns_1.addDays)(new Date(year.year, index, 1), item), "EEEEE")))); }, title: (0, date_fns_1.format)(new Date(year.year, index, 1), "MMMM yyyy") }),
252
+ react_1.default.createElement(exports.GanttColumns, { columns: month.days, isColumnSecondary: function (item) {
253
+ return [0, 6].includes((0, date_fns_1.addDays)(new Date(year.year, index, 1), item).getDay());
254
+ } }))); });
255
+ });
256
+ };
257
+ var MonthlyHeader = function () {
258
+ var gantt = (0, react_1.useContext)(GanttContext);
259
+ return gantt.timelineData.map(function (year) { return (react_1.default.createElement("div", { className: "relative flex flex-col", key: year.year },
260
+ react_1.default.createElement(exports.GanttContentHeader, { columns: year.quarters.flatMap(function (quarter) { return quarter.months; }).length, renderHeaderItem: function (item) { return (react_1.default.createElement("p", null, (0, date_fns_1.format)(new Date(year.year, item, 1), "MMM"))); }, title: "".concat(year.year) }),
261
+ react_1.default.createElement(exports.GanttColumns, { columns: year.quarters.flatMap(function (quarter) { return quarter.months; }).length }))); });
262
+ };
263
+ var QuarterlyHeader = function () {
264
+ var gantt = (0, react_1.useContext)(GanttContext);
265
+ return gantt.timelineData.map(function (year) {
266
+ return year.quarters.map(function (quarter, quarterIndex) { return (react_1.default.createElement("div", { className: "relative flex flex-col", key: "".concat(year.year, "-").concat(quarterIndex) },
267
+ react_1.default.createElement(exports.GanttContentHeader, { columns: quarter.months.length, renderHeaderItem: function (item) { return (react_1.default.createElement("p", null, (0, date_fns_1.format)(new Date(year.year, quarterIndex * 3 + item, 1), "MMM"))); }, title: "Q".concat(quarterIndex + 1, " ").concat(year.year) }),
268
+ react_1.default.createElement(exports.GanttColumns, { columns: quarter.months.length }))); });
269
+ });
270
+ };
271
+ var headers = {
272
+ daily: DailyHeader,
273
+ monthly: MonthlyHeader,
274
+ quarterly: QuarterlyHeader,
275
+ };
276
+ var GanttHeader = function (_a) {
277
+ var className = _a.className;
278
+ var gantt = (0, react_1.useContext)(GanttContext);
279
+ var Header = headers[gantt.range];
280
+ return (react_1.default.createElement("div", { className: (0, utils_1.cn)("-space-x-px flex h-full w-max divide-x divide-border/50", className) },
281
+ react_1.default.createElement(Header, null)));
282
+ };
283
+ exports.GanttHeader = GanttHeader;
284
+ var GanttSidebarItem = function (_a) {
285
+ var feature = _a.feature, onSelectItem = _a.onSelectItem, className = _a.className;
286
+ var gantt = (0, react_1.useContext)(GanttContext);
287
+ var tempEndAt = feature.endAt && (0, date_fns_1.isSameDay)(feature.startAt, feature.endAt)
288
+ ? (0, date_fns_1.addDays)(feature.endAt, 1)
289
+ : feature.endAt;
290
+ var duration = tempEndAt
291
+ ? (0, date_fns_1.formatDistance)(feature.startAt, tempEndAt)
292
+ : "".concat((0, date_fns_1.formatDistance)(feature.startAt, new Date()), " so far");
293
+ var handleClick = function (event) {
294
+ var _a;
295
+ if (event.target === event.currentTarget) {
296
+ // Scroll to the feature in the timeline
297
+ (_a = gantt.scrollToFeature) === null || _a === void 0 ? void 0 : _a.call(gantt, feature);
298
+ // Call the original onSelectItem callback
299
+ onSelectItem === null || onSelectItem === void 0 ? void 0 : onSelectItem(feature.id);
300
+ }
301
+ };
302
+ var handleKeyDown = function (event) {
303
+ var _a;
304
+ if (event.key === "Enter") {
305
+ // Scroll to the feature in the timeline
306
+ (_a = gantt.scrollToFeature) === null || _a === void 0 ? void 0 : _a.call(gantt, feature);
307
+ // Call the original onSelectItem callback
308
+ onSelectItem === null || onSelectItem === void 0 ? void 0 : onSelectItem(feature.id);
309
+ }
310
+ };
311
+ return (react_1.default.createElement("div", { className: (0, utils_1.cn)("relative flex items-center gap-2.5 p-2.5 text-xs hover:bg-secondary", className), key: feature.id, onClick: handleClick, onKeyDown: handleKeyDown,
312
+ // biome-ignore lint/a11y/useSemanticElements: "This is a clickable item"
313
+ role: "button", style: {
314
+ height: "var(--gantt-row-height)",
315
+ }, tabIndex: 0 },
316
+ react_1.default.createElement("div", { className: "pointer-events-none h-2 w-2 shrink-0 rounded-full", style: {
317
+ backgroundColor: feature.status.color,
318
+ } }),
319
+ react_1.default.createElement("p", { className: "pointer-events-none flex-1 truncate text-left font-medium" }, feature.name),
320
+ react_1.default.createElement("p", { className: "pointer-events-none text-muted-foreground" }, duration)));
321
+ };
322
+ exports.GanttSidebarItem = GanttSidebarItem;
323
+ var GanttSidebarHeader = function () { return (react_1.default.createElement("div", { className: "sticky top-0 z-10 flex shrink-0 items-end justify-between gap-2.5 border-border/50 border-b bg-backdrop/90 p-2.5 font-medium text-muted-foreground text-xs backdrop-blur-sm", style: { height: "var(--gantt-header-height)" } },
324
+ react_1.default.createElement("p", { className: "flex-1 truncate text-left" }, "Issues"),
325
+ react_1.default.createElement("p", { className: "shrink-0" }, "Duration"))); };
326
+ exports.GanttSidebarHeader = GanttSidebarHeader;
327
+ var GanttSidebarGroup = function (_a) {
328
+ var children = _a.children, name = _a.name, className = _a.className;
329
+ return (react_1.default.createElement("div", { className: className },
330
+ react_1.default.createElement("p", { className: "w-full truncate p-2.5 text-left font-medium text-muted-foreground text-xs", style: { height: "var(--gantt-row-height)" } }, name),
331
+ react_1.default.createElement("div", { className: "divide-y divide-border/50" }, children)));
332
+ };
333
+ exports.GanttSidebarGroup = GanttSidebarGroup;
334
+ var GanttSidebar = function (_a) {
335
+ var children = _a.children, className = _a.className;
336
+ return (react_1.default.createElement("div", { className: (0, utils_1.cn)("sticky left-0 z-30 h-max min-h-full overflow-clip border-border/50 border-r bg-background/90 backdrop-blur-md", className), "data-roadmap-ui": "gantt-sidebar" },
337
+ react_1.default.createElement(exports.GanttSidebarHeader, null),
338
+ react_1.default.createElement("div", { className: "space-y-4" }, children)));
339
+ };
340
+ exports.GanttSidebar = GanttSidebar;
341
+ var GanttAddFeatureHelper = function (_a) {
342
+ var top = _a.top, className = _a.className;
343
+ var scrollX = (0, exports.useGanttScrollX)()[0];
344
+ var gantt = (0, react_1.useContext)(GanttContext);
345
+ var _b = (0, usehooks_1.useMouse)(), mousePosition = _b[0], mouseRef = _b[1];
346
+ var handleClick = function () {
347
+ var _a, _b, _c, _d;
348
+ var ganttRect = (_b = (_a = gantt.ref) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect();
349
+ var x = mousePosition.x - ((_c = ganttRect === null || ganttRect === void 0 ? void 0 : ganttRect.left) !== null && _c !== void 0 ? _c : 0) + scrollX - gantt.sidebarWidth;
350
+ var currentDate = getDateByMousePosition(gantt, x);
351
+ (_d = gantt.onAddItem) === null || _d === void 0 ? void 0 : _d.call(gantt, currentDate);
352
+ };
353
+ return (react_1.default.createElement("div", { className: (0, utils_1.cn)("absolute top-0 w-full px-0.5", className), ref: mouseRef, style: {
354
+ marginTop: -gantt.rowHeight / 2,
355
+ transform: "translateY(".concat(top, "px)"),
356
+ } },
357
+ react_1.default.createElement("button", { className: "flex h-full w-full items-center justify-center rounded-md border border-dashed p-2", onClick: handleClick, type: "button" },
358
+ react_1.default.createElement(lucide_react_1.PlusIcon, { className: "pointer-events-none select-none text-muted-foreground", size: 16 }))));
359
+ };
360
+ exports.GanttAddFeatureHelper = GanttAddFeatureHelper;
361
+ var GanttColumn = function (_a) {
362
+ var _b, _c, _d;
363
+ var index = _a.index, isColumnSecondary = _a.isColumnSecondary;
364
+ var gantt = (0, react_1.useContext)(GanttContext);
365
+ var dragging = (0, exports.useGanttDragging)()[0];
366
+ var _e = (0, usehooks_1.useMouse)(), mousePosition = _e[0], mouseRef = _e[1];
367
+ var _f = (0, react_1.useState)(false), hovering = _f[0], setHovering = _f[1];
368
+ var windowScroll = (0, usehooks_1.useWindowScroll)()[0];
369
+ var handleMouseEnter = function () { return setHovering(true); };
370
+ var handleMouseLeave = function () { return setHovering(false); };
371
+ var top = (0, usehooks_1.useThrottle)(mousePosition.y -
372
+ ((_c = (_b = mouseRef.current) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect().y) !== null && _c !== void 0 ? _c : 0) -
373
+ ((_d = windowScroll.y) !== null && _d !== void 0 ? _d : 0), 10);
374
+ return (
375
+ // biome-ignore lint/a11y/noStaticElementInteractions: "This is a clickable column"
376
+ // biome-ignore lint/nursery/noNoninteractiveElementInteractions: "This is a clickable column"
377
+ react_1.default.createElement("div", { className: (0, utils_1.cn)("group relative h-full overflow-hidden", (isColumnSecondary === null || isColumnSecondary === void 0 ? void 0 : isColumnSecondary(index)) ? "bg-secondary" : ""), onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, ref: mouseRef }, !dragging && hovering && gantt.onAddItem ? (react_1.default.createElement(exports.GanttAddFeatureHelper, { top: top })) : null));
378
+ };
379
+ exports.GanttColumn = GanttColumn;
380
+ var GanttColumns = function (_a) {
381
+ var columns = _a.columns, isColumnSecondary = _a.isColumnSecondary;
382
+ var id = (0, react_1.useId)();
383
+ return (react_1.default.createElement("div", { className: "divide grid h-full w-full divide-x divide-border/50", style: {
384
+ gridTemplateColumns: "repeat(".concat(columns, ", var(--gantt-column-width))"),
385
+ } }, Array.from({ length: columns }).map(function (_, index) { return (react_1.default.createElement(exports.GanttColumn, { index: index, isColumnSecondary: isColumnSecondary, key: "".concat(id, "-").concat(index) })); })));
386
+ };
387
+ exports.GanttColumns = GanttColumns;
388
+ var GanttCreateMarkerTrigger = function (_a) {
389
+ var _b, _c, _d;
390
+ var onCreateMarker = _a.onCreateMarker, className = _a.className;
391
+ var gantt = (0, react_1.useContext)(GanttContext);
392
+ var _e = (0, usehooks_1.useMouse)(), mousePosition = _e[0], mouseRef = _e[1];
393
+ var windowScroll = (0, usehooks_1.useWindowScroll)()[0];
394
+ var x = (0, usehooks_1.useThrottle)(mousePosition.x -
395
+ ((_c = (_b = mouseRef.current) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect().x) !== null && _c !== void 0 ? _c : 0) -
396
+ ((_d = windowScroll.x) !== null && _d !== void 0 ? _d : 0), 10);
397
+ var date = getDateByMousePosition(gantt, x);
398
+ var handleClick = function () { return onCreateMarker(date); };
399
+ return (react_1.default.createElement("div", { className: (0, utils_1.cn)("group pointer-events-none absolute top-0 left-0 h-full w-full select-none overflow-visible", className), ref: mouseRef },
400
+ react_1.default.createElement("div", { className: "-ml-2 pointer-events-auto sticky top-6 z-20 flex w-4 flex-col items-center justify-center gap-1 overflow-visible opacity-0 group-hover:opacity-100", style: { transform: "translateX(".concat(x, "px)") } },
401
+ react_1.default.createElement("button", { className: "z-50 inline-flex h-4 w-4 items-center justify-center rounded-full bg-card", onClick: handleClick, type: "button" },
402
+ react_1.default.createElement(lucide_react_1.PlusIcon, { className: "text-muted-foreground", size: 12 })),
403
+ react_1.default.createElement("div", { className: "whitespace-nowrap rounded-full border border-border/50 bg-background/90 px-2 py-1 text-foreground text-xs backdrop-blur-lg" }, (0, date_fns_1.formatDate)(date, "MMM dd, yyyy")))));
404
+ };
405
+ exports.GanttCreateMarkerTrigger = GanttCreateMarkerTrigger;
406
+ var GanttFeatureDragHelper = function (_a) {
407
+ var direction = _a.direction, featureId = _a.featureId, date = _a.date;
408
+ var _b = (0, exports.useGanttDragging)(), setDragging = _b[1];
409
+ var _c = (0, core_1.useDraggable)({
410
+ id: "feature-drag-helper-".concat(featureId),
411
+ }), attributes = _c.attributes, listeners = _c.listeners, setNodeRef = _c.setNodeRef;
412
+ var isPressed = Boolean(attributes["aria-pressed"]);
413
+ (0, react_1.useEffect)(function () { return setDragging(isPressed); }, [isPressed, setDragging]);
414
+ return (react_1.default.createElement("div", __assign({ className: (0, utils_1.cn)("group -translate-y-1/2 !cursor-col-resize absolute top-1/2 z-[3] h-full w-6 rounded-md outline-none", direction === "left" ? "-left-2.5" : "-right-2.5"), ref: setNodeRef }, attributes, listeners),
415
+ react_1.default.createElement("div", { className: (0, utils_1.cn)("-translate-y-1/2 absolute top-1/2 h-[80%] w-1 rounded-sm bg-muted-foreground opacity-0 transition-all", direction === "left" ? "left-2.5" : "right-2.5", direction === "left" ? "group-hover:left-0" : "group-hover:right-0", isPressed && (direction === "left" ? "left-0" : "right-0"), "group-hover:opacity-100", isPressed && "opacity-100") }),
416
+ date && (react_1.default.createElement("div", { className: (0, utils_1.cn)("-translate-x-1/2 absolute top-10 hidden whitespace-nowrap rounded-lg border border-border/50 bg-background/90 px-2 py-1 text-foreground text-xs backdrop-blur-lg group-hover:block", isPressed && "block") }, (0, date_fns_1.format)(date, "MMM dd, yyyy")))));
417
+ };
418
+ exports.GanttFeatureDragHelper = GanttFeatureDragHelper;
419
+ var GanttFeatureItemCard = function (_a) {
420
+ var id = _a.id, children = _a.children;
421
+ var _b = (0, exports.useGanttDragging)(), setDragging = _b[1];
422
+ var _c = (0, core_1.useDraggable)({ id: id }), attributes = _c.attributes, listeners = _c.listeners, setNodeRef = _c.setNodeRef;
423
+ var isPressed = Boolean(attributes["aria-pressed"]);
424
+ (0, react_1.useEffect)(function () { return setDragging(isPressed); }, [isPressed, setDragging]);
425
+ return (react_1.default.createElement(card_1.Card, { className: "h-full w-full rounded-md bg-background p-2 text-xs shadow-sm" },
426
+ react_1.default.createElement("div", __assign({ className: (0, utils_1.cn)("flex h-full w-full items-center justify-between gap-2 text-left", isPressed && "cursor-grabbing") }, attributes, listeners, { ref: setNodeRef }), children)));
427
+ };
428
+ exports.GanttFeatureItemCard = GanttFeatureItemCard;
429
+ var GanttFeatureItem = function (_a) {
430
+ var onMove = _a.onMove, children = _a.children, className = _a.className, feature = __rest(_a, ["onMove", "children", "className"]);
431
+ var scrollX = (0, exports.useGanttScrollX)()[0];
432
+ var gantt = (0, react_1.useContext)(GanttContext);
433
+ var timelineStartDate = (0, react_1.useMemo)(function () { var _a, _b; return new Date((_b = (_a = gantt.timelineData.at(0)) === null || _a === void 0 ? void 0 : _a.year) !== null && _b !== void 0 ? _b : 0, 0, 1); }, [gantt.timelineData]);
434
+ var _b = (0, react_1.useState)(feature.startAt), startAt = _b[0], setStartAt = _b[1];
435
+ var _c = (0, react_1.useState)(feature.endAt), endAt = _c[0], setEndAt = _c[1];
436
+ // Memoize expensive calculations
437
+ var width = (0, react_1.useMemo)(function () { return getWidth(startAt, endAt, gantt); }, [startAt, endAt, gantt]);
438
+ var offset = (0, react_1.useMemo)(function () { return getOffset(startAt, timelineStartDate, gantt); }, [startAt, timelineStartDate, gantt]);
439
+ var addRange = (0, react_1.useMemo)(function () { return getAddRange(gantt.range); }, [gantt.range]);
440
+ var mousePosition = (0, usehooks_1.useMouse)()[0];
441
+ var _d = (0, react_1.useState)(0), previousMouseX = _d[0], setPreviousMouseX = _d[1];
442
+ var _e = (0, react_1.useState)(startAt), previousStartAt = _e[0], setPreviousStartAt = _e[1];
443
+ var _f = (0, react_1.useState)(endAt), previousEndAt = _f[0], setPreviousEndAt = _f[1];
444
+ var mouseSensor = (0, core_1.useSensor)(core_1.MouseSensor, {
445
+ activationConstraint: {
446
+ distance: 10,
447
+ },
448
+ });
449
+ var handleItemDragStart = (0, react_1.useCallback)(function () {
450
+ setPreviousMouseX(mousePosition.x);
451
+ setPreviousStartAt(startAt);
452
+ setPreviousEndAt(endAt);
453
+ }, [mousePosition.x, startAt, endAt]);
454
+ var handleItemDragMove = (0, react_1.useCallback)(function () {
455
+ var currentDate = getDateByMousePosition(gantt, mousePosition.x);
456
+ var originalDate = getDateByMousePosition(gantt, previousMouseX);
457
+ var delta = gantt.range === "daily"
458
+ ? getDifferenceIn(gantt.range)(currentDate, originalDate)
459
+ : getInnerDifferenceIn(gantt.range)(currentDate, originalDate);
460
+ var newStartDate = (0, date_fns_1.addDays)(previousStartAt, delta);
461
+ var newEndDate = previousEndAt ? (0, date_fns_1.addDays)(previousEndAt, delta) : null;
462
+ setStartAt(newStartDate);
463
+ setEndAt(newEndDate);
464
+ }, [gantt, mousePosition.x, previousMouseX, previousStartAt, previousEndAt]);
465
+ var onDragEnd = (0, react_1.useCallback)(function () { return onMove === null || onMove === void 0 ? void 0 : onMove(feature.id, startAt, endAt); }, [onMove, feature.id, startAt, endAt]);
466
+ var handleLeftDragMove = (0, react_1.useCallback)(function () {
467
+ var _a, _b, _c;
468
+ var ganttRect = (_b = (_a = gantt.ref) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect();
469
+ var x = mousePosition.x - ((_c = ganttRect === null || ganttRect === void 0 ? void 0 : ganttRect.left) !== null && _c !== void 0 ? _c : 0) + scrollX - gantt.sidebarWidth;
470
+ var newStartAt = getDateByMousePosition(gantt, x);
471
+ setStartAt(newStartAt);
472
+ }, [gantt, mousePosition.x, scrollX]);
473
+ var handleRightDragMove = (0, react_1.useCallback)(function () {
474
+ var _a, _b, _c;
475
+ var ganttRect = (_b = (_a = gantt.ref) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect();
476
+ var x = mousePosition.x - ((_c = ganttRect === null || ganttRect === void 0 ? void 0 : ganttRect.left) !== null && _c !== void 0 ? _c : 0) + scrollX - gantt.sidebarWidth;
477
+ var newEndAt = getDateByMousePosition(gantt, x);
478
+ setEndAt(newEndAt);
479
+ }, [gantt, mousePosition.x, scrollX]);
480
+ return (react_1.default.createElement("div", { className: (0, utils_1.cn)("relative flex w-max min-w-full py-0.5", className), style: { height: "var(--gantt-row-height)" } },
481
+ react_1.default.createElement("div", { className: "pointer-events-auto absolute top-0.5", style: {
482
+ height: "calc(var(--gantt-row-height) - 4px)",
483
+ width: Math.round(width),
484
+ left: Math.round(offset),
485
+ } },
486
+ onMove && (react_1.default.createElement(core_1.DndContext, { modifiers: [modifiers_1.restrictToHorizontalAxis], onDragEnd: onDragEnd, onDragMove: handleLeftDragMove, sensors: [mouseSensor] },
487
+ react_1.default.createElement(exports.GanttFeatureDragHelper, { date: startAt, direction: "left", featureId: feature.id }))),
488
+ react_1.default.createElement(core_1.DndContext, { modifiers: [modifiers_1.restrictToHorizontalAxis], onDragEnd: onDragEnd, onDragMove: handleItemDragMove, onDragStart: handleItemDragStart, sensors: [mouseSensor] },
489
+ react_1.default.createElement(exports.GanttFeatureItemCard, { id: feature.id }, children !== null && children !== void 0 ? children : (react_1.default.createElement("p", { className: "flex-1 truncate text-xs" }, feature.name)))),
490
+ onMove && (react_1.default.createElement(core_1.DndContext, { modifiers: [modifiers_1.restrictToHorizontalAxis], onDragEnd: onDragEnd, onDragMove: handleRightDragMove, sensors: [mouseSensor] },
491
+ react_1.default.createElement(exports.GanttFeatureDragHelper, { date: endAt !== null && endAt !== void 0 ? endAt : addRange(startAt, 2), direction: "right", featureId: feature.id }))))));
492
+ };
493
+ exports.GanttFeatureItem = GanttFeatureItem;
494
+ var GanttFeatureListGroup = function (_a) {
495
+ var children = _a.children, className = _a.className;
496
+ return (react_1.default.createElement("div", { className: className, style: { paddingTop: "var(--gantt-row-height)" } }, children));
497
+ };
498
+ exports.GanttFeatureListGroup = GanttFeatureListGroup;
499
+ var GanttFeatureRow = function (_a) {
500
+ var features = _a.features, onMove = _a.onMove, children = _a.children, className = _a.className;
501
+ // Sort features by start date to handle potential overlaps
502
+ var sortedFeatures = __spreadArray([], features, true).sort(function (a, b) { return a.startAt.getTime() - b.startAt.getTime(); });
503
+ // Calculate sub-row positions for overlapping features using a proper algorithm
504
+ var featureWithPositions = [];
505
+ var subRowEndTimes = []; // Track when each sub-row becomes free
506
+ for (var _i = 0, sortedFeatures_1 = sortedFeatures; _i < sortedFeatures_1.length; _i++) {
507
+ var feature = sortedFeatures_1[_i];
508
+ var subRow = 0;
509
+ // Find the first sub-row that's free (doesn't overlap)
510
+ while (subRow < subRowEndTimes.length &&
511
+ subRowEndTimes[subRow] > feature.startAt) {
512
+ subRow++;
513
+ }
514
+ // Update the end time for this sub-row
515
+ if (subRow === subRowEndTimes.length) {
516
+ subRowEndTimes.push(feature.endAt);
517
+ }
518
+ else {
519
+ subRowEndTimes[subRow] = feature.endAt;
520
+ }
521
+ featureWithPositions.push(__assign(__assign({}, feature), { subRow: subRow }));
522
+ }
523
+ var maxSubRows = Math.max(1, subRowEndTimes.length);
524
+ var subRowHeight = 36; // Base row height
525
+ return (react_1.default.createElement("div", { className: (0, utils_1.cn)("relative", className), style: {
526
+ height: "".concat(maxSubRows * subRowHeight, "px"),
527
+ minHeight: "var(--gantt-row-height)",
528
+ } }, featureWithPositions.map(function (feature) { return (react_1.default.createElement("div", { key: feature.id, className: "absolute w-full", style: {
529
+ top: "".concat(feature.subRow * subRowHeight, "px"),
530
+ height: "".concat(subRowHeight, "px"),
531
+ } },
532
+ react_1.default.createElement(exports.GanttFeatureItem, __assign({}, feature, { onMove: onMove }), children ? (children(feature)) : (react_1.default.createElement("p", { className: "flex-1 truncate text-xs" }, feature.name))))); })));
533
+ };
534
+ exports.GanttFeatureRow = GanttFeatureRow;
535
+ var GanttFeatureList = function (_a) {
536
+ var className = _a.className, children = _a.children;
537
+ return (react_1.default.createElement("div", { className: (0, utils_1.cn)("absolute top-0 left-0 h-full w-max space-y-4", className), style: { marginTop: "var(--gantt-header-height)" } }, children));
538
+ };
539
+ exports.GanttFeatureList = GanttFeatureList;
540
+ exports.GanttMarker = (0, react_1.memo)(function (_a) {
541
+ var label = _a.label, date = _a.date, id = _a.id, onRemove = _a.onRemove, className = _a.className;
542
+ var gantt = (0, react_1.useContext)(GanttContext);
543
+ var differenceIn = (0, react_1.useMemo)(function () { return getDifferenceIn(gantt.range); }, [gantt.range]);
544
+ var timelineStartDate = (0, react_1.useMemo)(function () { var _a, _b; return new Date((_b = (_a = gantt.timelineData.at(0)) === null || _a === void 0 ? void 0 : _a.year) !== null && _b !== void 0 ? _b : 0, 0, 1); }, [gantt.timelineData]);
545
+ // Memoize expensive calculations
546
+ var offset = (0, react_1.useMemo)(function () { return differenceIn(date, timelineStartDate); }, [differenceIn, date, timelineStartDate]);
547
+ var innerOffset = (0, react_1.useMemo)(function () {
548
+ return calculateInnerOffset(date, gantt.range, (gantt.columnWidth * gantt.zoom) / 100);
549
+ }, [date, gantt.range, gantt.columnWidth, gantt.zoom]);
550
+ var handleRemove = (0, react_1.useCallback)(function () { return onRemove === null || onRemove === void 0 ? void 0 : onRemove(id); }, [onRemove, id]);
551
+ return (react_1.default.createElement("div", { className: "pointer-events-none absolute top-0 left-0 z-20 flex h-full select-none flex-col items-center justify-center overflow-visible", style: {
552
+ width: 0,
553
+ transform: "translateX(calc(var(--gantt-column-width) * ".concat(offset, " + ").concat(innerOffset, "px))"),
554
+ } },
555
+ react_1.default.createElement(context_menu_1.ContextMenu, null,
556
+ react_1.default.createElement(context_menu_1.ContextMenuTrigger, { asChild: true },
557
+ react_1.default.createElement("div", { className: (0, utils_1.cn)("group pointer-events-auto sticky top-0 flex select-auto flex-col flex-nowrap items-center justify-center whitespace-nowrap rounded-b-md bg-card px-2 py-1 text-foreground text-xs", className) },
558
+ label,
559
+ react_1.default.createElement("span", { className: "max-h-[0] overflow-hidden opacity-80 transition-all group-hover:max-h-[2rem]" }, (0, date_fns_1.formatDate)(date, "MMM dd, yyyy")))),
560
+ react_1.default.createElement(context_menu_1.ContextMenuContent, null, onRemove ? (react_1.default.createElement(context_menu_1.ContextMenuItem, { className: "flex items-center gap-2 text-destructive", onClick: handleRemove },
561
+ react_1.default.createElement(lucide_react_1.TrashIcon, { size: 16 }),
562
+ "Remove marker")) : null)),
563
+ react_1.default.createElement("div", { className: (0, utils_1.cn)("h-full w-px bg-card", className) })));
564
+ });
565
+ exports.GanttMarker.displayName = "GanttMarker";
566
+ var GanttProvider = function (_a) {
567
+ var _b = _a.zoom, zoom = _b === void 0 ? 100 : _b, _c = _a.range, range = _c === void 0 ? "monthly" : _c, onAddItem = _a.onAddItem, children = _a.children, className = _a.className;
568
+ var scrollRef = (0, react_1.useRef)(null);
569
+ var _d = (0, react_1.useState)(createInitialTimelineData(new Date())), timelineData = _d[0], setTimelineData = _d[1];
570
+ var _e = (0, exports.useGanttScrollX)(), setScrollX = _e[1];
571
+ var _f = (0, react_1.useState)(0), sidebarWidth = _f[0], setSidebarWidth = _f[1];
572
+ var headerHeight = 60;
573
+ var rowHeight = 36;
574
+ var columnWidth = 50;
575
+ if (range === "monthly") {
576
+ columnWidth = 150;
577
+ }
578
+ else if (range === "quarterly") {
579
+ columnWidth = 100;
580
+ }
581
+ // Memoize CSS variables to prevent unnecessary re-renders
582
+ var cssVariables = (0, react_1.useMemo)(function () {
583
+ return ({
584
+ "--gantt-zoom": "".concat(zoom),
585
+ "--gantt-column-width": "".concat((zoom / 100) * columnWidth, "px"),
586
+ "--gantt-header-height": "".concat(headerHeight, "px"),
587
+ "--gantt-row-height": "".concat(rowHeight, "px"),
588
+ "--gantt-sidebar-width": "".concat(sidebarWidth, "px"),
589
+ });
590
+ }, [zoom, columnWidth, sidebarWidth]);
591
+ (0, react_1.useEffect)(function () {
592
+ if (scrollRef.current) {
593
+ scrollRef.current.scrollLeft =
594
+ scrollRef.current.scrollWidth / 2 - scrollRef.current.clientWidth / 2;
595
+ setScrollX(scrollRef.current.scrollLeft);
596
+ }
597
+ }, [setScrollX]);
598
+ // Update sidebar width when DOM is ready
599
+ (0, react_1.useEffect)(function () {
600
+ var updateSidebarWidth = function () {
601
+ var _a;
602
+ var sidebarElement = (_a = scrollRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('[data-roadmap-ui="gantt-sidebar"]');
603
+ var newWidth = sidebarElement ? 300 : 0;
604
+ setSidebarWidth(newWidth);
605
+ };
606
+ // Update immediately
607
+ updateSidebarWidth();
608
+ // Also update on resize or when children change
609
+ var observer = new MutationObserver(updateSidebarWidth);
610
+ if (scrollRef.current) {
611
+ observer.observe(scrollRef.current, {
612
+ childList: true,
613
+ subtree: true,
614
+ });
615
+ }
616
+ return function () {
617
+ observer.disconnect();
618
+ };
619
+ }, []);
620
+ // eslint-disable-next-line react-hooks/exhaustive-deps
621
+ var handleScroll = (0, react_1.useCallback)((0, lodash_throttle_1.default)(function () {
622
+ var _a, _b;
623
+ var scrollElement = scrollRef.current;
624
+ if (!scrollElement) {
625
+ return;
626
+ }
627
+ var scrollLeft = scrollElement.scrollLeft, scrollWidth = scrollElement.scrollWidth, clientWidth = scrollElement.clientWidth;
628
+ setScrollX(scrollLeft);
629
+ if (scrollLeft === 0) {
630
+ // Extend timelineData to the past
631
+ var firstYear_1 = (_a = timelineData[0]) === null || _a === void 0 ? void 0 : _a.year;
632
+ if (!firstYear_1) {
633
+ return;
634
+ }
635
+ var newTimelineData = __spreadArray([], timelineData, true);
636
+ newTimelineData.unshift({
637
+ year: firstYear_1 - 1,
638
+ quarters: new Array(4).fill(null).map(function (_, quarterIndex) { return ({
639
+ months: new Array(3).fill(null).map(function (_, monthIndex) {
640
+ var month = quarterIndex * 3 + monthIndex;
641
+ return {
642
+ days: (0, date_fns_1.getDaysInMonth)(new Date(firstYear_1, month, 1)),
643
+ };
644
+ }),
645
+ }); }),
646
+ });
647
+ setTimelineData(newTimelineData);
648
+ // Scroll a bit forward so it's not at the very start
649
+ scrollElement.scrollLeft = scrollElement.clientWidth;
650
+ setScrollX(scrollElement.scrollLeft);
651
+ }
652
+ else if (scrollLeft + clientWidth >= scrollWidth) {
653
+ // Extend timelineData to the future
654
+ var lastYear_1 = (_b = timelineData.at(-1)) === null || _b === void 0 ? void 0 : _b.year;
655
+ if (!lastYear_1) {
656
+ return;
657
+ }
658
+ var newTimelineData = __spreadArray([], timelineData, true);
659
+ newTimelineData.push({
660
+ year: lastYear_1 + 1,
661
+ quarters: new Array(4).fill(null).map(function (_, quarterIndex) { return ({
662
+ months: new Array(3).fill(null).map(function (_, monthIndex) {
663
+ var month = quarterIndex * 3 + monthIndex;
664
+ return {
665
+ days: (0, date_fns_1.getDaysInMonth)(new Date(lastYear_1, month, 1)),
666
+ };
667
+ }),
668
+ }); }),
669
+ });
670
+ setTimelineData(newTimelineData);
671
+ // Scroll a bit back so it's not at the very end
672
+ scrollElement.scrollLeft =
673
+ scrollElement.scrollWidth - scrollElement.clientWidth;
674
+ setScrollX(scrollElement.scrollLeft);
675
+ }
676
+ }, 100), []);
677
+ (0, react_1.useEffect)(function () {
678
+ var scrollElement = scrollRef.current;
679
+ if (scrollElement) {
680
+ scrollElement.addEventListener("scroll", handleScroll);
681
+ }
682
+ return function () {
683
+ // Fix memory leak by properly referencing the scroll element
684
+ if (scrollElement) {
685
+ scrollElement.removeEventListener("scroll", handleScroll);
686
+ }
687
+ };
688
+ }, [handleScroll]);
689
+ var scrollToFeature = (0, react_1.useCallback)(function (feature) {
690
+ var scrollElement = scrollRef.current;
691
+ if (!scrollElement) {
692
+ return;
693
+ }
694
+ // Calculate timeline start date from timelineData
695
+ var timelineStartDate = new Date(timelineData[0].year, 0, 1);
696
+ // Calculate the horizontal offset for the feature's start date
697
+ var offset = getOffset(feature.startAt, timelineStartDate, {
698
+ zoom: zoom,
699
+ range: range,
700
+ columnWidth: columnWidth,
701
+ sidebarWidth: sidebarWidth,
702
+ headerHeight: headerHeight,
703
+ rowHeight: rowHeight,
704
+ onAddItem: onAddItem,
705
+ placeholderLength: 2,
706
+ timelineData: timelineData,
707
+ ref: scrollRef,
708
+ });
709
+ // Scroll to align the feature's start with the right side of the sidebar
710
+ var targetScrollLeft = Math.max(0, offset);
711
+ scrollElement.scrollTo({
712
+ left: targetScrollLeft,
713
+ behavior: "smooth",
714
+ });
715
+ }, [
716
+ timelineData,
717
+ zoom,
718
+ range,
719
+ columnWidth,
720
+ sidebarWidth,
721
+ headerHeight,
722
+ rowHeight,
723
+ onAddItem,
724
+ ]);
725
+ return (react_1.default.createElement(GanttContext.Provider, { value: {
726
+ zoom: zoom,
727
+ range: range,
728
+ headerHeight: headerHeight,
729
+ columnWidth: columnWidth,
730
+ sidebarWidth: sidebarWidth,
731
+ rowHeight: rowHeight,
732
+ onAddItem: onAddItem,
733
+ timelineData: timelineData,
734
+ placeholderLength: 2,
735
+ ref: scrollRef,
736
+ scrollToFeature: scrollToFeature,
737
+ } },
738
+ react_1.default.createElement("div", { className: (0, utils_1.cn)("gantt relative grid h-full w-full flex-none select-none overflow-auto rounded-sm bg-secondary", range, className), ref: scrollRef, style: __assign(__assign({}, cssVariables), { gridTemplateColumns: "var(--gantt-sidebar-width) 1fr" }) }, children)));
739
+ };
740
+ exports.GanttProvider = GanttProvider;
741
+ var GanttTimeline = function (_a) {
742
+ var children = _a.children, className = _a.className;
743
+ return (react_1.default.createElement("div", { className: (0, utils_1.cn)("relative flex h-full w-max flex-none overflow-clip", className) }, children));
744
+ };
745
+ exports.GanttTimeline = GanttTimeline;
746
+ var GanttToday = function (_a) {
747
+ var className = _a.className;
748
+ var label = "Today";
749
+ var date = (0, react_1.useMemo)(function () { return new Date(); }, []);
750
+ var gantt = (0, react_1.useContext)(GanttContext);
751
+ var differenceIn = (0, react_1.useMemo)(function () { return getDifferenceIn(gantt.range); }, [gantt.range]);
752
+ var timelineStartDate = (0, react_1.useMemo)(function () { var _a, _b; return new Date((_b = (_a = gantt.timelineData.at(0)) === null || _a === void 0 ? void 0 : _a.year) !== null && _b !== void 0 ? _b : 0, 0, 1); }, [gantt.timelineData]);
753
+ // Memoize expensive calculations
754
+ var offset = (0, react_1.useMemo)(function () { return differenceIn(date, timelineStartDate); }, [differenceIn, date, timelineStartDate]);
755
+ var innerOffset = (0, react_1.useMemo)(function () {
756
+ return calculateInnerOffset(date, gantt.range, (gantt.columnWidth * gantt.zoom) / 100);
757
+ }, [date, gantt.range, gantt.columnWidth, gantt.zoom]);
758
+ return (react_1.default.createElement("div", { className: "pointer-events-none absolute top-0 left-0 z-20 flex h-full select-none flex-col items-center justify-center overflow-visible", style: {
759
+ width: 0,
760
+ transform: "translateX(calc(var(--gantt-column-width) * ".concat(offset, " + ").concat(innerOffset, "px))"),
761
+ } },
762
+ react_1.default.createElement("div", { className: (0, utils_1.cn)("group pointer-events-auto sticky top-0 flex select-auto flex-col flex-nowrap items-center justify-center whitespace-nowrap rounded-b-md bg-card px-2 py-1 text-foreground text-xs", className) },
763
+ label,
764
+ react_1.default.createElement("span", { className: "max-h-[0] overflow-hidden opacity-80 transition-all group-hover:max-h-[2rem]" }, (0, date_fns_1.formatDate)(date, "MMM dd, yyyy"))),
765
+ react_1.default.createElement("div", { className: (0, utils_1.cn)("h-full w-px bg-card", className) })));
766
+ };
767
+ exports.GanttToday = GanttToday;