ikoncomponents 1.1.8 → 1.1.9
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/dist/ikoncomponents/alert-dialog/dialog-context.d.ts +21 -0
- package/dist/ikoncomponents/alert-dialog/dialog-context.js +30 -0
- package/dist/ikoncomponents/app-breadcrumb/BreadcrumbProvider.d.ts +16 -0
- package/dist/ikoncomponents/app-breadcrumb/BreadcrumbProvider.js +32 -0
- package/dist/ikoncomponents/app-breadcrumb/index.d.ts +5 -0
- package/dist/ikoncomponents/app-breadcrumb/index.js +57 -0
- package/dist/ikoncomponents/form-fields/combobox-input/index.d.ts +2 -0
- package/dist/ikoncomponents/form-fields/combobox-input/index.js +21 -0
- package/dist/ikoncomponents/form-fields/combobox-input-value/index.d.ts +18 -0
- package/dist/ikoncomponents/form-fields/combobox-input-value/index.js +25 -0
- package/dist/ikoncomponents/form-fields/date-input/index.d.ts +2 -0
- package/dist/ikoncomponents/form-fields/date-input/index.js +15 -0
- package/dist/ikoncomponents/form-fields/file-input/index.d.ts +1 -0
- package/dist/ikoncomponents/form-fields/file-input/index.js +4 -0
- package/dist/ikoncomponents/form-fields/input/index.d.ts +2 -0
- package/dist/ikoncomponents/form-fields/input/index.js +18 -0
- package/dist/ikoncomponents/form-fields/multi-combobox-input/index.d.ts +6 -0
- package/dist/ikoncomponents/form-fields/multi-combobox-input/index.js +381 -0
- package/dist/ikoncomponents/form-fields/otp-input/index.d.ts +2 -0
- package/dist/ikoncomponents/form-fields/otp-input/index.js +18 -0
- package/dist/ikoncomponents/form-fields/phone-input/index.d.ts +1 -0
- package/dist/ikoncomponents/form-fields/phone-input/index.js +4 -0
- package/dist/ikoncomponents/form-fields/textarea/index.d.ts +2 -0
- package/dist/ikoncomponents/form-fields/textarea/index.js +18 -0
- package/dist/ikoncomponents/form-fields/types/index.d.ts +36 -0
- package/dist/ikoncomponents/form-fields/types/index.js +1 -0
- package/dist/ikoncomponents/main-layout/SidebarNavContext.d.ts +27 -0
- package/dist/ikoncomponents/main-layout/SidebarNavContext.js +40 -0
- package/dist/ikoncomponents/main-layout/app-sidebar.d.ts +3 -0
- package/dist/ikoncomponents/main-layout/app-sidebar.js +19 -0
- package/dist/ikoncomponents/main-layout/footer.d.ts +1 -0
- package/dist/ikoncomponents/main-layout/footer.js +4 -0
- package/dist/ikoncomponents/main-layout/header.d.ts +1 -0
- package/dist/ikoncomponents/main-layout/header.js +10 -0
- package/dist/ikoncomponents/main-layout/index.d.ts +5 -0
- package/dist/ikoncomponents/main-layout/index.js +11 -0
- package/dist/ikoncomponents/main-layout/main-sidebar.d.ts +27 -0
- package/dist/ikoncomponents/main-layout/main-sidebar.js +74 -0
- package/dist/ikoncomponents/main-layout/nav-main.d.ts +8 -0
- package/dist/ikoncomponents/main-layout/nav-main.js +31 -0
- package/dist/ikoncomponents/resource/index.d.ts +19 -0
- package/dist/ikoncomponents/resource/index.js +89 -0
- package/dist/ikoncomponents/skeleton-loader/skeleton-table.d.ts +5 -0
- package/dist/ikoncomponents/skeleton-loader/skeleton-table.js +6 -0
- package/dist/ikoncomponents/skeleton-loader/skeleton-widget.d.ts +3 -0
- package/dist/ikoncomponents/skeleton-loader/skeleton-widget.js +5 -0
- package/dist/ikoncomponents/theme-toggle-btn/index.d.ts +1 -1
- package/dist/ikoncomponents/theme-toggle-btn/index.js +112 -4
- package/dist/ikoncomponents/upload-tab/index.d.ts +1 -0
- package/dist/ikoncomponents/upload-tab/index.js +92 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +33 -0
- package/dist/shadcn/aspect-ratio.d.ts +3 -0
- package/dist/shadcn/aspect-ratio.js +19 -0
- package/dist/shadcn/breadcrumb.d.ts +11 -0
- package/dist/shadcn/breadcrumb.js +45 -0
- package/dist/shadcn/button.d.ts +1 -1
- package/dist/shadcn/button.js +3 -2
- package/dist/shadcn/collapsible.d.ts +5 -0
- package/dist/shadcn/collapsible.js +27 -0
- package/dist/shadcn/drawer.d.ts +13 -0
- package/dist/shadcn/drawer.js +56 -0
- package/dist/shadcn/form.d.ts +24 -0
- package/dist/shadcn/form.js +70 -0
- package/dist/shadcn/input-otp.d.ts +34 -0
- package/dist/shadcn/input-otp.js +40 -0
- package/dist/shadcn/radio-group.js +2 -4
- package/dist/shadcn/table.js +1 -1
- package/dist/shadcn/tabs.js +1 -1
- package/dist/shadcn/toggle-group.d.ts +9 -0
- package/dist/shadcn/toggle-group.js +35 -0
- package/dist/shadcn/toggle.d.ts +9 -0
- package/dist/shadcn/toggle.js +38 -0
- package/dist/shadcn/tooltip.js +2 -2
- package/dist/styles.css +534 -41
- package/dist/utils/border-radius-provider.d.ts +11 -0
- package/dist/utils/border-radius-provider.js +35 -0
- package/dist/utils/font-provider.d.ts +11 -0
- package/dist/utils/font-provider.js +37 -0
- package/dist/utils/session/cookieSession.d.ts +8 -0
- package/dist/utils/session/cookieSession.js +33 -0
- package/dist/utils/token-management/index.d.ts +7 -0
- package/dist/utils/token-management/index.js +78 -0
- package/dist/utils/token-management/types.d.ts +6 -0
- package/dist/utils/token-management/types.js +1 -0
- package/package.json +98 -91
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// import {
|
|
3
|
+
// FormControl,
|
|
4
|
+
// FormDescription,
|
|
5
|
+
// FormField,
|
|
6
|
+
// FormItem,
|
|
7
|
+
// FormLabel,
|
|
8
|
+
// FormMessage,
|
|
9
|
+
// } from "@/shadcn/ui/form";
|
|
10
|
+
// import React, { useState, useEffect, useRef, useCallback } from "react";
|
|
11
|
+
// // import { FormComboboxInputProps } from "@/ikon/components/form-fields/types";
|
|
12
|
+
// import { Popover, PopoverContent, PopoverTrigger } from "@/shadcn/ui/popover";
|
|
13
|
+
// import { Button } from "@/shadcn/ui/button";
|
|
14
|
+
// import { cn } from "@/shadcn/lib/utils";
|
|
15
|
+
// import { Check, ChevronsUpDown } from "lucide-react";
|
|
16
|
+
// import {
|
|
17
|
+
// Command,
|
|
18
|
+
// CommandEmpty,
|
|
19
|
+
// CommandGroup,
|
|
20
|
+
// CommandInput,
|
|
21
|
+
// CommandItem,
|
|
22
|
+
// CommandList,
|
|
23
|
+
// } from "@/shadcn/ui/command";
|
|
24
|
+
// import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/shadcn/ui/tooltip";
|
|
25
|
+
// import { X } from "lucide-react";
|
|
26
|
+
// import { FormComboboxInputProps as BaseFormComboboxInputProps } from "@/ikon/components/form-fields/types";
|
|
27
|
+
// interface FormComboboxInputProps extends BaseFormComboboxInputProps {
|
|
28
|
+
// defaultOptions?: number; // Add defaultOptions to the type
|
|
29
|
+
// }
|
|
30
|
+
// export default function dFormMultiComboboxInput({
|
|
31
|
+
// formControl,
|
|
32
|
+
// name,
|
|
33
|
+
// label,
|
|
34
|
+
// placeholder,
|
|
35
|
+
// formDescription,
|
|
36
|
+
// items = [], // fallback to empty array
|
|
37
|
+
// disabled,
|
|
38
|
+
// onSelect,
|
|
39
|
+
// defaultValue = [],
|
|
40
|
+
// defaultOptions = 2,
|
|
41
|
+
// }: FormComboboxInputProps) {
|
|
42
|
+
// const [search, setSearch] = useState("");
|
|
43
|
+
// const containerRef = useRef<HTMLDivElement>(null);
|
|
44
|
+
// // Filter items based on search
|
|
45
|
+
// const filteredItems = items.filter((item) =>
|
|
46
|
+
// item.label?.toLowerCase().includes(search.toLowerCase())
|
|
47
|
+
// )
|
|
48
|
+
// .sort((a, b) => (a?.label ?? "").localeCompare(b?.label ?? ""));
|
|
49
|
+
// return (
|
|
50
|
+
// <FormField
|
|
51
|
+
// control={formControl}
|
|
52
|
+
// name={name}
|
|
53
|
+
// render={({ field }) => {
|
|
54
|
+
// // Initialize defaultValue if field.value is undefined
|
|
55
|
+
// useEffect(() => {
|
|
56
|
+
// if (
|
|
57
|
+
// (field.value === undefined || field.value === null) &&
|
|
58
|
+
// defaultValue.length > 0
|
|
59
|
+
// ) {
|
|
60
|
+
// field.onChange(defaultValue);
|
|
61
|
+
// }
|
|
62
|
+
// }, [defaultValue, field]);
|
|
63
|
+
// // field.value is the selected array, default to [] if undefined
|
|
64
|
+
// const selectedItems = field.value || [];
|
|
65
|
+
// const [visibleCount, setVisibleCount] = useState(selectedItems.length);
|
|
66
|
+
// const calculateVisibleItems = useCallback(() => {
|
|
67
|
+
// const container = containerRef.current;
|
|
68
|
+
// if (!container) return visibleCount;
|
|
69
|
+
// const children = Array.from(container.children) as HTMLElement[];
|
|
70
|
+
// let availableWidth = container.offsetWidth;
|
|
71
|
+
// let usedWidth = 0;
|
|
72
|
+
// let fitCount = 0;
|
|
73
|
+
// for (const child of children) {
|
|
74
|
+
// const childWidth = child.offsetWidth + 4; // gap/margin
|
|
75
|
+
// if (usedWidth + childWidth <= availableWidth) {
|
|
76
|
+
// usedWidth += childWidth;
|
|
77
|
+
// fitCount++;
|
|
78
|
+
// } else {
|
|
79
|
+
// break;
|
|
80
|
+
// }
|
|
81
|
+
// }
|
|
82
|
+
// return fitCount;
|
|
83
|
+
// }, []); // No dependencies
|
|
84
|
+
// useEffect(() => {
|
|
85
|
+
// const container = containerRef.current;
|
|
86
|
+
// if (!container) return;
|
|
87
|
+
// let animationFrameId: number | null = null;
|
|
88
|
+
// const resizeObserver = new ResizeObserver(() => {
|
|
89
|
+
// if (animationFrameId) cancelAnimationFrame(animationFrameId);
|
|
90
|
+
// animationFrameId = requestAnimationFrame(() => {
|
|
91
|
+
// const newVisibleCount = calculateVisibleItems();
|
|
92
|
+
// setVisibleCount((prevVisibleCount: number) => {
|
|
93
|
+
// if (prevVisibleCount !== newVisibleCount) {
|
|
94
|
+
// return newVisibleCount;
|
|
95
|
+
// }
|
|
96
|
+
// return prevVisibleCount;
|
|
97
|
+
// });
|
|
98
|
+
// });
|
|
99
|
+
// });
|
|
100
|
+
// resizeObserver.observe(container);
|
|
101
|
+
// // Initial calculation
|
|
102
|
+
// setVisibleCount(calculateVisibleItems());
|
|
103
|
+
// // Cleanup
|
|
104
|
+
// return () => {
|
|
105
|
+
// if (animationFrameId) cancelAnimationFrame(animationFrameId);
|
|
106
|
+
// resizeObserver.disconnect();
|
|
107
|
+
// };
|
|
108
|
+
// }, [calculateVisibleItems]); // Only depend on calculateVisibleItems
|
|
109
|
+
// // Toggle select/unselect item
|
|
110
|
+
// const toggleItem = (value: string) => {
|
|
111
|
+
// let updatedItems;
|
|
112
|
+
// if (selectedItems.includes(value)) {
|
|
113
|
+
// updatedItems = selectedItems.filter((v: string) => v !== value);
|
|
114
|
+
// } else {
|
|
115
|
+
// updatedItems = [...selectedItems, value];
|
|
116
|
+
// }
|
|
117
|
+
// field.onChange(updatedItems);
|
|
118
|
+
// onSelect && onSelect(updatedItems);
|
|
119
|
+
// };
|
|
120
|
+
// const onWheel = (e: React.WheelEvent<HTMLDivElement>) => {
|
|
121
|
+
// const el = e.currentTarget;
|
|
122
|
+
// el.scrollTop += e.deltaY; // manually scroll
|
|
123
|
+
// e.preventDefault(); // prevent parent scroll
|
|
124
|
+
// };
|
|
125
|
+
// return (
|
|
126
|
+
// <FormItem>
|
|
127
|
+
// {label && <FormLabel>{label}</FormLabel>}
|
|
128
|
+
// <Popover>
|
|
129
|
+
// <PopoverTrigger asChild className="w-full">
|
|
130
|
+
// <FormControl>
|
|
131
|
+
// <Button
|
|
132
|
+
// variant="outline"
|
|
133
|
+
// role="combobox"
|
|
134
|
+
// className={cn(
|
|
135
|
+
// "justify-between",
|
|
136
|
+
// !selectedItems.length && "text-foreground/50"
|
|
137
|
+
// )}
|
|
138
|
+
// disabled={
|
|
139
|
+
// disabled === true || (disabled && disabled(...arguments))
|
|
140
|
+
// }
|
|
141
|
+
// >
|
|
142
|
+
// {selectedItems.length > 0 ? (
|
|
143
|
+
// <TooltipProvider>
|
|
144
|
+
// <div ref={containerRef} className="flex flex-wrap gap-2 items-center overflow-hidden">
|
|
145
|
+
// {selectedItems.slice(0, defaultOptions).map((value: string) => {
|
|
146
|
+
// const label = items.find((item) => item.value === value)?.label || value;
|
|
147
|
+
// return (
|
|
148
|
+
// <span
|
|
149
|
+
// key={value}
|
|
150
|
+
// className="flex items-center px-2 py-1 bg-secondary text-secondary-foreground rounded-md truncate max-w-full"
|
|
151
|
+
// title={label}
|
|
152
|
+
// >
|
|
153
|
+
// <span className="truncate max-w-[120px]">{label}</span>
|
|
154
|
+
// <span
|
|
155
|
+
// role="button"
|
|
156
|
+
// tabIndex={0}
|
|
157
|
+
// onClick={(e) => {
|
|
158
|
+
// e.stopPropagation(); // prevent popover toggle
|
|
159
|
+
// const updated = selectedItems.filter((v: string) => v !== value);
|
|
160
|
+
// field.onChange(updated);
|
|
161
|
+
// onSelect && onSelect(updated);
|
|
162
|
+
// }}
|
|
163
|
+
// onKeyDown={(e) => {
|
|
164
|
+
// if (e.key === 'Enter' || e.key === ' ') {
|
|
165
|
+
// e.preventDefault();
|
|
166
|
+
// e.stopPropagation();
|
|
167
|
+
// const updated = selectedItems.filter((v: string) => v !== value);
|
|
168
|
+
// field.onChange(updated);
|
|
169
|
+
// onSelect && onSelect(updated);
|
|
170
|
+
// }
|
|
171
|
+
// }}
|
|
172
|
+
// className="ml-1 text-muted-foreground hover:text-destructive cursor-pointer outline-none"
|
|
173
|
+
// >
|
|
174
|
+
// <X className="w-3 h-3 ml-1" />
|
|
175
|
+
// </span>
|
|
176
|
+
// </span>
|
|
177
|
+
// );
|
|
178
|
+
// })}
|
|
179
|
+
// {selectedItems.length > defaultOptions && (
|
|
180
|
+
// <Tooltip>
|
|
181
|
+
// <TooltipTrigger asChild>
|
|
182
|
+
// <span className="px-2 py-1 bg-secondary text-secondary-foreground rounded-md cursor-pointer">
|
|
183
|
+
// +{selectedItems.length - defaultOptions} more
|
|
184
|
+
// </span>
|
|
185
|
+
// </TooltipTrigger>
|
|
186
|
+
// <TooltipContent className="max-w-xs break-words">
|
|
187
|
+
// <div
|
|
188
|
+
// onWheel={onWheel}
|
|
189
|
+
// className="flex flex-col gap-1 max-h-[200px] overflow-auto"
|
|
190
|
+
// >
|
|
191
|
+
// {selectedItems.slice(defaultOptions).map((value: string) => (
|
|
192
|
+
// <span key={value} className="text-sm">
|
|
193
|
+
// {items.find((item) => item.value === value)?.label || value}
|
|
194
|
+
// </span>
|
|
195
|
+
// ))}
|
|
196
|
+
// </div>
|
|
197
|
+
// </TooltipContent>
|
|
198
|
+
// </Tooltip>
|
|
199
|
+
// )}
|
|
200
|
+
// </div>
|
|
201
|
+
// </TooltipProvider>
|
|
202
|
+
// ) : (
|
|
203
|
+
// placeholder
|
|
204
|
+
// )}
|
|
205
|
+
// <ChevronsUpDown className="opacity-50" />
|
|
206
|
+
// </Button>
|
|
207
|
+
// </FormControl>
|
|
208
|
+
// </PopoverTrigger>
|
|
209
|
+
// <PopoverContent id="multiSelectPopover" className="p-0 w-full max-w-[300px]" align="start">
|
|
210
|
+
// <Command id="commandPopover">
|
|
211
|
+
// <CommandInput
|
|
212
|
+
// placeholder="Search..."
|
|
213
|
+
// value={search}
|
|
214
|
+
// onValueChange={setSearch}
|
|
215
|
+
// autoFocus
|
|
216
|
+
// />
|
|
217
|
+
// <CommandList
|
|
218
|
+
// className="max-h-60 overflow-auto"
|
|
219
|
+
// onWheel={onWheel}
|
|
220
|
+
// >
|
|
221
|
+
// <CommandEmpty>No items found.</CommandEmpty>
|
|
222
|
+
// <CommandGroup>
|
|
223
|
+
// {filteredItems.map((item) => {
|
|
224
|
+
// const isSelected = selectedItems.includes(item.value);
|
|
225
|
+
// return (
|
|
226
|
+
// <CommandItem
|
|
227
|
+
// value={item.label ?? ""}
|
|
228
|
+
// key={item.value}
|
|
229
|
+
// onSelect={() => toggleItem(item.value)}
|
|
230
|
+
// >
|
|
231
|
+
// {item.label}
|
|
232
|
+
// <Check
|
|
233
|
+
// className={cn(
|
|
234
|
+
// "ml-auto",
|
|
235
|
+
// isSelected ? "opacity-100" : "opacity-0"
|
|
236
|
+
// )}
|
|
237
|
+
// />
|
|
238
|
+
// </CommandItem>
|
|
239
|
+
// );
|
|
240
|
+
// })}
|
|
241
|
+
// </CommandGroup>
|
|
242
|
+
// </CommandList>
|
|
243
|
+
// </Command>
|
|
244
|
+
// </PopoverContent>
|
|
245
|
+
// </Popover>
|
|
246
|
+
// {formDescription && (
|
|
247
|
+
// <FormDescription>{formDescription}</FormDescription>
|
|
248
|
+
// )}
|
|
249
|
+
// <FormMessage />
|
|
250
|
+
// </FormItem>
|
|
251
|
+
// );
|
|
252
|
+
// }}
|
|
253
|
+
// />
|
|
254
|
+
// );
|
|
255
|
+
// }
|
|
256
|
+
import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "../../../shadcn/form";
|
|
257
|
+
import { useState, useEffect, useRef, useCallback } from "react";
|
|
258
|
+
import { Popover, PopoverContent, PopoverTrigger } from "../../../shadcn/popover";
|
|
259
|
+
import { Button } from "../../../shadcn/button";
|
|
260
|
+
import { cn } from "../../../utils/cn";
|
|
261
|
+
import { ChevronsUpDown, X } from "lucide-react";
|
|
262
|
+
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "../../../shadcn/command";
|
|
263
|
+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../../../shadcn/tooltip";
|
|
264
|
+
import { Checkbox } from "../../../shadcn/checkbox";
|
|
265
|
+
export function dFormMultiComboboxInput({ formControl, name, label, placeholder, formDescription, items = [], disabled, onSelect, defaultValue = [], defaultOptions = 2, }) {
|
|
266
|
+
const [search, setSearch] = useState("");
|
|
267
|
+
const containerRef = useRef(null);
|
|
268
|
+
// Removed triggerRef and popoverWidth state, as we'll rely on CSS variables for sizing
|
|
269
|
+
// Filter items based on search
|
|
270
|
+
const filteredItems = items
|
|
271
|
+
.filter((item) => { var _a; return (_a = item.label) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes(search.toLowerCase()); })
|
|
272
|
+
.sort((a, b) => { var _a, _b; return ((_a = a === null || a === void 0 ? void 0 : a.label) !== null && _a !== void 0 ? _a : "").localeCompare((_b = b === null || b === void 0 ? void 0 : b.label) !== null && _b !== void 0 ? _b : ""); });
|
|
273
|
+
return (_jsx(FormField, { control: formControl, name: name, render: ({ field }) => {
|
|
274
|
+
useEffect(() => {
|
|
275
|
+
if ((field.value === undefined || field.value === null) &&
|
|
276
|
+
defaultValue.length > 0) {
|
|
277
|
+
field.onChange(defaultValue);
|
|
278
|
+
}
|
|
279
|
+
}, [defaultValue, field]);
|
|
280
|
+
const selectedItems = field.value || [];
|
|
281
|
+
const [visibleCount, setVisibleCount] = useState(selectedItems.length);
|
|
282
|
+
const calculateVisibleItems = useCallback(() => {
|
|
283
|
+
const container = containerRef.current;
|
|
284
|
+
if (!container)
|
|
285
|
+
return visibleCount;
|
|
286
|
+
const children = Array.from(container.children);
|
|
287
|
+
let availableWidth = container.offsetWidth;
|
|
288
|
+
let usedWidth = 0;
|
|
289
|
+
let fitCount = 0;
|
|
290
|
+
for (const child of children) {
|
|
291
|
+
const childWidth = child.offsetWidth + 4; // gap/margin
|
|
292
|
+
if (usedWidth + childWidth <= availableWidth) {
|
|
293
|
+
usedWidth += childWidth;
|
|
294
|
+
fitCount++;
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return fitCount;
|
|
301
|
+
}, [visibleCount]);
|
|
302
|
+
useEffect(() => {
|
|
303
|
+
const container = containerRef.current;
|
|
304
|
+
if (!container)
|
|
305
|
+
return;
|
|
306
|
+
let animationFrameId = null;
|
|
307
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
308
|
+
if (animationFrameId)
|
|
309
|
+
cancelAnimationFrame(animationFrameId);
|
|
310
|
+
animationFrameId = requestAnimationFrame(() => {
|
|
311
|
+
const newVisibleCount = calculateVisibleItems();
|
|
312
|
+
setVisibleCount((prevVisibleCount) => {
|
|
313
|
+
if (prevVisibleCount !== newVisibleCount) {
|
|
314
|
+
return newVisibleCount;
|
|
315
|
+
}
|
|
316
|
+
return prevVisibleCount;
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
resizeObserver.observe(container);
|
|
321
|
+
setVisibleCount(calculateVisibleItems());
|
|
322
|
+
return () => {
|
|
323
|
+
if (animationFrameId)
|
|
324
|
+
cancelAnimationFrame(animationFrameId);
|
|
325
|
+
resizeObserver.disconnect();
|
|
326
|
+
};
|
|
327
|
+
}, [calculateVisibleItems]);
|
|
328
|
+
const toggleItem = (value) => {
|
|
329
|
+
let updatedItems;
|
|
330
|
+
if (selectedItems.includes(value)) {
|
|
331
|
+
updatedItems = selectedItems.filter((v) => v !== value);
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
updatedItems = [...selectedItems, value];
|
|
335
|
+
}
|
|
336
|
+
field.onChange(updatedItems);
|
|
337
|
+
onSelect && onSelect(updatedItems);
|
|
338
|
+
};
|
|
339
|
+
const onWheel = (e) => {
|
|
340
|
+
const el = e.currentTarget;
|
|
341
|
+
el.scrollTop += e.deltaY;
|
|
342
|
+
e.preventDefault();
|
|
343
|
+
};
|
|
344
|
+
return (_jsxs(FormItem, { children: [label && _jsx(FormLabel, { children: label }), _jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, className: "w-full", children: _jsx(FormControl, { children: _jsxs(Button
|
|
345
|
+
// Removed ref={triggerRef} here as it's no longer needed for explicit width measurement
|
|
346
|
+
, {
|
|
347
|
+
// Removed ref={triggerRef} here as it's no longer needed for explicit width measurement
|
|
348
|
+
variant: "outline", role: "combobox", className: cn("justify-between", !selectedItems.length && "text-foreground/50"), disabled: disabled === true || (disabled && disabled(...arguments)), children: [selectedItems.length > 0 ? (_jsx(TooltipProvider, { children: _jsxs("div", { ref: containerRef, className: "flex flex-wrap gap-2 items-center overflow-hidden", children: [selectedItems.slice(0, defaultOptions).map((value) => {
|
|
349
|
+
var _a;
|
|
350
|
+
const label = ((_a = items.find((item) => item.value === value)) === null || _a === void 0 ? void 0 : _a.label) ||
|
|
351
|
+
value;
|
|
352
|
+
return (_jsxs("span", { className: "flex items-center px-2 py-1 bg-secondary text-secondary-foreground rounded-md truncate max-w-full", title: label, children: [_jsx("span", { className: "truncate max-w-[120px]", children: label }), _jsx("span", { role: "button", tabIndex: 0, onClick: (e) => {
|
|
353
|
+
e.stopPropagation();
|
|
354
|
+
const updated = selectedItems.filter((v) => v !== value);
|
|
355
|
+
field.onChange(updated);
|
|
356
|
+
onSelect && onSelect(updated);
|
|
357
|
+
}, onKeyDown: (e) => {
|
|
358
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
359
|
+
e.preventDefault();
|
|
360
|
+
e.stopPropagation();
|
|
361
|
+
const updated = selectedItems.filter((v) => v !== value);
|
|
362
|
+
field.onChange(updated);
|
|
363
|
+
onSelect && onSelect(updated);
|
|
364
|
+
}
|
|
365
|
+
}, className: "ml-1 text-muted-foreground hover:text-destructive cursor-pointer outline-none", children: _jsx(X, { className: "w-3 h-3 ml-1" }) })] }, value));
|
|
366
|
+
}), selectedItems.length > defaultOptions && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("span", { className: "px-2 py-1 bg-secondary text-secondary-foreground rounded-md cursor-pointer", children: ["+", selectedItems.length - defaultOptions, " more"] }) }), _jsx(TooltipContent, { className: "max-w-xs break-words", children: _jsx("div", { onWheel: onWheel, className: "flex flex-col gap-1 max-h-[200px] overflow-auto", children: selectedItems.slice(defaultOptions).map((value) => {
|
|
367
|
+
var _a;
|
|
368
|
+
return (_jsx("span", { className: "text-sm", children: ((_a = items.find((item) => item.value === value)) === null || _a === void 0 ? void 0 : _a.label) || value }, value));
|
|
369
|
+
}) }) })] }))] }) })) : (placeholder), _jsx(ChevronsUpDown, { className: "opacity-50" })] }) }) }), _jsx(PopoverContent, { id: "multiSelectPopover",
|
|
370
|
+
// New and improved width logic for PopoverContent
|
|
371
|
+
className: "p-0 min-w-[--radix-popover-trigger-width]" // Ensures at least trigger width
|
|
372
|
+
, style: {
|
|
373
|
+
width: 'max-content', // Allow to grow with content
|
|
374
|
+
maxWidth: 'min(500px, 90vw)' // Cap at 500px or 90% of viewport width, whichever is smaller
|
|
375
|
+
}, align: "start", children: _jsxs(Command, { id: "commandPopover", children: [_jsx(CommandInput, { placeholder: "Search...", value: search, onValueChange: setSearch, autoFocus: true }), _jsxs(CommandList, { className: "max-h-60 overflow-auto", onWheel: onWheel, children: [_jsx(CommandEmpty, { children: "No items found." }), _jsx(CommandGroup, { children: filteredItems.map((item) => {
|
|
376
|
+
var _a;
|
|
377
|
+
const isSelected = selectedItems.includes(item.value);
|
|
378
|
+
return (_jsxs(CommandItem, { value: (_a = item.label) !== null && _a !== void 0 ? _a : "", onSelect: () => toggleItem(item.value), className: "flex items-center space-x-2 justify-start", children: [_jsx(Checkbox, { checked: isSelected, onCheckedChange: () => toggleItem(item.value), onClick: (e) => e.stopPropagation() }), _jsx("span", { children: item.label })] }, item.value));
|
|
379
|
+
}) })] })] }) })] }), formDescription && (_jsx(FormDescription, { children: formDescription })), _jsx(FormMessage, {})] }));
|
|
380
|
+
} }));
|
|
381
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
13
|
+
import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '../../../shadcn/form';
|
|
14
|
+
import { InputOTP, InputOTPGroup, InputOTPSlot, } from "../../../shadcn/input-otp";
|
|
15
|
+
export function FormOtpInput(_a) {
|
|
16
|
+
var { formControl, label, formDescription, extraFormComponent, name } = _a, inputProps = __rest(_a, ["formControl", "label", "formDescription", "extraFormComponent", "name"]);
|
|
17
|
+
return (_jsx(_Fragment, { children: _jsx(FormField, { control: formControl, name: name, render: ({ field }) => (_jsxs(FormItem, { children: [label && _jsx(FormLabel, { children: label }), _jsx(FormControl, { children: _jsx(InputOTP, Object.assign({ maxLength: 4 }, field, { children: _jsxs(InputOTPGroup, { children: [_jsx(InputOTPSlot, { index: 0 }), _jsx(InputOTPSlot, { index: 1 }), _jsx(InputOTPSlot, { index: 2 }), _jsx(InputOTPSlot, { index: 3 })] }) })) }), extraFormComponent && extraFormComponent(field.value), formDescription && _jsx(FormDescription, { children: formDescription }), _jsx(FormMessage, {})] })) }) }));
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function FormPhoneInput(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
13
|
+
import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '../../../shadcn/form';
|
|
14
|
+
import { Textarea } from '../../../shadcn/textarea';
|
|
15
|
+
export function FormTextarea(_a) {
|
|
16
|
+
var { formControl, name, label, formItemClass, formDescription } = _a, textAreaProps = __rest(_a, ["formControl", "name", "label", "formItemClass", "formDescription"]);
|
|
17
|
+
return (_jsx(_Fragment, { children: _jsx(FormField, { control: formControl, name: name, render: ({ field }) => (_jsxs(FormItem, { className: formItemClass, children: [label && _jsx(FormLabel, { children: label }), _jsx(FormControl, { children: _jsx(Textarea, Object.assign({}, field, textAreaProps)) }), formDescription && _jsx(FormDescription, { children: formDescription }), _jsx(FormMessage, {})] })) }) }));
|
|
18
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { InputHTMLAttributes, ReactNode, TextareaHTMLAttributes } from "react";
|
|
2
|
+
import { Matcher } from "react-day-picker";
|
|
3
|
+
export interface FormFieldProps {
|
|
4
|
+
formControl: any;
|
|
5
|
+
label?: string;
|
|
6
|
+
formItemClass?: string;
|
|
7
|
+
formDescription?: string;
|
|
8
|
+
extraFormComponent?: (value: string) => ReactNode;
|
|
9
|
+
}
|
|
10
|
+
export interface FormInputProps extends FormFieldProps, InputHTMLAttributes<HTMLInputElement> {
|
|
11
|
+
name: string;
|
|
12
|
+
}
|
|
13
|
+
export interface FormTextareaProps extends FormFieldProps, TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
14
|
+
name: string;
|
|
15
|
+
}
|
|
16
|
+
export interface FormDateInputProps extends FormFieldProps {
|
|
17
|
+
name: string;
|
|
18
|
+
placeholder?: string;
|
|
19
|
+
dateFormat?: string;
|
|
20
|
+
calendarDateDisabled?: Matcher;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface FormComboboxInputProps extends FormFieldProps {
|
|
24
|
+
name: string;
|
|
25
|
+
placeholder?: string;
|
|
26
|
+
items: FormComboboxItemProps[];
|
|
27
|
+
onSelect?: (value: string | string[]) => void;
|
|
28
|
+
defaultValue?: [];
|
|
29
|
+
disabled?: ((...args: any) => boolean) | boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface FormComboboxItemProps {
|
|
32
|
+
value: string;
|
|
33
|
+
label?: string | undefined;
|
|
34
|
+
extra?: any;
|
|
35
|
+
disabled?: ((...args: any) => boolean) | boolean;
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { LucideIcon } from 'lucide-react';
|
|
3
|
+
export interface SidebarNavSubItem {
|
|
4
|
+
title: string;
|
|
5
|
+
url: string;
|
|
6
|
+
isActive?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface SidebarNavItem {
|
|
9
|
+
title: string;
|
|
10
|
+
url: string;
|
|
11
|
+
icon?: LucideIcon;
|
|
12
|
+
isActive?: boolean;
|
|
13
|
+
default?: boolean;
|
|
14
|
+
items?: SidebarNavSubItem[];
|
|
15
|
+
}
|
|
16
|
+
export interface SidebarNavContextType {
|
|
17
|
+
navItems: SidebarNavItem[];
|
|
18
|
+
setNavItems: (items: SidebarNavItem[]) => void;
|
|
19
|
+
addNavItem: (item: SidebarNavItem) => void;
|
|
20
|
+
removeNavItem: (title: string) => void;
|
|
21
|
+
updateNavItem: (title: string, updates: Partial<SidebarNavItem>) => void;
|
|
22
|
+
clearNavItems: () => void;
|
|
23
|
+
}
|
|
24
|
+
export declare function SidebarNavProvider({ children }: {
|
|
25
|
+
children: ReactNode;
|
|
26
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
export declare function useSidebarNav(): SidebarNavContextType;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext, useState } from 'react';
|
|
4
|
+
const SidebarNavContext = createContext(undefined);
|
|
5
|
+
export function SidebarNavProvider({ children }) {
|
|
6
|
+
const [navItems, setNavItems] = useState([]);
|
|
7
|
+
const addNavItem = (item) => {
|
|
8
|
+
setNavItems((prevItems) => {
|
|
9
|
+
const exists = prevItems.some((navItem) => navItem.title === item.title);
|
|
10
|
+
if (exists) {
|
|
11
|
+
return prevItems.map((navItem) => navItem.title === item.title ? Object.assign(Object.assign({}, navItem), item) : navItem);
|
|
12
|
+
}
|
|
13
|
+
return [...prevItems, item];
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
const removeNavItem = (title) => {
|
|
17
|
+
setNavItems((prevItems) => prevItems.filter((item) => item.title !== title));
|
|
18
|
+
};
|
|
19
|
+
const updateNavItem = (title, updates) => {
|
|
20
|
+
setNavItems((prevItems) => prevItems.map((item) => item.title === title ? Object.assign(Object.assign({}, item), updates) : item));
|
|
21
|
+
};
|
|
22
|
+
const clearNavItems = () => {
|
|
23
|
+
setNavItems([]);
|
|
24
|
+
};
|
|
25
|
+
return (_jsx(SidebarNavContext.Provider, { value: {
|
|
26
|
+
navItems,
|
|
27
|
+
setNavItems,
|
|
28
|
+
addNavItem,
|
|
29
|
+
removeNavItem,
|
|
30
|
+
updateNavItem,
|
|
31
|
+
clearNavItems,
|
|
32
|
+
}, children: children }));
|
|
33
|
+
}
|
|
34
|
+
export function useSidebarNav() {
|
|
35
|
+
const context = useContext(SidebarNavContext);
|
|
36
|
+
if (!context) {
|
|
37
|
+
throw new Error('useSidebarNav must be used within a SidebarNavProvider');
|
|
38
|
+
}
|
|
39
|
+
return context;
|
|
40
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
import { Sidebar, SidebarContent, SidebarFooter, SidebarRail, } from "../../shadcn/sidebar";
|
|
15
|
+
import { NavMain } from "./nav-main";
|
|
16
|
+
export function AppSidebar(_a) {
|
|
17
|
+
var props = __rest(_a, []);
|
|
18
|
+
return (_jsxs(Sidebar, Object.assign({ className: "ml-12", collapsible: "offcanvas" }, props, { children: [_jsx(SidebarContent, { children: _jsx(NavMain, {}) }), _jsx(SidebarFooter, {}), _jsx(SidebarRail, {})] })));
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Footer(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function Footer() {
|
|
3
|
+
return (_jsx("footer", { className: "ml-12 flex border-t px-4 py-2 justify-center lg:justify-start", children: _jsxs("div", { className: "flex gap-2 items-center", children: [_jsx("span", { children: "Powered By" }), _jsx("a", { href: "https://keross.com", target: "_blank", children: "Keross" }), _jsx("span", { className: "", children: "|" }), _jsx("span", { id: "txtCopyrightYear", className: "", children: new Date().getFullYear() })] }) }));
|
|
4
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Header(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { AppBreadcrumb } from "../app-breadcrumb";
|
|
3
|
+
import { ThemeToggleBtn } from "../theme-toggle-btn";
|
|
4
|
+
import { Separator } from "../../shadcn/separator";
|
|
5
|
+
import { SidebarTrigger } from "../../shadcn/sidebar";
|
|
6
|
+
import { LayoutGrid, Play } from "lucide-react";
|
|
7
|
+
import { IconButton, IconTextButton } from "../buttons";
|
|
8
|
+
export function Header() {
|
|
9
|
+
return (_jsx("header", { className: "ml-12 flex h-12 border-b shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-12", children: _jsxs("div", { className: "flex items-center justify-between gap-2 px-4 w-full", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(SidebarTrigger, { className: "-ml-1" }), _jsx(Separator, { orientation: "vertical", className: "mr-2 data-[orientation=vertical]:h-4" }), _jsx(AppBreadcrumb, {})] }), _jsxs("div", { className: "ml-auto flex gap-4", children: [_jsx(ThemeToggleBtn, {}), _jsxs(IconTextButton, { variant: "default", children: [_jsx(Play, {}), "App Store"] }), _jsx(IconButton, { children: _jsx(LayoutGrid, {}) })] })] }) }));
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { MainSidebar } from './main-sidebar';
|
|
3
|
+
import { SidebarInset, SidebarProvider } from '../../shadcn/sidebar';
|
|
4
|
+
import { DialogProvider } from '../alert-dialog/dialog-context';
|
|
5
|
+
import { AppSidebar } from './app-sidebar';
|
|
6
|
+
import { Header } from './header';
|
|
7
|
+
import { Footer } from './footer';
|
|
8
|
+
import { SidebarNavProvider } from './SidebarNavContext';
|
|
9
|
+
export function MainLayout({ children, baseUrl }) {
|
|
10
|
+
return (_jsxs(_Fragment, { children: [_jsx(MainSidebar, { baseUrl: baseUrl }), _jsx(SidebarProvider, { children: _jsx(DialogProvider, { children: _jsxs(SidebarNavProvider, { children: [_jsx(AppSidebar, {}), _jsxs(SidebarInset, { className: "flex flex-col h-screen", children: [_jsx(Header, {}), _jsx("div", { className: "flex flex-col gap-4 p-4 pt-0 ml-12 grow overflow-auto scrollbar-hidden", children: children }), _jsx(Footer, {})] })] }) }) })] }));
|
|
11
|
+
}
|