saha-ui 1.4.0 → 1.6.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 +1219 -217
- package/dist/components/Accordion/index.d.ts.map +1 -1
- package/dist/components/Accordion/index.js +73 -73
- package/dist/components/Alert/index.js +24 -24
- package/dist/components/Avatar/index.d.ts.map +1 -1
- package/dist/components/Avatar/index.js +42 -42
- package/dist/components/AvatarGroup/AvatarGroup.types.d.ts +4 -4
- package/dist/components/AvatarGroup/AvatarGroup.types.d.ts.map +1 -1
- package/dist/components/AvatarGroup/index.d.ts +7 -12
- package/dist/components/AvatarGroup/index.d.ts.map +1 -1
- package/dist/components/AvatarGroup/index.js +71 -70
- package/dist/components/Badge/index.js +34 -34
- package/dist/components/Breadcrumb/index.js +49 -49
- package/dist/components/ButtonGroup/index.d.ts.map +1 -1
- package/dist/components/ButtonGroup/index.js +74 -71
- package/dist/components/Carousel/index.d.ts.map +1 -1
- package/dist/components/Carousel/index.js +75 -75
- package/dist/components/Checkbox/Checkbox.types.d.ts +128 -0
- package/dist/components/Checkbox/Checkbox.types.d.ts.map +1 -0
- package/dist/components/Checkbox/index.d.ts +19 -0
- package/dist/components/Checkbox/index.d.ts.map +1 -0
- package/dist/components/Checkbox/index.js +409 -0
- package/dist/components/Chip/index.js +29 -29
- package/dist/components/Divider/index.js +20 -20
- package/dist/components/FloatingActionButton/FloatingActionButton.types.d.ts +41 -0
- package/dist/components/FloatingActionButton/FloatingActionButton.types.d.ts.map +1 -0
- package/dist/components/FloatingActionButton/index.d.ts +39 -0
- package/dist/components/FloatingActionButton/index.d.ts.map +1 -0
- package/dist/components/FloatingActionButton/index.js +172 -0
- package/dist/components/Image/index.d.ts.map +1 -1
- package/dist/components/Image/index.js +81 -78
- package/dist/components/Input/index.js +72 -72
- package/dist/components/Link/index.js +35 -35
- package/dist/components/List/index.d.ts.map +1 -1
- package/dist/components/List/index.js +43 -43
- package/dist/components/Pagination/index.d.ts.map +1 -1
- package/dist/components/Pagination/index.js +186 -92
- package/dist/components/PlayButton/index.d.ts.map +1 -1
- package/dist/components/PlayButton/index.js +34 -32
- package/dist/components/Progress/index.d.ts +2 -2
- package/dist/components/Progress/index.d.ts.map +1 -1
- package/dist/components/Progress/index.js +70 -53
- package/dist/components/Radio/Radio.types.d.ts +124 -0
- package/dist/components/Radio/Radio.types.d.ts.map +1 -0
- package/dist/components/Radio/index.d.ts +25 -0
- package/dist/components/Radio/index.d.ts.map +1 -0
- package/dist/components/Radio/index.js +349 -0
- package/dist/components/Rating/index.d.ts.map +1 -1
- package/dist/components/Rating/index.js +92 -92
- package/dist/components/Select/Select.types.d.ts +48 -0
- package/dist/components/Select/Select.types.d.ts.map +1 -0
- package/dist/components/Select/index.d.ts +35 -0
- package/dist/components/Select/index.d.ts.map +1 -0
- package/dist/components/Select/index.js +437 -0
- package/dist/components/Skeleton/index.d.ts.map +1 -1
- package/dist/components/Skeleton/index.js +59 -43
- package/dist/components/Spinner/Spinner.types.d.ts +76 -0
- package/dist/components/Spinner/Spinner.types.d.ts.map +1 -0
- package/dist/components/Spinner/index.d.ts +31 -0
- package/dist/components/Spinner/index.d.ts.map +1 -0
- package/dist/components/Spinner/index.js +590 -0
- package/dist/components/Steps/index.d.ts.map +1 -1
- package/dist/components/Steps/index.js +94 -94
- package/dist/components/Switch/Switch.types.d.ts +46 -0
- package/dist/components/Switch/Switch.types.d.ts.map +1 -0
- package/dist/components/Switch/index.d.ts +31 -0
- package/dist/components/Switch/index.d.ts.map +1 -0
- package/dist/components/Switch/index.js +279 -0
- package/dist/components/Tab/index.d.ts.map +1 -1
- package/dist/components/Tab/index.js +277 -104
- package/dist/components/Table/index.d.ts.map +1 -1
- package/dist/components/Table/index.js +101 -95
- package/dist/components/ThemeToggle/index.d.ts.map +1 -1
- package/dist/components/ThemeToggle/index.js +24 -12
- package/dist/components/Timeline/index.d.ts.map +1 -1
- package/dist/components/Timeline/index.js +79 -76
- package/dist/components/Tooltip/Tooltip.types.d.ts +46 -21
- package/dist/components/Tooltip/Tooltip.types.d.ts.map +1 -1
- package/dist/components/Tooltip/index.d.ts +31 -12
- package/dist/components/Tooltip/index.d.ts.map +1 -1
- package/dist/components/Tooltip/index.js +145 -109
- package/dist/components/Tree/index.d.ts.map +1 -1
- package/dist/components/Tree/index.js +47 -47
- package/dist/index.d.ts +14 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +84 -68
- package/package.json +1 -1
- package/dist/components/Accordion/Accordion.types.js +0 -1
- package/dist/components/Alert/Alert.types.js +0 -1
- package/dist/components/Avatar/Avatar.types.js +0 -1
- package/dist/components/AvatarGroup/AvatarGroup.types.js +0 -1
- package/dist/components/Badge/Badge.types.js +0 -1
- package/dist/components/Breadcrumb/Breadcrumb.types.js +0 -1
- package/dist/components/Button/Button.types.js +0 -1
- package/dist/components/ButtonGroup/ButtonGroup.types.js +0 -1
- package/dist/components/Card/Card.types.js +0 -1
- package/dist/components/Carousel/Carousel.types.js +0 -1
- package/dist/components/Chip/Chip.types.js +0 -1
- package/dist/components/DatePicker/DatePicker.types.js +0 -1
- package/dist/components/Divider/Divider.types.js +0 -1
- package/dist/components/Image/Image.types.js +0 -1
- package/dist/components/Input/Input.types.js +0 -1
- package/dist/components/Link/Link.types.js +0 -1
- package/dist/components/List/List.types.js +0 -1
- package/dist/components/Pagination/Pagination.types.js +0 -1
- package/dist/components/PlayButton/PlayButton.types.js +0 -1
- package/dist/components/Popover/Popover.types.js +0 -1
- package/dist/components/Progress/Progress.types.js +0 -1
- package/dist/components/Rating/Rating.types.js +0 -1
- package/dist/components/Skeleton/Skeleton.types.js +0 -1
- package/dist/components/Steps/Steps.types.js +0 -1
- package/dist/components/Tab/Tab.types.js +0 -1
- package/dist/components/Table/Table.types.js +0 -1
- package/dist/components/ThemeProvider/ThemeProvider.types.js +0 -1
- package/dist/components/ThemeToggle/ThemeToggle.types.js +0 -1
- package/dist/components/Timeline/Timeline.types.js +0 -1
- package/dist/components/Tooltip/Tooltip.types.js +0 -1
- package/dist/components/Tree/Tree.types.js +0 -1
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
## ✨ Features
|
|
29
29
|
|
|
30
|
-
- 🎨 **
|
|
30
|
+
- 🎨 **35 Modern Components** - Button, ButtonGroup, Alert, Badge, Breadcrumb, Card, Chip, Divider, Accordion, Avatar, AvatarGroup, Tooltip, Link, List, Timeline, Tree, Image, Carousel, Steps, Table, Rating, Progress, Popover, PlayButton, FloatingActionButton, Radio, Switch, Checkbox, CheckboxGroup, Select, Skeleton, Pagination, DatePicker, Tab, Input
|
|
31
31
|
- 🌓 **Dark Mode** - Seamless theme switching with full dark mode support
|
|
32
32
|
- 🔮 **Glass Morphism** - Beautiful backdrop blur effects across components
|
|
33
33
|
- 🎯 **Type-Safe** - Full TypeScript support with comprehensive prop types
|
|
@@ -139,43 +139,50 @@ import { cn } from "saha-ui/lib/utils";
|
|
|
139
139
|
|
|
140
140
|
### Overview
|
|
141
141
|
|
|
142
|
-
| Component
|
|
143
|
-
|
|
|
144
|
-
| **Button**
|
|
145
|
-
| **ButtonGroup**
|
|
146
|
-
| **Alert**
|
|
147
|
-
| **Badge**
|
|
148
|
-
| **Breadcrumb**
|
|
149
|
-
| **Card**
|
|
150
|
-
| **Chip**
|
|
151
|
-
| **Divider**
|
|
152
|
-
| **Accordion**
|
|
153
|
-
| **Avatar**
|
|
154
|
-
| **AvatarGroup**
|
|
155
|
-
| **Tooltip**
|
|
156
|
-
| **Link**
|
|
157
|
-
| **List**
|
|
158
|
-
| **Timeline**
|
|
159
|
-
| **Tree**
|
|
160
|
-
| **Image**
|
|
161
|
-
| **Carousel**
|
|
162
|
-
| **Steps**
|
|
163
|
-
| **Table**
|
|
164
|
-
| **Rating**
|
|
165
|
-
| **Progress**
|
|
166
|
-
| **Popover**
|
|
167
|
-
| **PlayButton**
|
|
168
|
-
| **
|
|
169
|
-
| **
|
|
170
|
-
| **
|
|
171
|
-
| **
|
|
172
|
-
| **
|
|
142
|
+
| Component | Description | Status | CVA |
|
|
143
|
+
| ------------------------ | ------------------------------------------------------------------------ | ------ | --- |
|
|
144
|
+
| **Button** | Action buttons with 9 variants and 4 sizes | ✅ | ✅ |
|
|
145
|
+
| **ButtonGroup** | Grouped buttons with horizontal/vertical layouts | ✅ | ✅ |
|
|
146
|
+
| **Alert** | Notification messages with 5 variants × 4 statuses | ✅ | ✅ |
|
|
147
|
+
| **Badge** | Status indicators and labels with 9 variants | ✅ | ✅ |
|
|
148
|
+
| **Breadcrumb** | Navigation trail with 5 variants, 4 separators, and collapsing | ✅ | ✅ |
|
|
149
|
+
| **Card** | Container with 5 variants and sub-components | ✅ | ✅ |
|
|
150
|
+
| **Chip** | Interactive tags with 5 variants, deletable, and avatars | ✅ | ✅ |
|
|
151
|
+
| **Divider** | Content separator with 5 variants and label support | ✅ | ✅ |
|
|
152
|
+
| **Accordion** | Collapsible content with 5 behavior modes | ✅ | ✅ |
|
|
153
|
+
| **Avatar** | User profile images with status indicators | ✅ | ✅ |
|
|
154
|
+
| **AvatarGroup** | Grouped avatars with overlap and count | ✅ | ✅ |
|
|
155
|
+
| **Tooltip** | Contextual hints with 9 variants, 4 triggers, and interactive mode | ✅ | ✅ |
|
|
156
|
+
| **Link** | Smart links with 9 variants and icon support | ✅ | ✅ |
|
|
157
|
+
| **List** | Modern lists with 5 variants and icon support | ✅ | ✅ |
|
|
158
|
+
| **Timeline** | Chronological events with 4 variants, positions, and statuses | ✅ | ✅ |
|
|
159
|
+
| **Tree** | Hierarchical data with 4 variants, icons, and expand/collapse | ✅ | ✅ |
|
|
160
|
+
| **Image** | Advanced image with lazy loading | ✅ | ✅ |
|
|
161
|
+
| **Carousel** | Image slider with 4 transition effects | ✅ | ✅ |
|
|
162
|
+
| **Steps** | Progress indicator with 4 variants, horizontal/vertical layouts | ✅ | ✅ |
|
|
163
|
+
| **Table** | Data table with sorting, selection, 5 variants, and responsive | ✅ | ✅ |
|
|
164
|
+
| **Rating** | Star rating with 6 variants, 4 sizes, multiple icons, half stars | ✅ | ✅ |
|
|
165
|
+
| **Progress** | Progress bar with 9 variants, 5 sizes, animations, striped | ✅ | ✅ |
|
|
166
|
+
| **Popover** | Rich content popover with 11 variants, 12 positions, 4 triggers | ✅ | ✅ |
|
|
167
|
+
| **PlayButton** | Animated play/pause button with 9 variants, 4 sizes, smooth transitions | ✅ | ✅ |
|
|
168
|
+
| **FloatingActionButton** | Modern FAB with 9 variants, 4 sizes, positions, extended mode | ✅ | ✅ |
|
|
169
|
+
| **Radio** | Radio button with 7 variants, 3 sizes, RadioGroup, descriptions | ✅ | ✅ |
|
|
170
|
+
| **Switch** | Toggle switch with 7 variants, 3 sizes, icons, loading state | ✅ | ✅ |
|
|
171
|
+
| **Checkbox** | Checkbox with 7 variants, 3 sizes, indeterminate, card mode, icons | ✅ | ✅ |
|
|
172
|
+
| **CheckboxGroup** | Grouped checkboxes with layouts, validation, card grid, custom children | ✅ | ✅ |
|
|
173
|
+
| **Select** | Advanced dropdown with search, multi-select, icons, avatars, grouping | ✅ | ✅ |
|
|
174
|
+
| **Skeleton** | Loading placeholder with 5 variants, 4 shapes, customizable animations | ✅ | ✅ |
|
|
175
|
+
| **Spinner** | Loading spinner with 10 variants, 6 sizes, 4 animations, fullscreen mode | ✅ | ✅ |
|
|
176
|
+
| **Pagination** | Page navigation with 5 variants, 3 sizes, ellipsis, customizable labels | ✅ | ✅ |
|
|
177
|
+
| **DatePicker** | Calendar date picker with 5 variants, 3 sizes, date restrictions | ✅ | ✅ |
|
|
178
|
+
| **Tab** | Tab navigation with 14 variants, 3 sizes, icons, badges, disabled states | ✅ | ✅ |
|
|
179
|
+
| **Input** | Text input with 10 variants, 4 sizes, icons, validation, all input types | ✅ | ✅ |
|
|
173
180
|
|
|
174
181
|
---
|
|
175
182
|
|
|
176
183
|
## ⚡ Quick Examples
|
|
177
184
|
|
|
178
|
-
Here are simple examples for all
|
|
185
|
+
Here are simple examples for all 32 components to get you started quickly:
|
|
179
186
|
|
|
180
187
|
### Button
|
|
181
188
|
|
|
@@ -202,10 +209,9 @@ import { ButtonGroup, Button } from "saha-ui";
|
|
|
202
209
|
```tsx
|
|
203
210
|
import { Alert } from "saha-ui";
|
|
204
211
|
|
|
205
|
-
<Alert status="success"
|
|
206
|
-
<Alert status="
|
|
207
|
-
|
|
208
|
-
</Alert>
|
|
212
|
+
<Alert status="success" message="Operation completed successfully!" />
|
|
213
|
+
<Alert status="danger" variant="solid" message="Error occurred!" closeable />
|
|
214
|
+
<Alert status="warning" variant="glass" title="Warning" message="Please review before proceeding." />
|
|
209
215
|
```
|
|
210
216
|
|
|
211
217
|
### Badge
|
|
@@ -221,16 +227,34 @@ import { Badge } from "saha-ui";
|
|
|
221
227
|
### Breadcrumb
|
|
222
228
|
|
|
223
229
|
```tsx
|
|
224
|
-
import { Breadcrumb } from "saha-ui";
|
|
225
|
-
|
|
226
|
-
const items = [
|
|
227
|
-
{ label: 'Home', href: '/' },
|
|
228
|
-
{ label: 'Products', href: '/products' },
|
|
229
|
-
{ label: 'Details', href: '/products/123' }
|
|
230
|
-
];
|
|
230
|
+
import { Breadcrumb, BreadcrumbItem, BreadcrumbSeparator } from "saha-ui";
|
|
231
231
|
|
|
232
|
-
|
|
233
|
-
<Breadcrumb
|
|
232
|
+
// Basic breadcrumb
|
|
233
|
+
<Breadcrumb>
|
|
234
|
+
<BreadcrumbItem href="/">Home</BreadcrumbItem>
|
|
235
|
+
<BreadcrumbSeparator />
|
|
236
|
+
<BreadcrumbItem href="/products">Products</BreadcrumbItem>
|
|
237
|
+
<BreadcrumbSeparator />
|
|
238
|
+
<BreadcrumbItem isCurrentPage>Details</BreadcrumbItem>
|
|
239
|
+
</Breadcrumb>
|
|
240
|
+
|
|
241
|
+
// With variants and separator types
|
|
242
|
+
<Breadcrumb variant="pills" separator="arrow">
|
|
243
|
+
<BreadcrumbItem href="/">Home</BreadcrumbItem>
|
|
244
|
+
<BreadcrumbSeparator />
|
|
245
|
+
<BreadcrumbItem href="/products">Products</BreadcrumbItem>
|
|
246
|
+
<BreadcrumbSeparator />
|
|
247
|
+
<BreadcrumbItem isCurrentPage>Electronics</BreadcrumbItem>
|
|
248
|
+
</Breadcrumb>
|
|
249
|
+
|
|
250
|
+
// Other separator options: "chevron" (default), "slash", "dot", "arrow"
|
|
251
|
+
<Breadcrumb variant="glass" separator="slash">
|
|
252
|
+
<BreadcrumbItem href="/">Home</BreadcrumbItem>
|
|
253
|
+
<BreadcrumbSeparator />
|
|
254
|
+
<BreadcrumbItem href="/docs">Docs</BreadcrumbItem>
|
|
255
|
+
<BreadcrumbSeparator />
|
|
256
|
+
<BreadcrumbItem isCurrentPage>API</BreadcrumbItem>
|
|
257
|
+
</Breadcrumb>
|
|
234
258
|
```
|
|
235
259
|
|
|
236
260
|
### Card
|
|
@@ -251,13 +275,26 @@ import { Card, CardHeader, CardTitle, CardContent } from "saha-ui";
|
|
|
251
275
|
```tsx
|
|
252
276
|
import { Chip } from "saha-ui";
|
|
253
277
|
|
|
254
|
-
|
|
255
|
-
<Chip
|
|
278
|
+
// Basic chips with variants
|
|
279
|
+
<Chip variant="filled" color="primary">JavaScript</Chip>
|
|
280
|
+
<Chip variant="outlined" color="secondary">TypeScript</Chip>
|
|
281
|
+
<Chip variant="soft" color="success">React</Chip>
|
|
282
|
+
<Chip variant="glass" color="primary">Saha UI</Chip>
|
|
283
|
+
|
|
284
|
+
// Deletable chip
|
|
285
|
+
<Chip deletable onDelete={() => console.log('deleted')} color="error">
|
|
256
286
|
Remove me
|
|
257
287
|
</Chip>
|
|
258
|
-
|
|
288
|
+
|
|
289
|
+
// Clickable chip
|
|
290
|
+
<Chip clickable onClick={() => alert('clicked')} color="info">
|
|
259
291
|
Click me
|
|
260
292
|
</Chip>
|
|
293
|
+
|
|
294
|
+
// With avatars
|
|
295
|
+
<Chip avatar={<Avatar name="JD" size="xs" />} color="primary">
|
|
296
|
+
John Doe
|
|
297
|
+
</Chip>
|
|
261
298
|
```
|
|
262
299
|
|
|
263
300
|
### Divider
|
|
@@ -274,21 +311,26 @@ import { Divider } from "saha-ui";
|
|
|
274
311
|
### Accordion
|
|
275
312
|
|
|
276
313
|
```tsx
|
|
277
|
-
import { Accordion } from "saha-ui";
|
|
314
|
+
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from "saha-ui";
|
|
278
315
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
316
|
+
<Accordion type="single" collapsible>
|
|
317
|
+
<AccordionItem value="item-1">
|
|
318
|
+
<AccordionTrigger>Section 1</AccordionTrigger>
|
|
319
|
+
<AccordionContent>Content for section 1</AccordionContent>
|
|
320
|
+
</AccordionItem>
|
|
321
|
+
<AccordionItem value="item-2">
|
|
322
|
+
<AccordionTrigger>Section 2</AccordionTrigger>
|
|
323
|
+
<AccordionContent>Content for section 2</AccordionContent>
|
|
324
|
+
</AccordionItem>
|
|
325
|
+
</Accordion>
|
|
289
326
|
|
|
290
|
-
|
|
291
|
-
<Accordion
|
|
327
|
+
// Multiple items open at once
|
|
328
|
+
<Accordion type="multiple" variant="glass">
|
|
329
|
+
<AccordionItem value="item-1">
|
|
330
|
+
<AccordionTrigger>Section 1</AccordionTrigger>
|
|
331
|
+
<AccordionContent>Content here</AccordionContent>
|
|
332
|
+
</AccordionItem>
|
|
333
|
+
</Accordion>
|
|
292
334
|
```
|
|
293
335
|
|
|
294
336
|
### Avatar
|
|
@@ -317,26 +359,32 @@ import { AvatarGroup, Avatar } from "saha-ui";
|
|
|
317
359
|
### Tooltip
|
|
318
360
|
|
|
319
361
|
```tsx
|
|
320
|
-
import { Tooltip } from "saha-ui";
|
|
362
|
+
import { Tooltip, TooltipTrigger, TooltipContent } from "saha-ui";
|
|
321
363
|
|
|
322
364
|
// Basic tooltip
|
|
323
|
-
<Tooltip
|
|
324
|
-
<
|
|
365
|
+
<Tooltip>
|
|
366
|
+
<TooltipTrigger>
|
|
367
|
+
<Button>Hover me</Button>
|
|
368
|
+
</TooltipTrigger>
|
|
369
|
+
<TooltipContent>This is a tooltip</TooltipContent>
|
|
325
370
|
</Tooltip>
|
|
326
371
|
|
|
327
372
|
// With variant and position
|
|
328
|
-
<Tooltip
|
|
329
|
-
<
|
|
373
|
+
<Tooltip variant="success" position="right">
|
|
374
|
+
<TooltipTrigger>
|
|
375
|
+
<Badge variant="success">Active</Badge>
|
|
376
|
+
</TooltipTrigger>
|
|
377
|
+
<TooltipContent>Success message!</TooltipContent>
|
|
330
378
|
</Tooltip>
|
|
331
379
|
|
|
332
380
|
// Interactive tooltip with click trigger
|
|
333
|
-
<Tooltip
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
>
|
|
339
|
-
|
|
381
|
+
<Tooltip interactive trigger="click" variant="glass">
|
|
382
|
+
<TooltipTrigger>
|
|
383
|
+
<Button>Click Me</Button>
|
|
384
|
+
</TooltipTrigger>
|
|
385
|
+
<TooltipContent>
|
|
386
|
+
<div>Click <a href="#">here</a> for more</div>
|
|
387
|
+
</TooltipContent>
|
|
340
388
|
</Tooltip>
|
|
341
389
|
```
|
|
342
390
|
|
|
@@ -355,54 +403,73 @@ import { Link } from "saha-ui";
|
|
|
355
403
|
### List
|
|
356
404
|
|
|
357
405
|
```tsx
|
|
358
|
-
import { List } from "saha-ui";
|
|
406
|
+
import { List, ListItem } from "saha-ui";
|
|
407
|
+
import { CheckCircle } from "lucide-react";
|
|
359
408
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
409
|
+
<List variant="bordered">
|
|
410
|
+
<ListItem>First item</ListItem>
|
|
411
|
+
<ListItem>Second item</ListItem>
|
|
412
|
+
<ListItem>Third item</ListItem>
|
|
413
|
+
</List>
|
|
365
414
|
|
|
366
|
-
|
|
367
|
-
<List
|
|
415
|
+
// With icons
|
|
416
|
+
<List variant="cards">
|
|
417
|
+
<ListItem icon={<CheckCircle size={18} />}>Completed task</ListItem>
|
|
418
|
+
<ListItem icon={<CheckCircle size={18} />}>Another task</ListItem>
|
|
419
|
+
</List>
|
|
368
420
|
```
|
|
369
421
|
|
|
370
422
|
### Timeline
|
|
371
423
|
|
|
372
424
|
```tsx
|
|
373
|
-
import { Timeline } from "saha-ui";
|
|
425
|
+
import { Timeline, TimelineItem } from "saha-ui";
|
|
374
426
|
import { Rocket, Package, Check } from "lucide-react";
|
|
375
427
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
428
|
+
<Timeline variant="gradient">
|
|
429
|
+
<TimelineItem
|
|
430
|
+
icon={<Rocket size={18} />}
|
|
431
|
+
title="Project Started"
|
|
432
|
+
description="Initial setup"
|
|
433
|
+
time="2 hours ago"
|
|
434
|
+
/>
|
|
435
|
+
<TimelineItem
|
|
436
|
+
icon={<Package size={18} />}
|
|
437
|
+
title="Development"
|
|
438
|
+
description="Building features"
|
|
439
|
+
time="1 hour ago"
|
|
440
|
+
status="primary"
|
|
441
|
+
/>
|
|
442
|
+
<TimelineItem
|
|
443
|
+
icon={<Check size={18} />}
|
|
444
|
+
title="Completed"
|
|
445
|
+
description="Ready to deploy"
|
|
446
|
+
time="Just now"
|
|
447
|
+
status="success"
|
|
448
|
+
/>
|
|
449
|
+
</Timeline>
|
|
381
450
|
|
|
382
|
-
|
|
383
|
-
<Timeline
|
|
451
|
+
// Alternate positioning
|
|
452
|
+
<Timeline position="alternate">
|
|
453
|
+
<TimelineItem title="Event 1" />
|
|
454
|
+
<TimelineItem title="Event 2" />
|
|
455
|
+
</Timeline>
|
|
384
456
|
```
|
|
385
457
|
|
|
386
458
|
### Tree
|
|
387
459
|
|
|
388
460
|
```tsx
|
|
389
|
-
import { Tree } from "saha-ui";
|
|
461
|
+
import { Tree, TreeItem } from "saha-ui";
|
|
390
462
|
import { Folder, File } from "lucide-react";
|
|
391
463
|
|
|
392
|
-
|
|
393
|
-
{
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
}
|
|
402
|
-
];
|
|
403
|
-
|
|
404
|
-
<Tree nodes={nodes} />
|
|
405
|
-
<Tree nodes={nodes} variant="glass" onNodeClick={(id) => console.log(id)} />
|
|
464
|
+
<Tree variant="glass">
|
|
465
|
+
<TreeItem label="src" icon={<Folder size={16} />}>
|
|
466
|
+
<TreeItem label="components" icon={<Folder size={16} />}>
|
|
467
|
+
<TreeItem label="Button.tsx" icon={<File size={16} />} />
|
|
468
|
+
<TreeItem label="Card.tsx" icon={<File size={16} />} />
|
|
469
|
+
</TreeItem>
|
|
470
|
+
<TreeItem label="App.tsx" icon={<File size={16} />} />
|
|
471
|
+
</TreeItem>
|
|
472
|
+
</Tree>;
|
|
406
473
|
```
|
|
407
474
|
|
|
408
475
|
### Image
|
|
@@ -428,51 +495,92 @@ import { Image } from "saha-ui";
|
|
|
428
495
|
### Carousel
|
|
429
496
|
|
|
430
497
|
```tsx
|
|
431
|
-
import { Carousel } from "saha-ui";
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
<
|
|
440
|
-
|
|
498
|
+
import { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext } from "saha-ui";
|
|
499
|
+
|
|
500
|
+
<Carousel autoplay autoplayInterval={3000}>
|
|
501
|
+
<CarouselContent>
|
|
502
|
+
<CarouselItem>
|
|
503
|
+
<img src="/image1.jpg" alt="Slide 1" />
|
|
504
|
+
</CarouselItem>
|
|
505
|
+
<CarouselItem>
|
|
506
|
+
<img src="/image2.jpg" alt="Slide 2" />
|
|
507
|
+
</CarouselItem>
|
|
508
|
+
<CarouselItem>
|
|
509
|
+
<img src="/image3.jpg" alt="Slide 3" />
|
|
510
|
+
</CarouselItem>
|
|
511
|
+
</CarouselContent>
|
|
512
|
+
<CarouselPrevious />
|
|
513
|
+
<CarouselNext />
|
|
514
|
+
</Carousel>
|
|
515
|
+
|
|
516
|
+
// With variants
|
|
517
|
+
<Carousel variant="glass" autoplay>
|
|
518
|
+
<CarouselContent>
|
|
519
|
+
{/* Your carousel items */}
|
|
520
|
+
</CarouselContent>
|
|
521
|
+
<CarouselPrevious />
|
|
522
|
+
<CarouselNext />
|
|
523
|
+
</Carousel>
|
|
441
524
|
```
|
|
442
525
|
|
|
443
526
|
### Steps
|
|
444
527
|
|
|
445
528
|
```tsx
|
|
446
|
-
import { Steps } from "saha-ui";
|
|
529
|
+
import { Steps, StepsItem } from "saha-ui";
|
|
530
|
+
import { User, CreditCard, Check } from "lucide-react";
|
|
447
531
|
|
|
448
|
-
|
|
449
|
-
{
|
|
450
|
-
{
|
|
451
|
-
{
|
|
452
|
-
|
|
532
|
+
<Steps defaultValue={2}>
|
|
533
|
+
<StepsItem value={1} title="Account" description="Create your account" />
|
|
534
|
+
<StepsItem value={2} title="Profile" description="Fill in your details" />
|
|
535
|
+
<StepsItem value={3} title="Complete" description="You're all set!" />
|
|
536
|
+
</Steps>
|
|
537
|
+
|
|
538
|
+
// With icons
|
|
539
|
+
<Steps defaultValue={2} variant="glass">
|
|
540
|
+
<StepsItem value={1} title="Info" icon={<User className="w-5 h-5" />} />
|
|
541
|
+
<StepsItem value={2} title="Payment" icon={<CreditCard className="w-5 h-5" />} />
|
|
542
|
+
<StepsItem value={3} title="Done" icon={<Check className="w-5 h-5" />} />
|
|
543
|
+
</Steps>
|
|
453
544
|
|
|
454
|
-
|
|
455
|
-
<Steps
|
|
545
|
+
// Vertical orientation
|
|
546
|
+
<Steps orientation="vertical" defaultValue={1}>
|
|
547
|
+
<StepsItem value={1} title="Step 1" status="completed" />
|
|
548
|
+
<StepsItem value={2} title="Step 2" status="current" />
|
|
549
|
+
<StepsItem value={3} title="Step 3" status="pending" />
|
|
550
|
+
</Steps>
|
|
456
551
|
```
|
|
457
552
|
|
|
458
553
|
### Table
|
|
459
554
|
|
|
460
555
|
```tsx
|
|
461
|
-
import { Table } from "saha-ui";
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
<
|
|
475
|
-
<
|
|
556
|
+
import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "saha-ui";
|
|
557
|
+
|
|
558
|
+
<Table>
|
|
559
|
+
<TableHeader>
|
|
560
|
+
<TableRow>
|
|
561
|
+
<TableHead>Name</TableHead>
|
|
562
|
+
<TableHead>Email</TableHead>
|
|
563
|
+
<TableHead>Role</TableHead>
|
|
564
|
+
</TableRow>
|
|
565
|
+
</TableHeader>
|
|
566
|
+
<TableBody>
|
|
567
|
+
<TableRow>
|
|
568
|
+
<TableCell>Alice Johnson</TableCell>
|
|
569
|
+
<TableCell>alice@example.com</TableCell>
|
|
570
|
+
<TableCell>Admin</TableCell>
|
|
571
|
+
</TableRow>
|
|
572
|
+
<TableRow>
|
|
573
|
+
<TableCell>Bob Smith</TableCell>
|
|
574
|
+
<TableCell>bob@example.com</TableCell>
|
|
575
|
+
<TableCell>Developer</TableCell>
|
|
576
|
+
</TableRow>
|
|
577
|
+
</TableBody>
|
|
578
|
+
</Table>
|
|
579
|
+
|
|
580
|
+
// With variants
|
|
581
|
+
<Table variant="bordered" hoverable>
|
|
582
|
+
{/* Table content */}
|
|
583
|
+
</Table>
|
|
476
584
|
```
|
|
477
585
|
|
|
478
586
|
### Rating
|
|
@@ -535,6 +643,214 @@ import { PlayButton } from "saha-ui";
|
|
|
535
643
|
/>
|
|
536
644
|
```
|
|
537
645
|
|
|
646
|
+
### FloatingActionButton
|
|
647
|
+
|
|
648
|
+
```tsx
|
|
649
|
+
import { FloatingActionButton } from "saha-ui";
|
|
650
|
+
import { Plus } from "lucide-react";
|
|
651
|
+
|
|
652
|
+
<FloatingActionButton
|
|
653
|
+
variant="primary"
|
|
654
|
+
position="bottom-right"
|
|
655
|
+
label="Create New"
|
|
656
|
+
onClick={() => console.log("FAB clicked!")}
|
|
657
|
+
>
|
|
658
|
+
<Plus size={24} />
|
|
659
|
+
</FloatingActionButton>;
|
|
660
|
+
|
|
661
|
+
{
|
|
662
|
+
/* Extended FAB */
|
|
663
|
+
}
|
|
664
|
+
<FloatingActionButton
|
|
665
|
+
variant="accent"
|
|
666
|
+
position="bottom-left"
|
|
667
|
+
label="Add Item"
|
|
668
|
+
extended
|
|
669
|
+
>
|
|
670
|
+
<Plus size={20} />
|
|
671
|
+
</FloatingActionButton>;
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### Radio
|
|
675
|
+
|
|
676
|
+
```tsx
|
|
677
|
+
import { Radio, RadioGroup } from "saha-ui";
|
|
678
|
+
|
|
679
|
+
{
|
|
680
|
+
/* Basic Radio */
|
|
681
|
+
}
|
|
682
|
+
<Radio label="Option 1" value="option1" />;
|
|
683
|
+
|
|
684
|
+
{
|
|
685
|
+
/* Radio with description */
|
|
686
|
+
}
|
|
687
|
+
<Radio
|
|
688
|
+
label="Pro Plan"
|
|
689
|
+
description="Advanced features for teams"
|
|
690
|
+
value="pro"
|
|
691
|
+
/>;
|
|
692
|
+
|
|
693
|
+
{
|
|
694
|
+
/* RadioGroup */
|
|
695
|
+
}
|
|
696
|
+
<RadioGroup
|
|
697
|
+
name="plan"
|
|
698
|
+
label="Choose Your Plan"
|
|
699
|
+
value={selectedPlan}
|
|
700
|
+
onChange={setSelectedPlan}
|
|
701
|
+
options={[
|
|
702
|
+
{ label: "Free", value: "free" },
|
|
703
|
+
{ label: "Pro", value: "pro" },
|
|
704
|
+
{ label: "Enterprise", value: "enterprise" },
|
|
705
|
+
]}
|
|
706
|
+
/>;
|
|
707
|
+
|
|
708
|
+
{
|
|
709
|
+
/* Advanced: Card Style with Icons & Badges */
|
|
710
|
+
}
|
|
711
|
+
<RadioGroup name="pricing" card>
|
|
712
|
+
<Radio
|
|
713
|
+
value="pro"
|
|
714
|
+
label="Professional"
|
|
715
|
+
description="For growing businesses"
|
|
716
|
+
icon={<Rocket />}
|
|
717
|
+
badge="Popular"
|
|
718
|
+
recommended
|
|
719
|
+
/>
|
|
720
|
+
</RadioGroup>;
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
### Switch
|
|
724
|
+
|
|
725
|
+
```tsx
|
|
726
|
+
import { Switch } from "saha-ui";
|
|
727
|
+
|
|
728
|
+
{
|
|
729
|
+
/* Basic Switch */
|
|
730
|
+
}
|
|
731
|
+
<Switch label="Enable Notifications" />;
|
|
732
|
+
|
|
733
|
+
{
|
|
734
|
+
/* With icons */
|
|
735
|
+
}
|
|
736
|
+
<Switch
|
|
737
|
+
label="Dark Mode"
|
|
738
|
+
description="Toggle dark theme"
|
|
739
|
+
onIcon={<Moon />}
|
|
740
|
+
offIcon={<Sun />}
|
|
741
|
+
/>;
|
|
742
|
+
|
|
743
|
+
{
|
|
744
|
+
/* With loading state */
|
|
745
|
+
}
|
|
746
|
+
<Switch label="Auto-save" loading />;
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
### Checkbox
|
|
750
|
+
|
|
751
|
+
```tsx
|
|
752
|
+
import { Checkbox } from "saha-ui";
|
|
753
|
+
|
|
754
|
+
// Basic checkbox
|
|
755
|
+
<Checkbox label="Accept terms" />
|
|
756
|
+
|
|
757
|
+
// With description
|
|
758
|
+
<Checkbox
|
|
759
|
+
label="Marketing emails"
|
|
760
|
+
description="Receive promotional content"
|
|
761
|
+
/>
|
|
762
|
+
|
|
763
|
+
// Indeterminate state
|
|
764
|
+
<Checkbox indeterminate label="Select all" />
|
|
765
|
+
|
|
766
|
+
// With custom icon
|
|
767
|
+
<Checkbox icon={<Star />} label="Favorite" variant="warning" />
|
|
768
|
+
|
|
769
|
+
// Card mode
|
|
770
|
+
<Checkbox
|
|
771
|
+
card
|
|
772
|
+
label="Premium Plan"
|
|
773
|
+
description="$29/month"
|
|
774
|
+
icon={<Crown />}
|
|
775
|
+
badge="Popular"
|
|
776
|
+
/>
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
### CheckboxGroup
|
|
780
|
+
|
|
781
|
+
```tsx
|
|
782
|
+
import { CheckboxGroup } from "saha-ui";
|
|
783
|
+
|
|
784
|
+
// Basic group
|
|
785
|
+
<CheckboxGroup
|
|
786
|
+
label="Select interests"
|
|
787
|
+
options={[
|
|
788
|
+
{ value: "coding", label: "Coding" },
|
|
789
|
+
{ value: "design", label: "Design" },
|
|
790
|
+
{ value: "marketing", label: "Marketing" },
|
|
791
|
+
]}
|
|
792
|
+
/>
|
|
793
|
+
|
|
794
|
+
// Horizontal layout
|
|
795
|
+
<CheckboxGroup
|
|
796
|
+
direction="horizontal"
|
|
797
|
+
options={[
|
|
798
|
+
{ value: "notifications", label: "Email Notifications" },
|
|
799
|
+
{ value: "newsletter", label: "Newsletter" },
|
|
800
|
+
]}
|
|
801
|
+
/>
|
|
802
|
+
|
|
803
|
+
// Card layout with icons
|
|
804
|
+
<CheckboxGroup
|
|
805
|
+
card
|
|
806
|
+
label="Choose features"
|
|
807
|
+
options={[
|
|
808
|
+
{ value: "basic", label: "Basic Support", icon: <Star />, badge: "Free" },
|
|
809
|
+
{ value: "premium", label: "Premium", icon: <Crown />, badge: "$29/mo", recommended: true },
|
|
810
|
+
]}
|
|
811
|
+
/>
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
### Select
|
|
815
|
+
|
|
816
|
+
```tsx
|
|
817
|
+
import { Select } from "saha-ui";
|
|
818
|
+
|
|
819
|
+
// Basic select
|
|
820
|
+
<Select
|
|
821
|
+
label="Country"
|
|
822
|
+
placeholder="Select your country"
|
|
823
|
+
options={[
|
|
824
|
+
{ value: "us", label: "United States" },
|
|
825
|
+
{ value: "uk", label: "United Kingdom" },
|
|
826
|
+
{ value: "ca", label: "Canada" },
|
|
827
|
+
]}
|
|
828
|
+
/>
|
|
829
|
+
|
|
830
|
+
// Multi-select with search
|
|
831
|
+
<Select
|
|
832
|
+
label="Skills"
|
|
833
|
+
placeholder="Select your skills"
|
|
834
|
+
options={[
|
|
835
|
+
{ value: "react", label: "React", icon: <Code /> },
|
|
836
|
+
{ value: "vue", label: "Vue.js", icon: <Code /> },
|
|
837
|
+
]}
|
|
838
|
+
multiple
|
|
839
|
+
searchable
|
|
840
|
+
clearable
|
|
841
|
+
/>
|
|
842
|
+
|
|
843
|
+
// With avatars
|
|
844
|
+
<Select
|
|
845
|
+
label="Assign to"
|
|
846
|
+
placeholder="Select team member"
|
|
847
|
+
options={[
|
|
848
|
+
{ value: "alice", label: "Alice", avatar: "/avatar1.jpg" },
|
|
849
|
+
{ value: "bob", label: "Bob", avatar: "/avatar2.jpg" },
|
|
850
|
+
]}
|
|
851
|
+
/>
|
|
852
|
+
```
|
|
853
|
+
|
|
538
854
|
### Skeleton
|
|
539
855
|
|
|
540
856
|
```tsx
|
|
@@ -547,6 +863,53 @@ import { Skeleton } from "saha-ui";
|
|
|
547
863
|
<Skeleton shape="circle" width="48px" height="48px" variant="pulse" />
|
|
548
864
|
```
|
|
549
865
|
|
|
866
|
+
### Spinner
|
|
867
|
+
|
|
868
|
+
```tsx
|
|
869
|
+
import { Spinner } from "saha-ui";
|
|
870
|
+
|
|
871
|
+
// Basic usage
|
|
872
|
+
<Spinner />
|
|
873
|
+
|
|
874
|
+
// With variants and sizes
|
|
875
|
+
<Spinner variant="success" size="lg" label="Loading..." />
|
|
876
|
+
|
|
877
|
+
// Different spinner types (15 types available!)
|
|
878
|
+
<Spinner type="ring" variant="primary" size="lg" />
|
|
879
|
+
<Spinner type="orbit" variant="gradient" size="xl" />
|
|
880
|
+
<Spinner type="flower" variant="success" size="lg" />
|
|
881
|
+
<Spinner type="infinity" variant="primary" size="2xl" />
|
|
882
|
+
<Spinner type="wave" variant="info" size="md" />
|
|
883
|
+
<Spinner type="spiral" variant="accent" size="lg" />
|
|
884
|
+
|
|
885
|
+
// Fullscreen overlay
|
|
886
|
+
<Spinner variant="gradient" animation="pulse" fullscreen />
|
|
887
|
+
|
|
888
|
+
// With custom logo/icon
|
|
889
|
+
<Spinner
|
|
890
|
+
variant="primary"
|
|
891
|
+
size="xl"
|
|
892
|
+
logo="/your-logo.png"
|
|
893
|
+
logoSize="md"
|
|
894
|
+
label="Loading..."
|
|
895
|
+
/>
|
|
896
|
+
|
|
897
|
+
// With custom component
|
|
898
|
+
<Spinner
|
|
899
|
+
type="orbit"
|
|
900
|
+
variant="success"
|
|
901
|
+
size="xl"
|
|
902
|
+
logo={<YourCustomIcon />}
|
|
903
|
+
logoSize="lg"
|
|
904
|
+
/>
|
|
905
|
+
|
|
906
|
+
// In buttons
|
|
907
|
+
<Button variant="primary" disabled>
|
|
908
|
+
<Spinner type="bounce" size="sm" variant="default" />
|
|
909
|
+
Loading...
|
|
910
|
+
</Button>
|
|
911
|
+
```
|
|
912
|
+
|
|
550
913
|
### Pagination
|
|
551
914
|
|
|
552
915
|
```tsx
|
|
@@ -564,33 +927,51 @@ import { Pagination } from "saha-ui";
|
|
|
564
927
|
```tsx
|
|
565
928
|
import { DatePicker } from "saha-ui";
|
|
566
929
|
|
|
567
|
-
|
|
930
|
+
// Single date picker
|
|
931
|
+
<DatePicker
|
|
932
|
+
value={{ startDate: date, endDate: date }}
|
|
933
|
+
onChange={(value) => setDate(value)}
|
|
934
|
+
asSingle
|
|
935
|
+
placeholder="Select date"
|
|
936
|
+
/>
|
|
568
937
|
|
|
569
|
-
|
|
938
|
+
// Date range picker
|
|
939
|
+
<DatePicker
|
|
940
|
+
value={{ startDate: null, endDate: null }}
|
|
941
|
+
onChange={(value) => setRange(value)}
|
|
942
|
+
placeholder="Select date range"
|
|
943
|
+
/>
|
|
570
944
|
|
|
571
|
-
|
|
945
|
+
// With variants and restrictions
|
|
946
|
+
<DatePicker
|
|
947
|
+
variant="primary"
|
|
948
|
+
minDate={new Date()}
|
|
949
|
+
maxDate={futureDate}
|
|
950
|
+
asSingle
|
|
951
|
+
/>
|
|
572
952
|
```
|
|
573
953
|
|
|
574
954
|
### Tab
|
|
575
955
|
|
|
576
956
|
```tsx
|
|
577
|
-
import {
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
<
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
957
|
+
import { Tabs, TabsList, TabsTrigger, TabsContent } from "saha-ui";
|
|
958
|
+
|
|
959
|
+
<Tabs defaultValue="profile">
|
|
960
|
+
<TabsList>
|
|
961
|
+
<TabsTrigger value="profile">Profile</TabsTrigger>
|
|
962
|
+
<TabsTrigger value="settings">Settings</TabsTrigger>
|
|
963
|
+
</TabsList>
|
|
964
|
+
<TabsContent value="profile">Profile content</TabsContent>
|
|
965
|
+
<TabsContent value="settings">Settings content</TabsContent>
|
|
966
|
+
</Tabs>
|
|
967
|
+
|
|
968
|
+
// With variants and sizes
|
|
969
|
+
<Tabs defaultValue="home" variant="primary" size="lg">
|
|
970
|
+
<TabsList>
|
|
971
|
+
<TabsTrigger value="home">Home</TabsTrigger>
|
|
972
|
+
<TabsTrigger value="messages">Messages</TabsTrigger>
|
|
973
|
+
</TabsList>
|
|
974
|
+
</Tabs>
|
|
594
975
|
```
|
|
595
976
|
|
|
596
977
|
### Input
|
|
@@ -1555,22 +1936,21 @@ Display multiple avatars with overlap and count indicator.
|
|
|
1555
1936
|
**Sizes:** `xs` `sm` `md` `lg` `xl` `2xl`
|
|
1556
1937
|
|
|
1557
1938
|
```tsx
|
|
1558
|
-
import { AvatarGroup } from "saha-ui";
|
|
1939
|
+
import { AvatarGroup, Avatar } from "saha-ui";
|
|
1559
1940
|
|
|
1560
1941
|
<AvatarGroup
|
|
1561
|
-
avatars={[
|
|
1562
|
-
{ src: "/user1.jpg", alt: "User 1" },
|
|
1563
|
-
{ src: "/user2.jpg", alt: "User 2" },
|
|
1564
|
-
{ src: "/user3.jpg", alt: "User 3" },
|
|
1565
|
-
{ src: "/user4.jpg", alt: "User 4" },
|
|
1566
|
-
]}
|
|
1567
1942
|
max={3}
|
|
1568
1943
|
size="md"
|
|
1569
1944
|
variant="stack"
|
|
1570
1945
|
gap={false}
|
|
1571
1946
|
withRing={false}
|
|
1572
1947
|
showCount
|
|
1573
|
-
|
|
1948
|
+
>
|
|
1949
|
+
<Avatar src="/user1.jpg" alt="User 1" />
|
|
1950
|
+
<Avatar src="/user2.jpg" alt="User 2" />
|
|
1951
|
+
<Avatar src="/user3.jpg" alt="User 3" />
|
|
1952
|
+
<Avatar src="/user4.jpg" alt="User 4" />
|
|
1953
|
+
</AvatarGroup>;
|
|
1574
1954
|
```
|
|
1575
1955
|
|
|
1576
1956
|
**Features:**
|
|
@@ -1593,62 +1973,63 @@ Contextual hints and information with smart positioning, multiple trigger types,
|
|
|
1593
1973
|
**Triggers:** `hover` `click` `focus` `manual`
|
|
1594
1974
|
|
|
1595
1975
|
```tsx
|
|
1596
|
-
import { Tooltip } from "saha-ui";
|
|
1976
|
+
import { Tooltip, TooltipTrigger, TooltipContent } from "saha-ui";
|
|
1597
1977
|
|
|
1598
1978
|
// Basic tooltip
|
|
1599
|
-
<Tooltip
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
>
|
|
1604
|
-
<Button>Hover me</Button>
|
|
1979
|
+
<Tooltip position="top" variant="glass">
|
|
1980
|
+
<TooltipTrigger>
|
|
1981
|
+
<Button>Hover me</Button>
|
|
1982
|
+
</TooltipTrigger>
|
|
1983
|
+
<TooltipContent>This is helpful information</TooltipContent>
|
|
1605
1984
|
</Tooltip>
|
|
1606
1985
|
|
|
1607
1986
|
// Status tooltips
|
|
1608
|
-
<Tooltip
|
|
1609
|
-
<
|
|
1987
|
+
<Tooltip variant="success">
|
|
1988
|
+
<TooltipTrigger>
|
|
1989
|
+
<Badge variant="success">Active</Badge>
|
|
1990
|
+
</TooltipTrigger>
|
|
1991
|
+
<TooltipContent>All systems operational</TooltipContent>
|
|
1610
1992
|
</Tooltip>
|
|
1611
1993
|
|
|
1612
|
-
<Tooltip
|
|
1613
|
-
<
|
|
1994
|
+
<Tooltip variant="warning" position="right">
|
|
1995
|
+
<TooltipTrigger>
|
|
1996
|
+
<span className="cursor-help">⚠</span>
|
|
1997
|
+
</TooltipTrigger>
|
|
1998
|
+
<TooltipContent>Warning: Check this!</TooltipContent>
|
|
1614
1999
|
</Tooltip>
|
|
1615
2000
|
|
|
1616
2001
|
// Interactive tooltip with click trigger
|
|
1617
|
-
<Tooltip
|
|
1618
|
-
|
|
2002
|
+
<Tooltip interactive trigger="click" variant="glass" maxWidth="200px">
|
|
2003
|
+
<TooltipTrigger>
|
|
2004
|
+
<Button>Click for Options</Button>
|
|
2005
|
+
</TooltipTrigger>
|
|
2006
|
+
<TooltipContent>
|
|
1619
2007
|
<div className="space-y-2">
|
|
1620
2008
|
<p className="font-semibold">Interactive Content</p>
|
|
1621
2009
|
<Button size="sm">Click Me</Button>
|
|
1622
2010
|
</div>
|
|
1623
|
-
|
|
1624
|
-
interactive={true}
|
|
1625
|
-
trigger="click"
|
|
1626
|
-
variant="glass"
|
|
1627
|
-
maxWidth="200px"
|
|
1628
|
-
>
|
|
1629
|
-
<Button>Click for Options</Button>
|
|
2011
|
+
</TooltipContent>
|
|
1630
2012
|
</Tooltip>
|
|
1631
2013
|
|
|
1632
2014
|
// Controlled tooltip
|
|
1633
2015
|
const [open, setOpen] = useState(false);
|
|
1634
|
-
<Tooltip
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
>
|
|
1640
|
-
<Button onClick={() => setOpen(!open)}>Toggle</Button>
|
|
2016
|
+
<Tooltip open={open} onOpenChange={setOpen} trigger="manual">
|
|
2017
|
+
<TooltipTrigger>
|
|
2018
|
+
<Button onClick={() => setOpen(!open)}>Toggle</Button>
|
|
2019
|
+
</TooltipTrigger>
|
|
2020
|
+
<TooltipContent>Controlled tooltip</TooltipContent>
|
|
1641
2021
|
</Tooltip>
|
|
1642
2022
|
|
|
1643
2023
|
// Help icon tooltips
|
|
1644
2024
|
<div className="flex items-center gap-2">
|
|
1645
2025
|
<span>Username</span>
|
|
1646
|
-
<Tooltip
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
2026
|
+
<Tooltip variant="info" size="sm">
|
|
2027
|
+
<TooltipTrigger>
|
|
2028
|
+
<span className="cursor-help text-muted-foreground">ⓘ</span>
|
|
2029
|
+
</TooltipTrigger>
|
|
2030
|
+
<TooltipContent>
|
|
2031
|
+
Enter your unique username (3-20 characters)
|
|
2032
|
+
</TooltipContent>
|
|
1652
2033
|
</Tooltip>
|
|
1653
2034
|
</div>
|
|
1654
2035
|
|
|
@@ -3260,6 +3641,366 @@ const [playing, setPlaying] = useState(false);
|
|
|
3260
3641
|
|
|
3261
3642
|
---
|
|
3262
3643
|
|
|
3644
|
+
### FloatingActionButton
|
|
3645
|
+
|
|
3646
|
+
A modern floating action button (FAB) with beautiful visual effects, multiple positioning options, and extended label support.
|
|
3647
|
+
|
|
3648
|
+
**Basic Usage:**
|
|
3649
|
+
|
|
3650
|
+
```tsx
|
|
3651
|
+
import { FloatingActionButton } from "saha-ui";
|
|
3652
|
+
import { Plus, MessageCircle, Send } from "lucide-react";
|
|
3653
|
+
|
|
3654
|
+
// Basic FAB (using children)
|
|
3655
|
+
<FloatingActionButton
|
|
3656
|
+
variant="primary"
|
|
3657
|
+
position="bottom-right"
|
|
3658
|
+
label="Create New"
|
|
3659
|
+
>
|
|
3660
|
+
<Plus size={24} />
|
|
3661
|
+
</FloatingActionButton>
|
|
3662
|
+
|
|
3663
|
+
// Extended FAB
|
|
3664
|
+
<FloatingActionButton
|
|
3665
|
+
variant="accent"
|
|
3666
|
+
label="Send Message"
|
|
3667
|
+
extended
|
|
3668
|
+
>
|
|
3669
|
+
<Send size={20} />
|
|
3670
|
+
</FloatingActionButton>
|
|
3671
|
+
|
|
3672
|
+
// Different positions
|
|
3673
|
+
<FloatingActionButton position="bottom-left" label="Messages">
|
|
3674
|
+
<MessageCircle />
|
|
3675
|
+
</FloatingActionButton>
|
|
3676
|
+
|
|
3677
|
+
<FloatingActionButton position="top-right" label="Add">
|
|
3678
|
+
<Plus />
|
|
3679
|
+
</FloatingActionButton>
|
|
3680
|
+
|
|
3681
|
+
// Sizes
|
|
3682
|
+
<FloatingActionButton size="sm">
|
|
3683
|
+
<Plus size={16} />
|
|
3684
|
+
</FloatingActionButton>
|
|
3685
|
+
|
|
3686
|
+
<FloatingActionButton size="lg">
|
|
3687
|
+
<Plus size={24} />
|
|
3688
|
+
</FloatingActionButton>
|
|
3689
|
+
|
|
3690
|
+
// Custom offset
|
|
3691
|
+
<FloatingActionButton offset={{ x: 20, y: 20 }} icon={<Plus />} />
|
|
3692
|
+
```
|
|
3693
|
+
|
|
3694
|
+
**Features:**
|
|
3695
|
+
|
|
3696
|
+
- 🎨 9 visual variants with gradients
|
|
3697
|
+
- 📍 4 screen positions + custom offset
|
|
3698
|
+
- 📐 4 size options
|
|
3699
|
+
- 🏷️ Label tooltip on hover
|
|
3700
|
+
- 📝 Extended mode with inline label
|
|
3701
|
+
- 💫 Scale & rotation animations
|
|
3702
|
+
- 🌈 Color-matched shadows
|
|
3703
|
+
- ♿ Fully accessible
|
|
3704
|
+
|
|
3705
|
+
---
|
|
3706
|
+
|
|
3707
|
+
### Radio
|
|
3708
|
+
|
|
3709
|
+
Modern radio buttons with beautiful animations and a powerful RadioGroup component.
|
|
3710
|
+
|
|
3711
|
+
**Basic Usage:**
|
|
3712
|
+
|
|
3713
|
+
```tsx
|
|
3714
|
+
import { Radio, RadioGroup } from "saha-ui";
|
|
3715
|
+
|
|
3716
|
+
// Basic Radio
|
|
3717
|
+
<Radio label="Option 1" value="option1" name="choice" />
|
|
3718
|
+
|
|
3719
|
+
// Radio with description
|
|
3720
|
+
<Radio
|
|
3721
|
+
label="Pro Plan"
|
|
3722
|
+
description="Advanced features for growing businesses"
|
|
3723
|
+
value="pro"
|
|
3724
|
+
name="plan"
|
|
3725
|
+
/>
|
|
3726
|
+
|
|
3727
|
+
// RadioGroup (Controlled)
|
|
3728
|
+
const [selected, setSelected] = useState("pro");
|
|
3729
|
+
|
|
3730
|
+
<RadioGroup
|
|
3731
|
+
name="plan"
|
|
3732
|
+
label="Choose Your Plan"
|
|
3733
|
+
value={selected}
|
|
3734
|
+
onChange={setSelected}
|
|
3735
|
+
options={[
|
|
3736
|
+
{ label: "Free", value: "free", description: "$0/month" },
|
|
3737
|
+
{ label: "Pro", value: "pro", description: "$29/month" },
|
|
3738
|
+
{ label: "Enterprise", value: "enterprise", description: "Custom" },
|
|
3739
|
+
]}
|
|
3740
|
+
/>
|
|
3741
|
+
```
|
|
3742
|
+
|
|
3743
|
+
**Variants:**
|
|
3744
|
+
|
|
3745
|
+
```tsx
|
|
3746
|
+
// Color variants
|
|
3747
|
+
<Radio variant="primary" label="Primary" />
|
|
3748
|
+
<Radio variant="secondary" label="Secondary" />
|
|
3749
|
+
<Radio variant="accent" label="Accent" />
|
|
3750
|
+
<Radio variant="success" label="Success" />
|
|
3751
|
+
<Radio variant="warning" label="Warning" />
|
|
3752
|
+
<Radio variant="error" label="Error" />
|
|
3753
|
+
```
|
|
3754
|
+
|
|
3755
|
+
**Sizes:**
|
|
3756
|
+
|
|
3757
|
+
```tsx
|
|
3758
|
+
<Radio size="sm" label="Small" />
|
|
3759
|
+
<Radio size="md" label="Medium" />
|
|
3760
|
+
<Radio size="lg" label="Large" />
|
|
3761
|
+
```
|
|
3762
|
+
|
|
3763
|
+
**RadioGroup with Children:**
|
|
3764
|
+
|
|
3765
|
+
```tsx
|
|
3766
|
+
<RadioGroup name="custom" value={value} onChange={setValue}>
|
|
3767
|
+
<Radio label="Option 1" value="1" />
|
|
3768
|
+
<Radio label="Option 2" value="2" />
|
|
3769
|
+
<Radio label="Option 3" value="3" />
|
|
3770
|
+
</RadioGroup>
|
|
3771
|
+
```
|
|
3772
|
+
|
|
3773
|
+
**Horizontal Layout:**
|
|
3774
|
+
|
|
3775
|
+
```tsx
|
|
3776
|
+
<RadioGroup
|
|
3777
|
+
name="color"
|
|
3778
|
+
direction="horizontal"
|
|
3779
|
+
value={color}
|
|
3780
|
+
onChange={setColor}
|
|
3781
|
+
options={[
|
|
3782
|
+
{ label: "Blue", value: "blue" },
|
|
3783
|
+
{ label: "Green", value: "green" },
|
|
3784
|
+
{ label: "Red", value: "red" },
|
|
3785
|
+
]}
|
|
3786
|
+
/>
|
|
3787
|
+
```
|
|
3788
|
+
|
|
3789
|
+
**With Validation:**
|
|
3790
|
+
|
|
3791
|
+
```tsx
|
|
3792
|
+
<RadioGroup
|
|
3793
|
+
name="terms"
|
|
3794
|
+
label="Terms and Conditions"
|
|
3795
|
+
error="You must accept the terms to continue"
|
|
3796
|
+
variant="error"
|
|
3797
|
+
>
|
|
3798
|
+
<Radio label="I accept" value="accept" />
|
|
3799
|
+
<Radio label="I decline" value="decline" />
|
|
3800
|
+
</RadioGroup>
|
|
3801
|
+
```
|
|
3802
|
+
|
|
3803
|
+
**Advanced Features:**
|
|
3804
|
+
|
|
3805
|
+
```tsx
|
|
3806
|
+
// Card Style Radio with Icons & Badges
|
|
3807
|
+
<RadioGroup name="pricing" card>
|
|
3808
|
+
<Radio
|
|
3809
|
+
value="free"
|
|
3810
|
+
label="Free"
|
|
3811
|
+
description="Perfect for getting started"
|
|
3812
|
+
icon={<Package />}
|
|
3813
|
+
badge="Free"
|
|
3814
|
+
/>
|
|
3815
|
+
<Radio
|
|
3816
|
+
value="pro"
|
|
3817
|
+
label="Professional"
|
|
3818
|
+
description="For growing businesses"
|
|
3819
|
+
icon={<Rocket />}
|
|
3820
|
+
badge="Popular"
|
|
3821
|
+
recommended
|
|
3822
|
+
/>
|
|
3823
|
+
<Radio
|
|
3824
|
+
value="enterprise"
|
|
3825
|
+
label="Enterprise"
|
|
3826
|
+
description="For large organizations"
|
|
3827
|
+
icon={<Crown />}
|
|
3828
|
+
badge="Custom"
|
|
3829
|
+
/>
|
|
3830
|
+
</RadioGroup>
|
|
3831
|
+
|
|
3832
|
+
// Standard Radio with Icons
|
|
3833
|
+
<Radio
|
|
3834
|
+
value="cloud"
|
|
3835
|
+
label="Cloud Storage"
|
|
3836
|
+
description="Store files securely"
|
|
3837
|
+
icon={<Cloud />}
|
|
3838
|
+
badge="Recommended"
|
|
3839
|
+
/>
|
|
3840
|
+
|
|
3841
|
+
// With Images (Card Mode)
|
|
3842
|
+
<Radio
|
|
3843
|
+
card
|
|
3844
|
+
value="plan-a"
|
|
3845
|
+
label="Plan A"
|
|
3846
|
+
image="/path/to/image.jpg"
|
|
3847
|
+
/>
|
|
3848
|
+
```
|
|
3849
|
+
|
|
3850
|
+
**Features:**
|
|
3851
|
+
|
|
3852
|
+
- 🎨 7 color variants
|
|
3853
|
+
- 📐 3 size options
|
|
3854
|
+
- 🎴 Card layout mode
|
|
3855
|
+
- 🎯 Icon support
|
|
3856
|
+
- 🏷️ Badge system
|
|
3857
|
+
- ⭐ Recommended flag
|
|
3858
|
+
- �️ Image support
|
|
3859
|
+
- �📝 Label descriptions
|
|
3860
|
+
- 🔄 Controlled & uncontrolled modes
|
|
3861
|
+
- 🗂️ RadioGroup component
|
|
3862
|
+
- 📍 Horizontal & vertical layouts
|
|
3863
|
+
- 🎭 Hover effects
|
|
3864
|
+
- ✅ Built-in validation
|
|
3865
|
+
- 💫 Smooth animations
|
|
3866
|
+
- 🌈 Color-matched shadows
|
|
3867
|
+
- ♿ Fully accessible
|
|
3868
|
+
|
|
3869
|
+
See [ADVANCED_RADIO_FEATURES.md](./ADVANCED_RADIO_FEATURES.md) for detailed documentation.
|
|
3870
|
+
|
|
3871
|
+
---
|
|
3872
|
+
|
|
3873
|
+
### Switch
|
|
3874
|
+
|
|
3875
|
+
Modern toggle switch with beautiful animations, icons, and loading states.
|
|
3876
|
+
|
|
3877
|
+
**Basic Usage:**
|
|
3878
|
+
|
|
3879
|
+
```tsx
|
|
3880
|
+
import { Switch } from "saha-ui";
|
|
3881
|
+
|
|
3882
|
+
// Basic Switch
|
|
3883
|
+
<Switch label="Enable Notifications" />
|
|
3884
|
+
|
|
3885
|
+
// With description
|
|
3886
|
+
<Switch
|
|
3887
|
+
label="Dark Mode"
|
|
3888
|
+
description="Toggle between light and dark themes"
|
|
3889
|
+
/>
|
|
3890
|
+
|
|
3891
|
+
// Controlled Switch
|
|
3892
|
+
const [enabled, setEnabled] = useState(false);
|
|
3893
|
+
|
|
3894
|
+
<Switch
|
|
3895
|
+
label="Auto-save"
|
|
3896
|
+
checked={enabled}
|
|
3897
|
+
onCheckedChange={setEnabled}
|
|
3898
|
+
/>
|
|
3899
|
+
```
|
|
3900
|
+
|
|
3901
|
+
**Variants:**
|
|
3902
|
+
|
|
3903
|
+
```tsx
|
|
3904
|
+
// Color variants
|
|
3905
|
+
<Switch variant="primary" label="Primary" />
|
|
3906
|
+
<Switch variant="secondary" label="Secondary" />
|
|
3907
|
+
<Switch variant="accent" label="Accent" />
|
|
3908
|
+
<Switch variant="success" label="Success" />
|
|
3909
|
+
<Switch variant="warning" label="Warning" />
|
|
3910
|
+
<Switch variant="error" label="Error" />
|
|
3911
|
+
```
|
|
3912
|
+
|
|
3913
|
+
**Sizes:**
|
|
3914
|
+
|
|
3915
|
+
```tsx
|
|
3916
|
+
<Switch size="sm" label="Small" />
|
|
3917
|
+
<Switch size="md" label="Medium" />
|
|
3918
|
+
<Switch size="lg" label="Large" />
|
|
3919
|
+
```
|
|
3920
|
+
|
|
3921
|
+
**With Icons:**
|
|
3922
|
+
|
|
3923
|
+
```tsx
|
|
3924
|
+
<Switch
|
|
3925
|
+
label="Dark Mode"
|
|
3926
|
+
onIcon={<Moon className="w-3 h-3" />}
|
|
3927
|
+
offIcon={<Sun className="w-3 h-3" />}
|
|
3928
|
+
/>
|
|
3929
|
+
|
|
3930
|
+
<Switch
|
|
3931
|
+
label="Wi-Fi"
|
|
3932
|
+
onIcon={<Wifi className="w-3 h-3" />}
|
|
3933
|
+
offIcon={<X className="w-3 h-3" />}
|
|
3934
|
+
/>
|
|
3935
|
+
```
|
|
3936
|
+
|
|
3937
|
+
**Loading State:**
|
|
3938
|
+
|
|
3939
|
+
```tsx
|
|
3940
|
+
<Switch label="Processing..." loading />;
|
|
3941
|
+
|
|
3942
|
+
// Async toggle
|
|
3943
|
+
const handleAsyncToggle = async (checked: boolean) => {
|
|
3944
|
+
setLoading(true);
|
|
3945
|
+
await saveSettings(checked);
|
|
3946
|
+
setLoading(false);
|
|
3947
|
+
};
|
|
3948
|
+
|
|
3949
|
+
<Switch
|
|
3950
|
+
label="Auto-save"
|
|
3951
|
+
checked={autoSave}
|
|
3952
|
+
onCheckedChange={handleAsyncToggle}
|
|
3953
|
+
loading={loading}
|
|
3954
|
+
/>;
|
|
3955
|
+
```
|
|
3956
|
+
|
|
3957
|
+
**With Badges:**
|
|
3958
|
+
|
|
3959
|
+
```tsx
|
|
3960
|
+
<Switch label="Beta Features" badge="Beta" />
|
|
3961
|
+
<Switch label="Premium Mode" badge="Pro" variant="accent" />
|
|
3962
|
+
```
|
|
3963
|
+
|
|
3964
|
+
**Label Position:**
|
|
3965
|
+
|
|
3966
|
+
```tsx
|
|
3967
|
+
<Switch label="Label on Right" labelPosition="right" />
|
|
3968
|
+
<Switch label="Label on Left" labelPosition="left" />
|
|
3969
|
+
```
|
|
3970
|
+
|
|
3971
|
+
**With Validation:**
|
|
3972
|
+
|
|
3973
|
+
```tsx
|
|
3974
|
+
<Switch
|
|
3975
|
+
label="Accept Terms"
|
|
3976
|
+
error="You must accept the terms to continue"
|
|
3977
|
+
variant="error"
|
|
3978
|
+
/>
|
|
3979
|
+
|
|
3980
|
+
<Switch
|
|
3981
|
+
label="Newsletter"
|
|
3982
|
+
helperText="You can unsubscribe at any time"
|
|
3983
|
+
/>
|
|
3984
|
+
```
|
|
3985
|
+
|
|
3986
|
+
**Features:**
|
|
3987
|
+
|
|
3988
|
+
- 🎨 7 color variants
|
|
3989
|
+
- 📐 3 size options
|
|
3990
|
+
- 🎯 Icon support (on/off states)
|
|
3991
|
+
- ⏳ Loading state
|
|
3992
|
+
- 🏷️ Badge system
|
|
3993
|
+
- 📝 Label descriptions
|
|
3994
|
+
- 🔄 Controlled & uncontrolled modes
|
|
3995
|
+
- 📍 Label position (left/right)
|
|
3996
|
+
- ✅ Built-in validation
|
|
3997
|
+
- 💫 Smooth animations
|
|
3998
|
+
- 🌈 Color-matched shadows
|
|
3999
|
+
- ♿ Fully accessible
|
|
4000
|
+
- ⌨️ Keyboard navigation
|
|
4001
|
+
|
|
4002
|
+
---
|
|
4003
|
+
|
|
3263
4004
|
### Skeleton
|
|
3264
4005
|
|
|
3265
4006
|
Loading placeholder component with smooth animations and multiple visual styles.
|
|
@@ -3379,6 +4120,267 @@ import { Skeleton } from "saha-ui";
|
|
|
3379
4120
|
|
|
3380
4121
|
---
|
|
3381
4122
|
|
|
4123
|
+
### Spinner
|
|
4124
|
+
|
|
4125
|
+
Modern loading spinner with multiple variants, animations, and fullscreen overlay support.
|
|
4126
|
+
|
|
4127
|
+
**Basic Usage:**
|
|
4128
|
+
|
|
4129
|
+
```tsx
|
|
4130
|
+
import { Spinner } from "saha-ui";
|
|
4131
|
+
|
|
4132
|
+
// Basic spinner
|
|
4133
|
+
<Spinner />
|
|
4134
|
+
|
|
4135
|
+
// With label
|
|
4136
|
+
<Spinner variant="primary" label="Loading..." />
|
|
4137
|
+
|
|
4138
|
+
// Custom size and variant
|
|
4139
|
+
<Spinner variant="success" size="lg" label="Processing..." />
|
|
4140
|
+
```
|
|
4141
|
+
|
|
4142
|
+
**Variants:**
|
|
4143
|
+
|
|
4144
|
+
```tsx
|
|
4145
|
+
// 10 beautiful variants
|
|
4146
|
+
<Spinner variant="default" />
|
|
4147
|
+
<Spinner variant="primary" />
|
|
4148
|
+
<Spinner variant="secondary" />
|
|
4149
|
+
<Spinner variant="accent" />
|
|
4150
|
+
<Spinner variant="info" />
|
|
4151
|
+
<Spinner variant="success" />
|
|
4152
|
+
<Spinner variant="warning" />
|
|
4153
|
+
<Spinner variant="error" />
|
|
4154
|
+
<Spinner variant="glass" />
|
|
4155
|
+
<Spinner variant="gradient" />
|
|
4156
|
+
```
|
|
4157
|
+
|
|
4158
|
+
**Sizes:**
|
|
4159
|
+
|
|
4160
|
+
```tsx
|
|
4161
|
+
<Spinner size="xs" /> // 16px
|
|
4162
|
+
<Spinner size="sm" /> // 24px
|
|
4163
|
+
<Spinner size="md" /> // 40px (default)
|
|
4164
|
+
<Spinner size="lg" /> // 64px
|
|
4165
|
+
<Spinner size="xl" /> // 96px
|
|
4166
|
+
<Spinner size="2xl" /> // 128px
|
|
4167
|
+
```
|
|
4168
|
+
|
|
4169
|
+
**Spinner Types (15 unique designs!):**
|
|
4170
|
+
|
|
4171
|
+
```tsx
|
|
4172
|
+
// Classic Types
|
|
4173
|
+
<Spinner type="ring" /> // Classic circular border (default)
|
|
4174
|
+
<Spinner type="dots" /> // Rotating dots in circle
|
|
4175
|
+
<Spinner type="dashed" /> // Dashed ring border
|
|
4176
|
+
<Spinner type="bars" /> // Rotating bars/lines
|
|
4177
|
+
<Spinner type="dotRing" /> // Complete circle of dots
|
|
4178
|
+
|
|
4179
|
+
// Creative & Unique Types ✨
|
|
4180
|
+
<Spinner type="orbit" /> // Multi-orbit planetary system
|
|
4181
|
+
<Spinner type="pulse" /> // Expanding concentric circles
|
|
4182
|
+
<Spinner type="square" /> // Rotating square corners
|
|
4183
|
+
<Spinner type="triangle" /> // Triangular rotating pattern
|
|
4184
|
+
<Spinner type="wave" /> // Sequential bouncing bars
|
|
4185
|
+
<Spinner type="spiral" /> // Expanding spiral pattern
|
|
4186
|
+
<Spinner type="infinity" /> // Infinity symbol (∞) path
|
|
4187
|
+
<Spinner type="flower" /> // Flower petal pattern
|
|
4188
|
+
<Spinner type="grid" /> // 3×3 pulsing grid
|
|
4189
|
+
<Spinner type="bounce" /> // Classic bouncing dots
|
|
4190
|
+
```
|
|
4191
|
+
|
|
4192
|
+
**Animation Types:**
|
|
4193
|
+
|
|
4194
|
+
```tsx
|
|
4195
|
+
<Spinner animation="spin" /> // Continuous rotation (default)
|
|
4196
|
+
<Spinner animation="pulse" /> // Scale pulsing
|
|
4197
|
+
<Spinner animation="bounce" /> // Bouncing effect
|
|
4198
|
+
<Spinner animation="ping" /> // Ping ripple effect
|
|
4199
|
+
```
|
|
4200
|
+
|
|
4201
|
+
**Thickness:**
|
|
4202
|
+
|
|
4203
|
+
```tsx
|
|
4204
|
+
<Spinner thickness="thin" /> // 2px border
|
|
4205
|
+
<Spinner thickness="default" /> // 4px border
|
|
4206
|
+
<Spinner thickness="thick" /> // 6px border
|
|
4207
|
+
```
|
|
4208
|
+
|
|
4209
|
+
**Speed Control:**
|
|
4210
|
+
|
|
4211
|
+
```tsx
|
|
4212
|
+
<Spinner speed={0.5} /> // Slower
|
|
4213
|
+
<Spinner speed={1} /> // Normal (default)
|
|
4214
|
+
<Spinner speed={2} /> // Faster
|
|
4215
|
+
<Spinner speed={3} /> // Very fast
|
|
4216
|
+
```
|
|
4217
|
+
|
|
4218
|
+
**Fullscreen Overlay:**
|
|
4219
|
+
|
|
4220
|
+
```tsx
|
|
4221
|
+
// Full screen loading overlay
|
|
4222
|
+
<Spinner
|
|
4223
|
+
fullscreen
|
|
4224
|
+
variant="gradient"
|
|
4225
|
+
size="2xl"
|
|
4226
|
+
label="Loading application..."
|
|
4227
|
+
/>
|
|
4228
|
+
```
|
|
4229
|
+
|
|
4230
|
+
**In Buttons:**
|
|
4231
|
+
|
|
4232
|
+
```tsx
|
|
4233
|
+
// Disabled button with loading spinner
|
|
4234
|
+
<Button variant="primary" disabled>
|
|
4235
|
+
<Spinner size="sm" variant="default" />
|
|
4236
|
+
Loading...
|
|
4237
|
+
</Button>
|
|
4238
|
+
|
|
4239
|
+
<Button variant="success" disabled>
|
|
4240
|
+
<Spinner size="sm" variant="default" />
|
|
4241
|
+
Saving...
|
|
4242
|
+
</Button>
|
|
4243
|
+
```
|
|
4244
|
+
|
|
4245
|
+
**In Cards:**
|
|
4246
|
+
|
|
4247
|
+
```tsx
|
|
4248
|
+
<Card>
|
|
4249
|
+
<CardHeader>
|
|
4250
|
+
<CardTitle>Loading Data</CardTitle>
|
|
4251
|
+
</CardHeader>
|
|
4252
|
+
<CardContent className="flex items-center justify-center py-8">
|
|
4253
|
+
<Spinner variant="primary" label="Fetching data..." />
|
|
4254
|
+
</CardContent>
|
|
4255
|
+
</Card>
|
|
4256
|
+
```
|
|
4257
|
+
|
|
4258
|
+
**With Custom Logo/Icon:**
|
|
4259
|
+
|
|
4260
|
+
```tsx
|
|
4261
|
+
// Image URL
|
|
4262
|
+
<Spinner
|
|
4263
|
+
variant="primary"
|
|
4264
|
+
size="xl"
|
|
4265
|
+
logo="/your-logo.png"
|
|
4266
|
+
logoSize="md"
|
|
4267
|
+
label="Loading..."
|
|
4268
|
+
/>
|
|
4269
|
+
|
|
4270
|
+
// Custom React component
|
|
4271
|
+
<Spinner
|
|
4272
|
+
variant="success"
|
|
4273
|
+
size="xl"
|
|
4274
|
+
logo={
|
|
4275
|
+
<div className="w-full h-full flex items-center justify-center bg-success/10 rounded-full">
|
|
4276
|
+
<span className="text-2xl font-bold text-success">S</span>
|
|
4277
|
+
</div>
|
|
4278
|
+
}
|
|
4279
|
+
logoSize="lg"
|
|
4280
|
+
/>
|
|
4281
|
+
|
|
4282
|
+
// SVG Icon
|
|
4283
|
+
<Spinner
|
|
4284
|
+
variant="gradient"
|
|
4285
|
+
size="2xl"
|
|
4286
|
+
logo={<YourSvgIcon />}
|
|
4287
|
+
logoSize="md"
|
|
4288
|
+
label="Building..."
|
|
4289
|
+
/>
|
|
4290
|
+
```
|
|
4291
|
+
|
|
4292
|
+
**Logo Sizes:**
|
|
4293
|
+
|
|
4294
|
+
```tsx
|
|
4295
|
+
<Spinner logo="/logo.png" logoSize="xs" /> // 25% of spinner size
|
|
4296
|
+
<Spinner logo="/logo.png" logoSize="sm" /> // 35% of spinner size
|
|
4297
|
+
<Spinner logo="/logo.png" logoSize="md" /> // 50% of spinner size (default)
|
|
4298
|
+
<Spinner logo="/logo.png" logoSize="lg" /> // 65% of spinner size
|
|
4299
|
+
<Spinner logo="/logo.png" logoSize="xl" /> // 80% of spinner size
|
|
4300
|
+
```
|
|
4301
|
+
|
|
4302
|
+
**Real-world Examples:**
|
|
4303
|
+
|
|
4304
|
+
```tsx
|
|
4305
|
+
// Form submission
|
|
4306
|
+
<Button type="submit" disabled={isSubmitting}>
|
|
4307
|
+
{isSubmitting && <Spinner size="sm" variant="default" />}
|
|
4308
|
+
{isSubmitting ? "Submitting..." : "Submit"}
|
|
4309
|
+
</Button>;
|
|
4310
|
+
|
|
4311
|
+
// Brand loading with logo
|
|
4312
|
+
<Spinner
|
|
4313
|
+
fullscreen
|
|
4314
|
+
variant="gradient"
|
|
4315
|
+
size="2xl"
|
|
4316
|
+
logo="/brand-logo.png"
|
|
4317
|
+
logoSize="lg"
|
|
4318
|
+
label="Loading your app..."
|
|
4319
|
+
/>;
|
|
4320
|
+
|
|
4321
|
+
// Page loading
|
|
4322
|
+
{
|
|
4323
|
+
isLoading && (
|
|
4324
|
+
<Spinner
|
|
4325
|
+
fullscreen
|
|
4326
|
+
variant="primary"
|
|
4327
|
+
size="xl"
|
|
4328
|
+
label="Loading content..."
|
|
4329
|
+
/>
|
|
4330
|
+
);
|
|
4331
|
+
}
|
|
4332
|
+
|
|
4333
|
+
// Inline loading
|
|
4334
|
+
<div className="flex items-center gap-3">
|
|
4335
|
+
<Spinner size="sm" variant="info" />
|
|
4336
|
+
<span>Syncing data...</span>
|
|
4337
|
+
</div>;
|
|
4338
|
+
|
|
4339
|
+
// Conditional rendering
|
|
4340
|
+
{
|
|
4341
|
+
isFetching ? (
|
|
4342
|
+
<Spinner variant="success" label="Loading items..." />
|
|
4343
|
+
) : (
|
|
4344
|
+
<ItemsList items={items} />
|
|
4345
|
+
);
|
|
4346
|
+
}
|
|
4347
|
+
```
|
|
4348
|
+
|
|
4349
|
+
**Variants:** `default` `primary` `secondary` `accent` `info` `success` `warning` `error` `glass` `gradient`
|
|
4350
|
+
**Sizes:** `xs` `sm` `md` `lg` `xl` `2xl`
|
|
4351
|
+
**Types:** `ring` `dots` `dashed` `bars` `dotRing` `orbit` `pulse` `square` `triangle` `wave` `spiral` `infinity` `flower` `grid` `bounce`
|
|
4352
|
+
**Animations:** `spin` `pulse` `bounce` `ping`
|
|
4353
|
+
**Thickness:** `thin` `default` `thick`
|
|
4354
|
+
**Logo Sizes:** `xs` `sm` `md` `lg` `xl`
|
|
4355
|
+
|
|
4356
|
+
**Features:**
|
|
4357
|
+
|
|
4358
|
+
- 🎨 10 stunning variants with shadows and effects
|
|
4359
|
+
- 🎯 **15 unique spinner types** - from classic to creative designs
|
|
4360
|
+
- 📏 6 size options from xs (16px) to 2xl (128px)
|
|
4361
|
+
- 🎭 4 different animation types
|
|
4362
|
+
- ⚡ Customizable animation speed (0.5x to 3x+)
|
|
4363
|
+
- 🎯 Optional loading labels
|
|
4364
|
+
- 🖼️ Fullscreen overlay mode with backdrop
|
|
4365
|
+
- 🔲 3 thickness options
|
|
4366
|
+
- 🌈 Gradient variant with multi-color effects
|
|
4367
|
+
- 💎 Glass variant with backdrop blur
|
|
4368
|
+
- 🖼️ **Custom logo/icon support** (image URL or React component)
|
|
4369
|
+
- 📐 5 logo size options for perfect fit
|
|
4370
|
+
- 🎨 Logo positioned in center with spinner animation around it
|
|
4371
|
+
- 🌌 **Creative types**: Orbit, Spiral, Infinity, Flower, Wave patterns
|
|
4372
|
+
- 🔄 All 15 types work with all 10 variants (150 combinations!)
|
|
4373
|
+
- ⚡ Mathematical precision for perfect centering
|
|
4374
|
+
- 🎪 **Unique designs**: Grid, Triangle, Pulse, Square, Bounce
|
|
4375
|
+
- 🌓 Theme-aware styling
|
|
4376
|
+
- ♿ Accessibility with proper ARIA attributes
|
|
4377
|
+
- 💫 Smooth CSS animations (GPU-accelerated)
|
|
4378
|
+
- 📱 Responsive and flexible
|
|
4379
|
+
- 🎛️ Works great in buttons, cards, and overlays
|
|
4380
|
+
- 🎨 **900+ possible configurations** (types × variants × sizes)
|
|
4381
|
+
|
|
4382
|
+
---
|
|
4383
|
+
|
|
3382
4384
|
### Pagination
|
|
3383
4385
|
|
|
3384
4386
|
Comprehensive pagination component for navigating through large datasets.
|
|
@@ -4044,24 +5046,24 @@ import { Mail, Lock, Search, User } from "lucide-react";
|
|
|
4044
5046
|
|
|
4045
5047
|
**Props:**
|
|
4046
5048
|
|
|
4047
|
-
| Prop
|
|
4048
|
-
|
|
|
4049
|
-
| `variant`
|
|
4050
|
-
| `size`
|
|
4051
|
-
| `type`
|
|
4052
|
-
| `label`
|
|
4053
|
-
| `helperText`
|
|
4054
|
-
| `error`
|
|
4055
|
-
| `startIcon`
|
|
4056
|
-
| `endIcon`
|
|
4057
|
-
| `showCounter`
|
|
4058
|
-
| `required`
|
|
4059
|
-
| `fullWidth`
|
|
4060
|
-
| `containerClassName`
|
|
4061
|
-
| `labelClassName`
|
|
4062
|
-
| `disabled`
|
|
4063
|
-
| `maxLength`
|
|
4064
|
-
| `...props`
|
|
5049
|
+
| Prop | Type | Default | Description |
|
|
5050
|
+
| -------------------- | --------------------- | ----------- | ---------------------------------------- |
|
|
5051
|
+
| `variant` | `InputVariant` | `'outline'` | Visual variant |
|
|
5052
|
+
| `size` | `InputSize` | `'md'` | Size variant |
|
|
5053
|
+
| `type` | `InputType` | `'text'` | HTML input type (excludes file) |
|
|
5054
|
+
| `label` | `string` | `undefined` | Label text for the input |
|
|
5055
|
+
| `helperText` | `string` | `undefined` | Helper text below input |
|
|
5056
|
+
| `error` | `string` | `undefined` | Error message (overrides helperText) |
|
|
5057
|
+
| `startIcon` | `ReactNode` | `undefined` | Icon on the left side |
|
|
5058
|
+
| `endIcon` | `ReactNode` | `undefined` | Icon on the right side |
|
|
5059
|
+
| `showCounter` | `boolean` | `false` | Show character counter (needs maxLength) |
|
|
5060
|
+
| `required` | `boolean` | `false` | Mark field as required |
|
|
5061
|
+
| `fullWidth` | `boolean` | `false` | Full width styling |
|
|
5062
|
+
| `containerClassName` | `string` | `undefined` | Custom className for container |
|
|
5063
|
+
| `labelClassName` | `string` | `undefined` | Custom className for label |
|
|
5064
|
+
| `disabled` | `boolean` | `false` | Disable the input |
|
|
5065
|
+
| `maxLength` | `number` | `undefined` | Maximum character length |
|
|
5066
|
+
| `...props` | `InputHTMLAttributes` | - | All standard input attributes |
|
|
4065
5067
|
|
|
4066
5068
|
**Features:**
|
|
4067
5069
|
|