@lark-apaas/coding-templates 0.1.0

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 (216) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +128 -0
  3. package/meta.json +22 -0
  4. package/package.json +22 -0
  5. package/template-html/README.md +148 -0
  6. package/template-html/_gitignore +2 -0
  7. package/template-html/index.html +22 -0
  8. package/template-html/package.json +12 -0
  9. package/template-html/routes.json +1 -0
  10. package/template-html/scripts/build.sh +31 -0
  11. package/template-nextjs-fullstack/README.md +169 -0
  12. package/template-nextjs-fullstack/_env.local.example +1 -0
  13. package/template-nextjs-fullstack/_gitignore +41 -0
  14. package/template-nextjs-fullstack/components.json +25 -0
  15. package/template-nextjs-fullstack/drizzle.config.ts +10 -0
  16. package/template-nextjs-fullstack/eslint.config.js +15 -0
  17. package/template-nextjs-fullstack/next.config.ts +5 -0
  18. package/template-nextjs-fullstack/package.json +85 -0
  19. package/template-nextjs-fullstack/postcss.config.js +8 -0
  20. package/template-nextjs-fullstack/scripts/build.sh +37 -0
  21. package/template-nextjs-fullstack/src/app/favicon.ico +0 -0
  22. package/template-nextjs-fullstack/src/app/globals.css +130 -0
  23. package/template-nextjs-fullstack/src/app/layout.tsx +24 -0
  24. package/template-nextjs-fullstack/src/app/page.tsx +69 -0
  25. package/template-nextjs-fullstack/src/app/todos/actions.ts +37 -0
  26. package/template-nextjs-fullstack/src/app/todos/page.tsx +26 -0
  27. package/template-nextjs-fullstack/src/app/todos/todo-form.tsx +27 -0
  28. package/template-nextjs-fullstack/src/app/todos/todo-list.tsx +44 -0
  29. package/template-nextjs-fullstack/src/components/header.tsx +32 -0
  30. package/template-nextjs-fullstack/src/components/theme-provider.tsx +8 -0
  31. package/template-nextjs-fullstack/src/components/ui/README.md +134 -0
  32. package/template-nextjs-fullstack/src/components/ui/accordion.tsx +66 -0
  33. package/template-nextjs-fullstack/src/components/ui/alert-dialog.tsx +157 -0
  34. package/template-nextjs-fullstack/src/components/ui/alert.tsx +71 -0
  35. package/template-nextjs-fullstack/src/components/ui/aspect-ratio.tsx +11 -0
  36. package/template-nextjs-fullstack/src/components/ui/avatar.tsx +53 -0
  37. package/template-nextjs-fullstack/src/components/ui/badge.tsx +42 -0
  38. package/template-nextjs-fullstack/src/components/ui/breadcrumb.tsx +109 -0
  39. package/template-nextjs-fullstack/src/components/ui/button-group.tsx +83 -0
  40. package/template-nextjs-fullstack/src/components/ui/button.tsx +69 -0
  41. package/template-nextjs-fullstack/src/components/ui/calendar.tsx +213 -0
  42. package/template-nextjs-fullstack/src/components/ui/card.tsx +82 -0
  43. package/template-nextjs-fullstack/src/components/ui/carousel.tsx +241 -0
  44. package/template-nextjs-fullstack/src/components/ui/chart.tsx +357 -0
  45. package/template-nextjs-fullstack/src/components/ui/checkbox.tsx +32 -0
  46. package/template-nextjs-fullstack/src/components/ui/collapsible.tsx +33 -0
  47. package/template-nextjs-fullstack/src/components/ui/command.tsx +208 -0
  48. package/template-nextjs-fullstack/src/components/ui/context-menu.tsx +324 -0
  49. package/template-nextjs-fullstack/src/components/ui/dialog.tsx +143 -0
  50. package/template-nextjs-fullstack/src/components/ui/drawer.tsx +135 -0
  51. package/template-nextjs-fullstack/src/components/ui/dropdown-menu.tsx +329 -0
  52. package/template-nextjs-fullstack/src/components/ui/empty.tsx +104 -0
  53. package/template-nextjs-fullstack/src/components/ui/field.tsx +248 -0
  54. package/template-nextjs-fullstack/src/components/ui/form.tsx +167 -0
  55. package/template-nextjs-fullstack/src/components/ui/hover-card.tsx +44 -0
  56. package/template-nextjs-fullstack/src/components/ui/icons/file-ae-colorful-icon.tsx +21 -0
  57. package/template-nextjs-fullstack/src/components/ui/icons/file-ai-colorful-icon.tsx +36 -0
  58. package/template-nextjs-fullstack/src/components/ui/icons/file-android-colorful-icon.tsx +33 -0
  59. package/template-nextjs-fullstack/src/components/ui/icons/file-audio-colorful-icon.tsx +21 -0
  60. package/template-nextjs-fullstack/src/components/ui/icons/file-code-colorful-icon.tsx +28 -0
  61. package/template-nextjs-fullstack/src/components/ui/icons/file-csv-colorful-icon.tsx +21 -0
  62. package/template-nextjs-fullstack/src/components/ui/icons/file-eml-colorful-icon.tsx +29 -0
  63. package/template-nextjs-fullstack/src/components/ui/icons/file-ios-colorful-icon.tsx +25 -0
  64. package/template-nextjs-fullstack/src/components/ui/icons/file-keynote-colorful-icon.tsx +29 -0
  65. package/template-nextjs-fullstack/src/components/ui/icons/file-pages-colorful-icon.tsx +29 -0
  66. package/template-nextjs-fullstack/src/components/ui/icons/file-ps-colorful-icon.tsx +21 -0
  67. package/template-nextjs-fullstack/src/components/ui/icons/file-sketch-colorful-icon.tsx +21 -0
  68. package/template-nextjs-fullstack/src/components/ui/icons/file-slide-colorful-icon.tsx +21 -0
  69. package/template-nextjs-fullstack/src/components/ui/icons/file-vcf-colorful-icon.tsx +29 -0
  70. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-excel-colorful-icon.tsx +23 -0
  71. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-image-colorful-icon.tsx +27 -0
  72. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-pdf-colorful-icon.tsx +20 -0
  73. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-ppt-colorful-icon.tsx +21 -0
  74. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-text-colorful-icon.tsx +12 -0
  75. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-unknown-colorful-icon.tsx +14 -0
  76. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-video-colorful-icon.tsx +23 -0
  77. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-word-colorful-icon.tsx +38 -0
  78. package/template-nextjs-fullstack/src/components/ui/icons/file-wiki-zip-colorful-icon.tsx +21 -0
  79. package/template-nextjs-fullstack/src/components/ui/image.tsx +183 -0
  80. package/template-nextjs-fullstack/src/components/ui/input-group.tsx +166 -0
  81. package/template-nextjs-fullstack/src/components/ui/input-otp.tsx +77 -0
  82. package/template-nextjs-fullstack/src/components/ui/input.tsx +21 -0
  83. package/template-nextjs-fullstack/src/components/ui/item.tsx +193 -0
  84. package/template-nextjs-fullstack/src/components/ui/kbd.tsx +28 -0
  85. package/template-nextjs-fullstack/src/components/ui/label.tsx +24 -0
  86. package/template-nextjs-fullstack/src/components/ui/menubar.tsx +348 -0
  87. package/template-nextjs-fullstack/src/components/ui/native-select.tsx +48 -0
  88. package/template-nextjs-fullstack/src/components/ui/navigation-menu.tsx +168 -0
  89. package/template-nextjs-fullstack/src/components/ui/pagination.tsx +127 -0
  90. package/template-nextjs-fullstack/src/components/ui/popover.tsx +48 -0
  91. package/template-nextjs-fullstack/src/components/ui/progress.tsx +31 -0
  92. package/template-nextjs-fullstack/src/components/ui/radio-group.tsx +45 -0
  93. package/template-nextjs-fullstack/src/components/ui/resizable.tsx +56 -0
  94. package/template-nextjs-fullstack/src/components/ui/scroll-area.tsx +58 -0
  95. package/template-nextjs-fullstack/src/components/ui/select.tsx +243 -0
  96. package/template-nextjs-fullstack/src/components/ui/separator.tsx +28 -0
  97. package/template-nextjs-fullstack/src/components/ui/sheet.tsx +139 -0
  98. package/template-nextjs-fullstack/src/components/ui/sidebar.tsx +727 -0
  99. package/template-nextjs-fullstack/src/components/ui/skeleton.tsx +13 -0
  100. package/template-nextjs-fullstack/src/components/ui/slider.tsx +87 -0
  101. package/template-nextjs-fullstack/src/components/ui/sonner.tsx +67 -0
  102. package/template-nextjs-fullstack/src/components/ui/spinner.tsx +16 -0
  103. package/template-nextjs-fullstack/src/components/ui/streamdown.tsx +186 -0
  104. package/template-nextjs-fullstack/src/components/ui/switch.tsx +31 -0
  105. package/template-nextjs-fullstack/src/components/ui/table.tsx +116 -0
  106. package/template-nextjs-fullstack/src/components/ui/tabs.tsx +66 -0
  107. package/template-nextjs-fullstack/src/components/ui/textarea.tsx +18 -0
  108. package/template-nextjs-fullstack/src/components/ui/toggle-group.tsx +83 -0
  109. package/template-nextjs-fullstack/src/components/ui/toggle.tsx +47 -0
  110. package/template-nextjs-fullstack/src/components/ui/tooltip.tsx +61 -0
  111. package/template-nextjs-fullstack/src/db/index.ts +8 -0
  112. package/template-nextjs-fullstack/src/db/schema.ts +11 -0
  113. package/template-nextjs-fullstack/src/hooks/use-mobile.ts +19 -0
  114. package/template-nextjs-fullstack/src/lib/utils.ts +6 -0
  115. package/template-nextjs-fullstack/tailwind.config.ts +10 -0
  116. package/template-nextjs-fullstack/tsconfig.json +34 -0
  117. package/template-nextjs-static/README.md +80 -0
  118. package/template-nextjs-static/_gitignore +41 -0
  119. package/template-nextjs-static/components.json +25 -0
  120. package/template-nextjs-static/eslint.config.js +15 -0
  121. package/template-nextjs-static/next.config.ts +8 -0
  122. package/template-nextjs-static/package.json +77 -0
  123. package/template-nextjs-static/postcss.config.js +8 -0
  124. package/template-nextjs-static/public/favicon.ico +0 -0
  125. package/template-nextjs-static/scripts/build.sh +36 -0
  126. package/template-nextjs-static/src/components/header.tsx +30 -0
  127. package/template-nextjs-static/src/components/theme-provider.tsx +6 -0
  128. package/template-nextjs-static/src/components/ui/README.md +134 -0
  129. package/template-nextjs-static/src/components/ui/accordion.tsx +66 -0
  130. package/template-nextjs-static/src/components/ui/alert-dialog.tsx +157 -0
  131. package/template-nextjs-static/src/components/ui/alert.tsx +71 -0
  132. package/template-nextjs-static/src/components/ui/aspect-ratio.tsx +11 -0
  133. package/template-nextjs-static/src/components/ui/avatar.tsx +53 -0
  134. package/template-nextjs-static/src/components/ui/badge.tsx +42 -0
  135. package/template-nextjs-static/src/components/ui/breadcrumb.tsx +109 -0
  136. package/template-nextjs-static/src/components/ui/button-group.tsx +83 -0
  137. package/template-nextjs-static/src/components/ui/button.tsx +69 -0
  138. package/template-nextjs-static/src/components/ui/calendar.tsx +213 -0
  139. package/template-nextjs-static/src/components/ui/card.tsx +82 -0
  140. package/template-nextjs-static/src/components/ui/carousel.tsx +241 -0
  141. package/template-nextjs-static/src/components/ui/chart.tsx +357 -0
  142. package/template-nextjs-static/src/components/ui/checkbox.tsx +32 -0
  143. package/template-nextjs-static/src/components/ui/collapsible.tsx +33 -0
  144. package/template-nextjs-static/src/components/ui/command.tsx +208 -0
  145. package/template-nextjs-static/src/components/ui/context-menu.tsx +324 -0
  146. package/template-nextjs-static/src/components/ui/dialog.tsx +143 -0
  147. package/template-nextjs-static/src/components/ui/drawer.tsx +135 -0
  148. package/template-nextjs-static/src/components/ui/dropdown-menu.tsx +329 -0
  149. package/template-nextjs-static/src/components/ui/empty.tsx +104 -0
  150. package/template-nextjs-static/src/components/ui/field.tsx +248 -0
  151. package/template-nextjs-static/src/components/ui/form.tsx +167 -0
  152. package/template-nextjs-static/src/components/ui/hover-card.tsx +44 -0
  153. package/template-nextjs-static/src/components/ui/icons/file-ae-colorful-icon.tsx +21 -0
  154. package/template-nextjs-static/src/components/ui/icons/file-ai-colorful-icon.tsx +36 -0
  155. package/template-nextjs-static/src/components/ui/icons/file-android-colorful-icon.tsx +33 -0
  156. package/template-nextjs-static/src/components/ui/icons/file-audio-colorful-icon.tsx +21 -0
  157. package/template-nextjs-static/src/components/ui/icons/file-code-colorful-icon.tsx +28 -0
  158. package/template-nextjs-static/src/components/ui/icons/file-csv-colorful-icon.tsx +21 -0
  159. package/template-nextjs-static/src/components/ui/icons/file-eml-colorful-icon.tsx +29 -0
  160. package/template-nextjs-static/src/components/ui/icons/file-ios-colorful-icon.tsx +25 -0
  161. package/template-nextjs-static/src/components/ui/icons/file-keynote-colorful-icon.tsx +29 -0
  162. package/template-nextjs-static/src/components/ui/icons/file-pages-colorful-icon.tsx +29 -0
  163. package/template-nextjs-static/src/components/ui/icons/file-ps-colorful-icon.tsx +21 -0
  164. package/template-nextjs-static/src/components/ui/icons/file-sketch-colorful-icon.tsx +21 -0
  165. package/template-nextjs-static/src/components/ui/icons/file-slide-colorful-icon.tsx +21 -0
  166. package/template-nextjs-static/src/components/ui/icons/file-vcf-colorful-icon.tsx +29 -0
  167. package/template-nextjs-static/src/components/ui/icons/file-wiki-excel-colorful-icon.tsx +23 -0
  168. package/template-nextjs-static/src/components/ui/icons/file-wiki-image-colorful-icon.tsx +27 -0
  169. package/template-nextjs-static/src/components/ui/icons/file-wiki-pdf-colorful-icon.tsx +20 -0
  170. package/template-nextjs-static/src/components/ui/icons/file-wiki-ppt-colorful-icon.tsx +21 -0
  171. package/template-nextjs-static/src/components/ui/icons/file-wiki-text-colorful-icon.tsx +12 -0
  172. package/template-nextjs-static/src/components/ui/icons/file-wiki-unknown-colorful-icon.tsx +14 -0
  173. package/template-nextjs-static/src/components/ui/icons/file-wiki-video-colorful-icon.tsx +23 -0
  174. package/template-nextjs-static/src/components/ui/icons/file-wiki-word-colorful-icon.tsx +38 -0
  175. package/template-nextjs-static/src/components/ui/icons/file-wiki-zip-colorful-icon.tsx +21 -0
  176. package/template-nextjs-static/src/components/ui/image.tsx +183 -0
  177. package/template-nextjs-static/src/components/ui/input-group.tsx +166 -0
  178. package/template-nextjs-static/src/components/ui/input-otp.tsx +77 -0
  179. package/template-nextjs-static/src/components/ui/input.tsx +21 -0
  180. package/template-nextjs-static/src/components/ui/item.tsx +193 -0
  181. package/template-nextjs-static/src/components/ui/kbd.tsx +28 -0
  182. package/template-nextjs-static/src/components/ui/label.tsx +24 -0
  183. package/template-nextjs-static/src/components/ui/menubar.tsx +348 -0
  184. package/template-nextjs-static/src/components/ui/native-select.tsx +48 -0
  185. package/template-nextjs-static/src/components/ui/navigation-menu.tsx +168 -0
  186. package/template-nextjs-static/src/components/ui/pagination.tsx +127 -0
  187. package/template-nextjs-static/src/components/ui/popover.tsx +48 -0
  188. package/template-nextjs-static/src/components/ui/progress.tsx +31 -0
  189. package/template-nextjs-static/src/components/ui/radio-group.tsx +45 -0
  190. package/template-nextjs-static/src/components/ui/resizable.tsx +56 -0
  191. package/template-nextjs-static/src/components/ui/scroll-area.tsx +58 -0
  192. package/template-nextjs-static/src/components/ui/select.tsx +243 -0
  193. package/template-nextjs-static/src/components/ui/separator.tsx +28 -0
  194. package/template-nextjs-static/src/components/ui/sheet.tsx +139 -0
  195. package/template-nextjs-static/src/components/ui/sidebar.tsx +727 -0
  196. package/template-nextjs-static/src/components/ui/skeleton.tsx +13 -0
  197. package/template-nextjs-static/src/components/ui/slider.tsx +87 -0
  198. package/template-nextjs-static/src/components/ui/sonner.tsx +67 -0
  199. package/template-nextjs-static/src/components/ui/spinner.tsx +16 -0
  200. package/template-nextjs-static/src/components/ui/streamdown.tsx +186 -0
  201. package/template-nextjs-static/src/components/ui/switch.tsx +31 -0
  202. package/template-nextjs-static/src/components/ui/table.tsx +116 -0
  203. package/template-nextjs-static/src/components/ui/tabs.tsx +66 -0
  204. package/template-nextjs-static/src/components/ui/textarea.tsx +18 -0
  205. package/template-nextjs-static/src/components/ui/toggle-group.tsx +83 -0
  206. package/template-nextjs-static/src/components/ui/toggle.tsx +47 -0
  207. package/template-nextjs-static/src/components/ui/tooltip.tsx +61 -0
  208. package/template-nextjs-static/src/hooks/use-mobile.ts +19 -0
  209. package/template-nextjs-static/src/lib/utils.ts +6 -0
  210. package/template-nextjs-static/src/pages/_app.tsx +11 -0
  211. package/template-nextjs-static/src/pages/_document.tsx +13 -0
  212. package/template-nextjs-static/src/pages/hello.tsx +32 -0
  213. package/template-nextjs-static/src/pages/index.tsx +76 -0
  214. package/template-nextjs-static/src/styles/globals.css +143 -0
  215. package/template-nextjs-static/tailwind.config.ts +10 -0
  216. package/template-nextjs-static/tsconfig.json +34 -0
@@ -0,0 +1,329 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
5
+ import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"
6
+
7
+ import { cn } from "@/lib/utils"
8
+
9
+ function DropdownMenu({
10
+ ...props
11
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
12
+ return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
13
+ }
14
+
15
+ function DropdownMenuPortal({
16
+ ...props
17
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
18
+ return (
19
+ <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
20
+ )
21
+ }
22
+
23
+ function DropdownMenuTrigger({
24
+ ...props
25
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
26
+ return (
27
+ <DropdownMenuPrimitive.Trigger
28
+ data-slot="dropdown-menu-trigger"
29
+ {...props}
30
+ />
31
+ )
32
+ }
33
+
34
+ function DropdownMenuContent({
35
+ className,
36
+ sideOffset = 4,
37
+ ...props
38
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
39
+ return (
40
+ <DropdownMenuPrimitive.Portal>
41
+ <DropdownMenuPrimitive.Content
42
+ data-slot="dropdown-menu-content"
43
+ sideOffset={sideOffset}
44
+ className={cn(
45
+ "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 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
46
+ className
47
+ )}
48
+ {...props}
49
+ />
50
+ </DropdownMenuPrimitive.Portal>
51
+ )
52
+ }
53
+
54
+ function DropdownMenuGroup({
55
+ ...props
56
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
57
+ return (
58
+ <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
59
+ )
60
+ }
61
+
62
+ function DropdownMenuItem({
63
+ className,
64
+ inset,
65
+ variant = "default",
66
+ disabled,
67
+ onClick,
68
+ onMouseDown,
69
+ onKeyDown,
70
+ onKeyUp,
71
+ onPointerDown,
72
+ ...props
73
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
74
+ inset?: boolean
75
+ variant?: "default" | "destructive"
76
+ }) {
77
+ return (
78
+ <DropdownMenuPrimitive.Item
79
+ data-slot="dropdown-menu-item"
80
+ data-inset={inset}
81
+ data-variant={variant}
82
+ className={cn(
83
+ "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 relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
84
+ className
85
+ )}
86
+ disabled={disabled}
87
+ onClick={(event) => {
88
+ if (disabled) {
89
+ event.preventDefault()
90
+ return
91
+ }
92
+ onClick?.(event)
93
+ }}
94
+ onMouseDown={disabled ? undefined : onMouseDown}
95
+ onKeyDown={disabled ? undefined : onKeyDown}
96
+ onKeyUp={disabled ? undefined : onKeyUp}
97
+ onPointerDown={(event) => {
98
+ if (disabled) {
99
+ event.preventDefault()
100
+ return
101
+ }
102
+ onPointerDown?.(event)
103
+ }}
104
+ {...props}
105
+ />
106
+ )
107
+ }
108
+
109
+ function DropdownMenuCheckboxItem({
110
+ className,
111
+ children,
112
+ checked,
113
+ disabled,
114
+ onClick,
115
+ onMouseDown,
116
+ onKeyDown,
117
+ onKeyUp,
118
+ onPointerDown,
119
+ ...props
120
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
121
+ return (
122
+ <DropdownMenuPrimitive.CheckboxItem
123
+ data-slot="dropdown-menu-checkbox-item"
124
+ className={cn(
125
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
126
+ className
127
+ )}
128
+ checked={checked}
129
+ disabled={disabled}
130
+ onClick={(event) => {
131
+ if (disabled) {
132
+ event.preventDefault()
133
+ return
134
+ }
135
+ onClick?.(event)
136
+ }}
137
+ onMouseDown={disabled ? undefined : onMouseDown}
138
+ onKeyDown={disabled ? undefined : onKeyDown}
139
+ onKeyUp={disabled ? undefined : onKeyUp}
140
+ onPointerDown={(event) => {
141
+ if (disabled) {
142
+ event.preventDefault()
143
+ return
144
+ }
145
+ onPointerDown?.(event)
146
+ }}
147
+ {...props}
148
+ >
149
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
150
+ <DropdownMenuPrimitive.ItemIndicator>
151
+ <CheckIcon className="size-4" />
152
+ </DropdownMenuPrimitive.ItemIndicator>
153
+ </span>
154
+ {children}
155
+ </DropdownMenuPrimitive.CheckboxItem>
156
+ )
157
+ }
158
+
159
+ function DropdownMenuRadioGroup({
160
+ ...props
161
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
162
+ return (
163
+ <DropdownMenuPrimitive.RadioGroup
164
+ data-slot="dropdown-menu-radio-group"
165
+ {...props}
166
+ />
167
+ )
168
+ }
169
+
170
+ function DropdownMenuRadioItem({
171
+ className,
172
+ children,
173
+ disabled,
174
+ onClick,
175
+ onMouseDown,
176
+ onKeyDown,
177
+ onKeyUp,
178
+ onPointerDown,
179
+ ...props
180
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
181
+ return (
182
+ <DropdownMenuPrimitive.RadioItem
183
+ data-slot="dropdown-menu-radio-item"
184
+ className={cn(
185
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
186
+ className
187
+ )}
188
+ disabled={disabled}
189
+ onClick={(event) => {
190
+ if (disabled) {
191
+ event.preventDefault()
192
+ return
193
+ }
194
+ onClick?.(event)
195
+ }}
196
+ onMouseDown={disabled ? undefined : onMouseDown}
197
+ onKeyDown={disabled ? undefined : onKeyDown}
198
+ onKeyUp={disabled ? undefined : onKeyUp}
199
+ onPointerDown={(event) => {
200
+ if (disabled) {
201
+ event.preventDefault()
202
+ return
203
+ }
204
+ onPointerDown?.(event)
205
+ }}
206
+ {...props}
207
+ >
208
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
209
+ <DropdownMenuPrimitive.ItemIndicator>
210
+ <CircleIcon className="size-2 fill-current" />
211
+ </DropdownMenuPrimitive.ItemIndicator>
212
+ </span>
213
+ {children}
214
+ </DropdownMenuPrimitive.RadioItem>
215
+ )
216
+ }
217
+
218
+ function DropdownMenuLabel({
219
+ className,
220
+ inset,
221
+ ...props
222
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
223
+ inset?: boolean
224
+ }) {
225
+ return (
226
+ <DropdownMenuPrimitive.Label
227
+ data-slot="dropdown-menu-label"
228
+ data-inset={inset}
229
+ className={cn(
230
+ "px-2 py-1.5 text-sm font-medium data-[inset]:pl-8",
231
+ className
232
+ )}
233
+ {...props}
234
+ />
235
+ )
236
+ }
237
+
238
+ function DropdownMenuSeparator({
239
+ className,
240
+ ...props
241
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
242
+ return (
243
+ <DropdownMenuPrimitive.Separator
244
+ data-slot="dropdown-menu-separator"
245
+ className={cn("bg-border -mx-1 my-1 h-px", className)}
246
+ {...props}
247
+ />
248
+ )
249
+ }
250
+
251
+ function DropdownMenuShortcut({
252
+ className,
253
+ ...props
254
+ }: React.ComponentProps<"span">) {
255
+ return (
256
+ <span
257
+ data-slot="dropdown-menu-shortcut"
258
+ className={cn(
259
+ "text-muted-foreground ml-auto text-xs tracking-widest",
260
+ className
261
+ )}
262
+ {...props}
263
+ />
264
+ )
265
+ }
266
+
267
+ function DropdownMenuSub({
268
+ ...props
269
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
270
+ return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
271
+ }
272
+
273
+ function DropdownMenuSubTrigger({
274
+ className,
275
+ inset,
276
+ children,
277
+ ...props
278
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
279
+ inset?: boolean
280
+ }) {
281
+ return (
282
+ <DropdownMenuPrimitive.SubTrigger
283
+ data-slot="dropdown-menu-sub-trigger"
284
+ data-inset={inset}
285
+ className={cn(
286
+ "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
287
+ className
288
+ )}
289
+ {...props}
290
+ >
291
+ {children}
292
+ <ChevronRightIcon className="ml-auto size-4" />
293
+ </DropdownMenuPrimitive.SubTrigger>
294
+ )
295
+ }
296
+
297
+ function DropdownMenuSubContent({
298
+ className,
299
+ ...props
300
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
301
+ return (
302
+ <DropdownMenuPrimitive.SubContent
303
+ data-slot="dropdown-menu-sub-content"
304
+ className={cn(
305
+ "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-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
306
+ className
307
+ )}
308
+ {...props}
309
+ />
310
+ )
311
+ }
312
+
313
+ export {
314
+ DropdownMenu,
315
+ DropdownMenuPortal,
316
+ DropdownMenuTrigger,
317
+ DropdownMenuContent,
318
+ DropdownMenuGroup,
319
+ DropdownMenuLabel,
320
+ DropdownMenuItem,
321
+ DropdownMenuCheckboxItem,
322
+ DropdownMenuRadioGroup,
323
+ DropdownMenuRadioItem,
324
+ DropdownMenuSeparator,
325
+ DropdownMenuShortcut,
326
+ DropdownMenuSub,
327
+ DropdownMenuSubTrigger,
328
+ DropdownMenuSubContent,
329
+ }
@@ -0,0 +1,104 @@
1
+ import { cva, type VariantProps } from "class-variance-authority"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ function Empty({ className, ...props }: React.ComponentProps<"div">) {
6
+ return (
7
+ <div
8
+ data-slot="empty"
9
+ className={cn(
10
+ "flex min-w-0 flex-1 flex-col items-center justify-center gap-4 rounded-lg border-dashed p-6 text-center text-balance md:p-12",
11
+ className
12
+ )}
13
+ {...props}
14
+ />
15
+ )
16
+ }
17
+
18
+ function EmptyHeader({ className, ...props }: React.ComponentProps<"div">) {
19
+ return (
20
+ <div
21
+ data-slot="empty-header"
22
+ className={cn(
23
+ "flex max-w-sm flex-col items-center gap-1 text-center",
24
+ className
25
+ )}
26
+ {...props}
27
+ />
28
+ )
29
+ }
30
+
31
+ const emptyMediaVariants = cva(
32
+ "flex shrink-0 items-center justify-center mb-3 [&_svg]:pointer-events-none [&_svg]:shrink-0",
33
+ {
34
+ variants: {
35
+ variant: {
36
+ default: "bg-transparent",
37
+ icon: "bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6",
38
+ },
39
+ },
40
+ defaultVariants: {
41
+ variant: "default",
42
+ },
43
+ }
44
+ )
45
+
46
+ function EmptyMedia({
47
+ className,
48
+ variant = "default",
49
+ ...props
50
+ }: React.ComponentProps<"div"> & VariantProps<typeof emptyMediaVariants>) {
51
+ return (
52
+ <div
53
+ data-slot="empty-icon"
54
+ data-variant={variant}
55
+ className={cn(emptyMediaVariants({ variant, className }))}
56
+ {...props}
57
+ />
58
+ )
59
+ }
60
+
61
+ function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
62
+ return (
63
+ <div
64
+ data-slot="empty-title"
65
+ className={cn("text-base font-medium tracking-tight", className)}
66
+ {...props}
67
+ />
68
+ )
69
+ }
70
+
71
+ function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
72
+ return (
73
+ <div
74
+ data-slot="empty-description"
75
+ className={cn(
76
+ "text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4",
77
+ className
78
+ )}
79
+ {...props}
80
+ />
81
+ )
82
+ }
83
+
84
+ function EmptyContent({ className, ...props }: React.ComponentProps<"div">) {
85
+ return (
86
+ <div
87
+ data-slot="empty-content"
88
+ className={cn(
89
+ "flex w-full max-w-sm min-w-0 flex-col items-center gap-2 text-sm text-balance",
90
+ className
91
+ )}
92
+ {...props}
93
+ />
94
+ )
95
+ }
96
+
97
+ export {
98
+ Empty,
99
+ EmptyHeader,
100
+ EmptyTitle,
101
+ EmptyDescription,
102
+ EmptyContent,
103
+ EmptyMedia,
104
+ }
@@ -0,0 +1,248 @@
1
+ "use client"
2
+
3
+ import { useMemo } from "react"
4
+ import { cva, type VariantProps } from "class-variance-authority"
5
+
6
+ import { cn } from "@/lib/utils"
7
+ import { Label } from "@/components/ui/label"
8
+ import { Separator } from "@/components/ui/separator"
9
+
10
+ function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
11
+ return (
12
+ <fieldset
13
+ data-slot="field-set"
14
+ className={cn(
15
+ "flex flex-col gap-6",
16
+ "has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
17
+ className
18
+ )}
19
+ {...props}
20
+ />
21
+ )
22
+ }
23
+
24
+ function FieldLegend({
25
+ className,
26
+ variant = "legend",
27
+ ...props
28
+ }: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) {
29
+ return (
30
+ <legend
31
+ data-slot="field-legend"
32
+ data-variant={variant}
33
+ className={cn(
34
+ "mb-3 font-normal",
35
+ "data-[variant=legend]:text-base",
36
+ "data-[variant=label]:text-sm",
37
+ className
38
+ )}
39
+ {...props}
40
+ />
41
+ )
42
+ }
43
+
44
+ function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
45
+ return (
46
+ <div
47
+ data-slot="field-group"
48
+ className={cn(
49
+ "group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4",
50
+ className
51
+ )}
52
+ {...props}
53
+ />
54
+ )
55
+ }
56
+
57
+ const fieldVariants = cva(
58
+ "group/field flex w-full gap-3 data-[invalid=true]:text-destructive",
59
+ {
60
+ variants: {
61
+ orientation: {
62
+ vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"],
63
+ horizontal: [
64
+ "flex-row items-center",
65
+ "[&>[data-slot=field-label]]:flex-auto",
66
+ "has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
67
+ ],
68
+ responsive: [
69
+ "flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto",
70
+ "@md/field-group:[&>[data-slot=field-label]]:flex-auto",
71
+ "@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
72
+ ],
73
+ },
74
+ },
75
+ defaultVariants: {
76
+ orientation: "vertical",
77
+ },
78
+ }
79
+ )
80
+
81
+ function Field({
82
+ className,
83
+ orientation = "vertical",
84
+ ...props
85
+ }: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) {
86
+ return (
87
+ <div
88
+ role="group"
89
+ data-slot="field"
90
+ data-orientation={orientation}
91
+ className={cn(fieldVariants({ orientation }), className)}
92
+ {...props}
93
+ />
94
+ )
95
+ }
96
+
97
+ function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
98
+ return (
99
+ <div
100
+ data-slot="field-content"
101
+ className={cn(
102
+ "group/field-content flex flex-1 flex-col gap-1.5 leading-snug",
103
+ className
104
+ )}
105
+ {...props}
106
+ />
107
+ )
108
+ }
109
+
110
+ function FieldLabel({
111
+ className,
112
+ ...props
113
+ }: React.ComponentProps<typeof Label>) {
114
+ return (
115
+ <Label
116
+ data-slot="field-label"
117
+ className={cn(
118
+ "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
119
+ "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4",
120
+ "has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10",
121
+ className
122
+ )}
123
+ {...props}
124
+ />
125
+ )
126
+ }
127
+
128
+ function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
129
+ return (
130
+ <div
131
+ data-slot="field-label"
132
+ className={cn(
133
+ "flex w-fit items-center gap-2 text-sm leading-snug font-normal group-data-[disabled=true]/field:opacity-50",
134
+ className
135
+ )}
136
+ {...props}
137
+ />
138
+ )
139
+ }
140
+
141
+ function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
142
+ return (
143
+ <p
144
+ data-slot="field-description"
145
+ className={cn(
146
+ "text-muted-foreground text-sm leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
147
+ "last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5",
148
+ "[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
149
+ className
150
+ )}
151
+ {...props}
152
+ />
153
+ )
154
+ }
155
+
156
+ function FieldSeparator({
157
+ children,
158
+ className,
159
+ ...props
160
+ }: React.ComponentProps<"div"> & {
161
+ children?: React.ReactNode
162
+ }) {
163
+ return (
164
+ <div
165
+ data-slot="field-separator"
166
+ data-content={!!children}
167
+ className={cn(
168
+ "relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
169
+ className
170
+ )}
171
+ {...props}
172
+ >
173
+ <Separator className="absolute inset-0 top-1/2" />
174
+ {children && (
175
+ <span
176
+ className="bg-background text-muted-foreground relative mx-auto block w-fit px-2"
177
+ data-slot="field-separator-content"
178
+ >
179
+ {children}
180
+ </span>
181
+ )}
182
+ </div>
183
+ )
184
+ }
185
+
186
+ function FieldError({
187
+ className,
188
+ children,
189
+ errors,
190
+ ...props
191
+ }: React.ComponentProps<"div"> & {
192
+ errors?: Array<{ message?: string } | undefined>
193
+ }) {
194
+ const content = useMemo(() => {
195
+ if (children) {
196
+ return children
197
+ }
198
+
199
+ if (!errors?.length) {
200
+ return null
201
+ }
202
+
203
+ const uniqueErrors = [
204
+ ...new Map(errors.map((error) => [error?.message, error])).values(),
205
+ ]
206
+
207
+ if (uniqueErrors?.length == 1) {
208
+ return uniqueErrors[0]?.message
209
+ }
210
+
211
+ return (
212
+ <ul className="ml-4 flex list-disc flex-col gap-1">
213
+ {uniqueErrors.map(
214
+ (error, index) =>
215
+ error?.message && <li key={index}>{error.message}</li>
216
+ )}
217
+ </ul>
218
+ )
219
+ }, [children, errors])
220
+
221
+ if (!content) {
222
+ return null
223
+ }
224
+
225
+ return (
226
+ <div
227
+ role="alert"
228
+ data-slot="field-error"
229
+ className={cn("text-destructive text-sm font-normal", className)}
230
+ {...props}
231
+ >
232
+ {content}
233
+ </div>
234
+ )
235
+ }
236
+
237
+ export {
238
+ Field,
239
+ FieldLabel,
240
+ FieldDescription,
241
+ FieldError,
242
+ FieldGroup,
243
+ FieldLegend,
244
+ FieldSeparator,
245
+ FieldSet,
246
+ FieldContent,
247
+ FieldTitle,
248
+ }