@tunjiadeyemi/ui 1.3.0 → 1.4.1

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
@@ -2,6 +2,12 @@
2
2
 
3
3
  A collection of reusable React UI components built with TypeScript.
4
4
 
5
+ ## Storybook
6
+
7
+ Explore all components in Storybook:
8
+
9
+ https://69a67d791bd8666f2b32dd2d-ujpylcgcxt.chromatic.com/
10
+
5
11
  ## Installation
6
12
 
7
13
  ```bash
@@ -14,36 +20,47 @@ or
14
20
  yarn add @tunjiadeyemi/ui framer-motion lucide-react
15
21
  ```
16
22
 
17
- ## Usage
23
+ ## Quick Start
18
24
 
19
- First, import the styles in your app's entry point (e.g., `App.tsx` or `main.tsx`):
25
+ Import styles once (for example in `main.tsx` or `App.tsx`):
20
26
 
21
27
  ```tsx
22
- import "@tunjiadeyemi/ui/styles.css";
28
+ import '@tunjiadeyemi/ui/styles.css';
23
29
  ```
24
30
 
25
- Then use the components:
31
+ Use the components:
26
32
 
27
33
  ```tsx
28
- import { Modal, Input, Skeleton } from "@tunjiadeyemi/ui";
29
- import { useState } from "react";
34
+ import { useState } from 'react';
35
+ import { Modal, Input, Skeleton, Accordion, Rating, ScrollToTop } from '@tunjiadeyemi/ui';
30
36
 
31
37
  function App() {
32
38
  const [showModal, setShowModal] = useState(false);
33
- const [email, setEmail] = useState("");
39
+ const [email, setEmail] = useState('');
34
40
 
35
41
  return (
36
42
  <>
43
+ <ScrollToTop />
44
+
37
45
  <Input
38
46
  type="email"
39
47
  value={email}
40
48
  onChange={(e) => setEmail(e.target.value)}
41
49
  placeholder="Enter your email"
42
- validate={true}
50
+ validate
43
51
  />
44
52
 
45
- <button onClick={() => setShowModal(true)}>Open Modal</button>
53
+ <Accordion
54
+ items={[
55
+ { question: 'What is this?', answer: 'A reusable UI library.' },
56
+ { question: 'Does it support TypeScript?', answer: 'Yes.' }
57
+ ]}
58
+ />
59
+
60
+ <Rating rating={4} total={5} />
61
+ <Skeleton width="200px" height="20px" animation="pulse" />
46
62
 
63
+ <button onClick={() => setShowModal(true)}>Open Modal</button>
47
64
  <Modal
48
65
  showModal={showModal}
49
66
  onClose={() => setShowModal(false)}
@@ -53,66 +70,62 @@ function App() {
53
70
  <h2 className="text-2xl font-bold mb-4">Modal Title</h2>
54
71
  <p>Modal content goes here</p>
55
72
  </Modal>
56
-
57
- <Skeleton width="200px" height="20px" animation="pulse" />
58
73
  </>
59
74
  );
60
75
  }
61
76
  ```
62
77
 
63
- ## Available Components
78
+ ## Components
64
79
 
65
80
  ### Modal
66
81
 
67
- A flexible modal component with multiple reveal animations and optional drag-to-dismiss.
68
-
69
- **Props:**
82
+ Flexible modal component with multiple reveal animations.
70
83
 
71
- - `showModal` (boolean): Controls modal visibility
72
- - `onClose` (function): Callback when modal is closed
73
- - `revealMode` ('fade' | 'slide-right' | 'slide-bottom'): Animation style - Default: `'fade'`
74
- - `isDrag` (boolean): Enable drag to dismiss (for slide-bottom mode) - Default: `false`
75
- - `className` (string): Custom classes for the modal content
76
- - `children` (ReactNode): Modal content
84
+ **Props**
77
85
 
78
- **Example:**
86
+ - `children: React.ReactNode`
87
+ - `className?: string`
88
+ - `revealMode?: 'fade' | 'slide-right' | 'slide-bottom'` (default: `'fade'`)
89
+ - `showModal?: boolean` (default: `true`)
90
+ - `onClose?: () => void`
91
+ - `isDrag?: boolean` (default: `false`)
79
92
 
80
93
  ```tsx
81
94
  <Modal
82
- showModal={true}
83
- onClose={() => console.log("Modal closed")}
95
+ showModal
96
+ onClose={() => console.log('Modal closed')}
84
97
  revealMode="slide-bottom"
85
- isDrag={true}
98
+ isDrag
86
99
  className="bg-white p-6 rounded-lg"
87
100
  >
88
- <h2>Your Content</h2>
101
+ <h2>Your content</h2>
89
102
  </Modal>
90
103
  ```
91
104
 
92
105
  ### Input
93
106
 
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:**
107
+ Customizable input with validation, password visibility toggle, and OTP resend support.
108
+
109
+ **Props**
110
+
111
+ - `type?: 'password' | 'otp' | 'text' | 'email' | 'number'`
112
+ - `value?: string`
113
+ - `onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void`
114
+ - `onOtpClick?: () => void`
115
+ - `placeholder?: string`
116
+ - `validate?: boolean` (default: `false`)
117
+ - `minLength?: number`
118
+ - `maxLength?: number`
119
+ - `errorMessage?: string`
120
+ - `className?: string`
121
+ - `backgroundColor?: string` (default: `'#1F1F23'`)
122
+ - `borderColor?: string` (default: `'#6B2CE9'`)
123
+ - `textColor?: string` (default: `'white'`)
124
+ - `borderRadius?: string` (default: `'10px'`)
125
+ - `height?: string` (default: `'40px'`)
126
+ - `width?: string` (default: `'100%'`)
127
+ - `eyeIcon?: React.ReactNode`
128
+ - `eyeClosedIcon?: React.ReactNode`
116
129
 
117
130
  ```tsx
118
131
  <Input
@@ -120,45 +133,74 @@ A customizable input component with built-in validation, password visibility tog
120
133
  value={email}
121
134
  onChange={(e) => setEmail(e.target.value)}
122
135
  placeholder="Enter your email"
123
- validate={true}
136
+ validate
124
137
  errorMessage="Please enter a valid email"
125
138
  />
139
+ ```
126
140
 
127
- <Input
128
- type="password"
129
- value={password}
130
- onChange={(e) => setPassword(e.target.value)}
131
- minLength={8}
132
- validate={true}
133
- />
141
+ ### Skeleton
134
142
 
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"
143
+ Loading placeholder component with shape variants and animation options.
144
+
145
+ **Props**
146
+
147
+ - `className?: string`
148
+ - `variant?: 'text' | 'circular' | 'rectangular'` (default: `'rectangular'`)
149
+ - `width?: string | number` (default: `'100%'`)
150
+ - `height?: string | number` (default: `'100%'`)
151
+ - `animation?: 'pulse' | 'wave' | 'none'` (default: `'pulse'`)
152
+
153
+ ```tsx
154
+ <Skeleton variant="text" width="200px" height="20px" />
155
+ <Skeleton variant="circular" width={50} height={50} />
156
+ <Skeleton variant="rectangular" width="100%" height="200px" animation="wave" />
157
+ ```
158
+
159
+ ### Accordion
160
+
161
+ Simple accordion that supports multiple open items.
162
+
163
+ **Types & Props**
164
+
165
+ - `AccordionItem`: `{ question: string; answer: React.ReactNode; icon?: React.ReactNode }`
166
+ - `icon?: React.ReactNode`
167
+ - `items: AccordionItem[]`
168
+ - `className?: string`
169
+ - `containerClassName?: string`
170
+ - `onIconClick?: (idx: number, item: AccordionItem) => void`
171
+
172
+ ```tsx
173
+ <Accordion
174
+ items={[
175
+ { question: 'What is this?', answer: 'An accordion item.' },
176
+ { question: 'Can multiple items be open?', answer: 'Yes.' }
177
+ ]}
141
178
  />
142
179
  ```
143
180
 
144
- ### Skeleton
181
+ ### Rating
182
+
183
+ Rating display with default star icon or custom icon image.
184
+
185
+ **Props**
145
186
 
146
- A loading placeholder component with multiple variants and animations.
187
+ - `rating: number`
188
+ - `total: number`
189
+ - `icon?: string`
190
+ - `showOnlyRated?: boolean` (default: `false`)
147
191
 
148
- **Props:**
192
+ ```tsx
193
+ <Rating rating={3} total={5} />
194
+ <Rating rating={4} total={5} icon="/icons/star.svg" />
195
+ <Rating rating={4} total={5} showOnlyRated />
196
+ ```
149
197
 
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
198
+ ### ScrollToTop
155
199
 
156
- **Example:**
200
+ Utility component that scrolls to top on mount and browser navigation events.
157
201
 
158
202
  ```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" />
203
+ <ScrollToTop />
162
204
  ```
163
205
 
164
206
  ## Development
@@ -167,13 +209,9 @@ A loading placeholder component with multiple variants and animations.
167
209
  # Install dependencies
168
210
  npm install
169
211
 
170
- # Build the package
212
+ # Build package (JS + types + styles)
171
213
  npm run build
172
214
 
173
- # Watch mode for development
215
+ # Watch mode
174
216
  npm run dev
175
217
  ```
176
-
177
- ## License
178
-
179
- MIT © Tunji Adeyemi
package/dist/index.d.mts CHANGED
@@ -24,7 +24,7 @@ interface TextInputProps {
24
24
  minLength?: number;
25
25
  maxLength?: number;
26
26
  errorMessage?: string;
27
- color?: string;
27
+ borderColor?: string;
28
28
  textColor?: string;
29
29
  borderRadius?: string;
30
30
  height?: string;
@@ -33,7 +33,7 @@ interface TextInputProps {
33
33
  eyeClosedIcon?: React.ReactNode;
34
34
  }
35
35
 
36
- declare const Input: ({ onChange, onOtpClick, validate, type, value, minLength, maxLength, className, placeholder, errorMessage, width, height, color, textColor, borderRadius, backgroundColor, eyeIcon, eyeClosedIcon }: TextInputProps) => react_jsx_runtime.JSX.Element;
36
+ declare const Input: ({ onChange, onOtpClick, validate, type, value, minLength, maxLength, className, placeholder, errorMessage, width, height, borderColor, textColor, borderRadius, backgroundColor, eyeIcon, eyeClosedIcon }: TextInputProps) => react_jsx_runtime.JSX.Element;
37
37
 
38
38
  interface SkeletonProps {
39
39
  className?: string;
@@ -45,4 +45,26 @@ interface SkeletonProps {
45
45
 
46
46
  declare const Skeleton: ({ className, variant, width, height, animation, }: SkeletonProps) => react_jsx_runtime.JSX.Element;
47
47
 
48
- export { Input, Modal, Skeleton };
48
+ declare const ScrollToTop: () => null;
49
+
50
+ interface AccordionItem {
51
+ question: string;
52
+ answer: React.ReactNode;
53
+ icon?: React.ReactNode;
54
+ }
55
+ interface AccordionProps {
56
+ icon?: React.ReactNode;
57
+ items: AccordionItem[];
58
+ className?: string;
59
+ containerClassName?: string;
60
+ onIconClick?: (idx: number, item: AccordionItem) => void;
61
+ }
62
+ declare const Accordion: ({ icon, items, containerClassName, className, onIconClick }: AccordionProps) => react_jsx_runtime.JSX.Element;
63
+
64
+ declare const Rating: ({ rating, total, icon }: {
65
+ rating: number;
66
+ total: number;
67
+ icon?: string;
68
+ }) => react_jsx_runtime.JSX.Element;
69
+
70
+ export { Accordion, Input, Modal, Rating, ScrollToTop, Skeleton };
package/dist/index.d.ts CHANGED
@@ -24,7 +24,7 @@ interface TextInputProps {
24
24
  minLength?: number;
25
25
  maxLength?: number;
26
26
  errorMessage?: string;
27
- color?: string;
27
+ borderColor?: string;
28
28
  textColor?: string;
29
29
  borderRadius?: string;
30
30
  height?: string;
@@ -33,7 +33,7 @@ interface TextInputProps {
33
33
  eyeClosedIcon?: React.ReactNode;
34
34
  }
35
35
 
36
- declare const Input: ({ onChange, onOtpClick, validate, type, value, minLength, maxLength, className, placeholder, errorMessage, width, height, color, textColor, borderRadius, backgroundColor, eyeIcon, eyeClosedIcon }: TextInputProps) => react_jsx_runtime.JSX.Element;
36
+ declare const Input: ({ onChange, onOtpClick, validate, type, value, minLength, maxLength, className, placeholder, errorMessage, width, height, borderColor, textColor, borderRadius, backgroundColor, eyeIcon, eyeClosedIcon }: TextInputProps) => react_jsx_runtime.JSX.Element;
37
37
 
38
38
  interface SkeletonProps {
39
39
  className?: string;
@@ -45,4 +45,26 @@ interface SkeletonProps {
45
45
 
46
46
  declare const Skeleton: ({ className, variant, width, height, animation, }: SkeletonProps) => react_jsx_runtime.JSX.Element;
47
47
 
48
- export { Input, Modal, Skeleton };
48
+ declare const ScrollToTop: () => null;
49
+
50
+ interface AccordionItem {
51
+ question: string;
52
+ answer: React.ReactNode;
53
+ icon?: React.ReactNode;
54
+ }
55
+ interface AccordionProps {
56
+ icon?: React.ReactNode;
57
+ items: AccordionItem[];
58
+ className?: string;
59
+ containerClassName?: string;
60
+ onIconClick?: (idx: number, item: AccordionItem) => void;
61
+ }
62
+ declare const Accordion: ({ icon, items, containerClassName, className, onIconClick }: AccordionProps) => react_jsx_runtime.JSX.Element;
63
+
64
+ declare const Rating: ({ rating, total, icon }: {
65
+ rating: number;
66
+ total: number;
67
+ icon?: string;
68
+ }) => react_jsx_runtime.JSX.Element;
69
+
70
+ export { Accordion, Input, Modal, Rating, ScrollToTop, Skeleton };
package/dist/index.js CHANGED
@@ -20,8 +20,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ Accordion: () => Accordion_default,
23
24
  Input: () => Input_default,
24
25
  Modal: () => Modal_default,
26
+ Rating: () => Rating_default,
27
+ ScrollToTop: () => ScrollToTop_default,
25
28
  Skeleton: () => Skeleton_default
26
29
  });
27
30
  module.exports = __toCommonJS(index_exports);
@@ -135,7 +138,7 @@ var Input = ({
135
138
  errorMessage,
136
139
  width = "100%",
137
140
  height = "40px",
138
- color = "#6B2CE9",
141
+ borderColor = "#6B2CE9",
139
142
  textColor = "white",
140
143
  borderRadius = "10px",
141
144
  backgroundColor = "#1F1F23",
@@ -217,7 +220,7 @@ var Input = ({
217
220
  width: "100%"
218
221
  },
219
222
  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}`,
220
- onFocus: (e) => !error && (e.target.style.borderColor = color),
223
+ onFocus: (e) => !error && (e.target.style.borderColor = borderColor),
221
224
  onBlur: (e) => e.target.style.borderColor = error ? "#ef4444" : "transparent"
222
225
  }
223
226
  ),
@@ -252,7 +255,7 @@ var Input = ({
252
255
  width: "100%"
253
256
  },
254
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}`,
255
- onFocus: (e) => !error && (e.target.style.borderColor = color),
258
+ onFocus: (e) => !error && (e.target.style.borderColor = borderColor),
256
259
  onBlur: (e) => e.target.style.borderColor = error ? "#ef4444" : "transparent"
257
260
  }
258
261
  ),
@@ -286,7 +289,7 @@ var Input = ({
286
289
  width: "100%"
287
290
  },
288
291
  className: `border ${error ? "border-red-500" : "border-transparent"} placeholder:text-sm text-sm px-4 placeholder:opacity-30 focus:outline-none transition ${className}`,
289
- onFocus: (e) => !error && (e.target.style.borderColor = color),
292
+ onFocus: (e) => !error && (e.target.style.borderColor = borderColor),
290
293
  onBlur: (e) => e.target.style.borderColor = error ? "#ef4444" : "transparent"
291
294
  }
292
295
  ),
@@ -340,9 +343,119 @@ var Skeleton = ({
340
343
  );
341
344
  };
342
345
  var Skeleton_default = Skeleton;
346
+
347
+ // src/components/ScrollToTop/ScrollToTop.tsx
348
+ var import_react2 = require("react");
349
+ var ScrollToTop = () => {
350
+ (0, import_react2.useEffect)(() => {
351
+ window.scrollTo(0, 0);
352
+ const handleNavigation = () => {
353
+ window.scrollTo(0, 0);
354
+ };
355
+ window.addEventListener("popstate", handleNavigation);
356
+ const originalPushState = history.pushState;
357
+ const originalReplaceState = history.replaceState;
358
+ history.pushState = function(...args) {
359
+ originalPushState.apply(this, args);
360
+ handleNavigation();
361
+ };
362
+ history.replaceState = function(...args) {
363
+ originalReplaceState.apply(this, args);
364
+ handleNavigation();
365
+ };
366
+ return () => {
367
+ window.removeEventListener("popstate", handleNavigation);
368
+ history.pushState = originalPushState;
369
+ history.replaceState = originalReplaceState;
370
+ };
371
+ }, []);
372
+ return null;
373
+ };
374
+ var ScrollToTop_default = ScrollToTop;
375
+
376
+ // src/components/Accordion/Accordion.tsx
377
+ var import_react3 = require("react");
378
+ var import_jsx_runtime4 = require("react/jsx-runtime");
379
+ var Accordion = ({ icon, items, containerClassName, className, onIconClick }) => {
380
+ const [openIndexes, setOpenIndexes] = (0, import_react3.useState)([]);
381
+ const toggleIndex = (idx) => {
382
+ setOpenIndexes((prev) => prev.includes(idx) ? prev.filter((i) => i !== idx) : [...prev, idx]);
383
+ };
384
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `space-y-2 ${containerClassName || ""}`, children: items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `${className || ""}`, children: [
385
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
386
+ "button",
387
+ {
388
+ className: "w-full flex justify-between items-center cursor-pointer py-3 text-left font-medium focus:outline-none",
389
+ onClick: () => toggleIndex(idx),
390
+ children: [
391
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: item.question }),
392
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
393
+ "span",
394
+ {
395
+ onClick: (e) => {
396
+ e.stopPropagation();
397
+ onIconClick && onIconClick(idx, item);
398
+ },
399
+ className: "ml-2 flex items-center",
400
+ style: {
401
+ cursor: onIconClick ? "pointer" : "default",
402
+ transform: openIndexes.includes(idx) ? "rotate(180deg)" : "rotate(0deg)",
403
+ transition: "transform 0.2s"
404
+ },
405
+ children: icon
406
+ }
407
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: openIndexes.includes(idx) ? "\u2212" : "+" })
408
+ ]
409
+ }
410
+ ),
411
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
412
+ "div",
413
+ {
414
+ className: `grid transition-all duration-300 ease-in-out ${openIndexes.includes(idx) ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0"}`,
415
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "pb-3", children: item.answer }) })
416
+ }
417
+ )
418
+ ] }, idx)) });
419
+ };
420
+ var Accordion_default = Accordion;
421
+
422
+ // src/components/Rating/Rating.tsx
423
+ var import_jsx_runtime5 = require("react/jsx-runtime");
424
+ var Rating = ({ rating, total, icon }) => {
425
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex items-center gap-1", children: Array.from({ length: total }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: icon ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
426
+ "img",
427
+ {
428
+ src: icon,
429
+ alt: "rating icon",
430
+ className: `w-4 h-4 ${i < rating ? "" : "opacity-30"}`
431
+ }
432
+ ) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
433
+ "svg",
434
+ {
435
+ xmlns: "http://www.w3.org/2000/svg",
436
+ fill: i < rating ? "currentColor" : "none",
437
+ viewBox: "0 0 24 24",
438
+ stroke: "currentColor",
439
+ className: `w-4 h-4 ${i < rating ? "text-yellow-400" : "text-gray-300"}`,
440
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
441
+ "path",
442
+ {
443
+ strokeLinecap: "round",
444
+ strokeLinejoin: "round",
445
+ strokeWidth: 2,
446
+ d: "M11.049 2.927c.3-.921 1.603-.921 1.902 0l2.036 6.29a1 1 0 00.95.69h6.6c.969 0 1.371 1.24.588 1.81l-5.347 3.89a1 1 0 00-.364 1.118l2.036 6.29c.3.921-.755 1.688-1.54 1.118l-5.347-3.89a1 1 0 00-1.176 0l-5.347 3.89c-.784.57-1.838-.197-1.54-1.118l2.036-6.29a1 1 0 00-.364-1.118l-5.347-3.89c-.783-.57-.38-1.81.588-1.81h6.6a1 1 0 00.95-.69l2.036-6.29z"
447
+ }
448
+ )
449
+ }
450
+ ) }, i)) });
451
+ };
452
+ var Rating_default = Rating;
343
453
  // Annotate the CommonJS export names for ESM import in node:
344
454
  0 && (module.exports = {
455
+ Accordion,
345
456
  Input,
346
457
  Modal,
458
+ Rating,
459
+ ScrollToTop,
347
460
  Skeleton
348
461
  });
package/dist/index.mjs CHANGED
@@ -107,7 +107,7 @@ var Input = ({
107
107
  errorMessage,
108
108
  width = "100%",
109
109
  height = "40px",
110
- color = "#6B2CE9",
110
+ borderColor = "#6B2CE9",
111
111
  textColor = "white",
112
112
  borderRadius = "10px",
113
113
  backgroundColor = "#1F1F23",
@@ -189,7 +189,7 @@ var Input = ({
189
189
  width: "100%"
190
190
  },
191
191
  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}`,
192
- onFocus: (e) => !error && (e.target.style.borderColor = color),
192
+ onFocus: (e) => !error && (e.target.style.borderColor = borderColor),
193
193
  onBlur: (e) => e.target.style.borderColor = error ? "#ef4444" : "transparent"
194
194
  }
195
195
  ),
@@ -224,7 +224,7 @@ var Input = ({
224
224
  width: "100%"
225
225
  },
226
226
  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}`,
227
- onFocus: (e) => !error && (e.target.style.borderColor = color),
227
+ onFocus: (e) => !error && (e.target.style.borderColor = borderColor),
228
228
  onBlur: (e) => e.target.style.borderColor = error ? "#ef4444" : "transparent"
229
229
  }
230
230
  ),
@@ -258,7 +258,7 @@ var Input = ({
258
258
  width: "100%"
259
259
  },
260
260
  className: `border ${error ? "border-red-500" : "border-transparent"} placeholder:text-sm text-sm px-4 placeholder:opacity-30 focus:outline-none transition ${className}`,
261
- onFocus: (e) => !error && (e.target.style.borderColor = color),
261
+ onFocus: (e) => !error && (e.target.style.borderColor = borderColor),
262
262
  onBlur: (e) => e.target.style.borderColor = error ? "#ef4444" : "transparent"
263
263
  }
264
264
  ),
@@ -312,8 +312,118 @@ var Skeleton = ({
312
312
  );
313
313
  };
314
314
  var Skeleton_default = Skeleton;
315
+
316
+ // src/components/ScrollToTop/ScrollToTop.tsx
317
+ import { useEffect as useEffect2 } from "react";
318
+ var ScrollToTop = () => {
319
+ useEffect2(() => {
320
+ window.scrollTo(0, 0);
321
+ const handleNavigation = () => {
322
+ window.scrollTo(0, 0);
323
+ };
324
+ window.addEventListener("popstate", handleNavigation);
325
+ const originalPushState = history.pushState;
326
+ const originalReplaceState = history.replaceState;
327
+ history.pushState = function(...args) {
328
+ originalPushState.apply(this, args);
329
+ handleNavigation();
330
+ };
331
+ history.replaceState = function(...args) {
332
+ originalReplaceState.apply(this, args);
333
+ handleNavigation();
334
+ };
335
+ return () => {
336
+ window.removeEventListener("popstate", handleNavigation);
337
+ history.pushState = originalPushState;
338
+ history.replaceState = originalReplaceState;
339
+ };
340
+ }, []);
341
+ return null;
342
+ };
343
+ var ScrollToTop_default = ScrollToTop;
344
+
345
+ // src/components/Accordion/Accordion.tsx
346
+ import { useState as useState2 } from "react";
347
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
348
+ var Accordion = ({ icon, items, containerClassName, className, onIconClick }) => {
349
+ const [openIndexes, setOpenIndexes] = useState2([]);
350
+ const toggleIndex = (idx) => {
351
+ setOpenIndexes((prev) => prev.includes(idx) ? prev.filter((i) => i !== idx) : [...prev, idx]);
352
+ };
353
+ return /* @__PURE__ */ jsx4("div", { className: `space-y-2 ${containerClassName || ""}`, children: items.map((item, idx) => /* @__PURE__ */ jsxs3("div", { className: `${className || ""}`, children: [
354
+ /* @__PURE__ */ jsxs3(
355
+ "button",
356
+ {
357
+ className: "w-full flex justify-between items-center cursor-pointer py-3 text-left font-medium focus:outline-none",
358
+ onClick: () => toggleIndex(idx),
359
+ children: [
360
+ /* @__PURE__ */ jsx4("span", { children: item.question }),
361
+ icon ? /* @__PURE__ */ jsx4(
362
+ "span",
363
+ {
364
+ onClick: (e) => {
365
+ e.stopPropagation();
366
+ onIconClick && onIconClick(idx, item);
367
+ },
368
+ className: "ml-2 flex items-center",
369
+ style: {
370
+ cursor: onIconClick ? "pointer" : "default",
371
+ transform: openIndexes.includes(idx) ? "rotate(180deg)" : "rotate(0deg)",
372
+ transition: "transform 0.2s"
373
+ },
374
+ children: icon
375
+ }
376
+ ) : /* @__PURE__ */ jsx4("span", { children: openIndexes.includes(idx) ? "\u2212" : "+" })
377
+ ]
378
+ }
379
+ ),
380
+ /* @__PURE__ */ jsx4(
381
+ "div",
382
+ {
383
+ className: `grid transition-all duration-300 ease-in-out ${openIndexes.includes(idx) ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0"}`,
384
+ children: /* @__PURE__ */ jsx4("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsx4("div", { className: "pb-3", children: item.answer }) })
385
+ }
386
+ )
387
+ ] }, idx)) });
388
+ };
389
+ var Accordion_default = Accordion;
390
+
391
+ // src/components/Rating/Rating.tsx
392
+ import { jsx as jsx5 } from "react/jsx-runtime";
393
+ var Rating = ({ rating, total, icon }) => {
394
+ return /* @__PURE__ */ jsx5("div", { className: "flex items-center gap-1", children: Array.from({ length: total }).map((_, i) => /* @__PURE__ */ jsx5("div", { children: icon ? /* @__PURE__ */ jsx5(
395
+ "img",
396
+ {
397
+ src: icon,
398
+ alt: "rating icon",
399
+ className: `w-4 h-4 ${i < rating ? "" : "opacity-30"}`
400
+ }
401
+ ) : /* @__PURE__ */ jsx5(
402
+ "svg",
403
+ {
404
+ xmlns: "http://www.w3.org/2000/svg",
405
+ fill: i < rating ? "currentColor" : "none",
406
+ viewBox: "0 0 24 24",
407
+ stroke: "currentColor",
408
+ className: `w-4 h-4 ${i < rating ? "text-yellow-400" : "text-gray-300"}`,
409
+ children: /* @__PURE__ */ jsx5(
410
+ "path",
411
+ {
412
+ strokeLinecap: "round",
413
+ strokeLinejoin: "round",
414
+ strokeWidth: 2,
415
+ d: "M11.049 2.927c.3-.921 1.603-.921 1.902 0l2.036 6.29a1 1 0 00.95.69h6.6c.969 0 1.371 1.24.588 1.81l-5.347 3.89a1 1 0 00-.364 1.118l2.036 6.29c.3.921-.755 1.688-1.54 1.118l-5.347-3.89a1 1 0 00-1.176 0l-5.347 3.89c-.784.57-1.838-.197-1.54-1.118l2.036-6.29a1 1 0 00-.364-1.118l-5.347-3.89c-.783-.57-.38-1.81.588-1.81h6.6a1 1 0 00.95-.69l2.036-6.29z"
416
+ }
417
+ )
418
+ }
419
+ ) }, i)) });
420
+ };
421
+ var Rating_default = Rating;
315
422
  export {
423
+ Accordion_default as Accordion,
316
424
  Input_default as Input,
317
425
  Modal_default as Modal,
426
+ Rating_default as Rating,
427
+ ScrollToTop_default as ScrollToTop,
318
428
  Skeleton_default as Skeleton
319
429
  };
package/dist/styles.css CHANGED
@@ -8,20 +8,50 @@
8
8
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
9
9
  "Liberation Mono", "Courier New", monospace;
10
10
  --color-red-500: oklch(0.637 0.237 25.331);
11
+ --color-yellow-400: oklch(0.852 0.199 91.936);
12
+ --color-violet-200: oklch(0.894 0.057 293.283);
13
+ --color-violet-500: oklch(0.606 0.25 292.717);
14
+ --color-violet-600: oklch(0.541 0.281 293.009);
15
+ --color-slate-100: oklch(0.968 0.007 247.896);
16
+ --color-slate-200: oklch(0.929 0.013 255.508);
17
+ --color-slate-300: oklch(0.869 0.022 252.894);
18
+ --color-slate-400: oklch(0.704 0.04 256.788);
19
+ --color-slate-600: oklch(0.446 0.043 257.281);
20
+ --color-slate-700: oklch(0.372 0.044 257.287);
21
+ --color-slate-800: oklch(0.279 0.041 260.031);
22
+ --color-slate-900: oklch(0.208 0.042 265.755);
23
+ --color-slate-950: oklch(0.129 0.042 264.695);
24
+ --color-gray-300: oklch(0.872 0.01 258.338);
11
25
  --color-gray-400: oklch(0.707 0.022 261.325);
12
26
  --color-black: #000;
13
27
  --color-white: #fff;
14
28
  --spacing: 0.25rem;
15
29
  --container-md: 28rem;
30
+ --container-2xl: 42rem;
31
+ --container-4xl: 56rem;
16
32
  --text-xs: 0.75rem;
17
33
  --text-xs--line-height: calc(1 / 0.75);
18
34
  --text-sm: 0.875rem;
19
35
  --text-sm--line-height: calc(1.25 / 0.875);
36
+ --text-base: 1rem;
37
+ --text-base--line-height: calc(1.5 / 1);
38
+ --text-lg: 1.125rem;
39
+ --text-lg--line-height: calc(1.75 / 1.125);
20
40
  --text-2xl: 1.5rem;
21
41
  --text-2xl--line-height: calc(2 / 1.5);
42
+ --text-3xl: 1.875rem;
43
+ --text-3xl--line-height: calc(2.25 / 1.875);
44
+ --text-4xl: 2.25rem;
45
+ --text-4xl--line-height: calc(2.5 / 2.25);
22
46
  --font-weight-medium: 500;
47
+ --font-weight-semibold: 600;
23
48
  --font-weight-bold: 700;
49
+ --tracking-tight: -0.025em;
50
+ --radius-md: 0.375rem;
24
51
  --radius-lg: 0.5rem;
52
+ --radius-xl: 0.75rem;
53
+ --radius-2xl: 1rem;
54
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
25
55
  --animate-pulse: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
26
56
  --default-transition-duration: 150ms;
27
57
  --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
@@ -195,6 +225,9 @@
195
225
  }
196
226
  }
197
227
  @layer utilities {
228
+ .visible {
229
+ visibility: visible;
230
+ }
198
231
  .absolute {
199
232
  position: absolute;
200
233
  }
@@ -216,18 +249,54 @@
216
249
  .z-50 {
217
250
  z-index: 50;
218
251
  }
252
+ .m-0 {
253
+ margin: calc(var(--spacing) * 0);
254
+ }
255
+ .mx-auto {
256
+ margin-inline: auto;
257
+ }
258
+ .mt-0 {
259
+ margin-top: calc(var(--spacing) * 0);
260
+ }
219
261
  .mt-1 {
220
262
  margin-top: calc(var(--spacing) * 1);
221
263
  }
264
+ .mt-3 {
265
+ margin-top: calc(var(--spacing) * 3);
266
+ }
267
+ .mb-2 {
268
+ margin-bottom: calc(var(--spacing) * 2);
269
+ }
222
270
  .mb-4 {
223
271
  margin-bottom: calc(var(--spacing) * 4);
224
272
  }
273
+ .mb-5 {
274
+ margin-bottom: calc(var(--spacing) * 5);
275
+ }
276
+ .ml-2 {
277
+ margin-left: calc(var(--spacing) * 2);
278
+ }
225
279
  .flex {
226
280
  display: flex;
227
281
  }
282
+ .grid {
283
+ display: grid;
284
+ }
285
+ .inline-flex {
286
+ display: inline-flex;
287
+ }
228
288
  .h-4 {
229
289
  height: calc(var(--spacing) * 4);
230
290
  }
291
+ .min-h-\[50vh\] {
292
+ min-height: 50vh;
293
+ }
294
+ .min-h-screen {
295
+ min-height: 100vh;
296
+ }
297
+ .w-4 {
298
+ width: calc(var(--spacing) * 4);
299
+ }
231
300
  .w-fit {
232
301
  width: -moz-fit-content;
233
302
  width: fit-content;
@@ -235,6 +304,12 @@
235
304
  .w-full {
236
305
  width: 100%;
237
306
  }
307
+ .max-w-2xl {
308
+ max-width: var(--container-2xl);
309
+ }
310
+ .max-w-4xl {
311
+ max-width: var(--container-4xl);
312
+ }
238
313
  .max-w-md {
239
314
  max-width: var(--container-md);
240
315
  }
@@ -242,24 +317,62 @@
242
317
  --tw-translate-y: calc(calc(1/2 * 100%) * -1);
243
318
  translate: var(--tw-translate-x) var(--tw-translate-y);
244
319
  }
320
+ .transform {
321
+ transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);
322
+ }
245
323
  .animate-pulse {
246
324
  animation: var(--animate-pulse);
247
325
  }
248
326
  .cursor-pointer {
249
327
  cursor: pointer;
250
328
  }
329
+ .grid-rows-\[0fr\] {
330
+ grid-template-rows: 0fr;
331
+ }
332
+ .grid-rows-\[1fr\] {
333
+ grid-template-rows: 1fr;
334
+ }
251
335
  .items-center {
252
336
  align-items: center;
253
337
  }
338
+ .justify-between {
339
+ justify-content: space-between;
340
+ }
254
341
  .justify-center {
255
342
  justify-content: center;
256
343
  }
257
344
  .justify-end {
258
345
  justify-content: flex-end;
259
346
  }
347
+ .gap-1 {
348
+ gap: calc(var(--spacing) * 1);
349
+ }
260
350
  .gap-4 {
261
351
  gap: calc(var(--spacing) * 4);
262
352
  }
353
+ .gap-6 {
354
+ gap: calc(var(--spacing) * 6);
355
+ }
356
+ .space-y-2 {
357
+ :where(& > :not(:last-child)) {
358
+ --tw-space-y-reverse: 0;
359
+ margin-block-start: calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));
360
+ margin-block-end: calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)));
361
+ }
362
+ }
363
+ .space-y-3 {
364
+ :where(& > :not(:last-child)) {
365
+ --tw-space-y-reverse: 0;
366
+ margin-block-start: calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));
367
+ margin-block-end: calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)));
368
+ }
369
+ }
370
+ .overflow-hidden {
371
+ overflow: hidden;
372
+ }
373
+ .rounded-2xl {
374
+ border-radius: var(--radius-2xl);
375
+ }
263
376
  .rounded-\[4px\] {
264
377
  border-radius: 4px;
265
378
  }
@@ -272,6 +385,12 @@
272
385
  .rounded-lg {
273
386
  border-radius: var(--radius-lg);
274
387
  }
388
+ .rounded-md {
389
+ border-radius: var(--radius-md);
390
+ }
391
+ .rounded-xl {
392
+ border-radius: var(--radius-xl);
393
+ }
275
394
  .border {
276
395
  border-style: var(--tw-border-style);
277
396
  border-width: 1px;
@@ -279,9 +398,24 @@
279
398
  .border-red-500 {
280
399
  border-color: var(--color-red-500);
281
400
  }
401
+ .border-slate-200 {
402
+ border-color: var(--color-slate-200);
403
+ }
404
+ .border-slate-300 {
405
+ border-color: var(--color-slate-300);
406
+ }
407
+ .border-slate-800 {
408
+ border-color: var(--color-slate-800);
409
+ }
282
410
  .border-transparent {
283
411
  border-color: transparent;
284
412
  }
413
+ .border-violet-500\/40 {
414
+ border-color: color-mix(in srgb, oklch(0.606 0.25 292.717) 40%, transparent);
415
+ @supports (color: color-mix(in lab, red, red)) {
416
+ border-color: color-mix(in oklab, var(--color-violet-500) 40%, transparent);
417
+ }
418
+ }
285
419
  .bg-\[\#27272E\] {
286
420
  background-color: #27272E;
287
421
  }
@@ -291,6 +425,24 @@
291
425
  background-color: color-mix(in oklab, var(--color-black) 80%, transparent);
292
426
  }
293
427
  }
428
+ .bg-slate-900\/80 {
429
+ background-color: color-mix(in srgb, oklch(0.208 0.042 265.755) 80%, transparent);
430
+ @supports (color: color-mix(in lab, red, red)) {
431
+ background-color: color-mix(in oklab, var(--color-slate-900) 80%, transparent);
432
+ }
433
+ }
434
+ .bg-slate-950 {
435
+ background-color: var(--color-slate-950);
436
+ }
437
+ .bg-violet-500\/10 {
438
+ background-color: color-mix(in srgb, oklch(0.606 0.25 292.717) 10%, transparent);
439
+ @supports (color: color-mix(in lab, red, red)) {
440
+ background-color: color-mix(in oklab, var(--color-violet-500) 10%, transparent);
441
+ }
442
+ }
443
+ .bg-violet-600 {
444
+ background-color: var(--color-violet-600);
445
+ }
294
446
  .bg-white {
295
447
  background-color: var(--color-white);
296
448
  }
@@ -314,6 +466,12 @@
314
466
  .bg-\[length\:200\%_100\%\] {
315
467
  background-size: 200% 100%;
316
468
  }
469
+ .p-4 {
470
+ padding: calc(var(--spacing) * 4);
471
+ }
472
+ .p-5 {
473
+ padding: calc(var(--spacing) * 5);
474
+ }
317
475
  .p-6 {
318
476
  padding: calc(var(--spacing) * 6);
319
477
  }
@@ -323,9 +481,24 @@
323
481
  .px-1 {
324
482
  padding-inline: calc(var(--spacing) * 1);
325
483
  }
484
+ .px-3 {
485
+ padding-inline: calc(var(--spacing) * 3);
486
+ }
326
487
  .px-4 {
327
488
  padding-inline: calc(var(--spacing) * 4);
328
489
  }
490
+ .py-1 {
491
+ padding-block: calc(var(--spacing) * 1);
492
+ }
493
+ .py-2 {
494
+ padding-block: calc(var(--spacing) * 2);
495
+ }
496
+ .py-3 {
497
+ padding-block: calc(var(--spacing) * 3);
498
+ }
499
+ .py-10 {
500
+ padding-block: calc(var(--spacing) * 10);
501
+ }
329
502
  .pt-2 {
330
503
  padding-top: calc(var(--spacing) * 2);
331
504
  }
@@ -335,10 +508,24 @@
335
508
  .pr-28 {
336
509
  padding-right: calc(var(--spacing) * 28);
337
510
  }
511
+ .pb-3 {
512
+ padding-bottom: calc(var(--spacing) * 3);
513
+ }
514
+ .text-left {
515
+ text-align: left;
516
+ }
338
517
  .text-2xl {
339
518
  font-size: var(--text-2xl);
340
519
  line-height: var(--tw-leading, var(--text-2xl--line-height));
341
520
  }
521
+ .text-3xl {
522
+ font-size: var(--text-3xl);
523
+ line-height: var(--tw-leading, var(--text-3xl--line-height));
524
+ }
525
+ .text-lg {
526
+ font-size: var(--text-lg);
527
+ line-height: var(--tw-leading, var(--text-lg--line-height));
528
+ }
342
529
  .text-sm {
343
530
  font-size: var(--text-sm);
344
531
  line-height: var(--tw-leading, var(--text-sm--line-height));
@@ -355,25 +542,89 @@
355
542
  --tw-font-weight: var(--font-weight-medium);
356
543
  font-weight: var(--font-weight-medium);
357
544
  }
545
+ .font-semibold {
546
+ --tw-font-weight: var(--font-weight-semibold);
547
+ font-weight: var(--font-weight-semibold);
548
+ }
549
+ .tracking-tight {
550
+ --tw-tracking: var(--tracking-tight);
551
+ letter-spacing: var(--tracking-tight);
552
+ }
358
553
  .text-\[\#A77BFF\] {
359
554
  color: #A77BFF;
360
555
  }
556
+ .text-gray-300 {
557
+ color: var(--color-gray-300);
558
+ }
361
559
  .text-gray-400 {
362
560
  color: var(--color-gray-400);
363
561
  }
364
562
  .text-red-500 {
365
563
  color: var(--color-red-500);
366
564
  }
565
+ .text-slate-100 {
566
+ color: var(--color-slate-100);
567
+ }
568
+ .text-slate-300 {
569
+ color: var(--color-slate-300);
570
+ }
571
+ .text-slate-400 {
572
+ color: var(--color-slate-400);
573
+ }
574
+ .text-slate-600 {
575
+ color: var(--color-slate-600);
576
+ }
577
+ .text-slate-700 {
578
+ color: var(--color-slate-700);
579
+ }
580
+ .text-slate-900 {
581
+ color: var(--color-slate-900);
582
+ }
583
+ .text-violet-200 {
584
+ color: var(--color-violet-200);
585
+ }
586
+ .text-white {
587
+ color: var(--color-white);
588
+ }
589
+ .text-yellow-400 {
590
+ color: var(--color-yellow-400);
591
+ }
592
+ .opacity-0 {
593
+ opacity: 0%;
594
+ }
595
+ .opacity-30 {
596
+ opacity: 30%;
597
+ }
598
+ .opacity-100 {
599
+ opacity: 100%;
600
+ }
601
+ .shadow-sm {
602
+ --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
603
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
604
+ }
367
605
  .transition {
368
606
  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;
369
607
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
370
608
  transition-duration: var(--tw-duration, var(--default-transition-duration));
371
609
  }
610
+ .transition-all {
611
+ transition-property: all;
612
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
613
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
614
+ }
372
615
  .transition-colors {
373
616
  transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
374
617
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
375
618
  transition-duration: var(--tw-duration, var(--default-transition-duration));
376
619
  }
620
+ .duration-300 {
621
+ --tw-duration: 300ms;
622
+ transition-duration: 300ms;
623
+ }
624
+ .ease-in-out {
625
+ --tw-ease: var(--ease-in-out);
626
+ transition-timing-function: var(--ease-in-out);
627
+ }
377
628
  .placeholder\:text-sm {
378
629
  &::-moz-placeholder {
379
630
  font-size: var(--text-sm);
@@ -392,6 +643,20 @@
392
643
  opacity: 30%;
393
644
  }
394
645
  }
646
+ .hover\:bg-slate-100 {
647
+ &:hover {
648
+ @media (hover: hover) {
649
+ background-color: var(--color-slate-100);
650
+ }
651
+ }
652
+ }
653
+ .hover\:bg-violet-500 {
654
+ &:hover {
655
+ @media (hover: hover) {
656
+ background-color: var(--color-violet-500);
657
+ }
658
+ }
659
+ }
395
660
  .hover\:text-white {
396
661
  &:hover {
397
662
  @media (hover: hover) {
@@ -405,6 +670,33 @@
405
670
  outline-style: none;
406
671
  }
407
672
  }
673
+ .sm\:p-6 {
674
+ @media (width >= 40rem) {
675
+ padding: calc(var(--spacing) * 6);
676
+ }
677
+ }
678
+ .sm\:p-8 {
679
+ @media (width >= 40rem) {
680
+ padding: calc(var(--spacing) * 8);
681
+ }
682
+ }
683
+ .sm\:px-6 {
684
+ @media (width >= 40rem) {
685
+ padding-inline: calc(var(--spacing) * 6);
686
+ }
687
+ }
688
+ .sm\:text-4xl {
689
+ @media (width >= 40rem) {
690
+ font-size: var(--text-4xl);
691
+ line-height: var(--tw-leading, var(--text-4xl--line-height));
692
+ }
693
+ }
694
+ .sm\:text-base {
695
+ @media (width >= 40rem) {
696
+ font-size: var(--text-base);
697
+ line-height: var(--tw-leading, var(--text-base--line-height));
698
+ }
699
+ }
408
700
  .lg\:hidden {
409
701
  @media (width >= 64rem) {
410
702
  display: none;
@@ -426,6 +718,31 @@
426
718
  inherits: false;
427
719
  initial-value: 0;
428
720
  }
721
+ @property --tw-rotate-x {
722
+ syntax: "*";
723
+ inherits: false;
724
+ }
725
+ @property --tw-rotate-y {
726
+ syntax: "*";
727
+ inherits: false;
728
+ }
729
+ @property --tw-rotate-z {
730
+ syntax: "*";
731
+ inherits: false;
732
+ }
733
+ @property --tw-skew-x {
734
+ syntax: "*";
735
+ inherits: false;
736
+ }
737
+ @property --tw-skew-y {
738
+ syntax: "*";
739
+ inherits: false;
740
+ }
741
+ @property --tw-space-y-reverse {
742
+ syntax: "*";
743
+ inherits: false;
744
+ initial-value: 0;
745
+ }
429
746
  @property --tw-border-style {
430
747
  syntax: "*";
431
748
  inherits: false;
@@ -477,6 +794,83 @@
477
794
  syntax: "*";
478
795
  inherits: false;
479
796
  }
797
+ @property --tw-tracking {
798
+ syntax: "*";
799
+ inherits: false;
800
+ }
801
+ @property --tw-shadow {
802
+ syntax: "*";
803
+ inherits: false;
804
+ initial-value: 0 0 #0000;
805
+ }
806
+ @property --tw-shadow-color {
807
+ syntax: "*";
808
+ inherits: false;
809
+ }
810
+ @property --tw-shadow-alpha {
811
+ syntax: "<percentage>";
812
+ inherits: false;
813
+ initial-value: 100%;
814
+ }
815
+ @property --tw-inset-shadow {
816
+ syntax: "*";
817
+ inherits: false;
818
+ initial-value: 0 0 #0000;
819
+ }
820
+ @property --tw-inset-shadow-color {
821
+ syntax: "*";
822
+ inherits: false;
823
+ }
824
+ @property --tw-inset-shadow-alpha {
825
+ syntax: "<percentage>";
826
+ inherits: false;
827
+ initial-value: 100%;
828
+ }
829
+ @property --tw-ring-color {
830
+ syntax: "*";
831
+ inherits: false;
832
+ }
833
+ @property --tw-ring-shadow {
834
+ syntax: "*";
835
+ inherits: false;
836
+ initial-value: 0 0 #0000;
837
+ }
838
+ @property --tw-inset-ring-color {
839
+ syntax: "*";
840
+ inherits: false;
841
+ }
842
+ @property --tw-inset-ring-shadow {
843
+ syntax: "*";
844
+ inherits: false;
845
+ initial-value: 0 0 #0000;
846
+ }
847
+ @property --tw-ring-inset {
848
+ syntax: "*";
849
+ inherits: false;
850
+ }
851
+ @property --tw-ring-offset-width {
852
+ syntax: "<length>";
853
+ inherits: false;
854
+ initial-value: 0px;
855
+ }
856
+ @property --tw-ring-offset-color {
857
+ syntax: "*";
858
+ inherits: false;
859
+ initial-value: #fff;
860
+ }
861
+ @property --tw-ring-offset-shadow {
862
+ syntax: "*";
863
+ inherits: false;
864
+ initial-value: 0 0 #0000;
865
+ }
866
+ @property --tw-duration {
867
+ syntax: "*";
868
+ inherits: false;
869
+ }
870
+ @property --tw-ease {
871
+ syntax: "*";
872
+ inherits: false;
873
+ }
480
874
  @keyframes pulse {
481
875
  50% {
482
876
  opacity: 0.5;
@@ -488,6 +882,12 @@
488
882
  --tw-translate-x: 0;
489
883
  --tw-translate-y: 0;
490
884
  --tw-translate-z: 0;
885
+ --tw-rotate-x: initial;
886
+ --tw-rotate-y: initial;
887
+ --tw-rotate-z: initial;
888
+ --tw-skew-x: initial;
889
+ --tw-skew-y: initial;
890
+ --tw-space-y-reverse: 0;
491
891
  --tw-border-style: solid;
492
892
  --tw-gradient-position: initial;
493
893
  --tw-gradient-from: #0000;
@@ -499,6 +899,23 @@
499
899
  --tw-gradient-via-position: 50%;
500
900
  --tw-gradient-to-position: 100%;
501
901
  --tw-font-weight: initial;
902
+ --tw-tracking: initial;
903
+ --tw-shadow: 0 0 #0000;
904
+ --tw-shadow-color: initial;
905
+ --tw-shadow-alpha: 100%;
906
+ --tw-inset-shadow: 0 0 #0000;
907
+ --tw-inset-shadow-color: initial;
908
+ --tw-inset-shadow-alpha: 100%;
909
+ --tw-ring-color: initial;
910
+ --tw-ring-shadow: 0 0 #0000;
911
+ --tw-inset-ring-color: initial;
912
+ --tw-inset-ring-shadow: 0 0 #0000;
913
+ --tw-ring-inset: initial;
914
+ --tw-ring-offset-width: 0px;
915
+ --tw-ring-offset-color: #fff;
916
+ --tw-ring-offset-shadow: 0 0 #0000;
917
+ --tw-duration: initial;
918
+ --tw-ease: initial;
502
919
  }
503
920
  }
504
921
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tunjiadeyemi/ui",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
4
4
  "description": "A collection of reusable UI components",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -22,6 +22,7 @@
22
22
  "build": "tsup src/index.ts --format cjs,esm --dts --external react --external react-dom --external framer-motion --external lucide-react && npm run build:css",
23
23
  "build:css": "postcss ./src/styles.css -o ./dist/styles.css",
24
24
  "dev": "tsup src/index.ts --format cjs,esm --dts --watch --external react --external react-dom --external framer-motion --external lucide-react",
25
+ "generate:stories": "node ./scripts/generate-stories.mjs",
25
26
  "prepublishOnly": "npm run build",
26
27
  "lint": "eslint src --ext .ts,.tsx"
27
28
  },
@@ -56,11 +57,13 @@
56
57
  "@types/react": "^18.2.0",
57
58
  "@types/react-dom": "^18.2.0",
58
59
  "autoprefixer": "^10.4.16",
59
- "lucide-react": "^0.562.0",
60
60
  "postcss": "^8.4.32",
61
61
  "postcss-cli": "^11.0.1",
62
62
  "tailwindcss": "4.0.0",
63
63
  "tsup": "^8.0.0",
64
64
  "typescript": "^5.3.0"
65
+ },
66
+ "overrides": {
67
+ "rollup": ">=4.59.0"
65
68
  }
66
69
  }