@syscore/ui-library 1.1.10 → 1.1.11

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 (100) hide show
  1. package/client/App.tsx +47 -0
  2. package/client/components/icons/ConceptIcons.tsx +667 -0
  3. package/client/components/icons/NavAccount.tsx +31 -0
  4. package/client/components/icons/NavBullet.tsx +19 -0
  5. package/client/components/icons/NavLogo.tsx +36 -0
  6. package/client/components/icons/ProviderBadges.tsx +295 -0
  7. package/client/components/icons/ProviderSeals.tsx +319 -0
  8. package/client/components/icons/SealHealthSafetyRating.tsx +65 -0
  9. package/client/components/icons/SealIwbiMember.tsx +86 -0
  10. package/client/components/icons/SealWell.tsx +84 -0
  11. package/client/components/icons/SealWellCertification.tsx +138 -0
  12. package/client/components/icons/SealWellCommunity.tsx +122 -0
  13. package/client/components/icons/SealWellResidence.tsx +122 -0
  14. package/client/components/icons/SealWorksWithWell.tsx +140 -0
  15. package/client/components/icons/UtilityAccordion.tsx +21 -0
  16. package/client/components/icons/UtilityChevronDown.tsx +36 -0
  17. package/client/components/icons/UtilityClassification.tsx +45 -0
  18. package/client/components/icons/UtilityClose.tsx +41 -0
  19. package/client/components/icons/UtilityDrag.tsx +69 -0
  20. package/client/components/icons/UtilityEdit.tsx +42 -0
  21. package/client/components/icons/UtilityOptions.tsx +45 -0
  22. package/client/components/icons/UtilityPortfolio.tsx +87 -0
  23. package/client/components/icons/UtilityReset.tsx +41 -0
  24. package/client/components/icons/UtilityScoring.tsx +43 -0
  25. package/client/components/icons/UtilitySearch.tsx +38 -0
  26. package/client/components/icons/UtilitySort.tsx +52 -0
  27. package/client/components/icons/UtilityText.tsx +34 -0
  28. package/client/components/icons/WaterMarkWWWProducts.tsx +26 -0
  29. package/client/components/icons/WaterMarkWellProjects.tsx +30 -0
  30. package/client/components/icons/WatermarkMemberOrg.tsx +59 -0
  31. package/client/components/icons/WellSeal.tsx +79 -0
  32. package/client/components/icons/X.tsx +35 -0
  33. package/client/hooks/UseTabs.tsx +35 -0
  34. package/client/hooks/use-mobile.tsx +21 -0
  35. package/client/hooks/use-segmented-control.ts +42 -0
  36. package/client/hooks/use-toast.ts +188 -0
  37. package/client/pages/Index.tsx +88 -0
  38. package/client/pages/NotFound.tsx +29 -0
  39. package/client/ui/Accordion/Accordion.stories.tsx +74 -0
  40. package/client/ui/Alert/Alert.stories.tsx +82 -0
  41. package/client/ui/AlertDialog/AlertDialog.stories.tsx +106 -0
  42. package/client/ui/AspectRatio.stories.tsx +78 -0
  43. package/client/ui/Avatar/Avatar.stories.tsx +94 -0
  44. package/client/ui/Badge/Badge.stories.tsx +60 -0
  45. package/client/ui/Breadcrumb/Breadcrumb.stories.tsx +97 -0
  46. package/client/ui/Button.stories.tsx +429 -0
  47. package/client/ui/Calendar/Calendar.stories.tsx +99 -0
  48. package/client/ui/Card.stories.tsx +84 -0
  49. package/client/ui/Carousel/Carousel.stories.tsx +85 -0
  50. package/client/ui/Chart/Chart.stories.tsx +58 -0
  51. package/client/ui/Checkbox/Checkbox.stories.tsx +112 -0
  52. package/client/ui/Collapsible/Collapsible.stories.tsx +101 -0
  53. package/client/ui/Colors.stories.tsx +1041 -0
  54. package/client/ui/Command/Command.stories.tsx +97 -0
  55. package/client/ui/ContextMenu/ContextMenu.stories.tsx +74 -0
  56. package/client/ui/Dialog.stories.tsx +69 -0
  57. package/client/ui/Drawer/Drawer.stories.tsx +87 -0
  58. package/client/ui/DropdownMenu/DropdownMenu.stories.tsx +139 -0
  59. package/client/ui/Form/Form.stories.tsx +74 -0
  60. package/client/ui/HoverCard/HoverCard.stories.tsx +94 -0
  61. package/client/ui/Icons.stories.tsx +328 -0
  62. package/client/ui/Input/Input.stories.tsx +69 -0
  63. package/client/ui/InputOTP/InputOTP.stories.tsx +85 -0
  64. package/client/ui/Label.stories.tsx +66 -0
  65. package/client/ui/Menubar/Menubar.stories.tsx +88 -0
  66. package/client/ui/Navigation.stories.tsx +57 -0
  67. package/client/ui/NavigationMenu/NavigationMenu.stories.tsx +106 -0
  68. package/client/ui/Pagination/Pagination.stories.tsx +115 -0
  69. package/client/ui/Popover/Popover.stories.tsx +99 -0
  70. package/client/ui/Progress/Progress.stories.tsx +63 -0
  71. package/client/ui/RadioGroup/RadioGroup.stories.tsx +110 -0
  72. package/client/ui/Resizable/Resizable.stories.tsx +88 -0
  73. package/client/ui/ScrollArea/ScrollArea.stories.tsx +64 -0
  74. package/client/ui/SearchField.stories.tsx +63 -0
  75. package/client/ui/Select/Select.stories.tsx +111 -0
  76. package/client/ui/Separator/Separator.stories.tsx +67 -0
  77. package/client/ui/Sheet/Sheet.stories.tsx +138 -0
  78. package/client/ui/Sidebar/Sidebar.stories.tsx +92 -0
  79. package/client/ui/Skeleton/Skeleton.stories.tsx +65 -0
  80. package/client/ui/Slider/Slider.stories.tsx +101 -0
  81. package/client/ui/Sonner/Sonner.stories.tsx +48 -0
  82. package/client/ui/StrategyTable.stories.tsx +138 -0
  83. package/client/ui/Switch/Switch.stories.tsx +96 -0
  84. package/client/ui/Table/Table.stories.tsx +135 -0
  85. package/client/ui/Tabs.stories.tsx +33 -0
  86. package/client/ui/Tag.stories.tsx +190 -0
  87. package/client/ui/Textarea/Textarea.stories.tsx +56 -0
  88. package/client/ui/Toast/Toast.stories.tsx +76 -0
  89. package/client/ui/Toaster/Toaster.stories.tsx +52 -0
  90. package/client/ui/Toggle.stories.tsx +248 -0
  91. package/client/ui/ToggleGroup/ToggleGroup.stories.tsx +88 -0
  92. package/client/ui/Tooltip.stories.tsx +72 -0
  93. package/client/ui/Typography.stories.tsx +421 -0
  94. package/client/ui/WELLDashboard/WELLDashboard.stories.tsx +115 -0
  95. package/client/ui/WELLDashboard/index.tsx +221 -0
  96. package/client/vite-env.d.ts +1 -0
  97. package/dist/ui/index.cjs.js +1 -1
  98. package/dist/ui/index.d.ts +1 -0
  99. package/dist/ui/index.es.js +163 -1
  100. package/package.json +2 -1
@@ -0,0 +1,97 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import {
3
+ Command,
4
+ CommandDialog,
5
+ CommandEmpty,
6
+ CommandGroup,
7
+ CommandInput,
8
+ CommandItem,
9
+ CommandList,
10
+ CommandSeparator,
11
+ } from "../../components/ui/command";
12
+ import { useState } from "react";
13
+ import { Search, FileText, Settings, Users } from "lucide-react";
14
+
15
+ const meta = {
16
+ title: "UI/Command",
17
+ component: Command,
18
+ tags: ["autodocs"],
19
+ parameters: {
20
+ layout: "padded",
21
+ },
22
+ } satisfies Meta<typeof Command>;
23
+
24
+ export default meta;
25
+
26
+ type Story = StoryObj<typeof meta>;
27
+
28
+ export const Default: Story = {
29
+ render: () => (
30
+ <Command className="rounded-lg border w-full max-w-sm">
31
+ <CommandInput placeholder="Type a command or search..." />
32
+ <CommandList>
33
+ <CommandEmpty>No results found.</CommandEmpty>
34
+ <CommandGroup heading="Suggestions">
35
+ <CommandItem>
36
+ <Search className="mr-2 h-4 w-4" />
37
+ <span>Search</span>
38
+ </CommandItem>
39
+ <CommandItem>
40
+ <FileText className="mr-2 h-4 w-4" />
41
+ <span>Create New</span>
42
+ </CommandItem>
43
+ </CommandGroup>
44
+ <CommandSeparator />
45
+ <CommandGroup heading="Settings">
46
+ <CommandItem>
47
+ <Settings className="mr-2 h-4 w-4" />
48
+ <span>Preferences</span>
49
+ </CommandItem>
50
+ <CommandItem>
51
+ <Users className="mr-2 h-4 w-4" />
52
+ <span>Team</span>
53
+ </CommandItem>
54
+ </CommandGroup>
55
+ </CommandList>
56
+ </Command>
57
+ ),
58
+ };
59
+
60
+ export const Dialog: Story = {
61
+ render: () => {
62
+ const [open, setOpen] = useState(false);
63
+ return (
64
+ <>
65
+ <button
66
+ onClick={() => setOpen(true)}
67
+ className="inline-flex items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium ring-offset-background transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"
68
+ >
69
+ Open Command Menu
70
+ </button>
71
+ <CommandDialog open={open} onOpenChange={setOpen}>
72
+ <CommandInput placeholder="Type a command or search..." />
73
+ <CommandList>
74
+ <CommandEmpty>No results found.</CommandEmpty>
75
+ <CommandGroup heading="Actions">
76
+ <CommandItem>
77
+ <Search className="mr-2 h-4 w-4" />
78
+ <span>Search</span>
79
+ </CommandItem>
80
+ <CommandItem>
81
+ <FileText className="mr-2 h-4 w-4" />
82
+ <span>Create Document</span>
83
+ </CommandItem>
84
+ </CommandGroup>
85
+ <CommandSeparator />
86
+ <CommandGroup heading="Settings">
87
+ <CommandItem>
88
+ <Settings className="mr-2 h-4 w-4" />
89
+ <span>Settings</span>
90
+ </CommandItem>
91
+ </CommandGroup>
92
+ </CommandList>
93
+ </CommandDialog>
94
+ </>
95
+ );
96
+ },
97
+ };
@@ -0,0 +1,74 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import {
3
+ ContextMenu,
4
+ ContextMenuTrigger,
5
+ ContextMenuContent,
6
+ ContextMenuItem,
7
+ ContextMenuSeparator,
8
+ ContextMenuCheckboxItem,
9
+ } from "../../components/ui/context-menu";
10
+ import { useState } from "react";
11
+
12
+ type Story = StoryObj;
13
+
14
+ const meta = {
15
+ title: "UI/ContextMenu",
16
+ tags: ["autodocs"],
17
+ parameters: {
18
+ layout: "padded",
19
+ },
20
+ } satisfies Meta;
21
+
22
+ export default meta;
23
+
24
+ export const Default: Story = {
25
+ render: () => (
26
+ <ContextMenu>
27
+ <ContextMenuTrigger className="flex h-40 w-40 items-center justify-center rounded-md border border-dashed text-sm text-gray-600">
28
+ Right click here
29
+ </ContextMenuTrigger>
30
+ <ContextMenuContent>
31
+ <ContextMenuItem>Back</ContextMenuItem>
32
+ <ContextMenuItem>Forward</ContextMenuItem>
33
+ <ContextMenuSeparator />
34
+ <ContextMenuItem>Reload</ContextMenuItem>
35
+ <ContextMenuSeparator />
36
+ <ContextMenuItem>View Page Source</ContextMenuItem>
37
+ </ContextMenuContent>
38
+ </ContextMenu>
39
+ ),
40
+ };
41
+
42
+ export const WithCheckboxes: Story = {
43
+ render: () => {
44
+ const [items, setItems] = useState({
45
+ showImages: true,
46
+ enableJavaScript: true,
47
+ });
48
+ return (
49
+ <ContextMenu>
50
+ <ContextMenuTrigger className="flex h-40 w-40 items-center justify-center rounded-md border border-dashed text-sm text-gray-600">
51
+ Right click here
52
+ </ContextMenuTrigger>
53
+ <ContextMenuContent>
54
+ <ContextMenuCheckboxItem
55
+ checked={items.showImages}
56
+ onCheckedChange={(checked) =>
57
+ setItems({ ...items, showImages: checked })
58
+ }
59
+ >
60
+ Show Images
61
+ </ContextMenuCheckboxItem>
62
+ <ContextMenuCheckboxItem
63
+ checked={items.enableJavaScript}
64
+ onCheckedChange={(checked) =>
65
+ setItems({ ...items, enableJavaScript: checked })
66
+ }
67
+ >
68
+ Enable JavaScript
69
+ </ContextMenuCheckboxItem>
70
+ </ContextMenuContent>
71
+ </ContextMenu>
72
+ );
73
+ },
74
+ };
@@ -0,0 +1,69 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Button } from "@/components/ui/Button";
3
+ import { useState } from "react";
4
+ import {
5
+ Dialog,
6
+ DialogContent,
7
+ DialogDescription,
8
+ DialogHeader,
9
+ DialogTitle,
10
+ DialogTrigger,
11
+ } from "@/components/ui/dialog";
12
+ import { cn } from "@/lib/utils";
13
+
14
+ const meta = {
15
+ title: "Review/Dialog",
16
+ component: Dialog,
17
+ tags: ["autodocs"],
18
+ parameters: {
19
+ layout: "centered",
20
+ },
21
+ } satisfies Meta<typeof Dialog>;
22
+
23
+ export default meta;
24
+
25
+ type Story = StoryObj<typeof meta>;
26
+
27
+ export const Default: Story = {
28
+ render: () => {
29
+ const [open, setOpen] = useState(false);
30
+ return (
31
+ <>
32
+ <Dialog open={open}>
33
+ <DialogTrigger asChild>
34
+ <Button
35
+ size="large"
36
+ variant="general-primary"
37
+ onClick={() => setOpen(true)}
38
+ >
39
+ Open Dialog
40
+ </Button>
41
+ </DialogTrigger>
42
+ <DialogContent className="sm:min-w-[297px]" showCloseButton={false}>
43
+ <DialogHeader>
44
+ <DialogTitle className="text-gray-800 text-center mb-8 h-8 justify-center items-center flex">
45
+ Are you sure?
46
+ </DialogTitle>
47
+ </DialogHeader>
48
+ <div className="flex gap-4 justify-center items-center">
49
+ <Button
50
+ size="utility"
51
+ variant="general-secondary"
52
+ onClick={() => setOpen(false)}
53
+ >
54
+ Nevermind
55
+ </Button>
56
+ <Button
57
+ size="utility"
58
+ variant="general-primary"
59
+ onClick={() => setOpen(false)}
60
+ >
61
+ Yes
62
+ </Button>
63
+ </div>
64
+ </DialogContent>
65
+ </Dialog>
66
+ </>
67
+ );
68
+ },
69
+ };
@@ -0,0 +1,87 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import {
3
+ Drawer,
4
+ DrawerTrigger,
5
+ DrawerContent,
6
+ DrawerHeader,
7
+ DrawerTitle,
8
+ DrawerDescription,
9
+ DrawerFooter,
10
+ DrawerClose,
11
+ } from "../../components/ui/drawer";
12
+ import { Button } from "../../components/ui/button";
13
+ import { useState } from "react";
14
+
15
+ const meta = {
16
+ title: "UI/Drawer",
17
+ component: Drawer,
18
+ tags: ["autodocs"],
19
+ parameters: {
20
+ layout: "centered",
21
+ },
22
+ } satisfies Meta<typeof Drawer>;
23
+
24
+ export default meta;
25
+
26
+ type Story = StoryObj<typeof meta>;
27
+
28
+ export const Default: Story = {
29
+ render: () => {
30
+ const [open, setOpen] = useState(false);
31
+ return (
32
+ <Drawer open={open} onOpenChange={setOpen}>
33
+ <DrawerTrigger asChild>
34
+ <Button>Open Drawer</Button>
35
+ </DrawerTrigger>
36
+ <DrawerContent>
37
+ <DrawerHeader>
38
+ <DrawerTitle>Drawer Title</DrawerTitle>
39
+ <DrawerDescription>This is a drawer component.</DrawerDescription>
40
+ </DrawerHeader>
41
+ <div className="p-4">
42
+ <p className="text-sm">Drawer content goes here.</p>
43
+ </div>
44
+ <DrawerFooter>
45
+ <Button onClick={() => setOpen(false)}>Close</Button>
46
+ </DrawerFooter>
47
+ </DrawerContent>
48
+ </Drawer>
49
+ );
50
+ },
51
+ };
52
+
53
+ export const Bottom: Story = {
54
+ render: () => {
55
+ const [open, setOpen] = useState(false);
56
+ return (
57
+ <Drawer open={open} onOpenChange={setOpen}>
58
+ <DrawerTrigger asChild>
59
+ <Button>Open Bottom Drawer</Button>
60
+ </DrawerTrigger>
61
+ <DrawerContent>
62
+ <div className="mx-auto w-full max-w-sm">
63
+ <DrawerHeader>
64
+ <DrawerTitle>Share</DrawerTitle>
65
+ </DrawerHeader>
66
+ <div className="p-4 space-y-2">
67
+ <button className="w-full px-4 py-2 text-left text-sm hover:bg-gray-100 rounded">
68
+ Copy Link
69
+ </button>
70
+ <button className="w-full px-4 py-2 text-left text-sm hover:bg-gray-100 rounded">
71
+ Share to Twitter
72
+ </button>
73
+ <button className="w-full px-4 py-2 text-left text-sm hover:bg-gray-100 rounded">
74
+ Share to Facebook
75
+ </button>
76
+ </div>
77
+ <DrawerFooter>
78
+ <DrawerClose asChild>
79
+ <Button variant="outline">Cancel</Button>
80
+ </DrawerClose>
81
+ </DrawerFooter>
82
+ </div>
83
+ </DrawerContent>
84
+ </Drawer>
85
+ );
86
+ },
87
+ };
@@ -0,0 +1,139 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import {
3
+ DropdownMenu,
4
+ DropdownMenuTrigger,
5
+ DropdownMenuContent,
6
+ DropdownMenuItem,
7
+ DropdownMenuSeparator,
8
+ DropdownMenuCheckboxItem,
9
+ DropdownMenuRadioGroup,
10
+ DropdownMenuRadioItem,
11
+ } from "../../components/ui/dropdown-menu";
12
+ import { Button } from "../../components/ui/button";
13
+ import { ChevronDown } from "lucide-react";
14
+ import { useState } from "react";
15
+
16
+ const meta = {
17
+ title: "UI/DropdownMenu",
18
+ component: DropdownMenu,
19
+ tags: ["autodocs"],
20
+ parameters: {
21
+ layout: "padded",
22
+ },
23
+ } satisfies Meta<typeof DropdownMenu>;
24
+
25
+ export default meta;
26
+
27
+ type Story = StoryObj<typeof meta>;
28
+
29
+ export const Default: Story = {
30
+ render: () => (
31
+ <DropdownMenu>
32
+ <DropdownMenuTrigger asChild>
33
+ <Button variant="outline">
34
+ Open Menu
35
+ <ChevronDown className="ml-2 h-4 w-4" />
36
+ </Button>
37
+ </DropdownMenuTrigger>
38
+ <DropdownMenuContent align="end" className="w-56">
39
+ <DropdownMenuItem>Profile</DropdownMenuItem>
40
+ <DropdownMenuItem>Settings</DropdownMenuItem>
41
+ <DropdownMenuSeparator />
42
+ <DropdownMenuItem>Sign Out</DropdownMenuItem>
43
+ </DropdownMenuContent>
44
+ </DropdownMenu>
45
+ ),
46
+ };
47
+
48
+ export const WithCheckboxes: Story = {
49
+ render: () => {
50
+ const [items, setItems] = useState({
51
+ bold: false,
52
+ italic: false,
53
+ underline: false,
54
+ });
55
+ return (
56
+ <DropdownMenu>
57
+ <DropdownMenuTrigger asChild>
58
+ <Button variant="outline">Text Options</Button>
59
+ </DropdownMenuTrigger>
60
+ <DropdownMenuContent className="w-56">
61
+ <DropdownMenuCheckboxItem
62
+ checked={items.bold}
63
+ onCheckedChange={(checked) => setItems({ ...items, bold: checked })}
64
+ >
65
+ Bold
66
+ </DropdownMenuCheckboxItem>
67
+ <DropdownMenuCheckboxItem
68
+ checked={items.italic}
69
+ onCheckedChange={(checked) =>
70
+ setItems({ ...items, italic: checked })
71
+ }
72
+ >
73
+ Italic
74
+ </DropdownMenuCheckboxItem>
75
+ <DropdownMenuCheckboxItem
76
+ checked={items.underline}
77
+ onCheckedChange={(checked) =>
78
+ setItems({ ...items, underline: checked })
79
+ }
80
+ >
81
+ Underline
82
+ </DropdownMenuCheckboxItem>
83
+ </DropdownMenuContent>
84
+ </DropdownMenu>
85
+ );
86
+ },
87
+ };
88
+
89
+ export const WithRadio: Story = {
90
+ render: () => {
91
+ const [theme, setTheme] = useState("light");
92
+ return (
93
+ <DropdownMenu>
94
+ <DropdownMenuTrigger asChild>
95
+ <Button variant="outline">Theme</Button>
96
+ </DropdownMenuTrigger>
97
+ <DropdownMenuContent className="w-56">
98
+ <DropdownMenuRadioGroup value={theme} onValueChange={setTheme}>
99
+ <DropdownMenuRadioItem value="light">Light</DropdownMenuRadioItem>
100
+ <DropdownMenuRadioItem value="dark">Dark</DropdownMenuRadioItem>
101
+ <DropdownMenuRadioItem value="system">System</DropdownMenuRadioItem>
102
+ </DropdownMenuRadioGroup>
103
+ </DropdownMenuContent>
104
+ </DropdownMenu>
105
+ );
106
+ },
107
+ };
108
+
109
+ export const Complex: Story = {
110
+ render: () => {
111
+ const [showNotifications, setShowNotifications] = useState(true);
112
+ const [theme, setTheme] = useState("light");
113
+ return (
114
+ <DropdownMenu>
115
+ <DropdownMenuTrigger asChild>
116
+ <Button variant="outline">Menu</Button>
117
+ </DropdownMenuTrigger>
118
+ <DropdownMenuContent className="w-56">
119
+ <DropdownMenuItem>Profile</DropdownMenuItem>
120
+ <DropdownMenuItem>Settings</DropdownMenuItem>
121
+ <DropdownMenuSeparator />
122
+ <DropdownMenuCheckboxItem
123
+ checked={showNotifications}
124
+ onCheckedChange={setShowNotifications}
125
+ >
126
+ Show Notifications
127
+ </DropdownMenuCheckboxItem>
128
+ <DropdownMenuSeparator />
129
+ <DropdownMenuRadioGroup value={theme} onValueChange={setTheme}>
130
+ <DropdownMenuRadioItem value="light">Light</DropdownMenuRadioItem>
131
+ <DropdownMenuRadioItem value="dark">Dark</DropdownMenuRadioItem>
132
+ </DropdownMenuRadioGroup>
133
+ <DropdownMenuSeparator />
134
+ <DropdownMenuItem className="text-red-600">Sign Out</DropdownMenuItem>
135
+ </DropdownMenuContent>
136
+ </DropdownMenu>
137
+ );
138
+ },
139
+ };
@@ -0,0 +1,74 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+
3
+ type Story = StoryObj;
4
+
5
+ const meta = {
6
+ title: "UI/Form",
7
+ tags: ["autodocs"],
8
+ parameters: {
9
+ layout: "padded",
10
+ },
11
+ } satisfies Meta;
12
+
13
+ export default meta;
14
+
15
+ export const Default: Story = {
16
+ render: () => (
17
+ <form className="w-full max-w-md space-y-6">
18
+ <div className="space-y-2">
19
+ <label className="text-sm font-medium">Name</label>
20
+ <input
21
+ type="text"
22
+ placeholder="Enter your name"
23
+ className="w-full px-3 py-2 border rounded-md text-sm focus:outline-hidden focus:ring-2 focus:ring-blue-500"
24
+ />
25
+ </div>
26
+ <div className="space-y-2">
27
+ <label className="text-sm font-medium">Email</label>
28
+ <input
29
+ type="email"
30
+ placeholder="Enter your email"
31
+ className="w-full px-3 py-2 border rounded-md text-sm focus:outline-hidden focus:ring-2 focus:ring-blue-500"
32
+ />
33
+ </div>
34
+ <div className="space-y-2">
35
+ <label className="text-sm font-medium">Message</label>
36
+ <textarea
37
+ placeholder="Enter your message"
38
+ className="w-full px-3 py-2 border rounded-md text-sm focus:outline-hidden focus:ring-2 focus:ring-blue-500"
39
+ />
40
+ </div>
41
+ <button className="w-full bg-blue-600 text-white py-2 rounded-md text-sm font-medium hover:bg-blue-700">
42
+ Submit
43
+ </button>
44
+ </form>
45
+ ),
46
+ };
47
+
48
+ export const WithValidation: Story = {
49
+ render: () => (
50
+ <form className="w-full max-w-md space-y-6">
51
+ <div className="space-y-2">
52
+ <label className="text-sm font-medium">Username *</label>
53
+ <input
54
+ type="text"
55
+ placeholder="Choose a username"
56
+ className="w-full px-3 py-2 border border-red-500 rounded-md text-sm focus:outline-hidden focus:ring-2 focus:ring-red-500"
57
+ />
58
+ <p className="text-sm text-red-600">Username is required</p>
59
+ </div>
60
+ <div className="space-y-2">
61
+ <label className="text-sm font-medium">Email *</label>
62
+ <input
63
+ type="email"
64
+ placeholder="Enter a valid email"
65
+ className="w-full px-3 py-2 border border-green-500 rounded-md text-sm focus:outline-hidden focus:ring-2 focus:ring-green-500"
66
+ />
67
+ <p className="text-sm text-green-600">✓ Email looks good</p>
68
+ </div>
69
+ <button className="w-full bg-blue-600 text-white py-2 rounded-md text-sm font-medium hover:bg-blue-700">
70
+ Create Account
71
+ </button>
72
+ </form>
73
+ ),
74
+ };
@@ -0,0 +1,94 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import {
3
+ HoverCard,
4
+ HoverCardTrigger,
5
+ HoverCardContent,
6
+ } from "../../components/ui/hover-card";
7
+
8
+ const meta = {
9
+ title: "UI/HoverCard",
10
+ component: HoverCard,
11
+ tags: ["autodocs"],
12
+ parameters: {
13
+ layout: "padded",
14
+ },
15
+ } satisfies Meta<typeof HoverCard>;
16
+
17
+ export default meta;
18
+
19
+ type Story = StoryObj<typeof meta>;
20
+
21
+ export const Default: Story = {
22
+ render: () => (
23
+ <HoverCard>
24
+ <HoverCardTrigger>Hover here</HoverCardTrigger>
25
+ <HoverCardContent>
26
+ <div className="space-y-2">
27
+ <h4 className="font-semibold">Hover Card</h4>
28
+ <p className="text-sm">This content appears when you hover.</p>
29
+ </div>
30
+ </HoverCardContent>
31
+ </HoverCard>
32
+ ),
33
+ };
34
+
35
+ export const Profile: Story = {
36
+ render: () => (
37
+ <HoverCard>
38
+ <HoverCardTrigger className="cursor-pointer underline">
39
+ @username
40
+ </HoverCardTrigger>
41
+ <HoverCardContent className="w-80">
42
+ <div className="space-y-4">
43
+ <div className="flex items-start gap-4">
44
+ <div className="w-12 h-12 rounded-full bg-gray-200"></div>
45
+ <div>
46
+ <h4 className="font-semibold">John Doe</h4>
47
+ <p className="text-sm text-gray-600">@username</p>
48
+ </div>
49
+ </div>
50
+ <p className="text-sm text-gray-600">
51
+ A passionate developer building amazing things.
52
+ </p>
53
+ <div className="flex gap-4 text-sm">
54
+ <span>Following: 500</span>
55
+ <span>Followers: 1.2K</span>
56
+ </div>
57
+ </div>
58
+ </HoverCardContent>
59
+ </HoverCard>
60
+ ),
61
+ };
62
+
63
+ export const Multiple: Story = {
64
+ render: () => (
65
+ <div className="flex gap-8">
66
+ <HoverCard>
67
+ <HoverCardTrigger className="cursor-pointer underline">
68
+ Feature 1
69
+ </HoverCardTrigger>
70
+ <HoverCardContent>
71
+ <p className="text-sm">Details about feature 1</p>
72
+ </HoverCardContent>
73
+ </HoverCard>
74
+
75
+ <HoverCard>
76
+ <HoverCardTrigger className="cursor-pointer underline">
77
+ Feature 2
78
+ </HoverCardTrigger>
79
+ <HoverCardContent>
80
+ <p className="text-sm">Details about feature 2</p>
81
+ </HoverCardContent>
82
+ </HoverCard>
83
+
84
+ <HoverCard>
85
+ <HoverCardTrigger className="cursor-pointer underline">
86
+ Feature 3
87
+ </HoverCardTrigger>
88
+ <HoverCardContent>
89
+ <p className="text-sm">Details about feature 3</p>
90
+ </HoverCardContent>
91
+ </HoverCard>
92
+ </div>
93
+ ),
94
+ };