kmod-cli 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 (66) hide show
  1. package/README.md +53 -0
  2. package/bin/gen-components.js +68 -0
  3. package/bin/index.js +153 -0
  4. package/component-templates/components/access-denied.tsx +130 -0
  5. package/component-templates/components/breadcumb.tsx +42 -0
  6. package/component-templates/components/count-down.tsx +94 -0
  7. package/component-templates/components/count-input.tsx +221 -0
  8. package/component-templates/components/date-range-calendar/button.tsx +61 -0
  9. package/component-templates/components/date-range-calendar/calendar.tsx +132 -0
  10. package/component-templates/components/date-range-calendar/date-input.tsx +259 -0
  11. package/component-templates/components/date-range-calendar/date-range-picker.tsx +594 -0
  12. package/component-templates/components/date-range-calendar/label.tsx +31 -0
  13. package/component-templates/components/date-range-calendar/popover.tsx +32 -0
  14. package/component-templates/components/date-range-calendar/select.tsx +125 -0
  15. package/component-templates/components/date-range-calendar/switch.tsx +30 -0
  16. package/component-templates/components/datetime-picker/button.tsx +61 -0
  17. package/component-templates/components/datetime-picker/calendar.tsx +156 -0
  18. package/component-templates/components/datetime-picker/datetime-picker.tsx +75 -0
  19. package/component-templates/components/datetime-picker/input.tsx +20 -0
  20. package/component-templates/components/datetime-picker/label.tsx +18 -0
  21. package/component-templates/components/datetime-picker/period-input.tsx +62 -0
  22. package/component-templates/components/datetime-picker/popover.tsx +32 -0
  23. package/component-templates/components/datetime-picker/select.tsx +125 -0
  24. package/component-templates/components/datetime-picker/time-picker-input.tsx +131 -0
  25. package/component-templates/components/datetime-picker/time-picker-utils.tsx +204 -0
  26. package/component-templates/components/datetime-picker/time-picker.tsx +59 -0
  27. package/component-templates/components/gradient-outline.tsx +233 -0
  28. package/component-templates/components/gradient-svg.tsx +157 -0
  29. package/component-templates/components/grid-layout.tsx +69 -0
  30. package/component-templates/components/hydrate-guard.tsx +40 -0
  31. package/component-templates/components/image.tsx +92 -0
  32. package/component-templates/components/loader-slash-gradient.tsx +85 -0
  33. package/component-templates/components/masonry-gallery.tsx +221 -0
  34. package/component-templates/components/modal.tsx +110 -0
  35. package/component-templates/components/multi-select.tsx +447 -0
  36. package/component-templates/components/non-hydration.tsx +27 -0
  37. package/component-templates/components/portal.tsx +34 -0
  38. package/component-templates/components/segments-circle.tsx +235 -0
  39. package/component-templates/components/single-select.tsx +248 -0
  40. package/component-templates/components/stroke-circle.tsx +57 -0
  41. package/component-templates/components/table/column-table.tsx +15 -0
  42. package/component-templates/components/table/data-table.tsx +339 -0
  43. package/component-templates/components/table/readme.tsx +95 -0
  44. package/component-templates/components/table/table.tsx +60 -0
  45. package/component-templates/components/text-hover-effect.tsx +120 -0
  46. package/component-templates/components/timout-loader.tsx +52 -0
  47. package/component-templates/components/toast.tsx +994 -0
  48. package/component-templates/configs/config.ts +33 -0
  49. package/component-templates/configs/feature-config.tsx +432 -0
  50. package/component-templates/configs/keys.ts +7 -0
  51. package/component-templates/core/api-service.ts +202 -0
  52. package/component-templates/core/calculate.ts +18 -0
  53. package/component-templates/core/idb.ts +166 -0
  54. package/component-templates/core/storage.ts +213 -0
  55. package/component-templates/hooks/count-down.ts +38 -0
  56. package/component-templates/hooks/fade-on-scroll.ts +52 -0
  57. package/component-templates/hooks/safe-action.ts +59 -0
  58. package/component-templates/hooks/spam-guard.ts +31 -0
  59. package/component-templates/lib/utils.ts +6 -0
  60. package/component-templates/providers/feature-guard.tsx +432 -0
  61. package/component-templates/queries/query.tsx +775 -0
  62. package/component-templates/utils/colors/color-by-text.ts +307 -0
  63. package/component-templates/utils/colors/stripe-effect.ts +100 -0
  64. package/component-templates/utils/hash/hash-aes.ts +35 -0
  65. package/components.json +348 -0
  66. package/package.json +60 -0
@@ -0,0 +1,221 @@
1
+ import 'react-loading-skeleton/dist/skeleton.css';
2
+
3
+ import React from 'react';
4
+
5
+ import { Ellipsis } from 'lucide-react';
6
+ import Skeleton from 'react-loading-skeleton';
7
+ import Masonry, { ResponsiveMasonry } from 'react-responsive-masonry';
8
+
9
+ import { Button } from '../ui/button';
10
+ import {
11
+ Popover,
12
+ PopoverContent,
13
+ PopoverTrigger,
14
+ } from '../ui/popover';
15
+ import { Image } from './image';
16
+
17
+ // ================== Types ==================
18
+ export type ImageInfo = {
19
+ id: any;
20
+ key: string;
21
+ url: string;
22
+ preview_image: string;
23
+ mimetype: string;
24
+ name: string;
25
+ size: number;
26
+ alt: string;
27
+ created_at: string;
28
+ show_edit: boolean;
29
+ user: {
30
+ id: number;
31
+ name: string;
32
+ avt: string;
33
+ };
34
+ };
35
+
36
+ export type ImageCardAction = {
37
+ key: string;
38
+ label: string;
39
+ icon?: React.ReactNode;
40
+ onClick: (item: ImageInfo) => void;
41
+ className?: string;
42
+ };
43
+
44
+ type ImageCardProps = {
45
+ item: ImageInfo;
46
+ onClick: (item: ImageInfo) => void;
47
+ actions?: ImageCardAction[];
48
+ renderHeader?: (item: ImageInfo) => React.ReactNode;
49
+ renderFooter?: (item: ImageInfo) => React.ReactNode;
50
+ };
51
+
52
+ // ================== ImageCard ==================
53
+ const ImageCard: React.FC<ImageCardProps> = ({
54
+ item,
55
+ onClick,
56
+ actions = [],
57
+ renderHeader,
58
+ renderFooter,
59
+ }) => {
60
+ return (
61
+ <div className="group animate-fade-up relative flex w-full flex-col overflow-hidden rounded-xl transition-all duration-300 hover:bg-foreground/5">
62
+ {/* Header */}
63
+ {renderHeader ? (
64
+ renderHeader(item)
65
+ ) : (
66
+ item.mimetype && (
67
+ <span className="absolute top-2 left-2 rounded-md bg-foreground/10 px-2 py-0.5 text-xs font-medium text-background backdrop-blur-sm">
68
+ {item.mimetype.replace(/^image\//, "").toUpperCase()}
69
+ </span>
70
+ )
71
+ )}
72
+
73
+ {/* Image */}
74
+ <Image
75
+ src={item.preview_image}
76
+ alt={item.alt}
77
+ className="border-border bg-background min-h-[100px] cursor-pointer rounded-xl border transition-all duration-300 group-hover:border-green-500"
78
+ imageClass="transition-all duration-300 group-hover:scale-105"
79
+ onClick={() => onClick(item)}
80
+ />
81
+
82
+ {/* Footer */}
83
+ {renderFooter ? (
84
+ renderFooter(item)
85
+ ) : (
86
+ <div className="flex w-full items-center justify-between gap-2 p-3">
87
+ <div className="flex items-center gap-2">
88
+ <Image src={item.user.avt} className="h-5 w-5 rounded-full" />
89
+ <p className="line-clamp-1 text-sm font-medium text-foreground">
90
+ {item.user.name}
91
+ </p>
92
+ </div>
93
+ {actions.length > 0 && (
94
+ <Popover>
95
+ <PopoverTrigger asChild>
96
+ <Button
97
+ variant="ghost"
98
+ size="icon"
99
+ className="rounded-full p-1 shadow-none"
100
+ >
101
+ <Ellipsis className="h-4 w-4" />
102
+ </Button>
103
+ </PopoverTrigger>
104
+ <PopoverContent className="z-[120] max-w-[200px] p-1">
105
+ <div className="flex flex-col">
106
+ {actions.map((action) => (
107
+ <Button
108
+ key={action.key}
109
+ variant="ghost"
110
+ onClick={(e) => {
111
+ e.stopPropagation();
112
+ action.onClick(item);
113
+ }}
114
+ className={`flex items-center gap-2 shadow-none ${action.className ?? ""}`}
115
+ >
116
+ {action.icon}
117
+ <p className="text-sm font-medium">{action.label}</p>
118
+ </Button>
119
+ ))}
120
+ </div>
121
+ </PopoverContent>
122
+ </Popover>
123
+ )}
124
+ </div>
125
+ )}
126
+ </div>
127
+ );
128
+ };
129
+
130
+ // ================== MasonryWithSkeleton ==================
131
+ type MasonryWithSkeletonProps = {
132
+ items: ImageInfo[];
133
+ loading?: boolean;
134
+ onClick: (item: ImageInfo) => void;
135
+ actions?: ImageCardAction[];
136
+ renderHeader?: (item: ImageInfo) => React.ReactNode;
137
+ renderFooter?: (item: ImageInfo) => React.ReactNode;
138
+ breakpoint?: Record<number, number>;
139
+ };
140
+
141
+ const MasonryWithSkeleton: React.FC<MasonryWithSkeletonProps> = ({
142
+ items,
143
+ loading = false,
144
+ onClick,
145
+ actions,
146
+ renderHeader,
147
+ renderFooter,
148
+ breakpoint = { 350: 2, 750: 3, 1200: 5 },
149
+ }) => {
150
+ const placeholders = Array.from({ length: 12 });
151
+ return (
152
+ <ResponsiveMasonry columnsCountBreakPoints={breakpoint}>
153
+ <Masonry>
154
+ {loading &&
155
+ placeholders.map((_, i) => <ImageCardSkeleton key={i} keyId={i} />)}
156
+ {!loading &&
157
+ items.map((item) => (
158
+ <ImageCard
159
+ key={item.id}
160
+ item={item}
161
+ onClick={onClick}
162
+ actions={actions}
163
+ renderHeader={renderHeader}
164
+ renderFooter={renderFooter}
165
+ />
166
+ ))}
167
+ </Masonry>
168
+ </ResponsiveMasonry>
169
+ );
170
+ };
171
+
172
+ export default MasonryWithSkeleton;
173
+
174
+ // ================== Skeleton ==================
175
+ const ImageCardSkeleton = ({ keyId }: { keyId: number }) => (
176
+ <div className="group animate-fade-up flex w-full flex-col overflow-hidden rounded-xl transition-all duration-300">
177
+ <Skeleton height={keyId % 2 === 0 ? 320 : 200} className="rounded-xl" />
178
+ <div className="flex w-full justify-between p-3">
179
+ <div className="flex items-center gap-2">
180
+ <Skeleton circle width={20} height={20} />
181
+ <Skeleton width={80} height={14} />
182
+ </div>
183
+ <Skeleton width={32} height={32} circle />
184
+ </div>
185
+ </div>
186
+ );
187
+
188
+ // // ================== Example actions ==================
189
+ // export const defaultActions: ImageCardAction[] = [
190
+ // {
191
+ // key: "share",
192
+ // label: "Share",
193
+ // icon: <Share2 className="h-4 w-4" />,
194
+ // onClick: (item) => console.log("share", item),
195
+ // },
196
+ // {
197
+ // key: "save",
198
+ // label: "Save",
199
+ // icon: <FolderPlus className="h-4 w-4" />,
200
+ // onClick: (item) => console.log("save", item),
201
+ // },
202
+ // {
203
+ // key: "edit",
204
+ // label: "Edit",
205
+ // icon: <PenLine className="h-4 w-4" />,
206
+ // onClick: (item) => console.log("edit", item),
207
+ // },
208
+ // {
209
+ // key: "download",
210
+ // label: "Download",
211
+ // icon: <Download className="h-4 w-4" />,
212
+ // onClick: (item) => downloadImage(item.url),
213
+ // },
214
+ // {
215
+ // key: "delete",
216
+ // label: "Delete",
217
+ // icon: <Trash2 className="h-4 w-4 text-red-500" />,
218
+ // onClick: (item) => console.log("delete", item),
219
+ // className: "text-red-500",
220
+ // },
221
+ // ];
@@ -0,0 +1,110 @@
1
+ "use client";
2
+ import React, {
3
+ ReactNode,
4
+ useEffect,
5
+ useRef,
6
+ } from 'react';
7
+ import { createPortal } from 'react-dom';
8
+
9
+ import { cn } from '../lib/utils';
10
+
11
+ /** base z-100 */
12
+ type ModalProps = {
13
+ open: boolean;
14
+ type: "modal" | "drawer";
15
+ onClose: () => void;
16
+ title?: ReactNode | string;
17
+ children: React.ReactNode;
18
+ footer?: React.ReactNode;
19
+ className?: string;
20
+ pos?: "center" | "top" | "bottom" | "right" | "left";
21
+ containerClassName?: string;
22
+ };
23
+
24
+ export default function Modal({
25
+ open,
26
+ type = "modal",
27
+ onClose,
28
+ title,
29
+ children,
30
+ footer,
31
+ pos = "center",
32
+ className = "",
33
+ containerClassName = "",
34
+ }: ModalProps) {
35
+ const overlayRef = useRef<HTMLDivElement>(null);
36
+
37
+ const handleOverlayClick = (e: React.MouseEvent) => {
38
+ if (e.target === overlayRef.current) {
39
+ onClose();
40
+ }
41
+ };
42
+
43
+ useEffect(() => {
44
+ const onEsc = (e: KeyboardEvent) => {
45
+ if (e.key === "Escape") onClose();
46
+ };
47
+ if (open) {
48
+ document.body.style.overflow = "hidden";
49
+ document.addEventListener("keydown", onEsc);
50
+ } else {
51
+ document.body.style.overflow = "";
52
+ }
53
+ return () => {
54
+ document.body.style.overflow = "";
55
+ document.removeEventListener("keydown", onEsc);
56
+ };
57
+ }, [open]);
58
+
59
+ if (typeof window === "undefined") return null;
60
+
61
+ if (type === "modal")
62
+ return createPortal(
63
+ open && (
64
+ <div
65
+ ref={overlayRef}
66
+ onClick={handleOverlayClick}
67
+ className={cn("fixed inset-0 backdrop-blur-lg !z-[100] flex justify-center bg-black/10 p-6 transition-opacity duration-300", containerClassName)}
68
+ >
69
+ <div
70
+ className={cn(
71
+ pos === "center" && "top-1/2 -translate-y-1/2",
72
+ pos === "top" && "top-0",
73
+ pos === "bottom" && "bottom-0 translate-y-full",
74
+ pos === "right" && "right-0",
75
+ pos === "left" && "left-0",
76
+ `animate-fade-up !animate-duration-500 relative mx-4 h-fit w-full max-w-lg scale-100 transform rounded-lg bg-white p-6 opacity-100 shadow-xl transition-all duration-300 dark:bg-zinc-900`,
77
+ className,
78
+ )}
79
+ >
80
+ {title && <h2 className="text-lg font-semibold">{title}</h2>}
81
+ {children}
82
+ {footer && footer}
83
+ </div>
84
+ </div>
85
+ ),
86
+ document.body,
87
+ );
88
+ if (type === "drawer")
89
+ return createPortal(
90
+ open && (
91
+ <div
92
+ ref={overlayRef}
93
+ onClick={handleOverlayClick}
94
+ className={cn("fixed inset-0 !z-[100] flex justify-end bg-black/50 transition-opacity duration-300")}
95
+ >
96
+ <div
97
+ className={cn(
98
+ `animate-fade-up !animate-duration-500 h-full w-full max-w-full transform bg-white p-6 shadow-xl transition-all duration-300 dark:bg-zinc-900`,
99
+ className,
100
+ )}
101
+ >
102
+ {title && <div className="text-lg font-semibold">{title}</div>}
103
+ {children}
104
+ {footer && footer}
105
+ </div>
106
+ </div>
107
+ ),
108
+ document.body,
109
+ );
110
+ }