@djangocfg/ui-core 2.1.381 → 2.1.383

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 (78) hide show
  1. package/README.md +85 -21
  2. package/package.json +5 -12
  3. package/src/components/boundary/Boundary.tsx +204 -33
  4. package/src/components/boundary/README.md +249 -0
  5. package/src/components/boundary/index.ts +9 -2
  6. package/src/components/index.ts +9 -2
  7. package/src/components/select/combobox.tsx +47 -19
  8. package/src/hooks/audio/createSoundBus.ts +172 -0
  9. package/src/hooks/audio/index.ts +21 -0
  10. package/src/hooks/audio/useAudioPrefs.ts +91 -0
  11. package/src/hooks/audio/useNotificationSounds.ts +271 -0
  12. package/src/hooks/audio/useSoundEffect.ts +78 -0
  13. package/src/hooks/hotkey/formatHotkey.ts +96 -0
  14. package/src/hooks/hotkey/index.ts +10 -0
  15. package/src/hooks/hotkey/useHotkey.ts +106 -34
  16. package/src/hooks/hotkey/useHotkeyChord.ts +96 -0
  17. package/src/hooks/hotkey/useHotkeyHelp.ts +68 -0
  18. package/src/hooks/index.ts +1 -0
  19. package/src/components/boundary/boundary.story.tsx +0 -109
  20. package/src/components/data/avatar/avatar.story.tsx +0 -115
  21. package/src/components/data/badge/badge.story.tsx +0 -56
  22. package/src/components/data/calendar/calendar.story.tsx +0 -127
  23. package/src/components/data/carousel/carousel.story.tsx +0 -122
  24. package/src/components/data/progress/progress.story.tsx +0 -97
  25. package/src/components/data/table/table.story.tsx +0 -148
  26. package/src/components/data/toggle/toggle.story.tsx +0 -104
  27. package/src/components/data/toggle-group/toggle-group.story.tsx +0 -118
  28. package/src/components/feedback/alert/alert.story.tsx +0 -77
  29. package/src/components/feedback/empty/empty.story.tsx +0 -115
  30. package/src/components/feedback/preloader/preloader.story.tsx +0 -86
  31. package/src/components/feedback/spinner/spinner.story.tsx +0 -66
  32. package/src/components/forms/button/button.story.tsx +0 -116
  33. package/src/components/forms/button-download/button-download.story.tsx +0 -112
  34. package/src/components/forms/button-group/button-group.story.tsx +0 -79
  35. package/src/components/forms/checkbox/checkbox.story.tsx +0 -89
  36. package/src/components/forms/input/input.story.tsx +0 -77
  37. package/src/components/forms/input-group/input-group.story.tsx +0 -119
  38. package/src/components/forms/input-otp/input-otp.story.tsx +0 -105
  39. package/src/components/forms/label/label.story.tsx +0 -52
  40. package/src/components/forms/radio-group/radio-group.story.tsx +0 -113
  41. package/src/components/forms/slider/slider.story.tsx +0 -134
  42. package/src/components/forms/switch/switch.story.tsx +0 -98
  43. package/src/components/forms/textarea/textarea.story.tsx +0 -94
  44. package/src/components/layout/aspect-ratio/aspect-ratio.story.tsx +0 -94
  45. package/src/components/layout/card/card.story.tsx +0 -105
  46. package/src/components/layout/resizable/resizable.story.tsx +0 -119
  47. package/src/components/layout/scroll-area/scroll-area.story.tsx +0 -172
  48. package/src/components/layout/separator/separator.story.tsx +0 -69
  49. package/src/components/layout/skeleton/skeleton.story.tsx +0 -101
  50. package/src/components/navigation/accordion/accordion.story.tsx +0 -110
  51. package/src/components/navigation/collapsible/collapsible.story.tsx +0 -133
  52. package/src/components/navigation/command/command.story.tsx +0 -121
  53. package/src/components/navigation/context-menu/context-menu.story.tsx +0 -125
  54. package/src/components/navigation/dropdown-menu/dropdown-menu.story.tsx +0 -208
  55. package/src/components/navigation/menubar/menubar.story.tsx +0 -152
  56. package/src/components/navigation/navigation-menu/navigation-menu.story.tsx +0 -154
  57. package/src/components/navigation/tabs/tabs.story.tsx +0 -98
  58. package/src/components/overlay/alert-dialog/alert-dialog.story.tsx +0 -104
  59. package/src/components/overlay/dialog/dialog.story.tsx +0 -212
  60. package/src/components/overlay/drawer/drawer.story.tsx +0 -359
  61. package/src/components/overlay/hover-card/hover-card.story.tsx +0 -102
  62. package/src/components/overlay/popover/popover.story.tsx +0 -127
  63. package/src/components/overlay/responsive-sheet/responsive-sheet.story.tsx +0 -117
  64. package/src/components/overlay/sheet/sheet.story.tsx +0 -148
  65. package/src/components/overlay/tooltip/tooltip.story.tsx +0 -139
  66. package/src/components/select/combobox-async.story.tsx +0 -215
  67. package/src/components/select/combobox.story.tsx +0 -226
  68. package/src/components/select/country-select.story.tsx +0 -261
  69. package/src/components/select/language-select.story.tsx +0 -264
  70. package/src/components/select/multi-select.story.tsx +0 -122
  71. package/src/components/select/select.story.tsx +0 -112
  72. package/src/components/specialized/copy/copy.story.tsx +0 -77
  73. package/src/components/specialized/flag/flag.story.tsx +0 -82
  74. package/src/components/specialized/image-with-fallback/image-with-fallback.story.tsx +0 -105
  75. package/src/components/specialized/kbd/kbd.story.tsx +0 -113
  76. package/src/lib/dialog-service/dialog-service.story.tsx +0 -263
  77. package/src/stories/index.ts +0 -28
  78. package/src/styles/theme/theme-tokens.story.tsx +0 -157
@@ -1,102 +0,0 @@
1
- import { defineStory } from '@djangocfg/playground';
2
- import { HoverCard, HoverCardContent, HoverCardTrigger } from '.';
3
- import { Avatar, AvatarFallback, AvatarImage } from '../../data/avatar';
4
- import { Button } from '../../forms/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
- );
@@ -1,127 +0,0 @@
1
- import { defineStory, useSelect } from '@djangocfg/playground';
2
- import { Popover, PopoverContent, PopoverTrigger } from '.';
3
- import { Button } from '../../forms/button';
4
- import { Input } from '../../forms/input';
5
- import { Label } from '../../forms/label';
6
-
7
- export default defineStory({
8
- title: 'Core/Popover',
9
- component: Popover,
10
- description: 'Floating content panel triggered by a button.',
11
- });
12
-
13
- export const Interactive = () => {
14
- const [side] = useSelect('side', {
15
- options: ['top', 'right', 'bottom', 'left'] as const,
16
- defaultValue: 'bottom',
17
- label: 'Side',
18
- description: 'Popover position',
19
- });
20
-
21
- const [align] = useSelect('align', {
22
- options: ['start', 'center', 'end'] as const,
23
- defaultValue: 'center',
24
- label: 'Align',
25
- description: 'Popover alignment',
26
- });
27
-
28
- return (
29
- <div className="flex justify-center p-20">
30
- <Popover>
31
- <PopoverTrigger asChild>
32
- <Button variant="outline">Open popover</Button>
33
- </PopoverTrigger>
34
- <PopoverContent side={side} align={align} className="w-80">
35
- <div className="grid gap-4">
36
- <div className="space-y-2">
37
- <h4 className="font-medium leading-none">Dimensions</h4>
38
- <p className="text-sm text-muted-foreground">
39
- Set the dimensions for the layer.
40
- </p>
41
- </div>
42
- <div className="grid gap-2">
43
- <div className="grid grid-cols-3 items-center gap-4">
44
- <Label htmlFor="width">Width</Label>
45
- <Input id="width" defaultValue="100%" className="col-span-2 h-8" />
46
- </div>
47
- <div className="grid grid-cols-3 items-center gap-4">
48
- <Label htmlFor="height">Height</Label>
49
- <Input id="height" defaultValue="25px" className="col-span-2 h-8" />
50
- </div>
51
- </div>
52
- </div>
53
- </PopoverContent>
54
- </Popover>
55
- </div>
56
- );
57
- };
58
-
59
- export const Default = () => (
60
- <Popover>
61
- <PopoverTrigger asChild>
62
- <Button variant="outline">Open popover</Button>
63
- </PopoverTrigger>
64
- <PopoverContent className="w-80">
65
- <div className="grid gap-4">
66
- <div className="space-y-2">
67
- <h4 className="font-medium leading-none">Dimensions</h4>
68
- <p className="text-sm text-muted-foreground">
69
- Set the dimensions for the layer.
70
- </p>
71
- </div>
72
- <div className="grid gap-2">
73
- <div className="grid grid-cols-3 items-center gap-4">
74
- <Label htmlFor="width">Width</Label>
75
- <Input id="width" defaultValue="100%" className="col-span-2 h-8" />
76
- </div>
77
- <div className="grid grid-cols-3 items-center gap-4">
78
- <Label htmlFor="maxWidth">Max. width</Label>
79
- <Input id="maxWidth" defaultValue="300px" className="col-span-2 h-8" />
80
- </div>
81
- </div>
82
- </div>
83
- </PopoverContent>
84
- </Popover>
85
- );
86
-
87
- export const WithForm = () => (
88
- <Popover>
89
- <PopoverTrigger asChild>
90
- <Button>Update settings</Button>
91
- </PopoverTrigger>
92
- <PopoverContent className="w-80">
93
- <div className="grid gap-4">
94
- <div className="space-y-2">
95
- <h4 className="font-medium leading-none">Settings</h4>
96
- <p className="text-sm text-muted-foreground">
97
- Configure your preferences.
98
- </p>
99
- </div>
100
- <div className="space-y-4">
101
- <div className="space-y-2">
102
- <Label htmlFor="name">Display Name</Label>
103
- <Input id="name" placeholder="Enter name" />
104
- </div>
105
- <div className="space-y-2">
106
- <Label htmlFor="email">Email</Label>
107
- <Input id="email" type="email" placeholder="Enter email" />
108
- </div>
109
- <Button className="w-full">Save</Button>
110
- </div>
111
- </div>
112
- </PopoverContent>
113
- </Popover>
114
- );
115
-
116
- export const Simple = () => (
117
- <Popover>
118
- <PopoverTrigger asChild>
119
- <Button variant="outline" size="sm">Info</Button>
120
- </PopoverTrigger>
121
- <PopoverContent className="w-64">
122
- <p className="text-sm">
123
- This is a simple popover with just some text content.
124
- </p>
125
- </PopoverContent>
126
- </Popover>
127
- );
@@ -1,117 +0,0 @@
1
- import { useState } from 'react';
2
- import { defineStory } from '@djangocfg/playground';
3
- import {
4
- ResponsiveSheet,
5
- ResponsiveSheetContent,
6
- ResponsiveSheetHeader,
7
- ResponsiveSheetTitle,
8
- ResponsiveSheetDescription,
9
- ResponsiveSheetFooter,
10
- } from '.';
11
- import { Button } from '../../forms/button';
12
- import { Input } from '../../forms/input';
13
- import { Label } from '../../forms/label';
14
-
15
- export default defineStory({
16
- title: 'Core/ResponsiveSheet',
17
- component: ResponsiveSheet,
18
- description: 'Dialog on desktop, Drawer on mobile.',
19
- });
20
-
21
- export const Default = () => {
22
- const [open, setOpen] = useState(false);
23
-
24
- return (
25
- <>
26
- <Button onClick={() => setOpen(true)}>Open Sheet</Button>
27
- <ResponsiveSheet open={open} onOpenChange={setOpen}>
28
- <ResponsiveSheetContent>
29
- <ResponsiveSheetHeader>
30
- <ResponsiveSheetTitle>Responsive Sheet</ResponsiveSheetTitle>
31
- <ResponsiveSheetDescription>
32
- This component shows as a Dialog on desktop and a Drawer on mobile.
33
- </ResponsiveSheetDescription>
34
- </ResponsiveSheetHeader>
35
- <div className="p-4">
36
- <p className="text-sm text-muted-foreground">
37
- Resize your browser window to see the responsive behavior.
38
- </p>
39
- </div>
40
- <ResponsiveSheetFooter>
41
- <Button variant="outline" onClick={() => setOpen(false)}>
42
- Cancel
43
- </Button>
44
- <Button onClick={() => setOpen(false)}>Continue</Button>
45
- </ResponsiveSheetFooter>
46
- </ResponsiveSheetContent>
47
- </ResponsiveSheet>
48
- </>
49
- );
50
- };
51
-
52
- export const WithForm = () => {
53
- const [open, setOpen] = useState(false);
54
-
55
- return (
56
- <>
57
- <Button onClick={() => setOpen(true)}>Edit Profile</Button>
58
- <ResponsiveSheet open={open} onOpenChange={setOpen}>
59
- <ResponsiveSheetContent className="sm:max-w-md">
60
- <ResponsiveSheetHeader>
61
- <ResponsiveSheetTitle>Edit Profile</ResponsiveSheetTitle>
62
- <ResponsiveSheetDescription>
63
- Make changes to your profile here. Click save when you're done.
64
- </ResponsiveSheetDescription>
65
- </ResponsiveSheetHeader>
66
- <div className="space-y-4 p-4">
67
- <div className="space-y-2">
68
- <Label htmlFor="name">Name</Label>
69
- <Input id="name" defaultValue="John Doe" />
70
- </div>
71
- <div className="space-y-2">
72
- <Label htmlFor="email">Email</Label>
73
- <Input id="email" type="email" defaultValue="john@example.com" />
74
- </div>
75
- </div>
76
- <ResponsiveSheetFooter>
77
- <Button variant="outline" onClick={() => setOpen(false)}>
78
- Cancel
79
- </Button>
80
- <Button onClick={() => setOpen(false)}>Save changes</Button>
81
- </ResponsiveSheetFooter>
82
- </ResponsiveSheetContent>
83
- </ResponsiveSheet>
84
- </>
85
- );
86
- };
87
-
88
- export const Confirmation = () => {
89
- const [open, setOpen] = useState(false);
90
-
91
- return (
92
- <>
93
- <Button variant="destructive" onClick={() => setOpen(true)}>
94
- Delete Account
95
- </Button>
96
- <ResponsiveSheet open={open} onOpenChange={setOpen}>
97
- <ResponsiveSheetContent>
98
- <ResponsiveSheetHeader>
99
- <ResponsiveSheetTitle>Are you sure?</ResponsiveSheetTitle>
100
- <ResponsiveSheetDescription>
101
- This action cannot be undone. This will permanently delete your
102
- account and remove your data from our servers.
103
- </ResponsiveSheetDescription>
104
- </ResponsiveSheetHeader>
105
- <ResponsiveSheetFooter>
106
- <Button variant="outline" onClick={() => setOpen(false)}>
107
- Cancel
108
- </Button>
109
- <Button variant="destructive" onClick={() => setOpen(false)}>
110
- Delete Account
111
- </Button>
112
- </ResponsiveSheetFooter>
113
- </ResponsiveSheetContent>
114
- </ResponsiveSheet>
115
- </>
116
- );
117
- };
@@ -1,148 +0,0 @@
1
- import { defineStory, useSelect } from '@djangocfg/playground';
2
- import {
3
- Sheet,
4
- SheetTrigger,
5
- SheetContent,
6
- SheetHeader,
7
- SheetFooter,
8
- SheetTitle,
9
- SheetDescription,
10
- SheetClose,
11
- } from '.';
12
- import { Button } from '../../forms/button';
13
- import { Input } from '../../forms/input';
14
- import { Label } from '../../forms/label';
15
-
16
- export default defineStory({
17
- title: 'Core/Sheet',
18
- component: Sheet,
19
- description: 'Slide-out panel from the edge of the screen.',
20
- });
21
-
22
- export const Interactive = () => {
23
- const [side] = useSelect('side', {
24
- options: ['top', 'right', 'bottom', 'left'] as const,
25
- defaultValue: 'right',
26
- label: 'Side',
27
- description: 'Sheet position',
28
- });
29
-
30
- return (
31
- <Sheet>
32
- <SheetTrigger asChild>
33
- <Button variant="outline">Open Sheet</Button>
34
- </SheetTrigger>
35
- <SheetContent side={side}>
36
- <SheetHeader>
37
- <SheetTitle>Sheet Title</SheetTitle>
38
- <SheetDescription>
39
- This is a sheet that slides in from the {side}.
40
- </SheetDescription>
41
- </SheetHeader>
42
- <div className="py-4">
43
- <p>Sheet content goes here.</p>
44
- </div>
45
- <SheetFooter>
46
- <SheetClose asChild>
47
- <Button variant="outline">Cancel</Button>
48
- </SheetClose>
49
- <Button>Save</Button>
50
- </SheetFooter>
51
- </SheetContent>
52
- </Sheet>
53
- );
54
- };
55
-
56
- export const Right = () => (
57
- <Sheet>
58
- <SheetTrigger asChild>
59
- <Button variant="outline">Open Right</Button>
60
- </SheetTrigger>
61
- <SheetContent side="right">
62
- <SheetHeader>
63
- <SheetTitle>Edit Profile</SheetTitle>
64
- <SheetDescription>
65
- Make changes to your profile here.
66
- </SheetDescription>
67
- </SheetHeader>
68
- <div className="space-y-4 py-4">
69
- <div className="space-y-2">
70
- <Label htmlFor="name">Name</Label>
71
- <Input id="name" defaultValue="John Doe" />
72
- </div>
73
- <div className="space-y-2">
74
- <Label htmlFor="email">Email</Label>
75
- <Input id="email" defaultValue="john@example.com" />
76
- </div>
77
- </div>
78
- <SheetFooter>
79
- <SheetClose asChild>
80
- <Button variant="outline">Cancel</Button>
81
- </SheetClose>
82
- <Button>Save changes</Button>
83
- </SheetFooter>
84
- </SheetContent>
85
- </Sheet>
86
- );
87
-
88
- export const Left = () => (
89
- <Sheet>
90
- <SheetTrigger asChild>
91
- <Button variant="outline">Open Left</Button>
92
- </SheetTrigger>
93
- <SheetContent side="left">
94
- <SheetHeader>
95
- <SheetTitle>Navigation</SheetTitle>
96
- </SheetHeader>
97
- <nav className="flex flex-col gap-2 py-4">
98
- <Button variant="ghost" className="justify-start">Dashboard</Button>
99
- <Button variant="ghost" className="justify-start">Projects</Button>
100
- <Button variant="ghost" className="justify-start">Settings</Button>
101
- <Button variant="ghost" className="justify-start">Help</Button>
102
- </nav>
103
- </SheetContent>
104
- </Sheet>
105
- );
106
-
107
- export const Bottom = () => (
108
- <Sheet>
109
- <SheetTrigger asChild>
110
- <Button variant="outline">Open Bottom</Button>
111
- </SheetTrigger>
112
- <SheetContent side="bottom">
113
- <SheetHeader>
114
- <SheetTitle>Quick Actions</SheetTitle>
115
- <SheetDescription>
116
- Choose an action to perform.
117
- </SheetDescription>
118
- </SheetHeader>
119
- <div className="flex gap-2 py-4">
120
- <Button className="flex-1">Share</Button>
121
- <Button className="flex-1" variant="outline">Copy Link</Button>
122
- <Button className="flex-1" variant="destructive">Delete</Button>
123
- </div>
124
- </SheetContent>
125
- </Sheet>
126
- );
127
-
128
- export const Top = () => (
129
- <Sheet>
130
- <SheetTrigger asChild>
131
- <Button variant="outline">Open Top</Button>
132
- </SheetTrigger>
133
- <SheetContent side="top">
134
- <SheetHeader>
135
- <SheetTitle>Notification</SheetTitle>
136
- <SheetDescription>
137
- You have new updates available.
138
- </SheetDescription>
139
- </SheetHeader>
140
- <div className="flex gap-2 py-4">
141
- <Button>Update Now</Button>
142
- <SheetClose asChild>
143
- <Button variant="outline">Later</Button>
144
- </SheetClose>
145
- </div>
146
- </SheetContent>
147
- </Sheet>
148
- );
@@ -1,139 +0,0 @@
1
- import { defineStory, useSelect } from '@djangocfg/playground';
2
- import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '.';
3
- import { Button } from '../../forms/button';
4
- import { Plus, Settings, HelpCircle } from 'lucide-react';
5
-
6
- export default defineStory({
7
- title: 'Core/Tooltip',
8
- component: Tooltip,
9
- description: 'Tooltip for showing additional information on hover.',
10
- });
11
-
12
- export const Interactive = () => {
13
- const [side] = useSelect('side', {
14
- options: ['top', 'right', 'bottom', 'left'] as const,
15
- defaultValue: 'top',
16
- label: 'Side',
17
- description: 'Tooltip position',
18
- });
19
-
20
- return (
21
- <div className="flex justify-center p-20">
22
- <TooltipProvider>
23
- <Tooltip>
24
- <TooltipTrigger asChild>
25
- <Button variant="outline">Hover me</Button>
26
- </TooltipTrigger>
27
- <TooltipContent side={side}>
28
- <p>This is a tooltip</p>
29
- </TooltipContent>
30
- </Tooltip>
31
- </TooltipProvider>
32
- </div>
33
- );
34
- };
35
-
36
- export const Default = () => (
37
- <TooltipProvider>
38
- <Tooltip>
39
- <TooltipTrigger asChild>
40
- <Button variant="outline">Hover me</Button>
41
- </TooltipTrigger>
42
- <TooltipContent>
43
- <p>Add to library</p>
44
- </TooltipContent>
45
- </Tooltip>
46
- </TooltipProvider>
47
- );
48
-
49
- export const Positions = () => (
50
- <TooltipProvider>
51
- <div className="flex gap-4 p-10">
52
- <Tooltip>
53
- <TooltipTrigger asChild>
54
- <Button variant="outline">Top</Button>
55
- </TooltipTrigger>
56
- <TooltipContent side="top">
57
- <p>Top tooltip</p>
58
- </TooltipContent>
59
- </Tooltip>
60
- <Tooltip>
61
- <TooltipTrigger asChild>
62
- <Button variant="outline">Right</Button>
63
- </TooltipTrigger>
64
- <TooltipContent side="right">
65
- <p>Right tooltip</p>
66
- </TooltipContent>
67
- </Tooltip>
68
- <Tooltip>
69
- <TooltipTrigger asChild>
70
- <Button variant="outline">Bottom</Button>
71
- </TooltipTrigger>
72
- <TooltipContent side="bottom">
73
- <p>Bottom tooltip</p>
74
- </TooltipContent>
75
- </Tooltip>
76
- <Tooltip>
77
- <TooltipTrigger asChild>
78
- <Button variant="outline">Left</Button>
79
- </TooltipTrigger>
80
- <TooltipContent side="left">
81
- <p>Left tooltip</p>
82
- </TooltipContent>
83
- </Tooltip>
84
- </div>
85
- </TooltipProvider>
86
- );
87
-
88
- export const WithIcons = () => (
89
- <TooltipProvider>
90
- <div className="flex gap-2">
91
- <Tooltip>
92
- <TooltipTrigger asChild>
93
- <Button size="icon" variant="outline">
94
- <Plus className="h-4 w-4" />
95
- </Button>
96
- </TooltipTrigger>
97
- <TooltipContent>
98
- <p>Add new item</p>
99
- </TooltipContent>
100
- </Tooltip>
101
- <Tooltip>
102
- <TooltipTrigger asChild>
103
- <Button size="icon" variant="outline">
104
- <Settings className="h-4 w-4" />
105
- </Button>
106
- </TooltipTrigger>
107
- <TooltipContent>
108
- <p>Settings</p>
109
- </TooltipContent>
110
- </Tooltip>
111
- <Tooltip>
112
- <TooltipTrigger asChild>
113
- <Button size="icon" variant="outline">
114
- <HelpCircle className="h-4 w-4" />
115
- </Button>
116
- </TooltipTrigger>
117
- <TooltipContent>
118
- <p>Help & Support</p>
119
- </TooltipContent>
120
- </Tooltip>
121
- </div>
122
- </TooltipProvider>
123
- );
124
-
125
- export const WithShortcut = () => (
126
- <TooltipProvider>
127
- <Tooltip>
128
- <TooltipTrigger asChild>
129
- <Button variant="outline">Save</Button>
130
- </TooltipTrigger>
131
- <TooltipContent className="flex items-center gap-2">
132
- <span>Save document</span>
133
- <kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground">
134
- <span className="text-xs">⌘</span>S
135
- </kbd>
136
- </TooltipContent>
137
- </Tooltip>
138
- </TooltipProvider>
139
- );