@appcorp/shadcn 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/app-sidebar.js +16 -23
- package/components/audio.js +11 -19
- package/components/dashboard.js +27 -65
- package/components/drawer-generic.js +20 -28
- package/components/enhanced-checkbox.js +10 -57
- package/components/enhanced-combobox.js +99 -143
- package/components/enhanced-drawer-footer.js +22 -31
- package/components/enhanced-drawer-header.js +6 -14
- package/components/enhanced-dropzone-impl.d.ts +32 -0
- package/components/enhanced-dropzone-impl.js +218 -0
- package/components/enhanced-dropzone.d.ts +2 -63
- package/components/enhanced-dropzone.js +6 -294
- package/components/enhanced-input.js +10 -57
- package/components/enhanced-label.js +6 -52
- package/components/enhanced-radio.js +12 -20
- package/components/enhanced-select.js +13 -61
- package/components/enhanced-slider.js +11 -58
- package/components/enhanced-switch.js +11 -58
- package/components/enhanced-table-footer-action.js +11 -19
- package/components/enhanced-table-footer-page.js +16 -24
- package/components/enhanced-table-footer-pagination.js +11 -21
- package/components/enhanced-table-header-action.js +22 -30
- package/components/enhanced-table-header-search.js +9 -17
- package/components/enhanced-table.js +125 -153
- package/components/enhanced-textarea.js +10 -57
- package/components/field.d.ts +1 -1
- package/components/field.js +31 -88
- package/components/image-resize-dialog.js +61 -159
- package/components/nav-main.js +32 -78
- package/components/nav-projects.js +37 -48
- package/components/nav-user.js +41 -51
- package/components/show-toast.js +5 -9
- package/components/sidebar.d.ts +1 -1
- package/components/sidebar.js +115 -184
- package/components/team-switcher.js +36 -47
- package/components/theme-provider.js +36 -84
- package/components/timeline.js +12 -20
- package/components/tooltip.js +10 -59
- package/components/ui/accordion.js +17 -67
- package/components/ui/alert-dialog.js +32 -89
- package/components/ui/alert.d.ts +1 -1
- package/components/ui/alert.js +14 -63
- package/components/ui/area-chart-v1-impl.d.ts +19 -0
- package/components/ui/area-chart-v1-impl.js +75 -0
- package/components/ui/area-chart-v1.d.ts +2 -19
- package/components/ui/area-chart-v1.js +4 -113
- package/components/ui/aspect-ratio.js +3 -39
- package/components/ui/avatar.js +13 -62
- package/components/ui/badge.d.ts +2 -2
- package/components/ui/badge.js +7 -55
- package/components/ui/breadcrumb.js +27 -80
- package/components/ui/button.d.ts +2 -2
- package/components/ui/button.js +10 -58
- package/components/ui/calendar-impl.d.ts +8 -0
- package/components/ui/calendar-impl.js +55 -0
- package/components/ui/calendar.d.ts +2 -8
- package/components/ui/calendar.js +5 -108
- package/components/ui/card.js +21 -73
- package/components/ui/carousel-impl.d.ts +18 -0
- package/components/ui/carousel-impl.js +117 -0
- package/components/ui/carousel.d.ts +6 -18
- package/components/ui/carousel.js +8 -170
- package/components/ui/chart-impl.d.ts +62 -0
- package/components/ui/chart-impl.js +162 -0
- package/components/ui/chart.d.ts +7 -62
- package/components/ui/chart.js +9 -219
- package/components/ui/checkbox.js +10 -57
- package/components/ui/collapsible.js +5 -43
- package/components/ui/combobox.js +22 -58
- package/components/ui/command-impl.d.ts +80 -0
- package/components/ui/command-impl.js +63 -0
- package/components/ui/command.d.ts +9 -80
- package/components/ui/command.js +12 -117
- package/components/ui/context-menu.js +41 -102
- package/components/ui/dialog.js +28 -84
- package/components/ui/drawer-impl.d.ts +22 -0
- package/components/ui/drawer-impl.js +56 -0
- package/components/ui/drawer.d.ts +10 -22
- package/components/ui/drawer.js +13 -111
- package/components/ui/dropdown-menu.js +41 -102
- package/components/ui/form.d.ts +4 -2
- package/components/ui/form.js +41 -95
- package/components/ui/hover-card.js +9 -58
- package/components/ui/input-otp-impl.d.ts +34 -0
- package/components/ui/input-otp-impl.js +43 -0
- package/components/ui/input-otp.d.ts +4 -34
- package/components/ui/input-otp.js +7 -92
- package/components/ui/input.js +6 -53
- package/components/ui/label.d.ts +1 -1
- package/components/ui/label.js +9 -56
- package/components/ui/language-selector.js +17 -55
- package/components/ui/menubar.js +46 -108
- package/components/ui/navigation-menu.d.ts +1 -1
- package/components/ui/navigation-menu.js +29 -84
- package/components/ui/pagination.js +30 -83
- package/components/ui/popover.js +10 -60
- package/components/ui/progress.js +8 -55
- package/components/ui/radio-group.js +12 -60
- package/components/ui/resizable-impl.d.ts +24 -0
- package/components/ui/resizable-impl.js +27 -0
- package/components/ui/resizable.d.ts +3 -24
- package/components/ui/resizable.js +6 -78
- package/components/ui/scroll-area.js +10 -58
- package/components/ui/select.js +34 -90
- package/components/ui/separator.js +7 -54
- package/components/ui/sheet.d.ts +1 -1
- package/components/ui/sheet.js +30 -86
- package/components/ui/skeleton.js +5 -21
- package/components/ui/slider.js +10 -57
- package/components/ui/sonner.js +7 -24
- package/components/ui/switch.js +8 -55
- package/components/ui/table.js +27 -81
- package/components/ui/tabs.js +14 -64
- package/components/ui/textarea.js +6 -53
- package/components/ui/theme-switcher.js +41 -91
- package/components/ui/toggle.d.ts +2 -2
- package/components/ui/toggle.js +9 -57
- package/data/admin-dashboard.js +16 -19
- package/hooks/use-enhanced-combobox.js +47 -124
- package/hooks/use-mobile.js +8 -44
- package/hooks/use-outside-click.js +6 -10
- package/lib/themes.js +1 -4
- package/lib/toast-utils.js +78 -120
- package/lib/utils.js +4 -11
- package/package.json +9 -90
- package/utils/transform-breadcrumbs.js +4 -8
- package/utils/transform-navitems.js +7 -22
- package/components/aceternity-ui/apple-cards-carousel.d.ts +0 -35
- package/components/aceternity-ui/apple-cards-carousel.js +0 -263
- package/components/shadcn-example/ai-chat/chat-interface.d.ts +0 -11
- package/components/shadcn-example/ai-chat/chat-interface.js +0 -70
- package/components/shadcn-example/ai-chat/index.d.ts +0 -38
- package/components/shadcn-example/ai-chat/index.js +0 -66
- package/components/shadcn-example/ai-chat/sidebar.d.ts +0 -15
- package/components/shadcn-example/ai-chat/sidebar.js +0 -68
- package/components/shadcn-example/ai-chat/welcome-section.d.ts +0 -12
- package/components/shadcn-example/ai-chat/welcome-section.js +0 -26
- package/components/shadcn-example/authentication/index.d.ts +0 -24
- package/components/shadcn-example/authentication/index.js +0 -59
- package/components/shadcn-example/authentication/user-auth-form.d.ts +0 -11
- package/components/shadcn-example/authentication/user-auth-form.js +0 -54
- package/components/shadcn-example/blog-detail-page/comment-section.d.ts +0 -15
- package/components/shadcn-example/blog-detail-page/comment-section.js +0 -83
- package/components/shadcn-example/blog-detail-page/content.d.ts +0 -7
- package/components/shadcn-example/blog-detail-page/content.js +0 -15
- package/components/shadcn-example/blog-detail-page/header.d.ts +0 -11
- package/components/shadcn-example/blog-detail-page/header.js +0 -36
- package/components/shadcn-example/blog-detail-page/index.d.ts +0 -25
- package/components/shadcn-example/blog-detail-page/index.js +0 -74
- package/components/shadcn-example/blog-page/blog-post-card.d.ts +0 -13
- package/components/shadcn-example/blog-page/blog-post-card.js +0 -30
- package/components/shadcn-example/blog-page/featured-post-sidebar-item.d.ts +0 -10
- package/components/shadcn-example/blog-page/featured-post-sidebar-item.js +0 -19
- package/components/shadcn-example/blog-page/index.d.ts +0 -20
- package/components/shadcn-example/blog-page/index.js +0 -36
- package/components/shadcn-example/coming-soon/countdown.d.ts +0 -2
- package/components/shadcn-example/coming-soon/countdown.js +0 -82
- package/components/shadcn-example/coming-soon/index.d.ts +0 -10
- package/components/shadcn-example/coming-soon/index.js +0 -41
- package/components/shadcn-io/color-picker/index.d.ts +0 -43
- package/components/shadcn-io/color-picker/index.js +0 -304
- package/components/shadcn-io/copy-button/index.d.ts +0 -16
- package/components/shadcn-io/copy-button/index.js +0 -121
- package/components/shadcn-io/dropzone/index.d.ts +0 -19
- package/components/shadcn-io/dropzone/index.js +0 -131
- package/components/shadcn-io/gantt/index.d.ts +0 -145
- package/components/shadcn-io/gantt/index.js +0 -766
- package/components/shadcn-io/table/index.d.ts +0 -60
- package/components/shadcn-io/table/index.js +0 -138
- package/templates/appcorp-v1/footer/bottom-bar.d.ts +0 -6
- package/templates/appcorp-v1/footer/bottom-bar.js +0 -25
- package/templates/appcorp-v1/footer/cta.d.ts +0 -6
- package/templates/appcorp-v1/footer/cta.js +0 -21
- package/templates/appcorp-v1/footer/footer-grid.d.ts +0 -14
- package/templates/appcorp-v1/footer/footer-grid.js +0 -52
- package/templates/appcorp-v1/footer/index.d.ts +0 -3
- package/templates/appcorp-v1/footer/index.js +0 -28
- package/templates/appcorp-v1/footer/newsletter.d.ts +0 -11
- package/templates/appcorp-v1/footer/newsletter.js +0 -28
- package/templates/appcorp-v1/footer/stats.d.ts +0 -6
- package/templates/appcorp-v1/footer/stats.js +0 -15
- package/templates/appcorp-v1/header/announcement-bar.d.ts +0 -3
- package/templates/appcorp-v1/header/announcement-bar.js +0 -15
- package/templates/appcorp-v1/header/dropdown-panel.d.ts +0 -8
- package/templates/appcorp-v1/header/dropdown-panel.js +0 -72
- package/templates/appcorp-v1/header/index.d.ts +0 -12
- package/templates/appcorp-v1/header/index.js +0 -16
- package/templates/appcorp-v1/header/mobile-menu.d.ts +0 -14
- package/templates/appcorp-v1/header/mobile-menu.js +0 -101
- package/templates/appcorp-v1/header/navigation-bar.d.ts +0 -3
- package/templates/appcorp-v1/header/navigation-bar.js +0 -117
- package/templates/appcorp-v1/header/social-button.d.ts +0 -7
- package/templates/appcorp-v1/header/social-button.js +0 -48
- package/templates/appcorp-v1/home.d.ts +0 -3
- package/templates/appcorp-v1/home.js +0 -27
- package/templates/data/appcorp-v1.d.ts +0 -93
- package/templates/data/appcorp-v1.js +0 -348
- package/templates/data/edupilotpro-v1.d.ts +0 -33
- package/templates/data/edupilotpro-v1.js +0 -116
- package/templates/data/school-v1.d.ts +0 -328
- package/templates/data/school-v1.js +0 -1563
- package/templates/edupilotpro-v1/feature-card.d.ts +0 -13
- package/templates/edupilotpro-v1/feature-card.js +0 -28
- package/templates/edupilotpro-v1/mockups/dashboard-mockup.d.ts +0 -3
- package/templates/edupilotpro-v1/mockups/dashboard-mockup.js +0 -55
- package/templates/school-v1/footer.d.ts +0 -3
- package/templates/school-v1/footer.js +0 -75
- package/templates/school-v1/index.d.ts +0 -18
- package/templates/school-v1/index.js +0 -60
- package/templates/school-v1/navigation.d.ts +0 -3
- package/templates/school-v1/navigation.js +0 -123
- package/templates/school-v1/sections/about.d.ts +0 -3
- package/templates/school-v1/sections/about.js +0 -49
- package/templates/school-v1/sections/admissions.d.ts +0 -3
- package/templates/school-v1/sections/admissions.js +0 -77
- package/templates/school-v1/sections/contact.d.ts +0 -3
- package/templates/school-v1/sections/contact.js +0 -67
- package/templates/school-v1/sections/faqs.d.ts +0 -3
- package/templates/school-v1/sections/faqs.js +0 -50
- package/templates/school-v1/sections/hero.d.ts +0 -3
- package/templates/school-v1/sections/hero.js +0 -132
- package/templates/school-v1/sections/management.d.ts +0 -3
- package/templates/school-v1/sections/management.js +0 -34
- package/templates/school-v1/sections/policies.d.ts +0 -3
- package/templates/school-v1/sections/policies.js +0 -127
- package/templates/school-v1/sections/programs.d.ts +0 -3
- package/templates/school-v1/sections/programs.js +0 -107
- package/templates/school-v1/sections/testimonials.d.ts +0 -3
- package/templates/school-v1/sections/testimonials.js +0 -46
- package/templates/school-v1/sections/why-choose-us.d.ts +0 -3
- package/templates/school-v1/sections/why-choose-us.js +0 -57
|
@@ -1,72 +1,33 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (k2 === undefined) k2 = k;
|
|
12
|
-
o[k2] = m[k];
|
|
13
|
-
}));
|
|
14
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
-
}) : function(o, v) {
|
|
17
|
-
o["default"] = v;
|
|
18
|
-
});
|
|
19
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
-
var ownKeys = function(o) {
|
|
21
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
-
var ar = [];
|
|
23
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
-
return ar;
|
|
25
|
-
};
|
|
26
|
-
return ownKeys(o);
|
|
27
|
-
};
|
|
28
|
-
return function (mod) {
|
|
29
|
-
if (mod && mod.__esModule) return mod;
|
|
30
|
-
var result = {};
|
|
31
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
-
__setModuleDefault(result, mod);
|
|
33
|
-
return result;
|
|
34
|
-
};
|
|
35
|
-
})();
|
|
36
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
-
exports.EnhancedCombobox = EnhancedCombobox;
|
|
38
|
-
exports.CompanyCombobox = CompanyCombobox;
|
|
39
|
-
exports.CountryCombobox = CountryCombobox;
|
|
40
|
-
var react_1 = __importStar(require("react"));
|
|
41
|
-
var lucide_react_1 = require("lucide-react");
|
|
42
|
-
var utils_1 = require("../lib/utils");
|
|
43
|
-
var button_1 = require("./ui/button");
|
|
44
|
-
var enhanced_label_1 = require("./enhanced-label");
|
|
45
|
-
var command_1 = require("./ui/command");
|
|
46
|
-
var popover_1 = require("./ui/popover");
|
|
47
|
-
function VirtualizedList(_a) {
|
|
48
|
-
var options = _a.options, selectedValue = _a.selectedValue, onSelect = _a.onSelect, scrollContainer = _a.scrollContainer, testIdOptionPrefix = _a.testIdOptionPrefix;
|
|
49
|
-
var _b = (0, react_1.useState)({
|
|
2
|
+
import React, { useState, useRef, useEffect, useCallback } from "react";
|
|
3
|
+
import { Check, ChevronsUpDown, ChevronUp, ChevronDown } from "lucide-react";
|
|
4
|
+
import { cn } from "../lib/utils";
|
|
5
|
+
import { Button } from "./ui/button";
|
|
6
|
+
import { EnhancedLabel } from "./enhanced-label";
|
|
7
|
+
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, } from "./ui/command";
|
|
8
|
+
import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover";
|
|
9
|
+
function VirtualizedList({ options, selectedValue, onSelect, scrollContainer, testIdOptionPrefix, }) {
|
|
10
|
+
const [visibleRange, setVisibleRange] = useState({
|
|
50
11
|
start: 0,
|
|
51
12
|
end: Math.min(options.length, 25), // Increased initial visible items
|
|
52
|
-
})
|
|
53
|
-
|
|
13
|
+
});
|
|
14
|
+
const handleScroll = useCallback(() => {
|
|
54
15
|
if (!scrollContainer.current)
|
|
55
16
|
return;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
17
|
+
const { scrollTop, clientHeight } = scrollContainer.current;
|
|
18
|
+
const itemHeight = 32; // Approximate item height
|
|
19
|
+
const containerHeight = clientHeight;
|
|
59
20
|
// Calculate visible range with proper bounds checking
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
21
|
+
const start = Math.max(0, Math.floor(scrollTop / itemHeight));
|
|
22
|
+
const visibleCount = Math.ceil(containerHeight / itemHeight);
|
|
23
|
+
const bufferSize = Math.min(10, Math.ceil(visibleCount * 0.5)); // Dynamic buffer
|
|
24
|
+
const end = Math.min(options.length, start + visibleCount + bufferSize);
|
|
25
|
+
const newRange = {
|
|
65
26
|
start: Math.max(0, start - bufferSize),
|
|
66
27
|
end: end,
|
|
67
28
|
};
|
|
68
29
|
// Only update if the range actually changed to prevent unnecessary re-renders
|
|
69
|
-
setVisibleRange(
|
|
30
|
+
setVisibleRange((prevRange) => {
|
|
70
31
|
if (prevRange.start !== newRange.start ||
|
|
71
32
|
prevRange.end !== newRange.end) {
|
|
72
33
|
return newRange;
|
|
@@ -74,36 +35,36 @@ function VirtualizedList(_a) {
|
|
|
74
35
|
return prevRange;
|
|
75
36
|
});
|
|
76
37
|
}, [options.length, scrollContainer]);
|
|
77
|
-
|
|
78
|
-
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const container = scrollContainer.current;
|
|
79
40
|
if (container) {
|
|
80
41
|
// Add scroll listener with passive option for better performance
|
|
81
42
|
container.addEventListener("scroll", handleScroll, { passive: true });
|
|
82
43
|
// Also listen to parent containers that might interfere (like drawer)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
while (
|
|
86
|
-
|
|
44
|
+
let parentContainer = container.parentElement;
|
|
45
|
+
const parentScrollHandler = () => handleScroll();
|
|
46
|
+
while (parentContainer) {
|
|
47
|
+
const hasOverflow = getComputedStyle(parentContainer).overflowY;
|
|
87
48
|
if (hasOverflow === "auto" || hasOverflow === "scroll") {
|
|
88
|
-
|
|
49
|
+
parentContainer.addEventListener("scroll", parentScrollHandler, {
|
|
89
50
|
passive: true,
|
|
90
51
|
});
|
|
91
52
|
break;
|
|
92
53
|
}
|
|
93
|
-
|
|
54
|
+
parentContainer = parentContainer.parentElement;
|
|
94
55
|
}
|
|
95
|
-
return
|
|
56
|
+
return () => {
|
|
96
57
|
container.removeEventListener("scroll", handleScroll);
|
|
97
|
-
if (
|
|
98
|
-
|
|
58
|
+
if (parentContainer) {
|
|
59
|
+
parentContainer.removeEventListener("scroll", parentScrollHandler);
|
|
99
60
|
}
|
|
100
61
|
};
|
|
101
62
|
}
|
|
102
63
|
}, [handleScroll, scrollContainer]);
|
|
103
64
|
// Reset visible range when options change (e.g., due to search filtering)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
setVisibleRange(
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
const newEnd = Math.min(options.length, 25);
|
|
67
|
+
setVisibleRange(() => {
|
|
107
68
|
// Force update if options changed
|
|
108
69
|
return {
|
|
109
70
|
start: 0,
|
|
@@ -116,29 +77,28 @@ function VirtualizedList(_a) {
|
|
|
116
77
|
}
|
|
117
78
|
}, [options.length, options, scrollContainer]); // Watch both length and options array
|
|
118
79
|
// Ensure we always have valid visible range
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
return (
|
|
125
|
-
topSpacer > 0 &&
|
|
126
|
-
visibleOptions.map(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
bottomSpacer > 0 &&
|
|
80
|
+
const safeStart = Math.max(0, Math.min(visibleRange.start, options.length - 1));
|
|
81
|
+
const safeEnd = Math.max(safeStart + 1, Math.min(visibleRange.end, options.length));
|
|
82
|
+
const visibleOptions = options.slice(safeStart, safeEnd);
|
|
83
|
+
const topSpacer = safeStart * 32; // Approximate item height
|
|
84
|
+
const bottomSpacer = Math.max(0, (options.length - safeEnd) * 32);
|
|
85
|
+
return (React.createElement(React.Fragment, null,
|
|
86
|
+
topSpacer > 0 && React.createElement("div", { style: { height: topSpacer } }),
|
|
87
|
+
visibleOptions.map((option, index) => (React.createElement(CommandItem, { key: `${option.value}-${safeStart + index}`, value: option.label, onSelect: () => onSelect(option.value), "data-testid": `${testIdOptionPrefix !== null && testIdOptionPrefix !== void 0 ? testIdOptionPrefix : "combobox-option"}-${option.value}`, className: "cursor-pointer hover:bg-accent hover:text-accent-foreground transition-colors h-8 flex items-center" },
|
|
88
|
+
React.createElement(Check, { className: cn("mr-2 h-4 w-4", selectedValue === option.value ? "opacity-100" : "opacity-0") }),
|
|
89
|
+
React.createElement("span", { className: "truncate" }, option.label)))),
|
|
90
|
+
bottomSpacer > 0 && React.createElement("div", { style: { height: bottomSpacer } })));
|
|
130
91
|
}
|
|
131
|
-
function EnhancedCombobox(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
var shouldVirtualize = options.length > virtualizeThreshold;
|
|
92
|
+
export function EnhancedCombobox({ className, disabled = false, emptyText = "No options found.", error, id, info, label, loading = false, maxHeight = 256, onSearchChange, onValueChange, options = [], placeholder = "Select option...", required = false, searchPlaceholder = "Search...", showScrollIndicators = true, value, virtualizeThreshold = 50, testIdTrigger, testIdSearchInput, testIdPopoverContent, testIdEmpty, testIdList, testIdOptionPrefix, testIdScrollUp, testIdScrollDown, }) {
|
|
93
|
+
const [open, setOpen] = useState(false);
|
|
94
|
+
const [searchValue, setSearchValue] = useState("");
|
|
95
|
+
const [canScrollUp, setCanScrollUp] = useState(false);
|
|
96
|
+
const [canScrollDown, setCanScrollDown] = useState(false);
|
|
97
|
+
const scrollContainerRef = useRef(null);
|
|
98
|
+
const selectedOption = options.find((option) => option.value === value);
|
|
99
|
+
const shouldVirtualize = options.length > virtualizeThreshold;
|
|
140
100
|
// Filter options based on search - always handle filtering at this level for virtualization
|
|
141
|
-
|
|
101
|
+
const filteredOptions = React.useMemo(() => {
|
|
142
102
|
if (!searchValue) {
|
|
143
103
|
// No search query, return all options
|
|
144
104
|
return options;
|
|
@@ -153,15 +113,13 @@ function EnhancedCombobox(_a) {
|
|
|
153
113
|
return options;
|
|
154
114
|
}
|
|
155
115
|
// Local filtering for non-external search or as fallback
|
|
156
|
-
return options.filter(
|
|
157
|
-
return option.label.toLowerCase().includes(searchValue.toLowerCase());
|
|
158
|
-
});
|
|
116
|
+
return options.filter((option) => option.label.toLowerCase().includes(searchValue.toLowerCase()));
|
|
159
117
|
}, [options, searchValue, onSearchChange, shouldVirtualize]);
|
|
160
|
-
|
|
118
|
+
const handleSearchChange = (search) => {
|
|
161
119
|
setSearchValue(search);
|
|
162
120
|
onSearchChange === null || onSearchChange === void 0 ? void 0 : onSearchChange(search);
|
|
163
121
|
};
|
|
164
|
-
|
|
122
|
+
const handleSelect = (selectedValue) => {
|
|
165
123
|
if (selectedValue === value) {
|
|
166
124
|
onValueChange("");
|
|
167
125
|
}
|
|
@@ -172,74 +130,73 @@ function EnhancedCombobox(_a) {
|
|
|
172
130
|
setSearchValue("");
|
|
173
131
|
};
|
|
174
132
|
// Handle scroll indicators
|
|
175
|
-
|
|
133
|
+
const updateScrollIndicators = () => {
|
|
176
134
|
if (!scrollContainerRef.current)
|
|
177
135
|
return;
|
|
178
|
-
|
|
136
|
+
const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current;
|
|
179
137
|
setCanScrollUp(scrollTop > 0);
|
|
180
138
|
setCanScrollDown(scrollTop < scrollHeight - clientHeight - 1);
|
|
181
139
|
};
|
|
182
140
|
// Update scroll indicators when options change or component opens
|
|
183
|
-
|
|
141
|
+
useEffect(() => {
|
|
184
142
|
if (open) {
|
|
185
143
|
// Small delay to ensure DOM is updated
|
|
186
144
|
setTimeout(updateScrollIndicators, 10);
|
|
187
145
|
}
|
|
188
146
|
}, [open, options]);
|
|
189
|
-
|
|
147
|
+
const scrollToTop = () => {
|
|
190
148
|
var _a;
|
|
191
149
|
(_a = scrollContainerRef.current) === null || _a === void 0 ? void 0 : _a.scrollTo({ top: 0, behavior: "smooth" });
|
|
192
150
|
};
|
|
193
|
-
|
|
151
|
+
const scrollToBottom = () => {
|
|
194
152
|
if (!scrollContainerRef.current)
|
|
195
153
|
return;
|
|
196
|
-
|
|
154
|
+
const { scrollHeight } = scrollContainerRef.current;
|
|
197
155
|
scrollContainerRef.current.scrollTo({
|
|
198
156
|
top: scrollHeight,
|
|
199
157
|
behavior: "smooth",
|
|
200
158
|
});
|
|
201
159
|
};
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
160
|
+
const comboboxElement = (React.createElement(Popover, { open: open, onOpenChange: setOpen, modal: true },
|
|
161
|
+
React.createElement(PopoverTrigger, { asChild: true },
|
|
162
|
+
React.createElement(Button, { id: id, "data-testid": testIdTrigger, variant: "outline", role: "combobox", "aria-expanded": open, disabled: disabled, className: cn("w-full justify-between", !selectedOption && "text-muted-foreground", className) },
|
|
205
163
|
(selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) || placeholder,
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
showScrollIndicators && canScrollUp && (
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
), style: { maxHeight:
|
|
164
|
+
React.createElement(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" }))),
|
|
165
|
+
React.createElement(PopoverContent, { "data-testid": testIdPopoverContent, className: "w-[var(--radix-popover-trigger-width)] p-0", side: "bottom", align: "start", avoidCollisions: true, collisionPadding: 8, style: { zIndex: 1000 }, onOpenAutoFocus: (e) => e.preventDefault() },
|
|
166
|
+
React.createElement(Command, { shouldFilter: false },
|
|
167
|
+
React.createElement(CommandInput, { "data-slot": "command-input", "data-testid": testIdSearchInput, placeholder: searchPlaceholder, value: searchValue, onValueChange: handleSearchChange }),
|
|
168
|
+
React.createElement(CommandEmpty, { "data-slot": "command-empty", "data-testid": testIdEmpty }, loading ? (React.createElement("div", { className: "flex items-center justify-center py-6" },
|
|
169
|
+
React.createElement("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2 border-primary" }),
|
|
170
|
+
React.createElement("span", { className: "ml-2 text-sm" }, "Searching..."))) : (emptyText)),
|
|
171
|
+
React.createElement("div", { className: "relative" },
|
|
172
|
+
showScrollIndicators && canScrollUp && (React.createElement("div", { className: "absolute top-0 left-0 right-0 z-10 h-8 bg-gradient-to-b from-background to-transparent pointer-events-none" },
|
|
173
|
+
React.createElement("button", { "data-testid": testIdScrollUp, onClick: scrollToTop, className: "absolute top-1 left-1/2 transform -translate-x-1/2 p-1 rounded-full bg-background shadow-sm border pointer-events-auto hover:bg-muted transition-colors", "aria-label": "Scroll to top" },
|
|
174
|
+
React.createElement(ChevronUp, { className: "h-3 w-3" })))),
|
|
175
|
+
React.createElement(CommandGroup, { "data-testid": testIdList, ref: scrollContainerRef, className: cn("overflow-y-auto smooth-scroll", "scrollbar-thin scrollbar-thumb-muted-foreground/20 scrollbar-track-transparent hover:scrollbar-thumb-muted-foreground/40", "scroll-smooth", filteredOptions.length > 10 && "pb-2" // Extra padding for many options
|
|
176
|
+
), style: { maxHeight: `${maxHeight}px` }, onScroll: updateScrollIndicators }, shouldVirtualize &&
|
|
219
177
|
filteredOptions.length > virtualizeThreshold ? (
|
|
220
178
|
// Virtualized rendering for large lists
|
|
221
|
-
|
|
179
|
+
React.createElement(VirtualizedList, { options: filteredOptions, selectedValue: value, onSelect: handleSelect, scrollContainer: scrollContainerRef, testIdOptionPrefix: testIdOptionPrefix })) : (
|
|
222
180
|
// Regular rendering for smaller lists or filtered results
|
|
223
|
-
filteredOptions.map(
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
showScrollIndicators && canScrollDown && (
|
|
227
|
-
|
|
228
|
-
|
|
181
|
+
filteredOptions.map((option) => (React.createElement(CommandItem, { key: option.value, value: option.label, onSelect: () => handleSelect(option.value), "data-testid": `${testIdOptionPrefix !== null && testIdOptionPrefix !== void 0 ? testIdOptionPrefix : "combobox-option"}-${option.value}`, className: "cursor-pointer hover:bg-accent hover:text-accent-foreground transition-colors" },
|
|
182
|
+
React.createElement(Check, { className: cn("mr-2 h-4 w-4", value === option.value ? "opacity-100" : "opacity-0") }),
|
|
183
|
+
React.createElement("span", { className: "truncate" }, option.label)))))),
|
|
184
|
+
showScrollIndicators && canScrollDown && (React.createElement("div", { className: "absolute bottom-0 left-0 right-0 z-10 h-8 bg-gradient-to-t from-background to-transparent pointer-events-none" },
|
|
185
|
+
React.createElement("button", { "data-testid": testIdScrollDown, onClick: scrollToBottom, className: "absolute bottom-1 left-1/2 transform -translate-x-1/2 p-1 rounded-full bg-background shadow-sm border pointer-events-auto hover:bg-muted transition-colors", "aria-label": "Scroll to bottom" },
|
|
186
|
+
React.createElement(ChevronDown, { className: "h-3 w-3" })))))))));
|
|
229
187
|
// If label is provided, render the complete combobox with label structure
|
|
230
188
|
if (label) {
|
|
231
|
-
return (
|
|
232
|
-
|
|
189
|
+
return (React.createElement("div", { className: "w-full space-y-2" },
|
|
190
|
+
React.createElement(EnhancedLabel, { htmlFor: id, required: required }, label),
|
|
233
191
|
comboboxElement,
|
|
234
|
-
error && (
|
|
235
|
-
info && !error && (
|
|
192
|
+
error && (React.createElement("p", { className: "text-xs text-destructive dark:text-red-400" }, error)),
|
|
193
|
+
info && !error && (React.createElement("p", { className: "text-xs text-blue-600 dark:text-blue-400" }, info))));
|
|
236
194
|
}
|
|
237
195
|
// If no label, render just the combobox (backward compatibility)
|
|
238
196
|
return comboboxElement;
|
|
239
197
|
}
|
|
240
|
-
function CompanyCombobox(
|
|
241
|
-
|
|
242
|
-
var options = companies.map(function (company) {
|
|
198
|
+
export function CompanyCombobox({ companies = [], value, onValueChange, onSearchChange, loading = false, placeholder = "Select company...", className, maxHeight = 320, showScrollIndicators = true, label, required = false, id, info, error, }) {
|
|
199
|
+
const options = companies.map((company) => {
|
|
243
200
|
var _a, _b;
|
|
244
201
|
return ({
|
|
245
202
|
value: ((_a = company.id) === null || _a === void 0 ? void 0 : _a.toString()) || "",
|
|
@@ -247,12 +204,11 @@ function CompanyCombobox(_a) {
|
|
|
247
204
|
id: (_b = company.id) === null || _b === void 0 ? void 0 : _b.toString(),
|
|
248
205
|
});
|
|
249
206
|
});
|
|
250
|
-
return (
|
|
207
|
+
return (React.createElement(EnhancedCombobox, { options: options, value: value, onValueChange: onValueChange, onSearchChange: onSearchChange, placeholder: placeholder, searchPlaceholder: "Search companies...", emptyText: "No companies found.", loading: loading, className: className, maxHeight: maxHeight, showScrollIndicators: showScrollIndicators, virtualizeThreshold: 100, label: label, required: required, id: id, info: info, error: error }));
|
|
251
208
|
}
|
|
252
|
-
function CountryCombobox(
|
|
253
|
-
var _b = _a.countries, countries = _b === void 0 ? [] : _b, value = _a.value, onValueChange = _a.onValueChange, onSearchChange = _a.onSearchChange, _c = _a.loading, loading = _c === void 0 ? false : _c, _d = _a.placeholder, placeholder = _d === void 0 ? "Select country..." : _d, className = _a.className, _e = _a.maxHeight, maxHeight = _e === void 0 ? 280 : _e, _f = _a.showScrollIndicators, showScrollIndicators = _f === void 0 ? true : _f, label = _a.label, _g = _a.required, required = _g === void 0 ? false : _g, id = _a.id, info = _a.info, error = _a.error;
|
|
209
|
+
export function CountryCombobox({ countries = [], value, onValueChange, onSearchChange, loading = false, placeholder = "Select country...", className, maxHeight = 280, showScrollIndicators = true, label, required = false, id, info, error, }) {
|
|
254
210
|
// Default countries if none provided or if provided list is empty
|
|
255
|
-
|
|
211
|
+
const defaultCountries = [
|
|
256
212
|
{ name: "Afghanistan", code: "AF" },
|
|
257
213
|
{ name: "Albania", code: "AL" },
|
|
258
214
|
{ name: "Algeria", code: "DZ" },
|
|
@@ -306,10 +262,10 @@ function CountryCombobox(_a) {
|
|
|
306
262
|
{ name: "United States", code: "US" },
|
|
307
263
|
{ name: "Vietnam", code: "VN" },
|
|
308
264
|
];
|
|
309
|
-
|
|
310
|
-
|
|
265
|
+
const countryList = countries.length > 0 ? countries : defaultCountries;
|
|
266
|
+
const options = countryList.map((country) => ({
|
|
311
267
|
value: country.name,
|
|
312
268
|
label: country.name,
|
|
313
|
-
})
|
|
314
|
-
return (
|
|
269
|
+
}));
|
|
270
|
+
return (React.createElement(EnhancedCombobox, { options: options, value: value, onValueChange: onValueChange, onSearchChange: onSearchChange, placeholder: placeholder, searchPlaceholder: "Search countries...", emptyText: "No countries found.", loading: loading, className: className, maxHeight: maxHeight, showScrollIndicators: showScrollIndicators, virtualizeThreshold: 30, label: label, required: required, id: id, info: info, error: error }));
|
|
315
271
|
}
|
|
@@ -1,39 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.EnhancedDrawerFooter = exports.DRAWER_FOOTER_COMPONENT_TYPE = void 0;
|
|
7
|
-
var button_1 = require("./ui/button");
|
|
8
|
-
var react_1 = __importDefault(require("react"));
|
|
9
|
-
var DRAWER_FOOTER_COMPONENT_TYPE;
|
|
1
|
+
import { Button } from "./ui/button";
|
|
2
|
+
import React from "react";
|
|
3
|
+
export var DRAWER_FOOTER_COMPONENT_TYPE;
|
|
10
4
|
(function (DRAWER_FOOTER_COMPONENT_TYPE) {
|
|
11
5
|
DRAWER_FOOTER_COMPONENT_TYPE["MORE_ACTIONS_DRAWER"] = "MORE_ACTIONS_DRAWER";
|
|
12
6
|
DRAWER_FOOTER_COMPONENT_TYPE["FILTER_DRAWER"] = "FILTER_DRAWER";
|
|
13
7
|
DRAWER_FOOTER_COMPONENT_TYPE["FORM_DRAWER"] = "FORM_DRAWER";
|
|
14
8
|
DRAWER_FOOTER_COMPONENT_TYPE["VIEW_DRAWER"] = "VIEW_DRAWER";
|
|
15
|
-
})(DRAWER_FOOTER_COMPONENT_TYPE || (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
react_1.default.createElement(button_1.Button, { className: "flex-1", onClick: closeDrawer, variant: "outline" }, "Cancel"),
|
|
30
|
-
react_1.default.createElement(button_1.Button, { className: "flex-1", onClick: handleSubmit, variant: "default", disabled: updateLoading ||
|
|
9
|
+
})(DRAWER_FOOTER_COMPONENT_TYPE || (DRAWER_FOOTER_COMPONENT_TYPE = {}));
|
|
10
|
+
export const EnhancedDrawerFooter = ({ applyFilters, clearFilters, closeDrawer, disableSaveButton, drawerType, errors, handleSubmit, updateLoading, }) => {
|
|
11
|
+
const componentMap = {
|
|
12
|
+
[DRAWER_FOOTER_COMPONENT_TYPE.MORE_ACTIONS_DRAWER]: (React.createElement(React.Fragment, null,
|
|
13
|
+
React.createElement("div", { className: "flex gap-2" },
|
|
14
|
+
React.createElement(Button, { className: "flex-1", onClick: clearFilters, variant: "outline" }, "Close")))),
|
|
15
|
+
[DRAWER_FOOTER_COMPONENT_TYPE.FILTER_DRAWER]: (React.createElement(React.Fragment, null,
|
|
16
|
+
React.createElement("div", { className: "flex gap-2" },
|
|
17
|
+
React.createElement(Button, { className: "flex-1", onClick: clearFilters, variant: "outline" }, "Clear All"),
|
|
18
|
+
React.createElement(Button, { className: "flex-1", onClick: applyFilters }, "Apply Filters")))),
|
|
19
|
+
[DRAWER_FOOTER_COMPONENT_TYPE.FORM_DRAWER]: (React.createElement(React.Fragment, null,
|
|
20
|
+
React.createElement("div", { className: "flex gap-2" },
|
|
21
|
+
React.createElement(Button, { className: "flex-1", onClick: closeDrawer, variant: "outline" }, "Cancel"),
|
|
22
|
+
React.createElement(Button, { className: "flex-1", onClick: handleSubmit, variant: "default", disabled: updateLoading ||
|
|
31
23
|
disableSaveButton ||
|
|
32
24
|
(errors && Object.keys(errors).length > 0) }, "Save")))),
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return
|
|
25
|
+
[DRAWER_FOOTER_COMPONENT_TYPE.VIEW_DRAWER]: (React.createElement(React.Fragment, null,
|
|
26
|
+
React.createElement("div", { className: "flex gap-2" },
|
|
27
|
+
React.createElement(Button, { className: "flex-1", onClick: closeDrawer }, "Close")))),
|
|
28
|
+
};
|
|
29
|
+
return React.createElement(React.Fragment, null, componentMap[drawerType]);
|
|
38
30
|
};
|
|
39
|
-
exports.EnhancedDrawerFooter = EnhancedDrawerFooter;
|
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { DrawerDescription, DrawerTitle } from "./ui/drawer";
|
|
2
|
+
import React from "react";
|
|
3
|
+
export const EnhancedDrawerHeader = ({ title, description, }) => {
|
|
4
|
+
return (React.createElement(React.Fragment, null,
|
|
5
|
+
React.createElement(DrawerTitle, null, title),
|
|
6
|
+
React.createElement(DrawerDescription, null, description)));
|
|
4
7
|
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.EnhancedDrawerHeader = void 0;
|
|
7
|
-
var drawer_1 = require("./ui/drawer");
|
|
8
|
-
var react_1 = __importDefault(require("react"));
|
|
9
|
-
var EnhancedDrawerHeader = function (_a) {
|
|
10
|
-
var title = _a.title, description = _a.description;
|
|
11
|
-
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
12
|
-
react_1.default.createElement(drawer_1.DrawerTitle, null, title),
|
|
13
|
-
react_1.default.createElement(drawer_1.DrawerDescription, null, description)));
|
|
14
|
-
};
|
|
15
|
-
exports.EnhancedDrawerHeader = EnhancedDrawerHeader;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { DropzoneOptions } from "react-dropzone";
|
|
3
|
+
export type EnhancedDropzoneProps = {
|
|
4
|
+
id?: string;
|
|
5
|
+
className?: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
info?: string;
|
|
8
|
+
error?: string;
|
|
9
|
+
accept?: DropzoneOptions["accept"] | string[];
|
|
10
|
+
maxFiles?: number;
|
|
11
|
+
maxSize?: number;
|
|
12
|
+
minSize?: number;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
value?: string[];
|
|
15
|
+
onChange?: (files: File[]) => void;
|
|
16
|
+
onRemoveRemote?: (url: string) => void;
|
|
17
|
+
resize?: boolean;
|
|
18
|
+
testIdDropzone?: string;
|
|
19
|
+
testIdInput?: string;
|
|
20
|
+
testIdPrev?: string;
|
|
21
|
+
testIdNext?: string;
|
|
22
|
+
testIdPreviewPrefix?: string;
|
|
23
|
+
testIdImagePrefix?: string;
|
|
24
|
+
testIdRemovePrefix?: string;
|
|
25
|
+
testIdCount?: string;
|
|
26
|
+
testIdEmptyIcon?: string;
|
|
27
|
+
testIdEmptyTitle?: string;
|
|
28
|
+
testIdEmptySubtitle?: string;
|
|
29
|
+
testIdEmptyNote?: string;
|
|
30
|
+
testIdMessage?: string;
|
|
31
|
+
};
|
|
32
|
+
export declare const EnhancedDropzone: React.FC<EnhancedDropzoneProps>;
|