@a2v2ai/uikit 0.0.36 → 0.0.38

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 (185) hide show
  1. package/Alert/Alert.stories.tsx +121 -0
  2. package/Alert/Alert.tsx +71 -0
  3. package/AlertDialog/AlertDialog.stories.tsx +665 -0
  4. package/AlertDialog/AlertDialog.tsx +241 -0
  5. package/Avatar/Avatar.stories.tsx +128 -0
  6. package/Avatar/Avatar.tsx +71 -0
  7. package/Badge/Badge.stories.tsx +76 -0
  8. package/Badge/Badge.tsx +39 -0
  9. package/Breadcrumb/Breadcrumb.stories.tsx +231 -0
  10. package/Breadcrumb/Breadcrumb.tsx +114 -0
  11. package/Button/Button.stories.tsx +684 -0
  12. package/Button/Button.tsx +107 -0
  13. package/Calendar/Calendar.stories.tsx +291 -0
  14. package/Calendar/Calendar.tsx +246 -0
  15. package/Card/Card.stories.tsx +136 -0
  16. package/Card/Card.tsx +96 -0
  17. package/Carousel/Carousel.stories.tsx +256 -0
  18. package/Carousel/Carousel.tsx +301 -0
  19. package/ChatBubble/ChatBubble.stories.tsx +339 -0
  20. package/ChatBubble/ChatBubble.tsx +179 -0
  21. package/Checkbox/Checkbox.stories.tsx +137 -0
  22. package/Checkbox/Checkbox.tsx +53 -0
  23. package/DataTable/DataTable.stories.tsx +400 -0
  24. package/DataTable/DataTable.tsx +207 -0
  25. package/Drawer/Drawer.stories.tsx +721 -0
  26. package/Drawer/Drawer.tsx +201 -0
  27. package/DropdownMenu/DropdownMenu.stories.tsx +251 -0
  28. package/DropdownMenu/DropdownMenu.tsx +199 -0
  29. package/ErrorMessage/ErrorMessage.stories.tsx +159 -0
  30. package/ErrorMessage/ErrorMessage.tsx +55 -0
  31. package/Flex/Flex.stories.tsx +390 -0
  32. package/Flex/Flex.tsx +102 -0
  33. package/IconButton/IconButton.stories.tsx +566 -0
  34. package/IconButton/IconButton.tsx +95 -0
  35. package/Input/Input.stories.tsx +566 -0
  36. package/Input/Input.tsx +168 -0
  37. package/InputOTP/InputOTP.stories.tsx +246 -0
  38. package/InputOTP/InputOTP.tsx +127 -0
  39. package/Label/Label.stories.tsx +110 -0
  40. package/Label/Label.tsx +44 -0
  41. package/Loader/Loader.stories.tsx +170 -0
  42. package/Loader/Loader.tsx +62 -0
  43. package/Menubar/Menubar.stories.tsx +382 -0
  44. package/Menubar/Menubar.tsx +274 -0
  45. package/Menubar/index.ts +18 -0
  46. package/Pagination/Pagination.stories.tsx +196 -0
  47. package/Pagination/Pagination.tsx +122 -0
  48. package/Popover/Popover.stories.tsx +133 -0
  49. package/Popover/Popover.tsx +31 -0
  50. package/Progress/Progress.stories.tsx +146 -0
  51. package/Progress/Progress.tsx +67 -0
  52. package/RadioGroup/RadioGroup.stories.tsx +159 -0
  53. package/RadioGroup/RadioGroup.tsx +68 -0
  54. package/ScrollArea/ScrollArea.stories.tsx +136 -0
  55. package/ScrollArea/ScrollArea.tsx +46 -0
  56. package/Select/Select.stories.tsx +378 -0
  57. package/Select/Select.tsx +230 -0
  58. package/Separator/Separator.stories.tsx +110 -0
  59. package/Separator/Separator.tsx +29 -0
  60. package/Sidebar/Sidebar.stories.tsx +340 -0
  61. package/Sidebar/Sidebar.tsx +414 -0
  62. package/Sidebar/index.ts +28 -0
  63. package/Skeleton/Skeleton.stories.tsx +117 -0
  64. package/Skeleton/Skeleton.tsx +16 -0
  65. package/Slider/Slider.stories.tsx +216 -0
  66. package/Slider/Slider.tsx +29 -0
  67. package/Spinner/Spinner.stories.tsx +210 -0
  68. package/Spinner/Spinner.tsx +78 -0
  69. package/Switch/Switch.stories.tsx +146 -0
  70. package/Switch/Switch.tsx +59 -0
  71. package/Table/Table.stories.tsx +510 -0
  72. package/Table/Table.tsx +114 -0
  73. package/Tabs/Tabs.stories.tsx +197 -0
  74. package/Tabs/Tabs.tsx +74 -0
  75. package/Textarea/Textarea.stories.tsx +187 -0
  76. package/Textarea/Textarea.tsx +73 -0
  77. package/Toast/Toast.stories.tsx +285 -0
  78. package/Toast/Toast.tsx +59 -0
  79. package/Tooltip/Tooltip.stories.tsx +463 -0
  80. package/Tooltip/Tooltip.tsx +96 -0
  81. package/Typography/Typography.stories.tsx +425 -0
  82. package/Typography/Typography.tsx +106 -0
  83. package/helpers.ts +5 -0
  84. package/{icons.js → icons.ts} +1 -1
  85. package/index.ts +217 -0
  86. package/lib/typography-types.ts +223 -0
  87. package/lib/utils.ts +15 -0
  88. package/package.json +36 -33
  89. package/tsconfig.json +22 -0
  90. package/Alert/Alert.d.ts +0 -13
  91. package/Alert/Alert.js +0 -25
  92. package/AlertDialog/AlertDialog.d.ts +0 -43
  93. package/AlertDialog/AlertDialog.js +0 -71
  94. package/Avatar/Avatar.d.ts +0 -14
  95. package/Avatar/Avatar.js +0 -25
  96. package/Badge/Badge.d.ts +0 -11
  97. package/Badge/Badge.js +0 -23
  98. package/Breadcrumb/Breadcrumb.d.ts +0 -19
  99. package/Breadcrumb/Breadcrumb.js +0 -23
  100. package/Button/Button.d.ts +0 -23
  101. package/Button/Button.js +0 -52
  102. package/Calendar/Calendar.d.ts +0 -20
  103. package/Calendar/Calendar.js +0 -78
  104. package/Card/Card.d.ts +0 -16
  105. package/Card/Card.js +0 -28
  106. package/Carousel/Carousel.d.ts +0 -37
  107. package/Carousel/Carousel.js +0 -132
  108. package/ChatBubble/ChatBubble.d.ts +0 -33
  109. package/ChatBubble/ChatBubble.js +0 -107
  110. package/Checkbox/Checkbox.d.ts +0 -12
  111. package/Checkbox/Checkbox.js +0 -20
  112. package/DataTable/DataTable.d.ts +0 -35
  113. package/DataTable/DataTable.js +0 -51
  114. package/Dialog/Dialog.d.ts +0 -35
  115. package/Dialog/Dialog.js +0 -130
  116. package/Drawer/Drawer.d.ts +0 -33
  117. package/Drawer/Drawer.js +0 -55
  118. package/DropdownMenu/DropdownMenu.d.ts +0 -27
  119. package/DropdownMenu/DropdownMenu.js +0 -35
  120. package/ErrorMessage/ErrorMessage.d.ts +0 -27
  121. package/ErrorMessage/ErrorMessage.js +0 -14
  122. package/Flex/Flex.d.ts +0 -31
  123. package/Flex/Flex.js +0 -64
  124. package/IconButton/IconButton.d.ts +0 -23
  125. package/IconButton/IconButton.js +0 -48
  126. package/Input/Input.d.ts +0 -27
  127. package/Input/Input.js +0 -42
  128. package/InputOTP/InputOTP.d.ts +0 -20
  129. package/InputOTP/InputOTP.js +0 -44
  130. package/Label/Label.d.ts +0 -13
  131. package/Label/Label.js +0 -19
  132. package/Loader/Loader.d.ts +0 -21
  133. package/Loader/Loader.js +0 -30
  134. package/Menubar/Menubar.d.ts +0 -26
  135. package/Menubar/Menubar.js +0 -54
  136. package/Menubar/index.d.ts +0 -1
  137. package/Menubar/index.js +0 -1
  138. package/Pagination/Pagination.d.ts +0 -35
  139. package/Pagination/Pagination.js +0 -37
  140. package/Popover/Popover.d.ts +0 -7
  141. package/Popover/Popover.js +0 -10
  142. package/Progress/Progress.d.ts +0 -17
  143. package/Progress/Progress.js +0 -33
  144. package/RadioGroup/RadioGroup.d.ts +0 -13
  145. package/RadioGroup/RadioGroup.js +0 -26
  146. package/ScrollArea/ScrollArea.d.ts +0 -5
  147. package/ScrollArea/ScrollArea.js +0 -11
  148. package/Select/Select.d.ts +0 -29
  149. package/Select/Select.js +0 -50
  150. package/Separator/Separator.d.ts +0 -4
  151. package/Separator/Separator.js +0 -7
  152. package/Sidebar/Sidebar.d.ts +0 -48
  153. package/Sidebar/Sidebar.js +0 -116
  154. package/Sidebar/index.d.ts +0 -2
  155. package/Sidebar/index.js +0 -1
  156. package/Skeleton/Skeleton.d.ts +0 -4
  157. package/Skeleton/Skeleton.js +0 -7
  158. package/Slider/Slider.d.ts +0 -6
  159. package/Slider/Slider.js +0 -7
  160. package/Spinner/Spinner.d.ts +0 -19
  161. package/Spinner/Spinner.js +0 -31
  162. package/Switch/Switch.d.ts +0 -12
  163. package/Switch/Switch.js +0 -30
  164. package/Table/Table.d.ts +0 -10
  165. package/Table/Table.js +0 -20
  166. package/Tabs/Tabs.d.ts +0 -15
  167. package/Tabs/Tabs.js +0 -24
  168. package/Textarea/Textarea.d.ts +0 -19
  169. package/Textarea/Textarea.js +0 -31
  170. package/Toast/Toast.d.ts +0 -12
  171. package/Toast/Toast.js +0 -25
  172. package/Tooltip/Tooltip.d.ts +0 -17
  173. package/Tooltip/Tooltip.js +0 -29
  174. package/Typography/Typography.d.ts +0 -20
  175. package/Typography/Typography.js +0 -43
  176. package/helpers.d.ts +0 -4
  177. package/helpers.js +0 -5
  178. package/icons.d.ts +0 -1
  179. package/index.d.ts +0 -42
  180. package/index.js +0 -45
  181. package/lib/typography-types.d.ts +0 -4
  182. package/lib/typography-types.js +0 -90
  183. package/lib/utils.d.ts +0 -3
  184. package/lib/utils.js +0 -14
  185. package/tmpclaude-2407-cwd +0 -1
@@ -0,0 +1,274 @@
1
+ import * as React from "react"
2
+ import * as MenubarPrimitive from "@radix-ui/react-menubar"
3
+ import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"
4
+
5
+ import { cn } from "../lib/utils"
6
+
7
+ function Menubar({
8
+ className,
9
+ ...props
10
+ }: React.ComponentProps<typeof MenubarPrimitive.Root>) {
11
+ return (
12
+ <MenubarPrimitive.Root
13
+ data-slot="menubar"
14
+ className={cn(
15
+ "bg-background flex h-9 items-center gap-1 rounded-md border p-1 shadow-xs",
16
+ className
17
+ )}
18
+ {...props}
19
+ />
20
+ )
21
+ }
22
+
23
+ function MenubarMenu({
24
+ ...props
25
+ }: React.ComponentProps<typeof MenubarPrimitive.Menu>) {
26
+ return <MenubarPrimitive.Menu data-slot="menubar-menu" {...props} />
27
+ }
28
+
29
+ function MenubarGroup({
30
+ ...props
31
+ }: React.ComponentProps<typeof MenubarPrimitive.Group>) {
32
+ return <MenubarPrimitive.Group data-slot="menubar-group" {...props} />
33
+ }
34
+
35
+ function MenubarPortal({
36
+ ...props
37
+ }: React.ComponentProps<typeof MenubarPrimitive.Portal>) {
38
+ return <MenubarPrimitive.Portal data-slot="menubar-portal" {...props} />
39
+ }
40
+
41
+ function MenubarRadioGroup({
42
+ ...props
43
+ }: React.ComponentProps<typeof MenubarPrimitive.RadioGroup>) {
44
+ return (
45
+ <MenubarPrimitive.RadioGroup data-slot="menubar-radio-group" {...props} />
46
+ )
47
+ }
48
+
49
+ function MenubarTrigger({
50
+ className,
51
+ ...props
52
+ }: React.ComponentProps<typeof MenubarPrimitive.Trigger>) {
53
+ return (
54
+ <MenubarPrimitive.Trigger
55
+ data-slot="menubar-trigger"
56
+ className={cn(
57
+ "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none",
58
+ className
59
+ )}
60
+ {...props}
61
+ />
62
+ )
63
+ }
64
+
65
+ function MenubarContent({
66
+ className,
67
+ align = "start",
68
+ alignOffset = -4,
69
+ sideOffset = 8,
70
+ ...props
71
+ }: React.ComponentProps<typeof MenubarPrimitive.Content>) {
72
+ return (
73
+ <MenubarPortal>
74
+ <MenubarPrimitive.Content
75
+ data-slot="menubar-content"
76
+ align={align}
77
+ alignOffset={alignOffset}
78
+ sideOffset={sideOffset}
79
+ className={cn(
80
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[12rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-md",
81
+ className
82
+ )}
83
+ {...props}
84
+ />
85
+ </MenubarPortal>
86
+ )
87
+ }
88
+
89
+ function MenubarItem({
90
+ className,
91
+ inset,
92
+ variant = "default",
93
+ ...props
94
+ }: React.ComponentProps<typeof MenubarPrimitive.Item> & {
95
+ inset?: boolean
96
+ variant?: "default" | "destructive"
97
+ }) {
98
+ return (
99
+ <MenubarPrimitive.Item
100
+ data-slot="menubar-item"
101
+ data-inset={inset}
102
+ data-variant={variant}
103
+ className={cn(
104
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
105
+ className
106
+ )}
107
+ {...props}
108
+ />
109
+ )
110
+ }
111
+
112
+ function MenubarCheckboxItem({
113
+ className,
114
+ children,
115
+ checked,
116
+ ...props
117
+ }: React.ComponentProps<typeof MenubarPrimitive.CheckboxItem>) {
118
+ return (
119
+ <MenubarPrimitive.CheckboxItem
120
+ data-slot="menubar-checkbox-item"
121
+ className={cn(
122
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
123
+ className
124
+ )}
125
+ checked={checked}
126
+ {...props}
127
+ >
128
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
129
+ <MenubarPrimitive.ItemIndicator>
130
+ <CheckIcon className="size-4" />
131
+ </MenubarPrimitive.ItemIndicator>
132
+ </span>
133
+ {children}
134
+ </MenubarPrimitive.CheckboxItem>
135
+ )
136
+ }
137
+
138
+ function MenubarRadioItem({
139
+ className,
140
+ children,
141
+ ...props
142
+ }: React.ComponentProps<typeof MenubarPrimitive.RadioItem>) {
143
+ return (
144
+ <MenubarPrimitive.RadioItem
145
+ data-slot="menubar-radio-item"
146
+ className={cn(
147
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
148
+ className
149
+ )}
150
+ {...props}
151
+ >
152
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
153
+ <MenubarPrimitive.ItemIndicator>
154
+ <CircleIcon className="size-2 fill-current" />
155
+ </MenubarPrimitive.ItemIndicator>
156
+ </span>
157
+ {children}
158
+ </MenubarPrimitive.RadioItem>
159
+ )
160
+ }
161
+
162
+ function MenubarLabel({
163
+ className,
164
+ inset,
165
+ ...props
166
+ }: React.ComponentProps<typeof MenubarPrimitive.Label> & {
167
+ inset?: boolean
168
+ }) {
169
+ return (
170
+ <MenubarPrimitive.Label
171
+ data-slot="menubar-label"
172
+ data-inset={inset}
173
+ className={cn(
174
+ "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
175
+ className
176
+ )}
177
+ {...props}
178
+ />
179
+ )
180
+ }
181
+
182
+ function MenubarSeparator({
183
+ className,
184
+ ...props
185
+ }: React.ComponentProps<typeof MenubarPrimitive.Separator>) {
186
+ return (
187
+ <MenubarPrimitive.Separator
188
+ data-slot="menubar-separator"
189
+ className={cn("bg-border -mx-1 my-1 h-px", className)}
190
+ {...props}
191
+ />
192
+ )
193
+ }
194
+
195
+ function MenubarShortcut({
196
+ className,
197
+ ...props
198
+ }: React.ComponentProps<"span">) {
199
+ return (
200
+ <span
201
+ data-slot="menubar-shortcut"
202
+ className={cn(
203
+ "text-muted-foreground ml-auto text-xs tracking-widest",
204
+ className
205
+ )}
206
+ {...props}
207
+ />
208
+ )
209
+ }
210
+
211
+ function MenubarSub({
212
+ ...props
213
+ }: React.ComponentProps<typeof MenubarPrimitive.Sub>) {
214
+ return <MenubarPrimitive.Sub data-slot="menubar-sub" {...props} />
215
+ }
216
+
217
+ function MenubarSubTrigger({
218
+ className,
219
+ inset,
220
+ children,
221
+ ...props
222
+ }: React.ComponentProps<typeof MenubarPrimitive.SubTrigger> & {
223
+ inset?: boolean
224
+ }) {
225
+ return (
226
+ <MenubarPrimitive.SubTrigger
227
+ data-slot="menubar-sub-trigger"
228
+ data-inset={inset}
229
+ className={cn(
230
+ "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8",
231
+ className
232
+ )}
233
+ {...props}
234
+ >
235
+ {children}
236
+ <ChevronRightIcon className="ml-auto h-4 w-4" />
237
+ </MenubarPrimitive.SubTrigger>
238
+ )
239
+ }
240
+
241
+ function MenubarSubContent({
242
+ className,
243
+ ...props
244
+ }: React.ComponentProps<typeof MenubarPrimitive.SubContent>) {
245
+ return (
246
+ <MenubarPrimitive.SubContent
247
+ data-slot="menubar-sub-content"
248
+ className={cn(
249
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
250
+ className
251
+ )}
252
+ {...props}
253
+ />
254
+ )
255
+ }
256
+
257
+ export {
258
+ Menubar,
259
+ MenubarPortal,
260
+ MenubarMenu,
261
+ MenubarTrigger,
262
+ MenubarContent,
263
+ MenubarGroup,
264
+ MenubarSeparator,
265
+ MenubarLabel,
266
+ MenubarItem,
267
+ MenubarShortcut,
268
+ MenubarCheckboxItem,
269
+ MenubarRadioGroup,
270
+ MenubarRadioItem,
271
+ MenubarSub,
272
+ MenubarSubTrigger,
273
+ MenubarSubContent,
274
+ }
@@ -0,0 +1,18 @@
1
+ export {
2
+ Menubar,
3
+ MenubarPortal,
4
+ MenubarMenu,
5
+ MenubarTrigger,
6
+ MenubarContent,
7
+ MenubarGroup,
8
+ MenubarSeparator,
9
+ MenubarLabel,
10
+ MenubarItem,
11
+ MenubarShortcut,
12
+ MenubarCheckboxItem,
13
+ MenubarRadioGroup,
14
+ MenubarRadioItem,
15
+ MenubarSub,
16
+ MenubarSubTrigger,
17
+ MenubarSubContent,
18
+ } from "./Menubar"
@@ -0,0 +1,196 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+ import {
3
+ Pagination,
4
+ PaginationContent,
5
+ PaginationEllipsis,
6
+ PaginationItem,
7
+ PaginationLink,
8
+ PaginationNext,
9
+ PaginationPrevious,
10
+ } from "./Pagination"
11
+
12
+ const meta: Meta<typeof Pagination> = {
13
+ title: "Components/Pagination",
14
+ component: Pagination,
15
+ parameters: {
16
+ layout: "centered",
17
+ },
18
+ tags: ["autodocs"],
19
+ }
20
+
21
+ export default meta
22
+ type Story = StoryObj<typeof Pagination>
23
+
24
+ export const Default: Story = {
25
+ render: () => (
26
+ <Pagination>
27
+ <PaginationContent>
28
+ <PaginationItem>
29
+ <PaginationPrevious />
30
+ </PaginationItem>
31
+ <PaginationItem>
32
+ <PaginationLink>1</PaginationLink>
33
+ </PaginationItem>
34
+ <PaginationItem>
35
+ <PaginationLink isActive>2</PaginationLink>
36
+ </PaginationItem>
37
+ <PaginationItem>
38
+ <PaginationLink>3</PaginationLink>
39
+ </PaginationItem>
40
+ <PaginationItem>
41
+ <PaginationNext />
42
+ </PaginationItem>
43
+ </PaginationContent>
44
+ </Pagination>
45
+ ),
46
+ }
47
+
48
+ export const WithEllipsis: Story = {
49
+ render: () => (
50
+ <Pagination>
51
+ <PaginationContent>
52
+ <PaginationItem>
53
+ <PaginationPrevious />
54
+ </PaginationItem>
55
+ <PaginationItem>
56
+ <PaginationLink>1</PaginationLink>
57
+ </PaginationItem>
58
+ <PaginationItem>
59
+ <PaginationLink>2</PaginationLink>
60
+ </PaginationItem>
61
+ <PaginationItem>
62
+ <PaginationLink isActive>3</PaginationLink>
63
+ </PaginationItem>
64
+ <PaginationItem>
65
+ <PaginationEllipsis />
66
+ </PaginationItem>
67
+ <PaginationItem>
68
+ <PaginationLink>10</PaginationLink>
69
+ </PaginationItem>
70
+ <PaginationItem>
71
+ <PaginationNext />
72
+ </PaginationItem>
73
+ </PaginationContent>
74
+ </Pagination>
75
+ ),
76
+ }
77
+
78
+ export const FirstPage: Story = {
79
+ render: () => (
80
+ <Pagination>
81
+ <PaginationContent>
82
+ <PaginationItem>
83
+ <PaginationPrevious disabled />
84
+ </PaginationItem>
85
+ <PaginationItem>
86
+ <PaginationLink isActive>1</PaginationLink>
87
+ </PaginationItem>
88
+ <PaginationItem>
89
+ <PaginationLink>2</PaginationLink>
90
+ </PaginationItem>
91
+ <PaginationItem>
92
+ <PaginationLink>3</PaginationLink>
93
+ </PaginationItem>
94
+ <PaginationItem>
95
+ <PaginationEllipsis />
96
+ </PaginationItem>
97
+ <PaginationItem>
98
+ <PaginationLink>10</PaginationLink>
99
+ </PaginationItem>
100
+ <PaginationItem>
101
+ <PaginationNext />
102
+ </PaginationItem>
103
+ </PaginationContent>
104
+ </Pagination>
105
+ ),
106
+ }
107
+
108
+ export const LastPage: Story = {
109
+ render: () => (
110
+ <Pagination>
111
+ <PaginationContent>
112
+ <PaginationItem>
113
+ <PaginationPrevious />
114
+ </PaginationItem>
115
+ <PaginationItem>
116
+ <PaginationLink>1</PaginationLink>
117
+ </PaginationItem>
118
+ <PaginationItem>
119
+ <PaginationEllipsis />
120
+ </PaginationItem>
121
+ <PaginationItem>
122
+ <PaginationLink>8</PaginationLink>
123
+ </PaginationItem>
124
+ <PaginationItem>
125
+ <PaginationLink>9</PaginationLink>
126
+ </PaginationItem>
127
+ <PaginationItem>
128
+ <PaginationLink isActive>10</PaginationLink>
129
+ </PaginationItem>
130
+ <PaginationItem>
131
+ <PaginationNext disabled />
132
+ </PaginationItem>
133
+ </PaginationContent>
134
+ </Pagination>
135
+ ),
136
+ }
137
+
138
+ export const FewPages: Story = {
139
+ render: () => (
140
+ <Pagination>
141
+ <PaginationContent>
142
+ <PaginationItem>
143
+ <PaginationPrevious disabled />
144
+ </PaginationItem>
145
+ <PaginationItem>
146
+ <PaginationLink isActive>1</PaginationLink>
147
+ </PaginationItem>
148
+ <PaginationItem>
149
+ <PaginationLink>2</PaginationLink>
150
+ </PaginationItem>
151
+ <PaginationItem>
152
+ <PaginationLink>3</PaginationLink>
153
+ </PaginationItem>
154
+ <PaginationItem>
155
+ <PaginationNext />
156
+ </PaginationItem>
157
+ </PaginationContent>
158
+ </Pagination>
159
+ ),
160
+ }
161
+
162
+ export const ManyPages: Story = {
163
+ render: () => (
164
+ <Pagination>
165
+ <PaginationContent>
166
+ <PaginationItem>
167
+ <PaginationPrevious />
168
+ </PaginationItem>
169
+ <PaginationItem>
170
+ <PaginationLink>1</PaginationLink>
171
+ </PaginationItem>
172
+ <PaginationItem>
173
+ <PaginationEllipsis />
174
+ </PaginationItem>
175
+ <PaginationItem>
176
+ <PaginationLink>4</PaginationLink>
177
+ </PaginationItem>
178
+ <PaginationItem>
179
+ <PaginationLink isActive>5</PaginationLink>
180
+ </PaginationItem>
181
+ <PaginationItem>
182
+ <PaginationLink>6</PaginationLink>
183
+ </PaginationItem>
184
+ <PaginationItem>
185
+ <PaginationEllipsis />
186
+ </PaginationItem>
187
+ <PaginationItem>
188
+ <PaginationLink>20</PaginationLink>
189
+ </PaginationItem>
190
+ <PaginationItem>
191
+ <PaginationNext />
192
+ </PaginationItem>
193
+ </PaginationContent>
194
+ </Pagination>
195
+ ),
196
+ }
@@ -0,0 +1,122 @@
1
+ import * as React from "react"
2
+ import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"
3
+ import { cn } from "../lib/utils"
4
+ import { buttonVariants } from "../Button/Button"
5
+
6
+ function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
7
+ return (
8
+ <nav
9
+ role="navigation"
10
+ aria-label="pagination"
11
+ className={cn("mx-auto flex w-full justify-center", className)}
12
+ {...props}
13
+ />
14
+ )
15
+ }
16
+ Pagination.displayName = "Pagination"
17
+
18
+ function PaginationContent({ className, ...props }: React.ComponentProps<"ul">) {
19
+ return (
20
+ <ul
21
+ className={cn("flex flex-row items-center gap-1", className)}
22
+ {...props}
23
+ />
24
+ )
25
+ }
26
+ PaginationContent.displayName = "PaginationContent"
27
+
28
+ function PaginationItem({ ...props }: React.ComponentProps<"li">) {
29
+ return <li {...props} />
30
+ }
31
+ PaginationItem.displayName = "PaginationItem"
32
+
33
+ type PaginationLinkProps = {
34
+ isActive?: boolean
35
+ disabled?: boolean
36
+ } & React.ComponentProps<"button">
37
+
38
+ function PaginationLink({
39
+ className,
40
+ isActive,
41
+ disabled,
42
+ ...props
43
+ }: PaginationLinkProps) {
44
+ return (
45
+ <button
46
+ type="button"
47
+ aria-current={isActive ? "page" : undefined}
48
+ disabled={disabled}
49
+ className={cn(
50
+ buttonVariants({
51
+ variant: isActive ? "outline" : "ghost",
52
+ size: "small",
53
+ }),
54
+ "size-9",
55
+ disabled && "pointer-events-none opacity-50",
56
+ className
57
+ )}
58
+ {...props}
59
+ />
60
+ )
61
+ }
62
+ PaginationLink.displayName = "PaginationLink"
63
+
64
+ function PaginationPrevious({
65
+ className,
66
+ ...props
67
+ }: React.ComponentProps<typeof PaginationLink>) {
68
+ return (
69
+ <PaginationLink
70
+ aria-label="Go to previous page"
71
+ className={cn("gap-1 pl-2.5 pr-4 w-auto", className)}
72
+ {...props}
73
+ >
74
+ <ChevronLeft className="size-4" />
75
+ <span className="hidden sm:block">Previous</span>
76
+ </PaginationLink>
77
+ )
78
+ }
79
+ PaginationPrevious.displayName = "PaginationPrevious"
80
+
81
+ function PaginationNext({
82
+ className,
83
+ ...props
84
+ }: React.ComponentProps<typeof PaginationLink>) {
85
+ return (
86
+ <PaginationLink
87
+ aria-label="Go to next page"
88
+ className={cn("gap-1 pl-4 pr-2.5 w-auto", className)}
89
+ {...props}
90
+ >
91
+ <span className="hidden sm:block">Next</span>
92
+ <ChevronRight className="size-4" />
93
+ </PaginationLink>
94
+ )
95
+ }
96
+ PaginationNext.displayName = "PaginationNext"
97
+
98
+ function PaginationEllipsis({ className, ...props }: React.ComponentProps<"span">) {
99
+ return (
100
+ <span
101
+ aria-hidden
102
+ className={cn("flex size-9 items-center justify-center", className)}
103
+ {...props}
104
+ >
105
+ <MoreHorizontal className="size-4" />
106
+ <span className="sr-only">More pages</span>
107
+ </span>
108
+ )
109
+ }
110
+ PaginationEllipsis.displayName = "PaginationEllipsis"
111
+
112
+ export {
113
+ Pagination,
114
+ PaginationContent,
115
+ PaginationLink,
116
+ PaginationItem,
117
+ PaginationPrevious,
118
+ PaginationNext,
119
+ PaginationEllipsis,
120
+ }
121
+
122
+ export type { PaginationLinkProps }