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,233 @@
1
+ // "use client";
2
+ // import React, {FC, HTMLAttributes, useState, useEffect, useRef} from "react";
3
+
4
+ // type GradientOutlineProps = {
5
+ // children: React.ReactNode;
6
+ // strokeWidth?: number;
7
+ // borderRadius?: number;
8
+ // gradientColors?: string[];
9
+ // hoverGradientColors?: string[];
10
+ // gradientAngle?: number;
11
+ // allowHover?: boolean;
12
+ // className?: string;
13
+ // id: string;
14
+ // onClick?: () => void;
15
+ // } & HTMLAttributes<HTMLDivElement>;
16
+
17
+ // const GradientOutline: FC<GradientOutlineProps> = ({
18
+ // children,
19
+ // id,
20
+ // allowHover = true,
21
+ // strokeWidth = 1,
22
+ // borderRadius = 16,
23
+ // hoverGradientColors = ["#E6CAA4", "#E9B84E"],
24
+ // gradientColors = [
25
+ // "rgba(255, 255, 255, 0.08)",
26
+ // "rgba(255, 255, 255, 0.4)",
27
+ // "rgba(255, 255, 255, 0)",
28
+ // "rgba(255, 255, 255, 0)",
29
+ // "rgba(255, 255, 255, 0.1)",
30
+ // ],
31
+ // gradientAngle = 45,
32
+ // className = "",
33
+ // onClick,
34
+ // ...props
35
+ // }) => {
36
+ // const [isHovered, setIsHovered] = useState(false);
37
+ // const gradientId = `gradient-${Math.random().toString(36).substr(2, 9)}`;
38
+ // const containerRef = useRef<HTMLDivElement>(null);
39
+ // const [dimensions, setDimensions] = useState({width: 100, height: 100});
40
+
41
+ // useEffect(() => {
42
+ // if (containerRef.current) {
43
+ // const {width, height} = containerRef.current.getBoundingClientRect();
44
+ // setDimensions({width, height});
45
+ // }
46
+ // }, []);
47
+
48
+ // const colors = isHovered ? hoverGradientColors : gradientColors;
49
+
50
+ // return (
51
+ // <div
52
+ // ref={containerRef}
53
+ // id={id}
54
+ // onClick={onClick}
55
+ // onMouseEnter={() => allowHover && setIsHovered(true)}
56
+ // onMouseLeave={() => allowHover && setIsHovered(false)}
57
+ // className={`relative inline-block overflow-hidden p-2 ${className}`}
58
+ // style={{borderRadius}}
59
+ // {...props}
60
+ // >
61
+ // {children}
62
+ // <svg
63
+ // width="100%"
64
+ // height="100%"
65
+ // className="absolute top-0 left-0"
66
+ // viewBox={`0 0 ${dimensions.width} ${dimensions.height}`}
67
+ // preserveAspectRatio="none"
68
+ // >
69
+ // <defs>
70
+ // <linearGradient
71
+ // id={gradientId}
72
+ // x1={Math.cos((gradientAngle * Math.PI) / 180)}
73
+ // y1={Math.sin((gradientAngle * Math.PI) / 180)}
74
+ // x2={1 - Math.cos((gradientAngle * Math.PI) / 180)}
75
+ // y2={1 - Math.sin((gradientAngle * Math.PI) / 180)}
76
+ // >
77
+ // {colors.map((color, index) => (
78
+ // <stop
79
+ // key={index}
80
+ // offset={`${(index / (colors.length - 1)) * 100}%`}
81
+ // stopColor={color}
82
+ // />
83
+ // ))}
84
+ // </linearGradient>
85
+ // </defs>
86
+ // <rect
87
+ // x={strokeWidth / 2}
88
+ // y={strokeWidth / 2}
89
+ // width={dimensions.width - strokeWidth}
90
+ // height={dimensions.height - strokeWidth}
91
+ // rx={borderRadius}
92
+ // ry={borderRadius}
93
+ // stroke={`url(#${gradientId})`}
94
+ // strokeWidth={strokeWidth}
95
+ // fill="none"
96
+ // />
97
+ // </svg>
98
+ // </div>
99
+ // );
100
+ // };
101
+
102
+ // export default GradientOutline;
103
+
104
+ // // GradientOutline id="gc-1" className="w-full h-fit">
105
+ // // <div className="w-full text-white bg-black">
106
+ // // <span>abc cbac</span>
107
+ // // <span>abc cbac</span>
108
+ // // <span>abc cbac</span>
109
+ // // <span>abc cbac</span>
110
+ // // </div>
111
+ // // </GradientOutline>
112
+
113
+ "use client";
114
+ import React, {
115
+ FC,
116
+ HTMLAttributes,
117
+ useEffect,
118
+ useId,
119
+ useRef,
120
+ useState,
121
+ } from 'react';
122
+
123
+ export type GradientOutlineProps = {
124
+ children: React.ReactNode;
125
+ strokeWidth?: number;
126
+ borderRadius?: number;
127
+ gradientColors?: string[];
128
+ hoverGradientColors?: string[];
129
+ gradientAngle?: number;
130
+ allowHover?: boolean;
131
+ className?: string;
132
+ onClick?: () => void;
133
+ } & HTMLAttributes<HTMLDivElement>;
134
+
135
+ export const GradientOutline: FC<GradientOutlineProps> = ({
136
+ children,
137
+ allowHover = true,
138
+ strokeWidth = 1,
139
+ borderRadius = 16,
140
+ gradientColors = [
141
+ "rgba(255, 255, 255, 0.08)",
142
+ "rgba(255, 255, 255, 0.4)",
143
+ "rgba(255, 255, 255, 0)",
144
+ "rgba(255, 255, 255, 0)",
145
+ "rgba(255, 255, 255, 0.1)",
146
+ ],
147
+ hoverGradientColors = ["#E6CAA4", "#E9B84E"],
148
+ gradientAngle = 45,
149
+ className = "",
150
+ onClick,
151
+ ...props
152
+ }) => {
153
+ const [isHovered, setIsHovered] = useState(false);
154
+ const containerRef = useRef<HTMLDivElement>(null);
155
+ const [dimensions, setDimensions] = useState({ width: 100, height: 100 });
156
+ const gradientId = `gradient-${useId()}`; // SSR-safe ID
157
+
158
+ // Resize observer để responsive
159
+ useEffect(() => {
160
+ const updateDimensions = () => {
161
+ if (containerRef.current) {
162
+ const { width, height } = containerRef.current.getBoundingClientRect();
163
+ setDimensions({ width, height });
164
+ }
165
+ };
166
+ updateDimensions();
167
+
168
+ const resizeObserver = new ResizeObserver(updateDimensions);
169
+ if (containerRef.current) resizeObserver.observe(containerRef.current);
170
+ window.addEventListener("resize", updateDimensions);
171
+
172
+ return () => {
173
+ resizeObserver.disconnect();
174
+ window.removeEventListener("resize", updateDimensions);
175
+ };
176
+ }, []);
177
+
178
+ const colors = isHovered ? hoverGradientColors : gradientColors;
179
+
180
+ // Gradient angle helper
181
+ const rad = (gradientAngle % 360) * (Math.PI / 180);
182
+ const x1 = 0.5 - 0.5 * Math.cos(rad);
183
+ const y1 = 0.5 - 0.5 * Math.sin(rad);
184
+ const x2 = 0.5 + 0.5 * Math.cos(rad);
185
+ const y2 = 0.5 + 0.5 * Math.sin(rad);
186
+
187
+ return (
188
+ <div
189
+ ref={containerRef}
190
+ onClick={onClick}
191
+ role={onClick ? "button" : undefined}
192
+ tabIndex={onClick ? 0 : undefined}
193
+ onKeyDown={(e) => e.key === "Enter" && onClick?.()}
194
+ onMouseEnter={() => allowHover && setIsHovered(true)}
195
+ onMouseLeave={() => allowHover && setIsHovered(false)}
196
+ className={`relative inline-block overflow-hidden ${className}`}
197
+ style={{ borderRadius }}
198
+ {...props}
199
+ >
200
+ {children}
201
+ <svg
202
+ width="100%"
203
+ height="100%"
204
+ className="absolute top-0 left-0 pointer-events-none"
205
+ viewBox={`0 0 ${dimensions.width} ${dimensions.height}`}
206
+ preserveAspectRatio="none"
207
+ >
208
+ <defs>
209
+ <linearGradient id={gradientId} x1={x1} y1={y1} x2={x2} y2={y2}>
210
+ {colors.map((color, index) => (
211
+ <stop
212
+ key={index}
213
+ offset={`${(index / (colors.length - 1)) * 100}%`}
214
+ stopColor={color}
215
+ />
216
+ ))}
217
+ </linearGradient>
218
+ </defs>
219
+ <rect
220
+ x={strokeWidth / 2}
221
+ y={strokeWidth / 2}
222
+ width={dimensions.width - strokeWidth}
223
+ height={dimensions.height - strokeWidth}
224
+ rx={borderRadius}
225
+ ry={borderRadius}
226
+ stroke={`url(#${gradientId})`}
227
+ strokeWidth={strokeWidth}
228
+ fill="none"
229
+ />
230
+ </svg>
231
+ </div>
232
+ );
233
+ };
@@ -0,0 +1,157 @@
1
+ // import React from 'react';
2
+
3
+ // import { ReactSVG } from 'react-svg';
4
+
5
+ // export type GradientSVGProps = {
6
+ // image: string;
7
+ // isActive?: boolean;
8
+ // };
9
+ // export const GradientSVG = ({ image, isActive }: GradientSVGProps) => {
10
+ // return (
11
+ // <ReactSVG
12
+ // src={image}
13
+ // beforeInjection={(svg) => {
14
+ // const defs = document.createElementNS(
15
+ // "http://www.w3.org/2000/svg",
16
+ // "defs"
17
+ // );
18
+ // if (isActive) {
19
+ // defs.innerHTML = `
20
+ // <linearGradient id="customGradient" x1="0" y1="0" x2="0" y2="1">
21
+ // <stop offset="0%" stop-color="#A079FC" />
22
+ // <stop offset="100%" stop-color="#0D5BB5" />
23
+ // </linearGradient>
24
+ // `;
25
+ // }
26
+ // svg.prepend(defs);
27
+
28
+ // svg.querySelectorAll("[stroke]").forEach((el) => {
29
+ // el.setAttribute(
30
+ // "stroke",
31
+ // isActive ? "url(#customGradient)" : "#515158"
32
+ // );
33
+ // });
34
+ // svg.querySelectorAll("[fill]").forEach((el) => {
35
+ // el.setAttribute(
36
+ // "fill",
37
+ // isActive ? "url(#customGradient)" : "#515158"
38
+ // );
39
+ // });
40
+ // }}
41
+ // className="h-9 w-9"
42
+ // />
43
+ // );
44
+ // };
45
+
46
+ import React from 'react';
47
+
48
+ import { ReactSVG } from 'react-svg';
49
+
50
+ export type GradientStop = {
51
+ offset: string; // "0%", "50%", ...
52
+ color: string; // "#hex" or "rgb(...)"
53
+ };
54
+
55
+ export type GradientSVGProps = {
56
+ image: string;
57
+ isActive?: boolean;
58
+ gradientId?: string;
59
+ gradientStops?: GradientStop[];
60
+ stroke?: string | { gradient: true };
61
+ fill?: string | { gradient: true };
62
+ gradientType?: "linear" | "radial";
63
+ angle?: number; // For linear gradients, if needed
64
+ className?: string;
65
+ style: React.CSSProperties;
66
+ };
67
+
68
+ export const GradientSVG = ({
69
+ image,
70
+ isActive = false,
71
+ gradientId = "customGradient",
72
+ gradientStops = [
73
+ { offset: "0%", color: "#A079FC" },
74
+ { offset: "100%", color: "#0D5BB5" },
75
+ ],
76
+ stroke = { gradient: true },
77
+ fill = { gradient: true },
78
+ gradientType = "linear",
79
+ angle = 180, // it can be used for linear gradients
80
+ className = "h-9 w-9",
81
+ style = {},
82
+ ...props
83
+ }: GradientSVGProps) => {
84
+ return (
85
+ <ReactSVG
86
+ src={image}
87
+ beforeInjection={(svg) => {
88
+ if (isActive && ((stroke as any).gradient || (fill as any).gradient)) {
89
+ if (!svg.querySelector(`#${gradientId}`)) {
90
+ const defs = document.createElementNS(
91
+ "http://www.w3.org/2000/svg",
92
+ "defs"
93
+ );
94
+
95
+ const gradient = document.createElementNS(
96
+ "http://www.w3.org/2000/svg",
97
+ gradientType === "linear" ? "linearGradient" : "radialGradient"
98
+ );
99
+ gradient.setAttribute("id", gradientId);
100
+
101
+ if (gradientType === "linear") {
102
+ const rad = (angle % 360) * (Math.PI / 180);
103
+ const x1 = (Math.cos(rad) + 1) / 2;
104
+ const y1 = (Math.sin(rad) + 1) / 2;
105
+ const x2 = 1 - x1;
106
+ const y2 = 1 - y1;
107
+
108
+ gradient.setAttribute("x1", x1.toString());
109
+ gradient.setAttribute("y1", y1.toString());
110
+ gradient.setAttribute("x2", x2.toString());
111
+ gradient.setAttribute("y2", y2.toString());
112
+ } else {
113
+ gradient.setAttribute("cx", "50%");
114
+ gradient.setAttribute("cy", "50%");
115
+ gradient.setAttribute("r", "50%");
116
+ }
117
+
118
+ gradientStops.forEach((stop) => {
119
+ const stopEl = document.createElementNS(
120
+ "http://www.w3.org/2000/svg",
121
+ "stop"
122
+ );
123
+ stopEl.setAttribute("offset", stop.offset);
124
+ stopEl.setAttribute("stop-color", stop.color);
125
+ gradient.appendChild(stopEl);
126
+ });
127
+
128
+ defs.appendChild(gradient);
129
+ svg.prepend(defs);
130
+ }
131
+ }
132
+
133
+ svg.querySelectorAll("[stroke]").forEach((el) => {
134
+ let strokeVal = "#515158";
135
+ if (isActive) {
136
+ if (typeof stroke === "string") strokeVal = stroke;
137
+ else if ((stroke as any).gradient) strokeVal = `url(#${gradientId})`;
138
+ }
139
+ el.setAttribute("stroke", strokeVal);
140
+ });
141
+
142
+ svg.querySelectorAll("[fill]").forEach((el) => {
143
+ let fillVal = "#515158";
144
+ if (isActive) {
145
+ if (typeof fill === "string") fillVal = fill;
146
+ else if ((fill as any).gradient) fillVal = `url(#${gradientId})`;
147
+ }
148
+ el.setAttribute("fill", fillVal);
149
+ });
150
+ }}
151
+ className={className}
152
+ style={style}
153
+ {...props}
154
+ />
155
+ );
156
+ };
157
+
@@ -0,0 +1,69 @@
1
+ "use client";
2
+ import React, {
3
+ useEffect,
4
+ useRef,
5
+ useState,
6
+ } from 'react';
7
+
8
+ import { twMerge } from 'tailwind-merge';
9
+
10
+ interface GridLayoutProps extends React.HTMLAttributes<HTMLDivElement> {
11
+ columns?: number;
12
+ gap?: number;
13
+ responsive?: boolean;
14
+ className?: string;
15
+ children?: React.ReactNode;
16
+ breakpoints?: {
17
+ minWidth: number;
18
+ columns: number;
19
+ }[];
20
+ mode?: "window" | "container";
21
+ }
22
+
23
+ export const GridLayout: React.FC<GridLayoutProps> = ({
24
+ columns = 3,
25
+ gap = 4,
26
+ responsive = true,
27
+ breakpoints,
28
+ className,
29
+ children,
30
+ mode = "window",
31
+ ...props
32
+ }) => {
33
+ const [currentColumns, setCurrentColumns] = useState(columns);
34
+ const contentRef = useRef<HTMLDivElement>(null);
35
+
36
+ useEffect(() => {
37
+ const updateColumns = () => {
38
+ if (responsive && breakpoints) {
39
+ const width =
40
+ mode === "container" && contentRef.current
41
+ ? contentRef.current.offsetWidth
42
+ : window.innerWidth;
43
+
44
+ const sorted = [...breakpoints].sort((a, b) => b.minWidth - a.minWidth);
45
+ const match = sorted.find((bp) => width >= bp.minWidth);
46
+ setCurrentColumns(match ? match.columns : columns);
47
+ }
48
+ };
49
+
50
+ updateColumns(); // initial
51
+ window.addEventListener("resize", updateColumns);
52
+ return () => window.removeEventListener("resize", updateColumns);
53
+ }, [responsive, breakpoints, columns, mode]);
54
+
55
+ return (
56
+ <div
57
+ ref={contentRef}
58
+ style={{
59
+ gridTemplateColumns: `repeat(${currentColumns}, minmax(0, 1fr))`,
60
+ display: "grid",
61
+ gap: `${gap}px`,
62
+ }}
63
+ className={twMerge(`w-full`, className)}
64
+ {...props}
65
+ >
66
+ {children}
67
+ </div>
68
+ );
69
+ };
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+
3
+ import React, {
4
+ FC,
5
+ ReactNode,
6
+ useEffect,
7
+ useState,
8
+ } from 'react';
9
+
10
+ export type HydrationGuardProps = {
11
+ children: ReactNode;
12
+ }
13
+
14
+ /**
15
+ * HydrationGuard is a component that prevents its children from being
16
+ * rendered on the server, while still allowing them to be rendered on
17
+ * the client. This is useful for components that need to use browser
18
+ * APIs that are not available on the server, such as the `window`
19
+ * object or Web APIs that require user interaction.
20
+ *
21
+ * The component works by using the `useState` hook to keep track of
22
+ * whether the component has been mounted or not. On the server, the
23
+ * component is not mounted, so the `mounted` state is `false`, and
24
+ * the component does not render its children. On the client, the
25
+ * component is mounted, so the `mounted` state is `true`, and the
26
+ * component renders its children.
27
+ * @param {ReactNode} children - The children to render only on the client.
28
+ * @returns {ReactElement} The rendered children, or null if on the server.
29
+ */
30
+ export const HydrationGuard:FC<HydrationGuardProps> = ({ children }) => {
31
+ const [mounted, setMounted] = useState(false);
32
+
33
+ useEffect(() => {
34
+ setMounted(true);
35
+ }, []);
36
+
37
+ if (!mounted) return null;
38
+
39
+ return <>{children}</>;
40
+ }
@@ -0,0 +1,92 @@
1
+ "use client";
2
+ import React, { useState } from 'react';
3
+
4
+ export interface ImageProps extends React.HTMLAttributes<HTMLDivElement> {
5
+ src: string;
6
+ text?: string;
7
+ alt?: string;
8
+ className?: string;
9
+ imageClass?: string;
10
+ fallbackSrc?: string;
11
+ fit?: "w" | "h" | "both";
12
+ style?: React.CSSProperties;
13
+ containerStyle?: React.CSSProperties;
14
+ id?: string;
15
+ onClick?: (event: React.MouseEvent<HTMLImageElement>) => void;
16
+ resourceLoadPriority?: "auto" | "high" | "low";
17
+ loadmode?: "lazy" | "eager";
18
+ sendAccessUrlToImageServer?:
19
+ | "no-referrer"
20
+ | "no-referrer-when-downgrade"
21
+ | "origin"
22
+ | "strict-origin";
23
+ // crossOrigin?: "anonymous" | "use-credentials";
24
+ fetchPriority?: "auto" | "high" | "low";
25
+ }
26
+
27
+ export const Image: React.FC<ImageProps> = ({
28
+ src,
29
+ text,
30
+ alt = "image",
31
+ className = "",
32
+ imageClass = "",
33
+ fallbackSrc = "https://picsum.photos/200/300/?blur=8",
34
+ // fallbackSrc = "https://images.pexels.com/photos/349758/hummingbird-bird-birds-349758.jpeg",
35
+ fit = "both",
36
+ style = {},
37
+ containerStyle = {},
38
+ resourceLoadPriority = "auto",
39
+ loadmode = "lazy",
40
+ sendAccessUrlToImageServer = "no-referrer",
41
+ // crossOrigin = "anonymous",
42
+ id,
43
+ onClick,
44
+ ...props
45
+ }) => {
46
+ const [imgSrc, setImgSrc] = useState(src);
47
+ const [loading, setLoading] = useState(true);
48
+ // console.log("Image component rendered with src:", imgSrc);
49
+
50
+ return (
51
+ <div
52
+ style={containerStyle}
53
+ className={`relative overflow-hidden ${className}`}
54
+ onClick={onClick}
55
+ {...props}
56
+ >
57
+ {loading && (
58
+ <div className="absolute inset-0 bg-gray-200 animate-pulse" />
59
+ )}
60
+ <img
61
+ id={id}
62
+ style={style}
63
+ src={imgSrc}
64
+ // crossOrigin={crossOrigin}
65
+ loading={loadmode}
66
+ referrerPolicy={sendAccessUrlToImageServer}
67
+ fetchPriority={resourceLoadPriority}
68
+ alt={alt}
69
+ className={`${
70
+ fit === "w"
71
+ ? "w-full h-auto"
72
+ : fit === "h"
73
+ ? "h-full w-auto"
74
+ : "w-full h-full"
75
+ } object-cover transition-all duration-500 ${
76
+ loading ? "opacity-0" : "opacity-100"
77
+ } ${imageClass}`}
78
+ onLoad={() => setLoading(false)}
79
+ onError={(e) => {
80
+ // console.error("Error loading image:", e);
81
+ if (text) {
82
+ setImgSrc(text);
83
+ setLoading(false);
84
+ return;
85
+ }
86
+ setImgSrc(fallbackSrc);
87
+ setLoading(false);
88
+ }}
89
+ />
90
+ </div>
91
+ );
92
+ };
@@ -0,0 +1,85 @@
1
+ import React, {
2
+ HTMLAttributes,
3
+ JSX,
4
+ ReactNode,
5
+ } from 'react';
6
+
7
+ import { cn } from '../lib/utils';
8
+
9
+ export type LoadSlashBarProps = {
10
+ slashSize?: {
11
+ x: number;
12
+ y: number;
13
+ };
14
+ slashColors?: {
15
+ primary: string;
16
+ secondary: string;
17
+ };
18
+ rotate?: number;
19
+ className?: string;
20
+ containerClass?: string;
21
+ progressClass?: string;
22
+ elementClass?: string;
23
+ value?: number;
24
+ children?: ReactNode;
25
+ slashWidth?: number;
26
+ } & HTMLAttributes<HTMLDivElement>;
27
+ /**
28
+ * LoadSlashBar component renders a progress bar with a slash effect.
29
+ * It accepts various props to customize the appearance and behavior of the bar.
30
+ * @param {LoadSlashBarProps} props - Properties for customizing the LoadSlashBar component.
31
+ * @returns {JSX.Element} Rendered LoadSlashBar component.
32
+ */
33
+ export const LoaderSlashGradient: React.FC<LoadSlashBarProps> = ({
34
+ slashColors = {primary: "#ffffff", secondary: "transparent"},
35
+ slashSize = {x: 20, y: 10},
36
+ className,
37
+ containerClass = "bg-black",
38
+ progressClass,
39
+ elementClass,
40
+ value = 0,
41
+ rotate = 45,
42
+ slashWidth = 100,
43
+ children,
44
+ ...props
45
+ }):JSX.Element => {
46
+ return (
47
+ <div
48
+ {...props}
49
+ className={cn("w-full h-2 relative rounded-full", containerClass)}
50
+ >
51
+ <div
52
+ style={{
53
+ width: `${value}%`,
54
+ }}
55
+ className={cn(
56
+ "absolute z-[1] top-0 left-0 w-1/2 rounded-full h-full",
57
+ progressClass
58
+ )}
59
+ ></div>
60
+ <div
61
+ style={{
62
+ width: `${value}%`,
63
+ }}
64
+ className={cn(
65
+ "absolute z-[3] top-0 left-0 w-1/2 flex items-center justify-end bg-transparent rounded-full h-full",
66
+ elementClass
67
+ )}
68
+ >
69
+ {children}
70
+ </div>
71
+ <div
72
+ style={{
73
+ width: `${slashWidth}%`,
74
+ backgroundSize: `${slashSize?.x}px ${slashSize?.y}px`,
75
+ backgroundImage: `linear-gradient(${rotate}deg, ${slashColors?.primary} 35%, ${slashColors?.secondary} 10%, ${slashColors?.secondary} 75%, ${slashColors?.primary} 75%, ${slashColors?.primary})`,
76
+ }}
77
+ className={cn(
78
+ "absolute z-[2] top-0 left-0 h-full",
79
+ !slashWidth && "w-full",
80
+ className
81
+ )}
82
+ ></div>
83
+ </div>
84
+ );
85
+ };