@djangocfg/ui-core 2.1.120 → 2.1.123

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/package.json +8 -5
  2. package/src/components/accordion.story.tsx +110 -0
  3. package/src/components/alert-dialog.story.tsx +104 -0
  4. package/src/components/alert.story.tsx +77 -0
  5. package/src/components/aspect-ratio.story.tsx +94 -0
  6. package/src/components/avatar.story.tsx +115 -0
  7. package/src/components/badge.story.tsx +56 -0
  8. package/src/components/button-download.story.tsx +112 -0
  9. package/src/components/button-group.story.tsx +79 -0
  10. package/src/components/button.story.tsx +116 -0
  11. package/src/components/calendar.story.tsx +126 -0
  12. package/src/components/card.story.tsx +105 -0
  13. package/src/components/carousel.story.tsx +122 -0
  14. package/src/components/carousel.tsx +2 -2
  15. package/src/components/checkbox.story.tsx +89 -0
  16. package/src/components/collapsible.story.tsx +133 -0
  17. package/src/components/combobox.story.tsx +145 -0
  18. package/src/components/command.story.tsx +121 -0
  19. package/src/components/context-menu.story.tsx +125 -0
  20. package/src/components/copy.story.tsx +77 -0
  21. package/src/components/dialog.story.tsx +137 -0
  22. package/src/components/drawer.story.tsx +131 -0
  23. package/src/components/dropdown-menu.story.tsx +208 -0
  24. package/src/components/empty.story.tsx +115 -0
  25. package/src/components/hover-card.story.tsx +102 -0
  26. package/src/components/image-with-fallback.story.tsx +105 -0
  27. package/src/components/input-group.story.tsx +119 -0
  28. package/src/components/input-otp.story.tsx +105 -0
  29. package/src/components/input.story.tsx +77 -0
  30. package/src/components/kbd.story.tsx +113 -0
  31. package/src/components/label.story.tsx +52 -0
  32. package/src/components/menubar.story.tsx +152 -0
  33. package/src/components/multi-select.story.tsx +122 -0
  34. package/src/components/navigation-menu.story.tsx +154 -0
  35. package/src/components/popover.story.tsx +127 -0
  36. package/src/components/preloader.story.tsx +86 -0
  37. package/src/components/progress.story.tsx +97 -0
  38. package/src/components/radio-group.story.tsx +113 -0
  39. package/src/components/resizable.story.tsx +119 -0
  40. package/src/components/responsive-sheet.story.tsx +117 -0
  41. package/src/components/scroll-area.story.tsx +112 -0
  42. package/src/components/select.story.tsx +112 -0
  43. package/src/components/separator.story.tsx +69 -0
  44. package/src/components/sheet.story.tsx +148 -0
  45. package/src/components/skeleton.story.tsx +101 -0
  46. package/src/components/slider.story.tsx +113 -0
  47. package/src/components/spinner.story.tsx +66 -0
  48. package/src/components/switch.story.tsx +98 -0
  49. package/src/components/table.story.tsx +148 -0
  50. package/src/components/tabs.story.tsx +98 -0
  51. package/src/components/tabs.tsx +1 -1
  52. package/src/components/textarea.story.tsx +94 -0
  53. package/src/components/toggle-group.story.tsx +118 -0
  54. package/src/components/toggle.story.tsx +104 -0
  55. package/src/components/tooltip.story.tsx +139 -0
@@ -0,0 +1,112 @@
1
+ import { defineStory, useBoolean } from '@djangocfg/playground';
2
+ import { DownloadButton } from './button-download';
3
+
4
+ export default defineStory({
5
+ title: 'Core/DownloadButton',
6
+ component: DownloadButton,
7
+ description: 'Button with download functionality and status indicators.',
8
+ });
9
+
10
+ export const Interactive = () => {
11
+ const [showStatus] = useBoolean('showStatus', {
12
+ defaultValue: true,
13
+ label: 'Show Status',
14
+ description: 'Show loading/success/error icons',
15
+ });
16
+
17
+ return (
18
+ <DownloadButton
19
+ url="https://example.com/file.pdf"
20
+ filename="document.pdf"
21
+ showStatus={showStatus}
22
+ >
23
+ Download PDF
24
+ </DownloadButton>
25
+ );
26
+ };
27
+
28
+ export const Default = () => (
29
+ <DownloadButton
30
+ url="https://example.com/file.pdf"
31
+ filename="document.pdf"
32
+ >
33
+ Download File
34
+ </DownloadButton>
35
+ );
36
+
37
+ export const IconOnly = () => (
38
+ <DownloadButton
39
+ url="https://example.com/file.pdf"
40
+ filename="document.pdf"
41
+ size="icon"
42
+ />
43
+ );
44
+
45
+ export const Variants = () => (
46
+ <div className="flex gap-4">
47
+ <DownloadButton
48
+ url="https://example.com/file.pdf"
49
+ variant="default"
50
+ >
51
+ Default
52
+ </DownloadButton>
53
+ <DownloadButton
54
+ url="https://example.com/file.pdf"
55
+ variant="outline"
56
+ >
57
+ Outline
58
+ </DownloadButton>
59
+ <DownloadButton
60
+ url="https://example.com/file.pdf"
61
+ variant="ghost"
62
+ >
63
+ Ghost
64
+ </DownloadButton>
65
+ </div>
66
+ );
67
+
68
+ export const Sizes = () => (
69
+ <div className="flex items-center gap-4">
70
+ <DownloadButton url="https://example.com/file.pdf" size="sm">
71
+ Small
72
+ </DownloadButton>
73
+ <DownloadButton url="https://example.com/file.pdf" size="default">
74
+ Default
75
+ </DownloadButton>
76
+ <DownloadButton url="https://example.com/file.pdf" size="lg">
77
+ Large
78
+ </DownloadButton>
79
+ </div>
80
+ );
81
+
82
+ export const WithCallbacks = () => (
83
+ <DownloadButton
84
+ url="https://example.com/file.pdf"
85
+ filename="report.pdf"
86
+ onDownloadStart={() => console.log('Download started')}
87
+ onDownloadComplete={(name) => console.log(`Downloaded: ${name}`)}
88
+ onDownloadError={(err) => console.error('Error:', err)}
89
+ >
90
+ Download with Callbacks
91
+ </DownloadButton>
92
+ );
93
+
94
+ export const PostRequest = () => (
95
+ <DownloadButton
96
+ url="https://api.example.com/export"
97
+ method="POST"
98
+ body={{ format: 'pdf', includeImages: true }}
99
+ filename="export.pdf"
100
+ >
101
+ Export as PDF
102
+ </DownloadButton>
103
+ );
104
+
105
+ export const DisabledStatus = () => (
106
+ <DownloadButton
107
+ url="https://example.com/file.pdf"
108
+ showStatus={false}
109
+ >
110
+ No Status Icons
111
+ </DownloadButton>
112
+ );
@@ -0,0 +1,79 @@
1
+ import { defineStory } from '@djangocfg/playground';
2
+ import { ButtonGroup, ButtonGroupSeparator, ButtonGroupText } from './button-group';
3
+ import { Button } from './button';
4
+ import { Bold, Italic, Underline, AlignLeft, AlignCenter, AlignRight, ChevronDown } from 'lucide-react';
5
+
6
+ export default defineStory({
7
+ title: 'Core/ButtonGroup',
8
+ component: ButtonGroup,
9
+ description: 'Group of buttons with connected styling.',
10
+ });
11
+
12
+ export const Default = () => (
13
+ <ButtonGroup>
14
+ <Button variant="outline">First</Button>
15
+ <Button variant="outline">Second</Button>
16
+ <Button variant="outline">Third</Button>
17
+ </ButtonGroup>
18
+ );
19
+
20
+ export const TextFormatting = () => (
21
+ <ButtonGroup>
22
+ <Button variant="outline" size="icon">
23
+ <Bold className="h-4 w-4" />
24
+ </Button>
25
+ <Button variant="outline" size="icon">
26
+ <Italic className="h-4 w-4" />
27
+ </Button>
28
+ <Button variant="outline" size="icon">
29
+ <Underline className="h-4 w-4" />
30
+ </Button>
31
+ </ButtonGroup>
32
+ );
33
+
34
+ export const Alignment = () => (
35
+ <ButtonGroup>
36
+ <Button variant="outline" size="icon">
37
+ <AlignLeft className="h-4 w-4" />
38
+ </Button>
39
+ <Button variant="outline" size="icon">
40
+ <AlignCenter className="h-4 w-4" />
41
+ </Button>
42
+ <Button variant="outline" size="icon">
43
+ <AlignRight className="h-4 w-4" />
44
+ </Button>
45
+ </ButtonGroup>
46
+ );
47
+
48
+ export const WithSeparator = () => (
49
+ <ButtonGroup>
50
+ <Button variant="outline">Edit</Button>
51
+ <ButtonGroupSeparator />
52
+ <Button variant="outline" size="icon">
53
+ <ChevronDown className="h-4 w-4" />
54
+ </Button>
55
+ </ButtonGroup>
56
+ );
57
+
58
+ export const WithText = () => (
59
+ <ButtonGroup>
60
+ <ButtonGroupText>Label</ButtonGroupText>
61
+ <Button variant="outline">Action</Button>
62
+ </ButtonGroup>
63
+ );
64
+
65
+ export const Vertical = () => (
66
+ <ButtonGroup orientation="vertical">
67
+ <Button variant="outline">Top</Button>
68
+ <Button variant="outline">Middle</Button>
69
+ <Button variant="outline">Bottom</Button>
70
+ </ButtonGroup>
71
+ );
72
+
73
+ export const Mixed = () => (
74
+ <ButtonGroup>
75
+ <Button variant="default">Primary</Button>
76
+ <Button variant="outline">Secondary</Button>
77
+ <Button variant="ghost">Tertiary</Button>
78
+ </ButtonGroup>
79
+ );
@@ -0,0 +1,116 @@
1
+ import { defineStory, useSelect, useBoolean } from '@djangocfg/playground';
2
+ import { Mail, Send, Loader2, ChevronRight, Plus, Trash2 } from 'lucide-react';
3
+ import { Button, ButtonLink } from './button';
4
+
5
+ export default defineStory({
6
+ title: 'Core/Button',
7
+ component: Button,
8
+ description: 'Versatile button component with multiple variants and sizes.',
9
+ });
10
+
11
+ export const Interactive = () => {
12
+ const [variant] = useSelect('variant', {
13
+ options: ['default', 'secondary', 'destructive', 'outline', 'ghost', 'link'] as const,
14
+ defaultValue: 'default',
15
+ label: 'Variant',
16
+ description: 'Button style variant',
17
+ });
18
+
19
+ const [size] = useSelect('size', {
20
+ options: ['xs', 'sm', 'default', 'lg', 'huge', 'icon'] as const,
21
+ defaultValue: 'default',
22
+ label: 'Size',
23
+ description: 'Button size',
24
+ });
25
+
26
+ const [loading] = useBoolean('loading', {
27
+ defaultValue: false,
28
+ label: 'Loading',
29
+ description: 'Show loading spinner',
30
+ });
31
+
32
+ const [disabled] = useBoolean('disabled', {
33
+ defaultValue: false,
34
+ label: 'Disabled',
35
+ description: 'Disable button',
36
+ });
37
+
38
+ return (
39
+ <div className="flex flex-wrap gap-4 items-center">
40
+ <Button variant={variant} size={size} loading={loading} disabled={disabled}>
41
+ {size === 'icon' ? <Plus /> : 'Button'}
42
+ </Button>
43
+ <Button variant={variant} size={size} loading={loading} disabled={disabled}>
44
+ <Mail />
45
+ {size !== 'icon' && 'With Icon'}
46
+ </Button>
47
+ </div>
48
+ );
49
+ };
50
+
51
+ export const Variants = () => (
52
+ <div className="flex flex-wrap gap-4">
53
+ <Button variant="default">Default</Button>
54
+ <Button variant="secondary">Secondary</Button>
55
+ <Button variant="destructive">Destructive</Button>
56
+ <Button variant="outline">Outline</Button>
57
+ <Button variant="ghost">Ghost</Button>
58
+ <Button variant="link">Link</Button>
59
+ </div>
60
+ );
61
+
62
+ export const Sizes = () => (
63
+ <div className="flex flex-wrap gap-4 items-center">
64
+ <Button size="xs">Extra Small</Button>
65
+ <Button size="sm">Small</Button>
66
+ <Button size="default">Default</Button>
67
+ <Button size="lg">Large</Button>
68
+ <Button size="huge">Huge</Button>
69
+ <Button size="icon"><Plus /></Button>
70
+ </div>
71
+ );
72
+
73
+ export const WithIcons = () => (
74
+ <div className="flex flex-wrap gap-4">
75
+ <Button>
76
+ <Mail />
77
+ Login with Email
78
+ </Button>
79
+ <Button variant="secondary">
80
+ Send
81
+ <Send />
82
+ </Button>
83
+ <Button variant="outline">
84
+ Next
85
+ <ChevronRight />
86
+ </Button>
87
+ <Button variant="destructive">
88
+ <Trash2 />
89
+ Delete
90
+ </Button>
91
+ </div>
92
+ );
93
+
94
+ export const Loading = () => (
95
+ <div className="flex flex-wrap gap-4">
96
+ <Button loading>Loading...</Button>
97
+ <Button loading variant="secondary">Processing</Button>
98
+ <Button loading variant="outline">Please wait</Button>
99
+ </div>
100
+ );
101
+
102
+ export const Disabled = () => (
103
+ <div className="flex flex-wrap gap-4">
104
+ <Button disabled>Default</Button>
105
+ <Button disabled variant="secondary">Secondary</Button>
106
+ <Button disabled variant="outline">Outline</Button>
107
+ </div>
108
+ );
109
+
110
+ export const AsLink = () => (
111
+ <div className="flex flex-wrap gap-4">
112
+ <ButtonLink href="https://example.com">External Link</ButtonLink>
113
+ <ButtonLink href="/dashboard" variant="secondary">Dashboard</ButtonLink>
114
+ <ButtonLink href="/settings" variant="outline">Settings</ButtonLink>
115
+ </div>
116
+ );
@@ -0,0 +1,126 @@
1
+ import { useState } from 'react';
2
+ import { defineStory } from '@djangocfg/playground';
3
+ import { Calendar, DatePicker, DateRangePicker, type DateRange } from './calendar';
4
+
5
+ export default defineStory({
6
+ title: 'Core/Calendar',
7
+ component: Calendar,
8
+ description: 'Calendar and date picker components.',
9
+ });
10
+
11
+ export const Default = () => {
12
+ const [date, setDate] = useState<Date | undefined>(new Date());
13
+
14
+ return (
15
+ <Calendar
16
+ mode="single"
17
+ selected={date}
18
+ onSelect={setDate}
19
+ className="rounded-md border"
20
+ />
21
+ );
22
+ };
23
+
24
+ export const Range = () => {
25
+ const [range, setRange] = useState<DateRange | undefined>({
26
+ from: new Date(),
27
+ to: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
28
+ });
29
+
30
+ return (
31
+ <Calendar
32
+ mode="range"
33
+ selected={range}
34
+ onSelect={setRange}
35
+ className="rounded-md border"
36
+ numberOfMonths={2}
37
+ />
38
+ );
39
+ };
40
+
41
+ export const Multiple = () => {
42
+ const [dates, setDates] = useState<Date[] | undefined>([]);
43
+
44
+ return (
45
+ <Calendar
46
+ mode="multiple"
47
+ selected={dates}
48
+ onSelect={setDates}
49
+ className="rounded-md border"
50
+ />
51
+ );
52
+ };
53
+
54
+ export const Picker = () => {
55
+ const [date, setDate] = useState<Date>();
56
+
57
+ return (
58
+ <div className="max-w-xs">
59
+ <DatePicker
60
+ value={date}
61
+ onChange={setDate}
62
+ placeholder="Pick a date"
63
+ />
64
+ </div>
65
+ );
66
+ };
67
+
68
+ export const PickerWithLabel = () => {
69
+ const [date, setDate] = useState<Date>();
70
+
71
+ return (
72
+ <div className="max-w-xs space-y-2">
73
+ <label className="text-sm font-medium">Date of birth</label>
74
+ <DatePicker
75
+ value={date}
76
+ onChange={setDate}
77
+ placeholder="Select your birth date"
78
+ />
79
+ </div>
80
+ );
81
+ };
82
+
83
+ export const RangePicker = () => {
84
+ const [range, setRange] = useState<DateRange>();
85
+
86
+ return (
87
+ <div className="max-w-sm">
88
+ <DateRangePicker
89
+ value={range}
90
+ onChange={setRange}
91
+ placeholder="Select date range"
92
+ />
93
+ </div>
94
+ );
95
+ };
96
+
97
+ export const RangePickerWithPresets = () => {
98
+ const [range, setRange] = useState<DateRange>();
99
+
100
+ return (
101
+ <div className="max-w-sm space-y-2">
102
+ <label className="text-sm font-medium">Booking dates</label>
103
+ <DateRangePicker
104
+ value={range}
105
+ onChange={setRange}
106
+ placeholder="Check-in — Check-out"
107
+ numberOfMonths={2}
108
+ />
109
+ </div>
110
+ );
111
+ };
112
+
113
+ export const Disabled = () => {
114
+ const [date, setDate] = useState<Date>();
115
+
116
+ return (
117
+ <div className="max-w-xs">
118
+ <DatePicker
119
+ value={date}
120
+ onChange={setDate}
121
+ placeholder="Pick a date"
122
+ disabled
123
+ />
124
+ </div>
125
+ );
126
+ };
@@ -0,0 +1,105 @@
1
+ import { defineStory } from '@djangocfg/playground';
2
+ import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from './card';
3
+ import { Button } from './button';
4
+ import { Input } from './input';
5
+ import { Label } from './label';
6
+
7
+ export default defineStory({
8
+ title: 'Core/Card',
9
+ component: Card,
10
+ description: 'Card container for grouping related content.',
11
+ });
12
+
13
+ export const Default = () => (
14
+ <Card className="max-w-sm">
15
+ <CardHeader>
16
+ <CardTitle>Card Title</CardTitle>
17
+ <CardDescription>Card description goes here.</CardDescription>
18
+ </CardHeader>
19
+ <CardContent>
20
+ <p>This is the card content. You can put any content here.</p>
21
+ </CardContent>
22
+ <CardFooter>
23
+ <Button>Action</Button>
24
+ </CardFooter>
25
+ </Card>
26
+ );
27
+
28
+ export const LoginCard = () => (
29
+ <Card className="max-w-sm">
30
+ <CardHeader>
31
+ <CardTitle>Login</CardTitle>
32
+ <CardDescription>Enter your credentials to access your account.</CardDescription>
33
+ </CardHeader>
34
+ <CardContent className="space-y-4">
35
+ <div className="space-y-2">
36
+ <Label htmlFor="email">Email</Label>
37
+ <Input id="email" type="email" placeholder="Enter your email" />
38
+ </div>
39
+ <div className="space-y-2">
40
+ <Label htmlFor="password">Password</Label>
41
+ <Input id="password" type="password" placeholder="Enter password" />
42
+ </div>
43
+ </CardContent>
44
+ <CardFooter className="flex justify-between">
45
+ <Button variant="outline">Cancel</Button>
46
+ <Button>Login</Button>
47
+ </CardFooter>
48
+ </Card>
49
+ );
50
+
51
+ export const ProductCard = () => (
52
+ <Card className="max-w-xs overflow-hidden">
53
+ <div className="aspect-video bg-muted" />
54
+ <CardHeader>
55
+ <CardTitle>Product Name</CardTitle>
56
+ <CardDescription>$99.99</CardDescription>
57
+ </CardHeader>
58
+ <CardContent>
59
+ <p className="text-sm text-muted-foreground">
60
+ This is a brief description of the product with key features.
61
+ </p>
62
+ </CardContent>
63
+ <CardFooter>
64
+ <Button className="w-full">Add to Cart</Button>
65
+ </CardFooter>
66
+ </Card>
67
+ );
68
+
69
+ export const StatsCards = () => (
70
+ <div className="grid grid-cols-3 gap-4">
71
+ <Card>
72
+ <CardHeader className="pb-2">
73
+ <CardDescription>Total Revenue</CardDescription>
74
+ <CardTitle className="text-2xl">$45,231.89</CardTitle>
75
+ </CardHeader>
76
+ <CardContent>
77
+ <p className="text-xs text-muted-foreground">+20.1% from last month</p>
78
+ </CardContent>
79
+ </Card>
80
+ <Card>
81
+ <CardHeader className="pb-2">
82
+ <CardDescription>Subscriptions</CardDescription>
83
+ <CardTitle className="text-2xl">+2,350</CardTitle>
84
+ </CardHeader>
85
+ <CardContent>
86
+ <p className="text-xs text-muted-foreground">+180.1% from last month</p>
87
+ </CardContent>
88
+ </Card>
89
+ <Card>
90
+ <CardHeader className="pb-2">
91
+ <CardDescription>Active Now</CardDescription>
92
+ <CardTitle className="text-2xl">+573</CardTitle>
93
+ </CardHeader>
94
+ <CardContent>
95
+ <p className="text-xs text-muted-foreground">+201 since last hour</p>
96
+ </CardContent>
97
+ </Card>
98
+ </div>
99
+ );
100
+
101
+ export const SimpleCard = () => (
102
+ <Card className="max-w-md p-6">
103
+ <p>A simple card with just content and padding.</p>
104
+ </Card>
105
+ );
@@ -0,0 +1,122 @@
1
+ import { defineStory, type StoryMeta } from '@djangocfg/playground';
2
+ import {
3
+ Carousel,
4
+ CarouselContent,
5
+ CarouselItem,
6
+ CarouselNext,
7
+ CarouselPrevious,
8
+ } from './carousel';
9
+ import { Card, CardContent } from './card';
10
+
11
+ const meta: StoryMeta = defineStory({
12
+ title: 'Core/Carousel',
13
+ component: Carousel,
14
+ description: 'Carousel/slider component for cycling through content.',
15
+ });
16
+
17
+ export default meta;
18
+
19
+ export const Default = () => (
20
+ <Carousel className="w-full max-w-xs">
21
+ <CarouselContent>
22
+ {Array.from({ length: 5 }).map((_, index) => (
23
+ <CarouselItem key={index}>
24
+ <div className="p-1">
25
+ <Card>
26
+ <CardContent className="flex aspect-square items-center justify-center p-6">
27
+ <span className="text-4xl font-semibold">{index + 1}</span>
28
+ </CardContent>
29
+ </Card>
30
+ </div>
31
+ </CarouselItem>
32
+ ))}
33
+ </CarouselContent>
34
+ <CarouselPrevious />
35
+ <CarouselNext />
36
+ </Carousel>
37
+ );
38
+
39
+ export const Multiple = () => (
40
+ <Carousel
41
+ opts={{ align: 'start' }}
42
+ className="w-full max-w-sm"
43
+ >
44
+ <CarouselContent>
45
+ {Array.from({ length: 5 }).map((_, index) => (
46
+ <CarouselItem key={index} className="basis-1/3">
47
+ <div className="p-1">
48
+ <Card>
49
+ <CardContent className="flex aspect-square items-center justify-center p-6">
50
+ <span className="text-3xl font-semibold">{index + 1}</span>
51
+ </CardContent>
52
+ </Card>
53
+ </div>
54
+ </CarouselItem>
55
+ ))}
56
+ </CarouselContent>
57
+ <CarouselPrevious />
58
+ <CarouselNext />
59
+ </Carousel>
60
+ );
61
+
62
+ export const Wide = () => (
63
+ <Carousel className="w-full max-w-lg">
64
+ <CarouselContent>
65
+ {Array.from({ length: 3 }).map((_, index) => (
66
+ <CarouselItem key={index}>
67
+ <div className="p-1">
68
+ <Card>
69
+ <CardContent className="flex aspect-video items-center justify-center p-6 bg-muted">
70
+ <span className="text-4xl font-semibold">Slide {index + 1}</span>
71
+ </CardContent>
72
+ </Card>
73
+ </div>
74
+ </CarouselItem>
75
+ ))}
76
+ </CarouselContent>
77
+ <CarouselPrevious />
78
+ <CarouselNext />
79
+ </Carousel>
80
+ );
81
+
82
+ export const WithImages = () => (
83
+ <Carousel className="w-full max-w-md">
84
+ <CarouselContent>
85
+ {[
86
+ 'https://images.unsplash.com/photo-1494976388531-d1058494cdd8?w=400',
87
+ 'https://images.unsplash.com/photo-1503376780353-7e6692767b70?w=400',
88
+ 'https://images.unsplash.com/photo-1542362567-b07e54358753?w=400',
89
+ ].map((src, index) => (
90
+ <CarouselItem key={index}>
91
+ <div className="p-1">
92
+ <div className="aspect-video rounded-lg overflow-hidden">
93
+ <img src={src} alt={`Slide ${index + 1}`} className="w-full h-full object-cover" />
94
+ </div>
95
+ </div>
96
+ </CarouselItem>
97
+ ))}
98
+ </CarouselContent>
99
+ <CarouselPrevious />
100
+ <CarouselNext />
101
+ </Carousel>
102
+ );
103
+
104
+ export const Loop = () => (
105
+ <Carousel opts={{ loop: true }} className="w-full max-w-xs">
106
+ <CarouselContent>
107
+ {Array.from({ length: 5 }).map((_, index) => (
108
+ <CarouselItem key={index}>
109
+ <div className="p-1">
110
+ <Card>
111
+ <CardContent className="flex aspect-square items-center justify-center p-6">
112
+ <span className="text-4xl font-semibold">{index + 1}</span>
113
+ </CardContent>
114
+ </Card>
115
+ </div>
116
+ </CarouselItem>
117
+ ))}
118
+ </CarouselContent>
119
+ <CarouselPrevious />
120
+ <CarouselNext />
121
+ </Carousel>
122
+ );
@@ -157,11 +157,11 @@ const CarouselContent = React.forwardRef<
157
157
  const { carouselRef, orientation } = useCarousel()
158
158
 
159
159
  return (
160
- <div ref={carouselRef} className="overflow-hidden">
160
+ <div ref={carouselRef} className="overflow-hidden h-full">
161
161
  <div
162
162
  ref={ref}
163
163
  className={cn(
164
- "flex",
164
+ "flex h-full",
165
165
  orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
166
166
  className
167
167
  )}