@tunjiadeyemi/ui 1.0.1 → 1.2.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/README.md +109 -10
- package/dist/index.d.mts +22 -10
- package/dist/index.d.ts +22 -10
- package/dist/index.js +170 -64
- package/dist/index.mjs +169 -63
- package/dist/styles.css +21 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,24 +19,33 @@ yarn add @tunjiadeyemi/ui framer-motion lucide-react
|
|
|
19
19
|
First, import the styles in your app's entry point (e.g., `App.tsx` or `main.tsx`):
|
|
20
20
|
|
|
21
21
|
```tsx
|
|
22
|
-
import
|
|
22
|
+
import "@tunjiadeyemi/ui/styles.css";
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
Then use the components:
|
|
26
26
|
|
|
27
27
|
```tsx
|
|
28
|
-
import { Modal } from
|
|
29
|
-
import { useState } from
|
|
28
|
+
import { Modal, Input, Skeleton } from "@tunjiadeyemi/ui";
|
|
29
|
+
import { useState } from "react";
|
|
30
30
|
|
|
31
31
|
function App() {
|
|
32
32
|
const [showModal, setShowModal] = useState(false);
|
|
33
|
+
const [email, setEmail] = useState("");
|
|
33
34
|
|
|
34
35
|
return (
|
|
35
36
|
<>
|
|
37
|
+
<Input
|
|
38
|
+
type="email"
|
|
39
|
+
value={email}
|
|
40
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
41
|
+
placeholder="Enter your email"
|
|
42
|
+
validate={true}
|
|
43
|
+
/>
|
|
44
|
+
|
|
36
45
|
<button onClick={() => setShowModal(true)}>Open Modal</button>
|
|
37
|
-
|
|
38
|
-
<Modal
|
|
39
|
-
showModal={showModal}
|
|
46
|
+
|
|
47
|
+
<Modal
|
|
48
|
+
showModal={showModal}
|
|
40
49
|
onClose={() => setShowModal(false)}
|
|
41
50
|
revealMode="fade"
|
|
42
51
|
className="bg-white p-8 rounded-lg max-w-md"
|
|
@@ -44,24 +53,114 @@ function App() {
|
|
|
44
53
|
<h2 className="text-2xl font-bold mb-4">Modal Title</h2>
|
|
45
54
|
<p>Modal content goes here</p>
|
|
46
55
|
</Modal>
|
|
56
|
+
|
|
57
|
+
<Skeleton width="200px" height="20px" animation="pulse" />
|
|
47
58
|
</>
|
|
48
59
|
);
|
|
49
60
|
}
|
|
50
61
|
```
|
|
51
62
|
|
|
52
|
-
|
|
63
|
+
## Available Components
|
|
53
64
|
|
|
54
|
-
|
|
65
|
+
### Modal
|
|
55
66
|
|
|
56
|
-
A flexible modal component with multiple reveal animations.
|
|
67
|
+
A flexible modal component with multiple reveal animations and optional drag-to-dismiss.
|
|
57
68
|
|
|
58
69
|
**Props:**
|
|
70
|
+
|
|
59
71
|
- `showModal` (boolean): Controls modal visibility
|
|
60
72
|
- `onClose` (function): Callback when modal is closed
|
|
61
|
-
- `revealMode` ('fade' | 'slide-right' | 'slide-bottom'): Animation style
|
|
73
|
+
- `revealMode` ('fade' | 'slide-right' | 'slide-bottom'): Animation style - Default: `'fade'`
|
|
74
|
+
- `isDrag` (boolean): Enable drag to dismiss (for slide-bottom mode) - Default: `false`
|
|
62
75
|
- `className` (string): Custom classes for the modal content
|
|
63
76
|
- `children` (ReactNode): Modal content
|
|
64
77
|
|
|
78
|
+
**Example:**
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
<Modal
|
|
82
|
+
showModal={true}
|
|
83
|
+
onClose={() => console.log("Modal closed")}
|
|
84
|
+
revealMode="slide-bottom"
|
|
85
|
+
isDrag={true}
|
|
86
|
+
className="bg-white p-6 rounded-lg"
|
|
87
|
+
>
|
|
88
|
+
<h2>Your Content</h2>
|
|
89
|
+
</Modal>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Input
|
|
93
|
+
|
|
94
|
+
A customizable input component with built-in validation, password visibility toggle, and OTP support.
|
|
95
|
+
|
|
96
|
+
**Props:**
|
|
97
|
+
|
|
98
|
+
- `type` ('text' | 'email' | 'password' | 'otp' | 'number'): Input type - Default: `'text'`
|
|
99
|
+
- `value` (string): Input value
|
|
100
|
+
- `onChange` (function): Change handler
|
|
101
|
+
- `placeholder` (string): Placeholder text
|
|
102
|
+
- `validate` (boolean): Enable validation - Default: `false`
|
|
103
|
+
- `minLength` (number): Minimum character length
|
|
104
|
+
- `maxLength` (number): Maximum character length
|
|
105
|
+
- `errorMessage` (string): Custom error message
|
|
106
|
+
- `onOtpClick` (function): Callback for OTP button click (when type is 'otp')
|
|
107
|
+
- `className` (string): Additional CSS classes
|
|
108
|
+
- `width` (string): Input width - Default: `'100%'`
|
|
109
|
+
- `height` (string): Input height - Default: `'40px'`
|
|
110
|
+
- `color` (string): Accent color - Default: `'#6B2CE9'`
|
|
111
|
+
- `textColor` (string): Text color - Default: `'white'`
|
|
112
|
+
- `backgroundColor` (string): Background color - Default: `'#1F1F23'`
|
|
113
|
+
- `borderRadius` (string): Border radius - Default: `'10px'`
|
|
114
|
+
|
|
115
|
+
**Example:**
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
<Input
|
|
119
|
+
type="email"
|
|
120
|
+
value={email}
|
|
121
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
122
|
+
placeholder="Enter your email"
|
|
123
|
+
validate={true}
|
|
124
|
+
errorMessage="Please enter a valid email"
|
|
125
|
+
/>
|
|
126
|
+
|
|
127
|
+
<Input
|
|
128
|
+
type="password"
|
|
129
|
+
value={password}
|
|
130
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
131
|
+
minLength={8}
|
|
132
|
+
validate={true}
|
|
133
|
+
/>
|
|
134
|
+
|
|
135
|
+
<Input
|
|
136
|
+
type="otp"
|
|
137
|
+
value={otp}
|
|
138
|
+
onChange={(e) => setOtp(e.target.value)}
|
|
139
|
+
onOtpClick={() => console.log('Send OTP')}
|
|
140
|
+
placeholder="Enter OTP"
|
|
141
|
+
/>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Skeleton
|
|
145
|
+
|
|
146
|
+
A loading placeholder component with multiple variants and animations.
|
|
147
|
+
|
|
148
|
+
**Props:**
|
|
149
|
+
|
|
150
|
+
- `variant` ('text' | 'circular' | 'rectangular'): Skeleton shape - Default: `'rectangular'`
|
|
151
|
+
- `width` (string | number): Width of skeleton - Default: `'100%'`
|
|
152
|
+
- `height` (string | number): Height of skeleton - Default: `'100%'`
|
|
153
|
+
- `animation` ('pulse' | 'wave' | 'none'): Animation type - Default: `'pulse'`
|
|
154
|
+
- `className` (string): Additional CSS classes
|
|
155
|
+
|
|
156
|
+
**Example:**
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
<Skeleton variant="text" width="200px" height="20px" />
|
|
160
|
+
<Skeleton variant="circular" width="50px" height="50px" />
|
|
161
|
+
<Skeleton variant="rectangular" width="100%" height="200px" animation="wave" />
|
|
162
|
+
```
|
|
163
|
+
|
|
65
164
|
## Development
|
|
66
165
|
|
|
67
166
|
```bash
|
package/dist/index.d.mts
CHANGED
|
@@ -1,34 +1,46 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import React$1 from 'react';
|
|
3
2
|
|
|
4
3
|
type RevealMode = 'fade' | 'slide-right' | 'slide-bottom';
|
|
5
4
|
interface ModalProps {
|
|
6
|
-
children: React
|
|
5
|
+
children: React.ReactNode;
|
|
7
6
|
className?: string;
|
|
8
7
|
revealMode?: RevealMode;
|
|
9
8
|
showModal?: boolean;
|
|
10
9
|
onClose?: () => void;
|
|
11
10
|
isDrag?: boolean;
|
|
12
11
|
}
|
|
13
|
-
declare const Modal: ({ children, className, revealMode, showModal, onClose, isDrag }: ModalProps) => react_jsx_runtime.JSX.Element;
|
|
14
12
|
|
|
15
|
-
declare const
|
|
16
|
-
|
|
13
|
+
declare const Modal: ({ isDrag, showModal, onClose, children, className, revealMode, }: ModalProps) => react_jsx_runtime.JSX.Element;
|
|
14
|
+
|
|
15
|
+
interface TextInputProps {
|
|
16
|
+
type?: "password" | "otp" | "text" | "email" | "number";
|
|
17
17
|
value?: string;
|
|
18
18
|
onOtpClick?: () => void;
|
|
19
19
|
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
20
20
|
placeholder?: string;
|
|
21
21
|
className?: string;
|
|
22
22
|
backgroundColor?: string;
|
|
23
|
-
|
|
23
|
+
validate?: boolean;
|
|
24
|
+
minLength?: number;
|
|
25
|
+
maxLength?: number;
|
|
26
|
+
errorMessage?: string;
|
|
27
|
+
color?: string;
|
|
28
|
+
textColor?: string;
|
|
29
|
+
borderRadius?: string;
|
|
30
|
+
height?: string;
|
|
31
|
+
width?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
declare const Input: ({ onChange, onOtpClick, validate, type, value, minLength, maxLength, className, placeholder, errorMessage, width, height, color, textColor, borderRadius, backgroundColor, }: TextInputProps) => react_jsx_runtime.JSX.Element;
|
|
24
35
|
|
|
25
36
|
interface SkeletonProps {
|
|
26
37
|
className?: string;
|
|
27
|
-
variant?:
|
|
38
|
+
variant?: "text" | "circular" | "rectangular";
|
|
28
39
|
width?: string | number;
|
|
29
40
|
height?: string | number;
|
|
30
|
-
animation?:
|
|
41
|
+
animation?: "pulse" | "wave" | "none";
|
|
31
42
|
}
|
|
32
|
-
declare const Skeleton: ({ className, variant, width, height, animation }: SkeletonProps) => react_jsx_runtime.JSX.Element;
|
|
33
43
|
|
|
34
|
-
|
|
44
|
+
declare const Skeleton: ({ className, variant, width, height, animation, }: SkeletonProps) => react_jsx_runtime.JSX.Element;
|
|
45
|
+
|
|
46
|
+
export { Input, Modal, Skeleton };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,34 +1,46 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import React$1 from 'react';
|
|
3
2
|
|
|
4
3
|
type RevealMode = 'fade' | 'slide-right' | 'slide-bottom';
|
|
5
4
|
interface ModalProps {
|
|
6
|
-
children: React
|
|
5
|
+
children: React.ReactNode;
|
|
7
6
|
className?: string;
|
|
8
7
|
revealMode?: RevealMode;
|
|
9
8
|
showModal?: boolean;
|
|
10
9
|
onClose?: () => void;
|
|
11
10
|
isDrag?: boolean;
|
|
12
11
|
}
|
|
13
|
-
declare const Modal: ({ children, className, revealMode, showModal, onClose, isDrag }: ModalProps) => react_jsx_runtime.JSX.Element;
|
|
14
12
|
|
|
15
|
-
declare const
|
|
16
|
-
|
|
13
|
+
declare const Modal: ({ isDrag, showModal, onClose, children, className, revealMode, }: ModalProps) => react_jsx_runtime.JSX.Element;
|
|
14
|
+
|
|
15
|
+
interface TextInputProps {
|
|
16
|
+
type?: "password" | "otp" | "text" | "email" | "number";
|
|
17
17
|
value?: string;
|
|
18
18
|
onOtpClick?: () => void;
|
|
19
19
|
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
20
20
|
placeholder?: string;
|
|
21
21
|
className?: string;
|
|
22
22
|
backgroundColor?: string;
|
|
23
|
-
|
|
23
|
+
validate?: boolean;
|
|
24
|
+
minLength?: number;
|
|
25
|
+
maxLength?: number;
|
|
26
|
+
errorMessage?: string;
|
|
27
|
+
color?: string;
|
|
28
|
+
textColor?: string;
|
|
29
|
+
borderRadius?: string;
|
|
30
|
+
height?: string;
|
|
31
|
+
width?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
declare const Input: ({ onChange, onOtpClick, validate, type, value, minLength, maxLength, className, placeholder, errorMessage, width, height, color, textColor, borderRadius, backgroundColor, }: TextInputProps) => react_jsx_runtime.JSX.Element;
|
|
24
35
|
|
|
25
36
|
interface SkeletonProps {
|
|
26
37
|
className?: string;
|
|
27
|
-
variant?:
|
|
38
|
+
variant?: "text" | "circular" | "rectangular";
|
|
28
39
|
width?: string | number;
|
|
29
40
|
height?: string | number;
|
|
30
|
-
animation?:
|
|
41
|
+
animation?: "pulse" | "wave" | "none";
|
|
31
42
|
}
|
|
32
|
-
declare const Skeleton: ({ className, variant, width, height, animation }: SkeletonProps) => react_jsx_runtime.JSX.Element;
|
|
33
43
|
|
|
34
|
-
|
|
44
|
+
declare const Skeleton: ({ className, variant, width, height, animation, }: SkeletonProps) => react_jsx_runtime.JSX.Element;
|
|
45
|
+
|
|
46
|
+
export { Input, Modal, Skeleton };
|
package/dist/index.js
CHANGED
|
@@ -20,15 +20,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
Input: () => Input_default,
|
|
23
24
|
Modal: () => Modal_default,
|
|
24
|
-
Skeleton: () => Skeleton_default
|
|
25
|
-
TextInput: () => TextInput_default
|
|
25
|
+
Skeleton: () => Skeleton_default
|
|
26
26
|
});
|
|
27
27
|
module.exports = __toCommonJS(index_exports);
|
|
28
28
|
|
|
29
|
-
// src/components/Modal.tsx
|
|
29
|
+
// src/components/Modal/Modal.tsx
|
|
30
30
|
var import_framer_motion = require("framer-motion");
|
|
31
|
-
|
|
31
|
+
|
|
32
|
+
// src/components/Modal/constant.ts
|
|
32
33
|
var revealVariants = {
|
|
33
34
|
fade: {
|
|
34
35
|
initial: { opacity: 0 },
|
|
@@ -46,13 +47,16 @@ var revealVariants = {
|
|
|
46
47
|
exit: { y: "100%", opacity: 0 }
|
|
47
48
|
}
|
|
48
49
|
};
|
|
50
|
+
|
|
51
|
+
// src/components/Modal/Modal.tsx
|
|
52
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
49
53
|
var Modal = ({
|
|
50
|
-
|
|
51
|
-
className,
|
|
52
|
-
revealMode = "fade",
|
|
54
|
+
isDrag = false,
|
|
53
55
|
showModal = true,
|
|
54
56
|
onClose,
|
|
55
|
-
|
|
57
|
+
children,
|
|
58
|
+
className,
|
|
59
|
+
revealMode = "fade"
|
|
56
60
|
}) => {
|
|
57
61
|
const variants = revealVariants[revealMode];
|
|
58
62
|
const handleOverlayClick = (e) => {
|
|
@@ -114,88 +118,190 @@ var Modal = ({
|
|
|
114
118
|
};
|
|
115
119
|
var Modal_default = Modal;
|
|
116
120
|
|
|
117
|
-
// src/components/
|
|
121
|
+
// src/components/Input/Input.tsx
|
|
118
122
|
var import_react = require("react");
|
|
119
123
|
var import_lucide_react = require("lucide-react");
|
|
120
124
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
121
|
-
var
|
|
125
|
+
var Input = ({
|
|
126
|
+
onChange,
|
|
127
|
+
onOtpClick,
|
|
128
|
+
validate = false,
|
|
122
129
|
type,
|
|
123
130
|
value,
|
|
124
|
-
|
|
125
|
-
|
|
131
|
+
minLength,
|
|
132
|
+
maxLength,
|
|
126
133
|
className,
|
|
127
|
-
|
|
128
|
-
|
|
134
|
+
placeholder,
|
|
135
|
+
errorMessage,
|
|
136
|
+
width = "100%",
|
|
137
|
+
height = "40px",
|
|
138
|
+
color = "#6B2CE9",
|
|
139
|
+
textColor = "white",
|
|
140
|
+
borderRadius = "10px",
|
|
141
|
+
backgroundColor = "#1F1F23"
|
|
129
142
|
}) => {
|
|
130
143
|
const [showPassword, setShowPassword] = (0, import_react.useState)(false);
|
|
144
|
+
const [error, setError] = (0, import_react.useState)(null);
|
|
131
145
|
const togglePasswordVisibility = () => {
|
|
132
146
|
setShowPassword(!showPassword);
|
|
133
147
|
};
|
|
148
|
+
const validateInput = (inputValue = "") => {
|
|
149
|
+
if (!validate) {
|
|
150
|
+
setError(null);
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
if (minLength && inputValue.length < minLength) {
|
|
154
|
+
setError(errorMessage || `Minimum ${minLength} characters required`);
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
if (maxLength && inputValue.length > maxLength) {
|
|
158
|
+
setError(errorMessage || `Maximum ${maxLength} characters allowed`);
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
switch (type) {
|
|
162
|
+
case "email":
|
|
163
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
164
|
+
if (inputValue && !emailRegex.test(inputValue)) {
|
|
165
|
+
setError(errorMessage || "Invalid email address");
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
break;
|
|
169
|
+
case "password":
|
|
170
|
+
if (!minLength && inputValue.length < 8) {
|
|
171
|
+
setError(errorMessage || "Password must be at least 8 characters");
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
break;
|
|
175
|
+
case "otp":
|
|
176
|
+
if (inputValue && !/^\d*$/.test(inputValue)) {
|
|
177
|
+
setError(errorMessage || "OTP must contain only numbers");
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
if (!minLength && !maxLength && inputValue.length !== 6) {
|
|
181
|
+
setError(errorMessage || "OTP must be 6 digits");
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
break;
|
|
185
|
+
case "number":
|
|
186
|
+
if (inputValue && isNaN(Number(inputValue))) {
|
|
187
|
+
setError(errorMessage || "Must be a valid number");
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
setError(null);
|
|
193
|
+
return true;
|
|
194
|
+
};
|
|
195
|
+
(0, import_react.useEffect)(() => {
|
|
196
|
+
if (validate && value !== void 0) {
|
|
197
|
+
validateInput(value);
|
|
198
|
+
}
|
|
199
|
+
}, [value, validate, minLength, maxLength, type]);
|
|
134
200
|
if (type === "password") {
|
|
135
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
|
|
136
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
137
|
-
|
|
201
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { width }, children: [
|
|
202
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "relative", style: { width: "100%" }, children: [
|
|
203
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
204
|
+
"input",
|
|
205
|
+
{
|
|
206
|
+
type: showPassword ? "text" : "password",
|
|
207
|
+
value,
|
|
208
|
+
onChange,
|
|
209
|
+
placeholder,
|
|
210
|
+
style: {
|
|
211
|
+
backgroundColor,
|
|
212
|
+
color: textColor,
|
|
213
|
+
borderRadius,
|
|
214
|
+
height,
|
|
215
|
+
width: "100%"
|
|
216
|
+
},
|
|
217
|
+
className: `border ${error ? "border-red-500" : "border-transparent"} placeholder:text-sm text-sm px-4 pr-12 placeholder:opacity-30 focus:outline-none transition ${className}`,
|
|
218
|
+
onFocus: (e) => !error && (e.target.style.borderColor = color),
|
|
219
|
+
onBlur: (e) => e.target.style.borderColor = error ? "#ef4444" : "transparent"
|
|
220
|
+
}
|
|
221
|
+
),
|
|
222
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
223
|
+
"button",
|
|
224
|
+
{
|
|
225
|
+
type: "button",
|
|
226
|
+
onClick: togglePasswordVisibility,
|
|
227
|
+
className: "absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 hover:text-white transition-colors",
|
|
228
|
+
"aria-label": showPassword ? "Hide password" : "Show password",
|
|
229
|
+
children: showPassword ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Eye, { className: "cursor-pointer", size: 18 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.EyeClosed, { className: "cursor-pointer", size: 18 })
|
|
230
|
+
}
|
|
231
|
+
)
|
|
232
|
+
] }),
|
|
233
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-red-500 text-xs mt-1 px-1", children: error })
|
|
234
|
+
] });
|
|
235
|
+
} else if (type === "otp") {
|
|
236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { width }, children: [
|
|
237
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
238
|
+
"div",
|
|
138
239
|
{
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
240
|
+
className: "relative flex items-center gap-4",
|
|
241
|
+
style: { width: "100%" },
|
|
242
|
+
children: [
|
|
243
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
244
|
+
"input",
|
|
245
|
+
{
|
|
246
|
+
type: "number",
|
|
247
|
+
value,
|
|
248
|
+
onChange,
|
|
249
|
+
placeholder,
|
|
250
|
+
style: {
|
|
251
|
+
backgroundColor,
|
|
252
|
+
color: textColor,
|
|
253
|
+
borderRadius,
|
|
254
|
+
height,
|
|
255
|
+
width: "100%"
|
|
256
|
+
},
|
|
257
|
+
className: `border ${error ? "border-red-500" : "border-transparent"} placeholder:text-sm text-sm px-4 pr-28 placeholder:opacity-30 focus:outline-none transition ${className}`,
|
|
258
|
+
onFocus: (e) => !error && (e.target.style.borderColor = color),
|
|
259
|
+
onBlur: (e) => e.target.style.borderColor = error ? "#ef4444" : "transparent"
|
|
260
|
+
}
|
|
261
|
+
),
|
|
262
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
263
|
+
"button",
|
|
264
|
+
{
|
|
265
|
+
type: "button",
|
|
266
|
+
onClick: onOtpClick,
|
|
267
|
+
className: "text-[#A77BFF] cursor-pointer font-medium text-sm w-fit absolute right-4 top-1/2 -translate-y-1/2",
|
|
268
|
+
"aria-label": "Resend code",
|
|
269
|
+
children: "Resend code"
|
|
270
|
+
}
|
|
271
|
+
)
|
|
272
|
+
]
|
|
145
273
|
}
|
|
146
274
|
),
|
|
147
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
148
|
-
"button",
|
|
149
|
-
{
|
|
150
|
-
type: "button",
|
|
151
|
-
onClick: togglePasswordVisibility,
|
|
152
|
-
className: "absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 hover:text-white transition-colors",
|
|
153
|
-
"aria-label": showPassword ? "Hide password" : "Show password",
|
|
154
|
-
children: showPassword ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Eye, { className: "cursor-pointer", size: 18 }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.EyeClosed, { className: "cursor-pointer", size: 18 })
|
|
155
|
-
}
|
|
156
|
-
)
|
|
275
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-red-500 text-xs mt-1 px-1", children: error })
|
|
157
276
|
] });
|
|
158
|
-
} else
|
|
159
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
|
|
277
|
+
} else {
|
|
278
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { width }, children: [
|
|
160
279
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
161
280
|
"input",
|
|
162
281
|
{
|
|
163
|
-
type
|
|
282
|
+
type,
|
|
164
283
|
value,
|
|
165
284
|
onChange,
|
|
166
285
|
placeholder,
|
|
167
|
-
style: {
|
|
168
|
-
|
|
286
|
+
style: {
|
|
287
|
+
backgroundColor,
|
|
288
|
+
color: textColor,
|
|
289
|
+
borderRadius,
|
|
290
|
+
height,
|
|
291
|
+
width: "100%"
|
|
292
|
+
},
|
|
293
|
+
className: `border ${error ? "border-red-500" : "border-transparent"} placeholder:text-sm text-sm px-4 placeholder:opacity-30 focus:outline-none transition ${className}`,
|
|
294
|
+
onFocus: (e) => !error && (e.target.style.borderColor = color),
|
|
295
|
+
onBlur: (e) => e.target.style.borderColor = error ? "#ef4444" : "transparent"
|
|
169
296
|
}
|
|
170
297
|
),
|
|
171
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
172
|
-
"button",
|
|
173
|
-
{
|
|
174
|
-
type: "button",
|
|
175
|
-
onClick: onOtpClick,
|
|
176
|
-
className: "text-[#A77BFF] cursor-pointer font-medium text-sm w-fit absolute right-4 top-1/2 -translate-y-1/2",
|
|
177
|
-
"aria-label": showPassword ? "Hide password" : "Show password",
|
|
178
|
-
children: "Resend code"
|
|
179
|
-
}
|
|
180
|
-
)
|
|
298
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-red-500 text-xs mt-1 px-1", children: error })
|
|
181
299
|
] });
|
|
182
|
-
} else {
|
|
183
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
184
|
-
"input",
|
|
185
|
-
{
|
|
186
|
-
type,
|
|
187
|
-
value,
|
|
188
|
-
onChange,
|
|
189
|
-
placeholder,
|
|
190
|
-
style: { backgroundColor },
|
|
191
|
-
className: `w-full border rounded-[10px] border-transparent placeholder:text-sm text-sm px-4 h-[40px] text-white placeholder:opacity-30 focus:outline-none focus:border-[#6B2CE9] transition ${className}`
|
|
192
|
-
}
|
|
193
|
-
);
|
|
194
300
|
}
|
|
195
301
|
};
|
|
196
|
-
var
|
|
302
|
+
var Input_default = Input;
|
|
197
303
|
|
|
198
|
-
// src/components/Skeleton.tsx
|
|
304
|
+
// src/components/Skeleton/Skeleton.tsx
|
|
199
305
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
200
306
|
var Skeleton = ({
|
|
201
307
|
className = "",
|
|
@@ -241,7 +347,7 @@ var Skeleton = ({
|
|
|
241
347
|
var Skeleton_default = Skeleton;
|
|
242
348
|
// Annotate the CommonJS export names for ESM import in node:
|
|
243
349
|
0 && (module.exports = {
|
|
350
|
+
Input,
|
|
244
351
|
Modal,
|
|
245
|
-
Skeleton
|
|
246
|
-
TextInput
|
|
352
|
+
Skeleton
|
|
247
353
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
// src/components/Modal.tsx
|
|
1
|
+
// src/components/Modal/Modal.tsx
|
|
2
2
|
import { motion, AnimatePresence } from "framer-motion";
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
// src/components/Modal/constant.ts
|
|
4
5
|
var revealVariants = {
|
|
5
6
|
fade: {
|
|
6
7
|
initial: { opacity: 0 },
|
|
@@ -18,13 +19,16 @@ var revealVariants = {
|
|
|
18
19
|
exit: { y: "100%", opacity: 0 }
|
|
19
20
|
}
|
|
20
21
|
};
|
|
22
|
+
|
|
23
|
+
// src/components/Modal/Modal.tsx
|
|
24
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
21
25
|
var Modal = ({
|
|
22
|
-
|
|
23
|
-
className,
|
|
24
|
-
revealMode = "fade",
|
|
26
|
+
isDrag = false,
|
|
25
27
|
showModal = true,
|
|
26
28
|
onClose,
|
|
27
|
-
|
|
29
|
+
children,
|
|
30
|
+
className,
|
|
31
|
+
revealMode = "fade"
|
|
28
32
|
}) => {
|
|
29
33
|
const variants = revealVariants[revealMode];
|
|
30
34
|
const handleOverlayClick = (e) => {
|
|
@@ -86,88 +90,190 @@ var Modal = ({
|
|
|
86
90
|
};
|
|
87
91
|
var Modal_default = Modal;
|
|
88
92
|
|
|
89
|
-
// src/components/
|
|
90
|
-
import { useState } from "react";
|
|
93
|
+
// src/components/Input/Input.tsx
|
|
94
|
+
import { useState, useEffect } from "react";
|
|
91
95
|
import { Eye, EyeClosed } from "lucide-react";
|
|
92
96
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
93
|
-
var
|
|
97
|
+
var Input = ({
|
|
98
|
+
onChange,
|
|
99
|
+
onOtpClick,
|
|
100
|
+
validate = false,
|
|
94
101
|
type,
|
|
95
102
|
value,
|
|
96
|
-
|
|
97
|
-
|
|
103
|
+
minLength,
|
|
104
|
+
maxLength,
|
|
98
105
|
className,
|
|
99
|
-
|
|
100
|
-
|
|
106
|
+
placeholder,
|
|
107
|
+
errorMessage,
|
|
108
|
+
width = "100%",
|
|
109
|
+
height = "40px",
|
|
110
|
+
color = "#6B2CE9",
|
|
111
|
+
textColor = "white",
|
|
112
|
+
borderRadius = "10px",
|
|
113
|
+
backgroundColor = "#1F1F23"
|
|
101
114
|
}) => {
|
|
102
115
|
const [showPassword, setShowPassword] = useState(false);
|
|
116
|
+
const [error, setError] = useState(null);
|
|
103
117
|
const togglePasswordVisibility = () => {
|
|
104
118
|
setShowPassword(!showPassword);
|
|
105
119
|
};
|
|
120
|
+
const validateInput = (inputValue = "") => {
|
|
121
|
+
if (!validate) {
|
|
122
|
+
setError(null);
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
if (minLength && inputValue.length < minLength) {
|
|
126
|
+
setError(errorMessage || `Minimum ${minLength} characters required`);
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
if (maxLength && inputValue.length > maxLength) {
|
|
130
|
+
setError(errorMessage || `Maximum ${maxLength} characters allowed`);
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
switch (type) {
|
|
134
|
+
case "email":
|
|
135
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
136
|
+
if (inputValue && !emailRegex.test(inputValue)) {
|
|
137
|
+
setError(errorMessage || "Invalid email address");
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
case "password":
|
|
142
|
+
if (!minLength && inputValue.length < 8) {
|
|
143
|
+
setError(errorMessage || "Password must be at least 8 characters");
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
break;
|
|
147
|
+
case "otp":
|
|
148
|
+
if (inputValue && !/^\d*$/.test(inputValue)) {
|
|
149
|
+
setError(errorMessage || "OTP must contain only numbers");
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
if (!minLength && !maxLength && inputValue.length !== 6) {
|
|
153
|
+
setError(errorMessage || "OTP must be 6 digits");
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
break;
|
|
157
|
+
case "number":
|
|
158
|
+
if (inputValue && isNaN(Number(inputValue))) {
|
|
159
|
+
setError(errorMessage || "Must be a valid number");
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
setError(null);
|
|
165
|
+
return true;
|
|
166
|
+
};
|
|
167
|
+
useEffect(() => {
|
|
168
|
+
if (validate && value !== void 0) {
|
|
169
|
+
validateInput(value);
|
|
170
|
+
}
|
|
171
|
+
}, [value, validate, minLength, maxLength, type]);
|
|
106
172
|
if (type === "password") {
|
|
107
|
-
return /* @__PURE__ */ jsxs2("div", {
|
|
108
|
-
/* @__PURE__ */
|
|
109
|
-
|
|
173
|
+
return /* @__PURE__ */ jsxs2("div", { style: { width }, children: [
|
|
174
|
+
/* @__PURE__ */ jsxs2("div", { className: "relative", style: { width: "100%" }, children: [
|
|
175
|
+
/* @__PURE__ */ jsx2(
|
|
176
|
+
"input",
|
|
177
|
+
{
|
|
178
|
+
type: showPassword ? "text" : "password",
|
|
179
|
+
value,
|
|
180
|
+
onChange,
|
|
181
|
+
placeholder,
|
|
182
|
+
style: {
|
|
183
|
+
backgroundColor,
|
|
184
|
+
color: textColor,
|
|
185
|
+
borderRadius,
|
|
186
|
+
height,
|
|
187
|
+
width: "100%"
|
|
188
|
+
},
|
|
189
|
+
className: `border ${error ? "border-red-500" : "border-transparent"} placeholder:text-sm text-sm px-4 pr-12 placeholder:opacity-30 focus:outline-none transition ${className}`,
|
|
190
|
+
onFocus: (e) => !error && (e.target.style.borderColor = color),
|
|
191
|
+
onBlur: (e) => e.target.style.borderColor = error ? "#ef4444" : "transparent"
|
|
192
|
+
}
|
|
193
|
+
),
|
|
194
|
+
/* @__PURE__ */ jsx2(
|
|
195
|
+
"button",
|
|
196
|
+
{
|
|
197
|
+
type: "button",
|
|
198
|
+
onClick: togglePasswordVisibility,
|
|
199
|
+
className: "absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 hover:text-white transition-colors",
|
|
200
|
+
"aria-label": showPassword ? "Hide password" : "Show password",
|
|
201
|
+
children: showPassword ? /* @__PURE__ */ jsx2(Eye, { className: "cursor-pointer", size: 18 }) : /* @__PURE__ */ jsx2(EyeClosed, { className: "cursor-pointer", size: 18 })
|
|
202
|
+
}
|
|
203
|
+
)
|
|
204
|
+
] }),
|
|
205
|
+
error && /* @__PURE__ */ jsx2("p", { className: "text-red-500 text-xs mt-1 px-1", children: error })
|
|
206
|
+
] });
|
|
207
|
+
} else if (type === "otp") {
|
|
208
|
+
return /* @__PURE__ */ jsxs2("div", { style: { width }, children: [
|
|
209
|
+
/* @__PURE__ */ jsxs2(
|
|
210
|
+
"div",
|
|
110
211
|
{
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
212
|
+
className: "relative flex items-center gap-4",
|
|
213
|
+
style: { width: "100%" },
|
|
214
|
+
children: [
|
|
215
|
+
/* @__PURE__ */ jsx2(
|
|
216
|
+
"input",
|
|
217
|
+
{
|
|
218
|
+
type: "number",
|
|
219
|
+
value,
|
|
220
|
+
onChange,
|
|
221
|
+
placeholder,
|
|
222
|
+
style: {
|
|
223
|
+
backgroundColor,
|
|
224
|
+
color: textColor,
|
|
225
|
+
borderRadius,
|
|
226
|
+
height,
|
|
227
|
+
width: "100%"
|
|
228
|
+
},
|
|
229
|
+
className: `border ${error ? "border-red-500" : "border-transparent"} placeholder:text-sm text-sm px-4 pr-28 placeholder:opacity-30 focus:outline-none transition ${className}`,
|
|
230
|
+
onFocus: (e) => !error && (e.target.style.borderColor = color),
|
|
231
|
+
onBlur: (e) => e.target.style.borderColor = error ? "#ef4444" : "transparent"
|
|
232
|
+
}
|
|
233
|
+
),
|
|
234
|
+
/* @__PURE__ */ jsx2(
|
|
235
|
+
"button",
|
|
236
|
+
{
|
|
237
|
+
type: "button",
|
|
238
|
+
onClick: onOtpClick,
|
|
239
|
+
className: "text-[#A77BFF] cursor-pointer font-medium text-sm w-fit absolute right-4 top-1/2 -translate-y-1/2",
|
|
240
|
+
"aria-label": "Resend code",
|
|
241
|
+
children: "Resend code"
|
|
242
|
+
}
|
|
243
|
+
)
|
|
244
|
+
]
|
|
117
245
|
}
|
|
118
246
|
),
|
|
119
|
-
/* @__PURE__ */ jsx2(
|
|
120
|
-
"button",
|
|
121
|
-
{
|
|
122
|
-
type: "button",
|
|
123
|
-
onClick: togglePasswordVisibility,
|
|
124
|
-
className: "absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 hover:text-white transition-colors",
|
|
125
|
-
"aria-label": showPassword ? "Hide password" : "Show password",
|
|
126
|
-
children: showPassword ? /* @__PURE__ */ jsx2(Eye, { className: "cursor-pointer", size: 18 }) : /* @__PURE__ */ jsx2(EyeClosed, { className: "cursor-pointer", size: 18 })
|
|
127
|
-
}
|
|
128
|
-
)
|
|
247
|
+
error && /* @__PURE__ */ jsx2("p", { className: "text-red-500 text-xs mt-1 px-1", children: error })
|
|
129
248
|
] });
|
|
130
|
-
} else
|
|
131
|
-
return /* @__PURE__ */ jsxs2("div", {
|
|
249
|
+
} else {
|
|
250
|
+
return /* @__PURE__ */ jsxs2("div", { style: { width }, children: [
|
|
132
251
|
/* @__PURE__ */ jsx2(
|
|
133
252
|
"input",
|
|
134
253
|
{
|
|
135
|
-
type
|
|
254
|
+
type,
|
|
136
255
|
value,
|
|
137
256
|
onChange,
|
|
138
257
|
placeholder,
|
|
139
|
-
style: {
|
|
140
|
-
|
|
258
|
+
style: {
|
|
259
|
+
backgroundColor,
|
|
260
|
+
color: textColor,
|
|
261
|
+
borderRadius,
|
|
262
|
+
height,
|
|
263
|
+
width: "100%"
|
|
264
|
+
},
|
|
265
|
+
className: `border ${error ? "border-red-500" : "border-transparent"} placeholder:text-sm text-sm px-4 placeholder:opacity-30 focus:outline-none transition ${className}`,
|
|
266
|
+
onFocus: (e) => !error && (e.target.style.borderColor = color),
|
|
267
|
+
onBlur: (e) => e.target.style.borderColor = error ? "#ef4444" : "transparent"
|
|
141
268
|
}
|
|
142
269
|
),
|
|
143
|
-
/* @__PURE__ */ jsx2(
|
|
144
|
-
"button",
|
|
145
|
-
{
|
|
146
|
-
type: "button",
|
|
147
|
-
onClick: onOtpClick,
|
|
148
|
-
className: "text-[#A77BFF] cursor-pointer font-medium text-sm w-fit absolute right-4 top-1/2 -translate-y-1/2",
|
|
149
|
-
"aria-label": showPassword ? "Hide password" : "Show password",
|
|
150
|
-
children: "Resend code"
|
|
151
|
-
}
|
|
152
|
-
)
|
|
270
|
+
error && /* @__PURE__ */ jsx2("p", { className: "text-red-500 text-xs mt-1 px-1", children: error })
|
|
153
271
|
] });
|
|
154
|
-
} else {
|
|
155
|
-
return /* @__PURE__ */ jsx2(
|
|
156
|
-
"input",
|
|
157
|
-
{
|
|
158
|
-
type,
|
|
159
|
-
value,
|
|
160
|
-
onChange,
|
|
161
|
-
placeholder,
|
|
162
|
-
style: { backgroundColor },
|
|
163
|
-
className: `w-full border rounded-[10px] border-transparent placeholder:text-sm text-sm px-4 h-[40px] text-white placeholder:opacity-30 focus:outline-none focus:border-[#6B2CE9] transition ${className}`
|
|
164
|
-
}
|
|
165
|
-
);
|
|
166
272
|
}
|
|
167
273
|
};
|
|
168
|
-
var
|
|
274
|
+
var Input_default = Input;
|
|
169
275
|
|
|
170
|
-
// src/components/Skeleton.tsx
|
|
276
|
+
// src/components/Skeleton/Skeleton.tsx
|
|
171
277
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
172
278
|
var Skeleton = ({
|
|
173
279
|
className = "",
|
|
@@ -212,7 +318,7 @@ var Skeleton = ({
|
|
|
212
318
|
};
|
|
213
319
|
var Skeleton_default = Skeleton;
|
|
214
320
|
export {
|
|
321
|
+
Input_default as Input,
|
|
215
322
|
Modal_default as Modal,
|
|
216
|
-
Skeleton_default as Skeleton
|
|
217
|
-
TextInput_default as TextInput
|
|
323
|
+
Skeleton_default as Skeleton
|
|
218
324
|
};
|
package/dist/styles.css
CHANGED
|
@@ -7,11 +7,14 @@
|
|
|
7
7
|
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
8
8
|
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
|
|
9
9
|
"Liberation Mono", "Courier New", monospace;
|
|
10
|
+
--color-red-500: oklch(0.637 0.237 25.331);
|
|
10
11
|
--color-gray-400: oklch(0.707 0.022 261.325);
|
|
11
12
|
--color-black: #000;
|
|
12
13
|
--color-white: #fff;
|
|
13
14
|
--spacing: 0.25rem;
|
|
14
15
|
--container-md: 28rem;
|
|
16
|
+
--text-xs: 0.75rem;
|
|
17
|
+
--text-xs--line-height: calc(1 / 0.75);
|
|
15
18
|
--text-sm: 0.875rem;
|
|
16
19
|
--text-sm--line-height: calc(1.25 / 0.875);
|
|
17
20
|
--text-2xl: 1.5rem;
|
|
@@ -213,6 +216,9 @@
|
|
|
213
216
|
.z-50 {
|
|
214
217
|
z-index: 50;
|
|
215
218
|
}
|
|
219
|
+
.mt-1 {
|
|
220
|
+
margin-top: calc(var(--spacing) * 1);
|
|
221
|
+
}
|
|
216
222
|
.mb-4 {
|
|
217
223
|
margin-bottom: calc(var(--spacing) * 4);
|
|
218
224
|
}
|
|
@@ -222,9 +228,6 @@
|
|
|
222
228
|
.h-4 {
|
|
223
229
|
height: calc(var(--spacing) * 4);
|
|
224
230
|
}
|
|
225
|
-
.h-\[40px\] {
|
|
226
|
-
height: 40px;
|
|
227
|
-
}
|
|
228
231
|
.w-fit {
|
|
229
232
|
width: -moz-fit-content;
|
|
230
233
|
width: fit-content;
|
|
@@ -260,9 +263,6 @@
|
|
|
260
263
|
.rounded-\[4px\] {
|
|
261
264
|
border-radius: 4px;
|
|
262
265
|
}
|
|
263
|
-
.rounded-\[10px\] {
|
|
264
|
-
border-radius: 10px;
|
|
265
|
-
}
|
|
266
266
|
.rounded-\[12px\] {
|
|
267
267
|
border-radius: 12px;
|
|
268
268
|
}
|
|
@@ -276,6 +276,9 @@
|
|
|
276
276
|
border-style: var(--tw-border-style);
|
|
277
277
|
border-width: 1px;
|
|
278
278
|
}
|
|
279
|
+
.border-red-500 {
|
|
280
|
+
border-color: var(--color-red-500);
|
|
281
|
+
}
|
|
279
282
|
.border-transparent {
|
|
280
283
|
border-color: transparent;
|
|
281
284
|
}
|
|
@@ -311,9 +314,15 @@
|
|
|
311
314
|
.bg-\[length\:200\%_100\%\] {
|
|
312
315
|
background-size: 200% 100%;
|
|
313
316
|
}
|
|
317
|
+
.p-6 {
|
|
318
|
+
padding: calc(var(--spacing) * 6);
|
|
319
|
+
}
|
|
314
320
|
.p-8 {
|
|
315
321
|
padding: calc(var(--spacing) * 8);
|
|
316
322
|
}
|
|
323
|
+
.px-1 {
|
|
324
|
+
padding-inline: calc(var(--spacing) * 1);
|
|
325
|
+
}
|
|
317
326
|
.px-4 {
|
|
318
327
|
padding-inline: calc(var(--spacing) * 4);
|
|
319
328
|
}
|
|
@@ -334,6 +343,10 @@
|
|
|
334
343
|
font-size: var(--text-sm);
|
|
335
344
|
line-height: var(--tw-leading, var(--text-sm--line-height));
|
|
336
345
|
}
|
|
346
|
+
.text-xs {
|
|
347
|
+
font-size: var(--text-xs);
|
|
348
|
+
line-height: var(--tw-leading, var(--text-xs--line-height));
|
|
349
|
+
}
|
|
337
350
|
.font-bold {
|
|
338
351
|
--tw-font-weight: var(--font-weight-bold);
|
|
339
352
|
font-weight: var(--font-weight-bold);
|
|
@@ -348,8 +361,8 @@
|
|
|
348
361
|
.text-gray-400 {
|
|
349
362
|
color: var(--color-gray-400);
|
|
350
363
|
}
|
|
351
|
-
.text-
|
|
352
|
-
color: var(--color-
|
|
364
|
+
.text-red-500 {
|
|
365
|
+
color: var(--color-red-500);
|
|
353
366
|
}
|
|
354
367
|
.transition {
|
|
355
368
|
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, backdrop-filter, display, content-visibility, overlay, pointer-events;
|
|
@@ -386,11 +399,6 @@
|
|
|
386
399
|
}
|
|
387
400
|
}
|
|
388
401
|
}
|
|
389
|
-
.focus\:border-\[\#6B2CE9\] {
|
|
390
|
-
&:focus {
|
|
391
|
-
border-color: #6B2CE9;
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
402
|
.focus\:outline-none {
|
|
395
403
|
&:focus {
|
|
396
404
|
--tw-outline-style: none;
|