gbs-add-block 1.0.15 → 1.0.17
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/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# GBS Building Blocks 2.0 (v1.0.
|
|
1
|
+
# GBS Building Blocks 2.0 (v1.0.17)
|
|
2
2
|
|
|
3
3
|
Latest and upgraded version of GBS building blocks with headless UI and removed dependencies.
|
|
4
4
|
|
|
@@ -6,12 +6,9 @@ Latest and upgraded version of GBS building blocks with headless UI and removed
|
|
|
6
6
|
|
|
7
7
|
For detailed documentation on usage and props, Please visit: [Building Block Documentation v2.0](https://blackmax-designs.gitbook.io/building-block-v2.0)
|
|
8
8
|
|
|
9
|
-
## What's New 🎉 (Ver 1.0.
|
|
9
|
+
## What's New 🎉 (Ver 1.0.17)
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
- End of Support for Grid Component
|
|
13
|
-
- Select Enhancement
|
|
14
|
-
- Interactive mode
|
|
11
|
+
- Style Update
|
|
15
12
|
|
|
16
13
|
## Authors
|
|
17
14
|
|
package/index.cjs
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import React, { useState, useRef, useEffect } from "react";
|
|
2
|
+
import type { TextAreaProps } from "./types";
|
|
3
|
+
|
|
4
|
+
export const TextArea = ({
|
|
5
|
+
label,
|
|
6
|
+
placeholder = "Enter your text here...",
|
|
7
|
+
value,
|
|
8
|
+
onChange,
|
|
9
|
+
error,
|
|
10
|
+
helperText,
|
|
11
|
+
rows = 4,
|
|
12
|
+
maxLength,
|
|
13
|
+
required = false,
|
|
14
|
+
disabled = false,
|
|
15
|
+
variant = "default",
|
|
16
|
+
className = "",
|
|
17
|
+
...props
|
|
18
|
+
}: TextAreaProps) => {
|
|
19
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
20
|
+
const [charCount, setCharCount] = useState(0);
|
|
21
|
+
const textareaRef = useRef(null);
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (value) {
|
|
25
|
+
setCharCount(value.length);
|
|
26
|
+
}
|
|
27
|
+
}, [value]);
|
|
28
|
+
|
|
29
|
+
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
30
|
+
const newValue = e.target.value;
|
|
31
|
+
setCharCount(newValue.length);
|
|
32
|
+
if (onChange) {
|
|
33
|
+
onChange(e);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const handleFocus = () => {
|
|
38
|
+
setIsFocused(true);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const handleBlur = () => {
|
|
42
|
+
setIsFocused(false);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const getVariantClasses = () => {
|
|
46
|
+
switch (variant) {
|
|
47
|
+
case "minimal":
|
|
48
|
+
return {
|
|
49
|
+
container: "relative",
|
|
50
|
+
textarea: `w-full px-0 py-3 text-gray-900 placeholder-gray-400 bg-transparent border-0 border-b-2 border-gray-200 resize-none focus:border-blue-500 focus:outline-none ${
|
|
51
|
+
disabled ? "opacity-50 cursor-not-allowed" : ""
|
|
52
|
+
}`,
|
|
53
|
+
label: `absolute left-0 transition-all duration-200 pointer-events-none ${
|
|
54
|
+
isFocused || value
|
|
55
|
+
? "-top-6 text-sm text-blue-500"
|
|
56
|
+
: "top-3 text-base text-gray-400"
|
|
57
|
+
}`,
|
|
58
|
+
};
|
|
59
|
+
default:
|
|
60
|
+
return {
|
|
61
|
+
container: "relative",
|
|
62
|
+
textarea: `w-full px-4 py-3 text-gray-900 placeholder-gray-400 bg-white border-2 border-gray-200 rounded-lg resize-none focus:border-blue-500 focus:ring-blue-500/20 focus:outline-none transition-all duration-200 shadow-sm hover:border-gray-300 ${
|
|
63
|
+
error
|
|
64
|
+
? "border-red-500 focus:border-red-500 focus:ring-red-500/20"
|
|
65
|
+
: ""
|
|
66
|
+
} ${disabled ? "opacity-50 cursor-not-allowed bg-gray-50" : ""}`,
|
|
67
|
+
label: `block text-sm font-medium text-gray-700 mb-2 ${
|
|
68
|
+
required ? "after:content-['*'] after:text-red-500 after:ml-1" : ""
|
|
69
|
+
}`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const variantClasses = getVariantClasses();
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<div className={`${variantClasses.container} ${className}`}>
|
|
78
|
+
{label && <label className={variantClasses.label}>{label}</label>}
|
|
79
|
+
|
|
80
|
+
<div className="relative">
|
|
81
|
+
<textarea
|
|
82
|
+
ref={textareaRef}
|
|
83
|
+
value={value}
|
|
84
|
+
onChange={handleChange}
|
|
85
|
+
onFocus={handleFocus}
|
|
86
|
+
onBlur={handleBlur}
|
|
87
|
+
placeholder={
|
|
88
|
+
variant === "minimal" && isFocused
|
|
89
|
+
? placeholder
|
|
90
|
+
: variant === "minimal"
|
|
91
|
+
? ""
|
|
92
|
+
: placeholder
|
|
93
|
+
}
|
|
94
|
+
rows={rows}
|
|
95
|
+
maxLength={maxLength}
|
|
96
|
+
required={required}
|
|
97
|
+
disabled={disabled}
|
|
98
|
+
className={variantClasses.textarea}
|
|
99
|
+
{...props}
|
|
100
|
+
/>
|
|
101
|
+
|
|
102
|
+
{/* Floating label for minimal variant */}
|
|
103
|
+
{variant === "minimal" && label && (
|
|
104
|
+
<label className={variantClasses.label}>{label}</label>
|
|
105
|
+
)}
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
{/* Bottom section with helper text, error, and character count */}
|
|
109
|
+
<div className="flex justify-between items-start mt-2">
|
|
110
|
+
<div className="flex-1">
|
|
111
|
+
{error && (
|
|
112
|
+
<p className="text-sm text-red-600 flex items-center">
|
|
113
|
+
<svg
|
|
114
|
+
className="w-4 h-4 mr-1 flex-shrink-0"
|
|
115
|
+
fill="currentColor"
|
|
116
|
+
viewBox="0 0 20 20"
|
|
117
|
+
>
|
|
118
|
+
<path
|
|
119
|
+
fillRule="evenodd"
|
|
120
|
+
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z"
|
|
121
|
+
clipRule="evenodd"
|
|
122
|
+
/>
|
|
123
|
+
</svg>
|
|
124
|
+
{error}
|
|
125
|
+
</p>
|
|
126
|
+
)}
|
|
127
|
+
{!error && helperText && (
|
|
128
|
+
<p className="text-sm text-gray-500">{helperText}</p>
|
|
129
|
+
)}
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
{maxLength && (
|
|
133
|
+
<div className="ml-4 flex-shrink-0">
|
|
134
|
+
<span
|
|
135
|
+
className={`text-sm ${
|
|
136
|
+
charCount > maxLength * 0.9
|
|
137
|
+
? "text-amber-600"
|
|
138
|
+
: charCount === maxLength
|
|
139
|
+
? "text-red-600"
|
|
140
|
+
: "text-gray-400"
|
|
141
|
+
}`}
|
|
142
|
+
>
|
|
143
|
+
{charCount}/{maxLength}
|
|
144
|
+
</span>
|
|
145
|
+
</div>
|
|
146
|
+
)}
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
);
|
|
150
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface TextAreaProps
|
|
2
|
+
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
3
|
+
label?: string;
|
|
4
|
+
placeholder?: string;
|
|
5
|
+
value?: string;
|
|
6
|
+
onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
7
|
+
error?: string;
|
|
8
|
+
helperText?: string;
|
|
9
|
+
rows?: number;
|
|
10
|
+
maxLength?: number;
|
|
11
|
+
required?: boolean;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
variant?: "default" | "minimal" | "glass";
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
@@ -29,7 +29,7 @@ interface UseChunkedUploadOptions {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
interface UseChunkedUploadReturn {
|
|
32
|
-
uploadFiles: (files: File[]) => Promise<void>;
|
|
32
|
+
uploadFiles: (files: File[], customParams?: any) => Promise<void>;
|
|
33
33
|
isUploading: boolean;
|
|
34
34
|
uploadProgress: UploadProgress;
|
|
35
35
|
uploadStatus: string;
|
|
@@ -87,10 +87,17 @@ async function uploadChunk(
|
|
|
87
87
|
formData.append("chunkIndex", chunkIndex.toString());
|
|
88
88
|
formData.append("totalChunks", totalChunks.toString());
|
|
89
89
|
formData.append("fileSize", originalFile.size.toString());
|
|
90
|
+
formData.append(
|
|
91
|
+
"additionalParams",
|
|
92
|
+
additionalParams ? JSON.stringify(additionalParams) : "{}"
|
|
93
|
+
);
|
|
90
94
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
95
|
+
// If you have additional parameters to send, you can append them here
|
|
96
|
+
// Uncomment the following lines if you want to include additionalParams in the formData
|
|
97
|
+
|
|
98
|
+
// Object.entries(additionalParams).forEach(([key, value]: any) => {
|
|
99
|
+
// formData.append(key, value);
|
|
100
|
+
// });
|
|
94
101
|
|
|
95
102
|
const response = await fetch(`${baseUrl}`, {
|
|
96
103
|
method: "POST",
|
|
@@ -141,7 +148,7 @@ export function useChunkedUpload(
|
|
|
141
148
|
}, []);
|
|
142
149
|
|
|
143
150
|
const uploadFiles = useCallback(
|
|
144
|
-
async (files: File[]) => {
|
|
151
|
+
async (files: File[], customParams?: any) => {
|
|
145
152
|
if (files.length === 0) {
|
|
146
153
|
throw new Error("No files selected for upload.");
|
|
147
154
|
}
|
|
@@ -189,7 +196,7 @@ export function useChunkedUpload(
|
|
|
189
196
|
currentChunk.totalChunks,
|
|
190
197
|
baseUrl,
|
|
191
198
|
controller.signal,
|
|
192
|
-
additionalParams
|
|
199
|
+
{ ...additionalParams, ...customParams }
|
|
193
200
|
);
|
|
194
201
|
|
|
195
202
|
results.push(result);
|
package/source/globalStyle.ts
CHANGED
|
@@ -5,7 +5,7 @@ export const primary = {
|
|
|
5
5
|
|
|
6
6
|
export const popUp = {
|
|
7
7
|
"pop-up-style":
|
|
8
|
-
"w-full absolute overflow-y-auto px-2 border border-slate-200 rounded-lg mt-[2px] scrollbar bg-white z-90 scrollbar h-auto dark:bg-black dark:text-
|
|
8
|
+
"w-full absolute overflow-y-auto px-2 border border-slate-200 rounded-lg mt-[2px] scrollbar bg-white z-90 scrollbar h-auto dark:bg-black dark:text-black animate-fade-down animate-once animate-duration-200",
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
export const iconClass = {
|