@djangocfg/ui-core 2.1.120 → 2.1.121

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 (54) 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/checkbox.story.tsx +89 -0
  15. package/src/components/collapsible.story.tsx +133 -0
  16. package/src/components/combobox.story.tsx +145 -0
  17. package/src/components/command.story.tsx +121 -0
  18. package/src/components/context-menu.story.tsx +125 -0
  19. package/src/components/copy.story.tsx +77 -0
  20. package/src/components/dialog.story.tsx +137 -0
  21. package/src/components/drawer.story.tsx +131 -0
  22. package/src/components/dropdown-menu.story.tsx +208 -0
  23. package/src/components/empty.story.tsx +115 -0
  24. package/src/components/hover-card.story.tsx +102 -0
  25. package/src/components/image-with-fallback.story.tsx +105 -0
  26. package/src/components/input-group.story.tsx +119 -0
  27. package/src/components/input-otp.story.tsx +105 -0
  28. package/src/components/input.story.tsx +77 -0
  29. package/src/components/kbd.story.tsx +113 -0
  30. package/src/components/label.story.tsx +52 -0
  31. package/src/components/menubar.story.tsx +152 -0
  32. package/src/components/multi-select.story.tsx +122 -0
  33. package/src/components/navigation-menu.story.tsx +154 -0
  34. package/src/components/popover.story.tsx +127 -0
  35. package/src/components/preloader.story.tsx +86 -0
  36. package/src/components/progress.story.tsx +97 -0
  37. package/src/components/radio-group.story.tsx +113 -0
  38. package/src/components/resizable.story.tsx +119 -0
  39. package/src/components/responsive-sheet.story.tsx +117 -0
  40. package/src/components/scroll-area.story.tsx +112 -0
  41. package/src/components/select.story.tsx +112 -0
  42. package/src/components/separator.story.tsx +69 -0
  43. package/src/components/sheet.story.tsx +148 -0
  44. package/src/components/skeleton.story.tsx +101 -0
  45. package/src/components/slider.story.tsx +113 -0
  46. package/src/components/spinner.story.tsx +66 -0
  47. package/src/components/switch.story.tsx +98 -0
  48. package/src/components/table.story.tsx +148 -0
  49. package/src/components/tabs.story.tsx +98 -0
  50. package/src/components/tabs.tsx +1 -1
  51. package/src/components/textarea.story.tsx +94 -0
  52. package/src/components/toggle-group.story.tsx +118 -0
  53. package/src/components/toggle.story.tsx +104 -0
  54. package/src/components/tooltip.story.tsx +139 -0
@@ -0,0 +1,137 @@
1
+ import { defineStory } from '@djangocfg/playground';
2
+ import {
3
+ Dialog,
4
+ DialogTrigger,
5
+ DialogContent,
6
+ DialogHeader,
7
+ DialogFooter,
8
+ DialogTitle,
9
+ DialogDescription,
10
+ DialogClose,
11
+ } from './dialog';
12
+ import { Button } from './button';
13
+ import { Input } from './input';
14
+ import { Label } from './label';
15
+
16
+ export default defineStory({
17
+ title: 'Core/Dialog',
18
+ component: Dialog,
19
+ description: 'Modal dialog for focused interactions.',
20
+ });
21
+
22
+ export const Default = () => (
23
+ <Dialog>
24
+ <DialogTrigger asChild>
25
+ <Button variant="outline">Open Dialog</Button>
26
+ </DialogTrigger>
27
+ <DialogContent>
28
+ <DialogHeader>
29
+ <DialogTitle>Dialog Title</DialogTitle>
30
+ <DialogDescription>
31
+ This is a dialog description. It explains what this dialog is about.
32
+ </DialogDescription>
33
+ </DialogHeader>
34
+ <div className="py-4">
35
+ <p>Dialog content goes here.</p>
36
+ </div>
37
+ <DialogFooter>
38
+ <DialogClose asChild>
39
+ <Button variant="outline">Cancel</Button>
40
+ </DialogClose>
41
+ <Button>Confirm</Button>
42
+ </DialogFooter>
43
+ </DialogContent>
44
+ </Dialog>
45
+ );
46
+
47
+ export const EditProfile = () => (
48
+ <Dialog>
49
+ <DialogTrigger asChild>
50
+ <Button>Edit Profile</Button>
51
+ </DialogTrigger>
52
+ <DialogContent className="sm:max-w-md">
53
+ <DialogHeader>
54
+ <DialogTitle>Edit Profile</DialogTitle>
55
+ <DialogDescription>
56
+ Make changes to your profile here. Click save when you're done.
57
+ </DialogDescription>
58
+ </DialogHeader>
59
+ <div className="space-y-4 py-4">
60
+ <div className="space-y-2">
61
+ <Label htmlFor="name">Name</Label>
62
+ <Input id="name" defaultValue="John Doe" />
63
+ </div>
64
+ <div className="space-y-2">
65
+ <Label htmlFor="email">Email</Label>
66
+ <Input id="email" type="email" defaultValue="john@example.com" />
67
+ </div>
68
+ </div>
69
+ <DialogFooter>
70
+ <DialogClose asChild>
71
+ <Button variant="outline">Cancel</Button>
72
+ </DialogClose>
73
+ <Button>Save Changes</Button>
74
+ </DialogFooter>
75
+ </DialogContent>
76
+ </Dialog>
77
+ );
78
+
79
+ export const Confirmation = () => (
80
+ <Dialog>
81
+ <DialogTrigger asChild>
82
+ <Button variant="destructive">Delete Account</Button>
83
+ </DialogTrigger>
84
+ <DialogContent>
85
+ <DialogHeader>
86
+ <DialogTitle>Are you sure?</DialogTitle>
87
+ <DialogDescription>
88
+ This action cannot be undone. This will permanently delete your account
89
+ and remove all your data from our servers.
90
+ </DialogDescription>
91
+ </DialogHeader>
92
+ <DialogFooter>
93
+ <DialogClose asChild>
94
+ <Button variant="outline">Cancel</Button>
95
+ </DialogClose>
96
+ <Button variant="destructive">Delete Account</Button>
97
+ </DialogFooter>
98
+ </DialogContent>
99
+ </Dialog>
100
+ );
101
+
102
+ export const LongContent = () => (
103
+ <Dialog>
104
+ <DialogTrigger asChild>
105
+ <Button variant="outline">Terms of Service</Button>
106
+ </DialogTrigger>
107
+ <DialogContent className="max-h-[80vh] overflow-y-auto">
108
+ <DialogHeader>
109
+ <DialogTitle>Terms of Service</DialogTitle>
110
+ </DialogHeader>
111
+ <div className="space-y-4 py-4 text-sm text-muted-foreground">
112
+ <p>
113
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
114
+ tempor incididunt ut labore et dolore magna aliqua.
115
+ </p>
116
+ <p>
117
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
118
+ ut aliquip ex ea commodo consequat.
119
+ </p>
120
+ <p>
121
+ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
122
+ dolore eu fugiat nulla pariatur.
123
+ </p>
124
+ <p>
125
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
126
+ deserunt mollit anim id est laborum.
127
+ </p>
128
+ </div>
129
+ <DialogFooter>
130
+ <DialogClose asChild>
131
+ <Button variant="outline">Decline</Button>
132
+ </DialogClose>
133
+ <Button>Accept</Button>
134
+ </DialogFooter>
135
+ </DialogContent>
136
+ </Dialog>
137
+ );
@@ -0,0 +1,131 @@
1
+ import { defineStory } from '@djangocfg/playground';
2
+ import {
3
+ Drawer,
4
+ DrawerTrigger,
5
+ DrawerContent,
6
+ DrawerHeader,
7
+ DrawerFooter,
8
+ DrawerTitle,
9
+ DrawerDescription,
10
+ DrawerClose,
11
+ } from './drawer';
12
+ import { Button } from './button';
13
+ import { Input } from './input';
14
+ import { Label } from './label';
15
+
16
+ export default defineStory({
17
+ title: 'Core/Drawer',
18
+ component: Drawer,
19
+ description: 'Mobile-friendly drawer that slides up from the bottom.',
20
+ });
21
+
22
+ export const Default = () => (
23
+ <Drawer>
24
+ <DrawerTrigger asChild>
25
+ <Button variant="outline">Open Drawer</Button>
26
+ </DrawerTrigger>
27
+ <DrawerContent>
28
+ <DrawerHeader>
29
+ <DrawerTitle>Drawer Title</DrawerTitle>
30
+ <DrawerDescription>
31
+ This is a description of the drawer content.
32
+ </DrawerDescription>
33
+ </DrawerHeader>
34
+ <div className="p-4">
35
+ <p>Drawer content goes here.</p>
36
+ </div>
37
+ <DrawerFooter>
38
+ <Button>Submit</Button>
39
+ <DrawerClose asChild>
40
+ <Button variant="outline">Cancel</Button>
41
+ </DrawerClose>
42
+ </DrawerFooter>
43
+ </DrawerContent>
44
+ </Drawer>
45
+ );
46
+
47
+ export const WithForm = () => (
48
+ <Drawer>
49
+ <DrawerTrigger asChild>
50
+ <Button>Edit Profile</Button>
51
+ </DrawerTrigger>
52
+ <DrawerContent>
53
+ <DrawerHeader>
54
+ <DrawerTitle>Edit Profile</DrawerTitle>
55
+ <DrawerDescription>
56
+ Make changes to your profile information.
57
+ </DrawerDescription>
58
+ </DrawerHeader>
59
+ <div className="p-4 space-y-4">
60
+ <div className="space-y-2">
61
+ <Label htmlFor="name">Name</Label>
62
+ <Input id="name" defaultValue="John Doe" />
63
+ </div>
64
+ <div className="space-y-2">
65
+ <Label htmlFor="email">Email</Label>
66
+ <Input id="email" type="email" defaultValue="john@example.com" />
67
+ </div>
68
+ </div>
69
+ <DrawerFooter>
70
+ <Button>Save Changes</Button>
71
+ <DrawerClose asChild>
72
+ <Button variant="outline">Cancel</Button>
73
+ </DrawerClose>
74
+ </DrawerFooter>
75
+ </DrawerContent>
76
+ </Drawer>
77
+ );
78
+
79
+ export const Confirmation = () => (
80
+ <Drawer>
81
+ <DrawerTrigger asChild>
82
+ <Button variant="destructive">Delete Account</Button>
83
+ </DrawerTrigger>
84
+ <DrawerContent>
85
+ <DrawerHeader>
86
+ <DrawerTitle>Are you sure?</DrawerTitle>
87
+ <DrawerDescription>
88
+ This action cannot be undone. Your account and all associated data will be permanently deleted.
89
+ </DrawerDescription>
90
+ </DrawerHeader>
91
+ <DrawerFooter>
92
+ <Button variant="destructive">Yes, Delete My Account</Button>
93
+ <DrawerClose asChild>
94
+ <Button variant="outline">Cancel</Button>
95
+ </DrawerClose>
96
+ </DrawerFooter>
97
+ </DrawerContent>
98
+ </Drawer>
99
+ );
100
+
101
+ export const ActionSheet = () => (
102
+ <Drawer>
103
+ <DrawerTrigger asChild>
104
+ <Button variant="outline">Share</Button>
105
+ </DrawerTrigger>
106
+ <DrawerContent>
107
+ <DrawerHeader>
108
+ <DrawerTitle>Share this item</DrawerTitle>
109
+ </DrawerHeader>
110
+ <div className="p-4 space-y-2">
111
+ <Button variant="ghost" className="w-full justify-start">
112
+ Copy Link
113
+ </Button>
114
+ <Button variant="ghost" className="w-full justify-start">
115
+ Share to Twitter
116
+ </Button>
117
+ <Button variant="ghost" className="w-full justify-start">
118
+ Share to Facebook
119
+ </Button>
120
+ <Button variant="ghost" className="w-full justify-start">
121
+ Send via Email
122
+ </Button>
123
+ </div>
124
+ <DrawerFooter>
125
+ <DrawerClose asChild>
126
+ <Button variant="outline" className="w-full">Cancel</Button>
127
+ </DrawerClose>
128
+ </DrawerFooter>
129
+ </DrawerContent>
130
+ </Drawer>
131
+ );
@@ -0,0 +1,208 @@
1
+ import { defineStory } from '@djangocfg/playground';
2
+ import {
3
+ DropdownMenu,
4
+ DropdownMenuTrigger,
5
+ DropdownMenuContent,
6
+ DropdownMenuItem,
7
+ DropdownMenuCheckboxItem,
8
+ DropdownMenuRadioItem,
9
+ DropdownMenuLabel,
10
+ DropdownMenuSeparator,
11
+ DropdownMenuShortcut,
12
+ DropdownMenuGroup,
13
+ DropdownMenuSub,
14
+ DropdownMenuSubContent,
15
+ DropdownMenuSubTrigger,
16
+ DropdownMenuRadioGroup,
17
+ } from './dropdown-menu';
18
+ import { Button } from './button';
19
+ import { useState } from 'react';
20
+ import {
21
+ User,
22
+ CreditCard,
23
+ Settings,
24
+ Keyboard,
25
+ Users,
26
+ UserPlus,
27
+ Mail,
28
+ MessageSquare,
29
+ PlusCircle,
30
+ Plus,
31
+ Github,
32
+ LifeBuoy,
33
+ Cloud,
34
+ LogOut,
35
+ } from 'lucide-react';
36
+
37
+ export default defineStory({
38
+ title: 'Core/Dropdown Menu',
39
+ component: DropdownMenu,
40
+ description: 'Context menu with items, submenus, and shortcuts.',
41
+ });
42
+
43
+ export const Default = () => (
44
+ <DropdownMenu>
45
+ <DropdownMenuTrigger asChild>
46
+ <Button variant="outline">Open Menu</Button>
47
+ </DropdownMenuTrigger>
48
+ <DropdownMenuContent className="w-56">
49
+ <DropdownMenuLabel>My Account</DropdownMenuLabel>
50
+ <DropdownMenuSeparator />
51
+ <DropdownMenuGroup>
52
+ <DropdownMenuItem>
53
+ <User className="mr-2 h-4 w-4" />
54
+ <span>Profile</span>
55
+ <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
56
+ </DropdownMenuItem>
57
+ <DropdownMenuItem>
58
+ <CreditCard className="mr-2 h-4 w-4" />
59
+ <span>Billing</span>
60
+ <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
61
+ </DropdownMenuItem>
62
+ <DropdownMenuItem>
63
+ <Settings className="mr-2 h-4 w-4" />
64
+ <span>Settings</span>
65
+ <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
66
+ </DropdownMenuItem>
67
+ <DropdownMenuItem>
68
+ <Keyboard className="mr-2 h-4 w-4" />
69
+ <span>Keyboard shortcuts</span>
70
+ <DropdownMenuShortcut>⌘K</DropdownMenuShortcut>
71
+ </DropdownMenuItem>
72
+ </DropdownMenuGroup>
73
+ <DropdownMenuSeparator />
74
+ <DropdownMenuItem>
75
+ <LogOut className="mr-2 h-4 w-4" />
76
+ <span>Log out</span>
77
+ <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
78
+ </DropdownMenuItem>
79
+ </DropdownMenuContent>
80
+ </DropdownMenu>
81
+ );
82
+
83
+ export const WithSubmenus = () => (
84
+ <DropdownMenu>
85
+ <DropdownMenuTrigger asChild>
86
+ <Button variant="outline">Open Menu</Button>
87
+ </DropdownMenuTrigger>
88
+ <DropdownMenuContent className="w-56">
89
+ <DropdownMenuLabel>My Account</DropdownMenuLabel>
90
+ <DropdownMenuSeparator />
91
+ <DropdownMenuGroup>
92
+ <DropdownMenuItem>
93
+ <User className="mr-2 h-4 w-4" />
94
+ <span>Profile</span>
95
+ </DropdownMenuItem>
96
+ <DropdownMenuSub>
97
+ <DropdownMenuSubTrigger>
98
+ <UserPlus className="mr-2 h-4 w-4" />
99
+ <span>Invite users</span>
100
+ </DropdownMenuSubTrigger>
101
+ <DropdownMenuSubContent>
102
+ <DropdownMenuItem>
103
+ <Mail className="mr-2 h-4 w-4" />
104
+ <span>Email</span>
105
+ </DropdownMenuItem>
106
+ <DropdownMenuItem>
107
+ <MessageSquare className="mr-2 h-4 w-4" />
108
+ <span>Message</span>
109
+ </DropdownMenuItem>
110
+ <DropdownMenuSeparator />
111
+ <DropdownMenuItem>
112
+ <PlusCircle className="mr-2 h-4 w-4" />
113
+ <span>More...</span>
114
+ </DropdownMenuItem>
115
+ </DropdownMenuSubContent>
116
+ </DropdownMenuSub>
117
+ <DropdownMenuItem>
118
+ <Plus className="mr-2 h-4 w-4" />
119
+ <span>New Team</span>
120
+ </DropdownMenuItem>
121
+ </DropdownMenuGroup>
122
+ <DropdownMenuSeparator />
123
+ <DropdownMenuItem>
124
+ <Github className="mr-2 h-4 w-4" />
125
+ <span>GitHub</span>
126
+ </DropdownMenuItem>
127
+ <DropdownMenuItem>
128
+ <LifeBuoy className="mr-2 h-4 w-4" />
129
+ <span>Support</span>
130
+ </DropdownMenuItem>
131
+ <DropdownMenuItem disabled>
132
+ <Cloud className="mr-2 h-4 w-4" />
133
+ <span>API</span>
134
+ </DropdownMenuItem>
135
+ </DropdownMenuContent>
136
+ </DropdownMenu>
137
+ );
138
+
139
+ export const WithCheckboxes = () => {
140
+ const [showStatusBar, setShowStatusBar] = useState(true);
141
+ const [showActivityBar, setShowActivityBar] = useState(false);
142
+ const [showPanel, setShowPanel] = useState(false);
143
+
144
+ return (
145
+ <DropdownMenu>
146
+ <DropdownMenuTrigger asChild>
147
+ <Button variant="outline">View Options</Button>
148
+ </DropdownMenuTrigger>
149
+ <DropdownMenuContent className="w-56">
150
+ <DropdownMenuLabel>Appearance</DropdownMenuLabel>
151
+ <DropdownMenuSeparator />
152
+ <DropdownMenuCheckboxItem
153
+ checked={showStatusBar}
154
+ onCheckedChange={setShowStatusBar}
155
+ >
156
+ Status Bar
157
+ </DropdownMenuCheckboxItem>
158
+ <DropdownMenuCheckboxItem
159
+ checked={showActivityBar}
160
+ onCheckedChange={setShowActivityBar}
161
+ >
162
+ Activity Bar
163
+ </DropdownMenuCheckboxItem>
164
+ <DropdownMenuCheckboxItem
165
+ checked={showPanel}
166
+ onCheckedChange={setShowPanel}
167
+ >
168
+ Panel
169
+ </DropdownMenuCheckboxItem>
170
+ </DropdownMenuContent>
171
+ </DropdownMenu>
172
+ );
173
+ };
174
+
175
+ export const WithRadioGroup = () => {
176
+ const [position, setPosition] = useState('bottom');
177
+
178
+ return (
179
+ <DropdownMenu>
180
+ <DropdownMenuTrigger asChild>
181
+ <Button variant="outline">Panel Position</Button>
182
+ </DropdownMenuTrigger>
183
+ <DropdownMenuContent className="w-56">
184
+ <DropdownMenuLabel>Panel Position</DropdownMenuLabel>
185
+ <DropdownMenuSeparator />
186
+ <DropdownMenuRadioGroup value={position} onValueChange={setPosition}>
187
+ <DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
188
+ <DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
189
+ <DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>
190
+ </DropdownMenuRadioGroup>
191
+ </DropdownMenuContent>
192
+ </DropdownMenu>
193
+ );
194
+ };
195
+
196
+ export const Simple = () => (
197
+ <DropdownMenu>
198
+ <DropdownMenuTrigger asChild>
199
+ <Button variant="outline">Actions</Button>
200
+ </DropdownMenuTrigger>
201
+ <DropdownMenuContent>
202
+ <DropdownMenuItem>Edit</DropdownMenuItem>
203
+ <DropdownMenuItem>Duplicate</DropdownMenuItem>
204
+ <DropdownMenuSeparator />
205
+ <DropdownMenuItem className="text-destructive">Delete</DropdownMenuItem>
206
+ </DropdownMenuContent>
207
+ </DropdownMenu>
208
+ );
@@ -0,0 +1,115 @@
1
+ import { defineStory } from '@djangocfg/playground';
2
+ import {
3
+ Empty,
4
+ EmptyHeader,
5
+ EmptyTitle,
6
+ EmptyDescription,
7
+ EmptyContent,
8
+ EmptyMedia,
9
+ } from './empty';
10
+ import { Button } from './button';
11
+ import { Inbox, Search, FileQuestion, Plus, RefreshCw } from 'lucide-react';
12
+
13
+ export default defineStory({
14
+ title: 'Core/Empty',
15
+ component: Empty,
16
+ description: 'Empty state placeholder for no content.',
17
+ });
18
+
19
+ export const Default = () => (
20
+ <Empty className="max-w-md mx-auto py-10">
21
+ <EmptyMedia>
22
+ <Inbox className="h-12 w-12 text-muted-foreground" />
23
+ </EmptyMedia>
24
+ <EmptyHeader>
25
+ <EmptyTitle>No items</EmptyTitle>
26
+ <EmptyDescription>
27
+ You don't have any items yet. Create your first one to get started.
28
+ </EmptyDescription>
29
+ </EmptyHeader>
30
+ <EmptyContent>
31
+ <Button>
32
+ <Plus className="mr-2 h-4 w-4" />
33
+ Create Item
34
+ </Button>
35
+ </EmptyContent>
36
+ </Empty>
37
+ );
38
+
39
+ export const SearchNoResults = () => (
40
+ <Empty className="max-w-md mx-auto py-10">
41
+ <EmptyMedia>
42
+ <Search className="h-12 w-12 text-muted-foreground" />
43
+ </EmptyMedia>
44
+ <EmptyHeader>
45
+ <EmptyTitle>No results found</EmptyTitle>
46
+ <EmptyDescription>
47
+ We couldn't find anything matching your search. Try adjusting your filters.
48
+ </EmptyDescription>
49
+ </EmptyHeader>
50
+ <EmptyContent>
51
+ <Button variant="outline">Clear filters</Button>
52
+ </EmptyContent>
53
+ </Empty>
54
+ );
55
+
56
+ export const Error = () => (
57
+ <Empty className="max-w-md mx-auto py-10">
58
+ <EmptyMedia>
59
+ <FileQuestion className="h-12 w-12 text-muted-foreground" />
60
+ </EmptyMedia>
61
+ <EmptyHeader>
62
+ <EmptyTitle>Something went wrong</EmptyTitle>
63
+ <EmptyDescription>
64
+ We encountered an error while loading the data. Please try again.
65
+ </EmptyDescription>
66
+ </EmptyHeader>
67
+ <EmptyContent>
68
+ <Button variant="outline">
69
+ <RefreshCw className="mr-2 h-4 w-4" />
70
+ Retry
71
+ </Button>
72
+ </EmptyContent>
73
+ </Empty>
74
+ );
75
+
76
+ export const NoNotifications = () => (
77
+ <Empty className="max-w-sm mx-auto py-8">
78
+ <EmptyMedia>
79
+ <Inbox className="h-10 w-10 text-muted-foreground" />
80
+ </EmptyMedia>
81
+ <EmptyHeader>
82
+ <EmptyTitle>All caught up!</EmptyTitle>
83
+ <EmptyDescription>
84
+ You have no new notifications.
85
+ </EmptyDescription>
86
+ </EmptyHeader>
87
+ </Empty>
88
+ );
89
+
90
+ export const Simple = () => (
91
+ <Empty className="max-w-xs mx-auto py-6">
92
+ <EmptyHeader>
93
+ <EmptyTitle>No data</EmptyTitle>
94
+ <EmptyDescription>
95
+ Start by adding some data.
96
+ </EmptyDescription>
97
+ </EmptyHeader>
98
+ </Empty>
99
+ );
100
+
101
+ export const InCard = () => (
102
+ <div className="rounded-lg border p-6">
103
+ <Empty>
104
+ <EmptyMedia>
105
+ <Inbox className="h-8 w-8 text-muted-foreground" />
106
+ </EmptyMedia>
107
+ <EmptyHeader>
108
+ <EmptyTitle className="text-base">Empty inbox</EmptyTitle>
109
+ <EmptyDescription className="text-sm">
110
+ No messages to display
111
+ </EmptyDescription>
112
+ </EmptyHeader>
113
+ </Empty>
114
+ </div>
115
+ );
@@ -0,0 +1,102 @@
1
+ import { defineStory } from '@djangocfg/playground';
2
+ import { HoverCard, HoverCardContent, HoverCardTrigger } from './hover-card';
3
+ import { Avatar, AvatarFallback, AvatarImage } from './avatar';
4
+ import { Button } from './button';
5
+ import { CalendarDays } from 'lucide-react';
6
+
7
+ export default defineStory({
8
+ title: 'Core/Hover Card',
9
+ component: HoverCard,
10
+ description: 'Card that appears on hover, showing additional information.',
11
+ });
12
+
13
+ export const Default = () => (
14
+ <HoverCard>
15
+ <HoverCardTrigger asChild>
16
+ <Button variant="link">@nextjs</Button>
17
+ </HoverCardTrigger>
18
+ <HoverCardContent className="w-80">
19
+ <div className="flex justify-between space-x-4">
20
+ <Avatar>
21
+ <AvatarImage src="https://github.com/vercel.png" />
22
+ <AvatarFallback>VC</AvatarFallback>
23
+ </Avatar>
24
+ <div className="space-y-1">
25
+ <h4 className="text-sm font-semibold">@nextjs</h4>
26
+ <p className="text-sm">
27
+ The React Framework – created and maintained by @vercel.
28
+ </p>
29
+ <div className="flex items-center pt-2">
30
+ <CalendarDays className="mr-2 h-4 w-4 opacity-70" />
31
+ <span className="text-xs text-muted-foreground">
32
+ Joined December 2021
33
+ </span>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </HoverCardContent>
38
+ </HoverCard>
39
+ );
40
+
41
+ export const UserProfile = () => (
42
+ <HoverCard>
43
+ <HoverCardTrigger asChild>
44
+ <Button variant="link" className="p-0">John Doe</Button>
45
+ </HoverCardTrigger>
46
+ <HoverCardContent className="w-80">
47
+ <div className="flex space-x-4">
48
+ <Avatar className="h-12 w-12">
49
+ <AvatarImage src="https://github.com/shadcn.png" />
50
+ <AvatarFallback>JD</AvatarFallback>
51
+ </Avatar>
52
+ <div className="space-y-1">
53
+ <h4 className="text-sm font-semibold">John Doe</h4>
54
+ <p className="text-sm text-muted-foreground">
55
+ Software Engineer at Acme Inc.
56
+ </p>
57
+ <div className="flex gap-4 pt-2 text-xs text-muted-foreground">
58
+ <span><strong>128</strong> Following</span>
59
+ <span><strong>512</strong> Followers</span>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ </HoverCardContent>
64
+ </HoverCard>
65
+ );
66
+
67
+ export const Simple = () => (
68
+ <HoverCard>
69
+ <HoverCardTrigger asChild>
70
+ <span className="text-sm underline cursor-pointer">What is this?</span>
71
+ </HoverCardTrigger>
72
+ <HoverCardContent>
73
+ <p className="text-sm">
74
+ This is a hover card that appears when you hover over the trigger.
75
+ </p>
76
+ </HoverCardContent>
77
+ </HoverCard>
78
+ );
79
+
80
+ export const WithStats = () => (
81
+ <HoverCard>
82
+ <HoverCardTrigger asChild>
83
+ <Button variant="outline" size="sm">View Project</Button>
84
+ </HoverCardTrigger>
85
+ <HoverCardContent className="w-64">
86
+ <div className="space-y-2">
87
+ <h4 className="text-sm font-semibold">My Awesome Project</h4>
88
+ <p className="text-sm text-muted-foreground">
89
+ A React component library.
90
+ </p>
91
+ <div className="flex gap-4 pt-2 text-xs">
92
+ <span className="flex items-center gap-1">
93
+ <span className="h-2 w-2 rounded-full bg-yellow-500" />
94
+ TypeScript
95
+ </span>
96
+ <span>⭐ 1.2k</span>
97
+ <span>🍴 234</span>
98
+ </div>
99
+ </div>
100
+ </HoverCardContent>
101
+ </HoverCard>
102
+ );