@lark-apaas/coding-templates 0.1.3 → 0.1.5

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 (261) hide show
  1. package/package.json +2 -3
  2. package/template-vite-react/_gitignore +24 -0
  3. package/template-vite-react/client/index.html +13 -0
  4. package/template-vite-react/client/public/favicon.svg +1 -0
  5. package/template-vite-react/client/public/icons.svg +24 -0
  6. package/template-vite-react/client/src/api/index.ts +7 -0
  7. package/template-vite-react/client/src/app.tsx +19 -0
  8. package/{template-nextjs-static → template-vite-react/client}/src/components/header.tsx +5 -13
  9. package/template-vite-react/client/src/components/layout.tsx +13 -0
  10. package/template-vite-react/client/src/components/theme-provider.tsx +45 -0
  11. package/template-vite-react/client/src/components/ui/accordion.tsx +72 -0
  12. package/template-vite-react/client/src/components/ui/alert-dialog.tsx +187 -0
  13. package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/alert.tsx +15 -10
  14. package/template-vite-react/client/src/components/ui/aspect-ratio.tsx +22 -0
  15. package/template-vite-react/client/src/components/ui/avatar.tsx +109 -0
  16. package/template-vite-react/client/src/components/ui/badge.tsx +52 -0
  17. package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/breadcrumb.tsx +39 -23
  18. package/template-vite-react/client/src/components/ui/button.tsx +58 -0
  19. package/{template-nextjs-static → template-vite-react/client}/src/components/ui/calendar.tsx +43 -37
  20. package/template-vite-react/client/src/components/ui/card.tsx +103 -0
  21. package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/carousel.tsx +8 -7
  22. package/{template-nextjs-static → template-vite-react/client}/src/components/ui/chart.tsx +49 -35
  23. package/template-vite-react/client/src/components/ui/checkbox.tsx +29 -0
  24. package/template-vite-react/client/src/components/ui/collapsible.tsx +19 -0
  25. package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/command.tsx +40 -52
  26. package/template-vite-react/client/src/components/ui/context-menu.tsx +271 -0
  27. package/template-vite-react/client/src/components/ui/dialog.tsx +158 -0
  28. package/{template-nextjs-static → template-vite-react/client}/src/components/ui/drawer.tsx +9 -12
  29. package/template-vite-react/client/src/components/ui/dropdown-menu.tsx +268 -0
  30. package/template-vite-react/client/src/components/ui/hover-card.tsx +49 -0
  31. package/template-vite-react/client/src/components/ui/input-group.tsx +156 -0
  32. package/{template-nextjs-static → template-vite-react/client}/src/components/ui/input-otp.tsx +17 -7
  33. package/template-vite-react/client/src/components/ui/input.tsx +20 -0
  34. package/template-vite-react/client/src/components/ui/label.tsx +18 -0
  35. package/template-vite-react/client/src/components/ui/menubar.tsx +280 -0
  36. package/template-vite-react/client/src/components/ui/navigation-menu.tsx +168 -0
  37. package/{template-nextjs-static → template-vite-react/client}/src/components/ui/pagination.tsx +35 -32
  38. package/template-vite-react/client/src/components/ui/popover.tsx +90 -0
  39. package/template-vite-react/client/src/components/ui/progress.tsx +81 -0
  40. package/template-vite-react/client/src/components/ui/radio-group.tsx +38 -0
  41. package/template-vite-react/client/src/components/ui/resizable.tsx +48 -0
  42. package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/scroll-area.tsx +10 -13
  43. package/template-vite-react/client/src/components/ui/select.tsx +199 -0
  44. package/template-vite-react/client/src/components/ui/separator.tsx +25 -0
  45. package/template-vite-react/client/src/components/ui/sheet.tsx +138 -0
  46. package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/sidebar.tsx +156 -162
  47. package/{template-nextjs-static → template-vite-react/client}/src/components/ui/skeleton.tsx +1 -1
  48. package/template-vite-react/client/src/components/ui/slider.tsx +57 -0
  49. package/template-vite-react/client/src/components/ui/sonner.tsx +49 -0
  50. package/template-vite-react/client/src/components/ui/switch.tsx +30 -0
  51. package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/table.tsx +5 -5
  52. package/template-vite-react/client/src/components/ui/tabs.tsx +80 -0
  53. package/template-vite-react/client/src/components/ui/textarea.tsx +18 -0
  54. package/template-vite-react/client/src/components/ui/toggle-group.tsx +89 -0
  55. package/template-vite-react/client/src/components/ui/toggle.tsx +44 -0
  56. package/template-vite-react/client/src/components/ui/tooltip.tsx +64 -0
  57. package/template-vite-react/client/src/index.css +1 -0
  58. package/template-vite-react/client/src/main.tsx +13 -0
  59. package/template-vite-react/client/src/pages/home/index.tsx +12 -0
  60. package/template-vite-react/client/src/pages/not-found/index.tsx +11 -0
  61. package/template-vite-react/client/src/types/index.ts +1 -0
  62. package/{template-nextjs-static → template-vite-react}/components.json +2 -2
  63. package/template-vite-react/eslint.config.js +23 -0
  64. package/template-vite-react/package.json +58 -0
  65. package/template-vite-react/scripts/build.sh +40 -0
  66. package/template-vite-react/shared/types.ts +1 -0
  67. package/template-vite-react/tsconfig.app.json +33 -0
  68. package/template-vite-react/tsconfig.json +14 -0
  69. package/template-vite-react/tsconfig.node.json +26 -0
  70. package/template-vite-react/vite.config.ts +22 -0
  71. package/template-nextjs-fullstack/README.md +0 -169
  72. package/template-nextjs-fullstack/_env.local.example +0 -1
  73. package/template-nextjs-fullstack/_gitignore +0 -41
  74. package/template-nextjs-fullstack/components.json +0 -25
  75. package/template-nextjs-fullstack/drizzle.config.ts +0 -10
  76. package/template-nextjs-fullstack/eslint.config.js +0 -15
  77. package/template-nextjs-fullstack/next.config.ts +0 -5
  78. package/template-nextjs-fullstack/package.json +0 -85
  79. package/template-nextjs-fullstack/postcss.config.js +0 -8
  80. package/template-nextjs-fullstack/scripts/build.sh +0 -37
  81. package/template-nextjs-fullstack/src/app/favicon.ico +0 -0
  82. package/template-nextjs-fullstack/src/app/globals.css +0 -130
  83. package/template-nextjs-fullstack/src/app/layout.tsx +0 -24
  84. package/template-nextjs-fullstack/src/app/page.tsx +0 -69
  85. package/template-nextjs-fullstack/src/app/todos/actions.ts +0 -37
  86. package/template-nextjs-fullstack/src/app/todos/page.tsx +0 -26
  87. package/template-nextjs-fullstack/src/app/todos/todo-form.tsx +0 -27
  88. package/template-nextjs-fullstack/src/app/todos/todo-list.tsx +0 -44
  89. package/template-nextjs-fullstack/src/components/header.tsx +0 -32
  90. package/template-nextjs-fullstack/src/components/theme-provider.tsx +0 -8
  91. package/template-nextjs-fullstack/src/components/ui/README.md +0 -134
  92. package/template-nextjs-fullstack/src/components/ui/accordion.tsx +0 -66
  93. package/template-nextjs-fullstack/src/components/ui/alert-dialog.tsx +0 -157
  94. package/template-nextjs-fullstack/src/components/ui/aspect-ratio.tsx +0 -11
  95. package/template-nextjs-fullstack/src/components/ui/avatar.tsx +0 -53
  96. package/template-nextjs-fullstack/src/components/ui/badge.tsx +0 -42
  97. package/template-nextjs-fullstack/src/components/ui/button.tsx +0 -69
  98. package/template-nextjs-fullstack/src/components/ui/calendar.tsx +0 -213
  99. package/template-nextjs-fullstack/src/components/ui/card.tsx +0 -82
  100. package/template-nextjs-fullstack/src/components/ui/chart.tsx +0 -357
  101. package/template-nextjs-fullstack/src/components/ui/checkbox.tsx +0 -32
  102. package/template-nextjs-fullstack/src/components/ui/collapsible.tsx +0 -33
  103. package/template-nextjs-fullstack/src/components/ui/context-menu.tsx +0 -324
  104. package/template-nextjs-fullstack/src/components/ui/dialog.tsx +0 -143
  105. package/template-nextjs-fullstack/src/components/ui/drawer.tsx +0 -135
  106. package/template-nextjs-fullstack/src/components/ui/dropdown-menu.tsx +0 -329
  107. package/template-nextjs-fullstack/src/components/ui/hover-card.tsx +0 -44
  108. package/template-nextjs-fullstack/src/components/ui/input-group.tsx +0 -166
  109. package/template-nextjs-fullstack/src/components/ui/input-otp.tsx +0 -77
  110. package/template-nextjs-fullstack/src/components/ui/input.tsx +0 -21
  111. package/template-nextjs-fullstack/src/components/ui/label.tsx +0 -24
  112. package/template-nextjs-fullstack/src/components/ui/menubar.tsx +0 -348
  113. package/template-nextjs-fullstack/src/components/ui/navigation-menu.tsx +0 -168
  114. package/template-nextjs-fullstack/src/components/ui/pagination.tsx +0 -127
  115. package/template-nextjs-fullstack/src/components/ui/popover.tsx +0 -48
  116. package/template-nextjs-fullstack/src/components/ui/progress.tsx +0 -31
  117. package/template-nextjs-fullstack/src/components/ui/radio-group.tsx +0 -45
  118. package/template-nextjs-fullstack/src/components/ui/resizable.tsx +0 -56
  119. package/template-nextjs-fullstack/src/components/ui/select.tsx +0 -243
  120. package/template-nextjs-fullstack/src/components/ui/separator.tsx +0 -28
  121. package/template-nextjs-fullstack/src/components/ui/sheet.tsx +0 -139
  122. package/template-nextjs-fullstack/src/components/ui/skeleton.tsx +0 -13
  123. package/template-nextjs-fullstack/src/components/ui/slider.tsx +0 -87
  124. package/template-nextjs-fullstack/src/components/ui/sonner.tsx +0 -67
  125. package/template-nextjs-fullstack/src/components/ui/switch.tsx +0 -31
  126. package/template-nextjs-fullstack/src/components/ui/tabs.tsx +0 -66
  127. package/template-nextjs-fullstack/src/components/ui/textarea.tsx +0 -18
  128. package/template-nextjs-fullstack/src/components/ui/toggle-group.tsx +0 -83
  129. package/template-nextjs-fullstack/src/components/ui/toggle.tsx +0 -47
  130. package/template-nextjs-fullstack/src/components/ui/tooltip.tsx +0 -61
  131. package/template-nextjs-fullstack/src/db/index.ts +0 -8
  132. package/template-nextjs-fullstack/src/db/schema.ts +0 -11
  133. package/template-nextjs-fullstack/tailwind.config.ts +0 -10
  134. package/template-nextjs-fullstack/tsconfig.json +0 -34
  135. package/template-nextjs-static/README.md +0 -80
  136. package/template-nextjs-static/_gitignore +0 -41
  137. package/template-nextjs-static/eslint.config.js +0 -15
  138. package/template-nextjs-static/next.config.ts +0 -8
  139. package/template-nextjs-static/package.json +0 -77
  140. package/template-nextjs-static/postcss.config.js +0 -8
  141. package/template-nextjs-static/public/favicon.ico +0 -0
  142. package/template-nextjs-static/scripts/build.sh +0 -36
  143. package/template-nextjs-static/src/components/theme-provider.tsx +0 -6
  144. package/template-nextjs-static/src/components/ui/README.md +0 -134
  145. package/template-nextjs-static/src/components/ui/accordion.tsx +0 -66
  146. package/template-nextjs-static/src/components/ui/alert-dialog.tsx +0 -157
  147. package/template-nextjs-static/src/components/ui/alert.tsx +0 -71
  148. package/template-nextjs-static/src/components/ui/aspect-ratio.tsx +0 -11
  149. package/template-nextjs-static/src/components/ui/avatar.tsx +0 -53
  150. package/template-nextjs-static/src/components/ui/badge.tsx +0 -42
  151. package/template-nextjs-static/src/components/ui/breadcrumb.tsx +0 -109
  152. package/template-nextjs-static/src/components/ui/button-group.tsx +0 -83
  153. package/template-nextjs-static/src/components/ui/button.tsx +0 -69
  154. package/template-nextjs-static/src/components/ui/card.tsx +0 -82
  155. package/template-nextjs-static/src/components/ui/carousel.tsx +0 -241
  156. package/template-nextjs-static/src/components/ui/checkbox.tsx +0 -32
  157. package/template-nextjs-static/src/components/ui/collapsible.tsx +0 -33
  158. package/template-nextjs-static/src/components/ui/command.tsx +0 -208
  159. package/template-nextjs-static/src/components/ui/context-menu.tsx +0 -324
  160. package/template-nextjs-static/src/components/ui/dialog.tsx +0 -143
  161. package/template-nextjs-static/src/components/ui/dropdown-menu.tsx +0 -329
  162. package/template-nextjs-static/src/components/ui/empty.tsx +0 -104
  163. package/template-nextjs-static/src/components/ui/field.tsx +0 -248
  164. package/template-nextjs-static/src/components/ui/form.tsx +0 -167
  165. package/template-nextjs-static/src/components/ui/hover-card.tsx +0 -44
  166. package/template-nextjs-static/src/components/ui/icons/file-ae-colorful-icon.tsx +0 -21
  167. package/template-nextjs-static/src/components/ui/icons/file-ai-colorful-icon.tsx +0 -36
  168. package/template-nextjs-static/src/components/ui/icons/file-android-colorful-icon.tsx +0 -33
  169. package/template-nextjs-static/src/components/ui/icons/file-audio-colorful-icon.tsx +0 -21
  170. package/template-nextjs-static/src/components/ui/icons/file-code-colorful-icon.tsx +0 -28
  171. package/template-nextjs-static/src/components/ui/icons/file-csv-colorful-icon.tsx +0 -21
  172. package/template-nextjs-static/src/components/ui/icons/file-eml-colorful-icon.tsx +0 -29
  173. package/template-nextjs-static/src/components/ui/icons/file-ios-colorful-icon.tsx +0 -25
  174. package/template-nextjs-static/src/components/ui/icons/file-keynote-colorful-icon.tsx +0 -29
  175. package/template-nextjs-static/src/components/ui/icons/file-pages-colorful-icon.tsx +0 -29
  176. package/template-nextjs-static/src/components/ui/icons/file-ps-colorful-icon.tsx +0 -21
  177. package/template-nextjs-static/src/components/ui/icons/file-sketch-colorful-icon.tsx +0 -21
  178. package/template-nextjs-static/src/components/ui/icons/file-slide-colorful-icon.tsx +0 -21
  179. package/template-nextjs-static/src/components/ui/icons/file-vcf-colorful-icon.tsx +0 -29
  180. package/template-nextjs-static/src/components/ui/icons/file-wiki-excel-colorful-icon.tsx +0 -23
  181. package/template-nextjs-static/src/components/ui/icons/file-wiki-image-colorful-icon.tsx +0 -27
  182. package/template-nextjs-static/src/components/ui/icons/file-wiki-pdf-colorful-icon.tsx +0 -20
  183. package/template-nextjs-static/src/components/ui/icons/file-wiki-ppt-colorful-icon.tsx +0 -21
  184. package/template-nextjs-static/src/components/ui/icons/file-wiki-text-colorful-icon.tsx +0 -12
  185. package/template-nextjs-static/src/components/ui/icons/file-wiki-unknown-colorful-icon.tsx +0 -14
  186. package/template-nextjs-static/src/components/ui/icons/file-wiki-video-colorful-icon.tsx +0 -23
  187. package/template-nextjs-static/src/components/ui/icons/file-wiki-word-colorful-icon.tsx +0 -38
  188. package/template-nextjs-static/src/components/ui/icons/file-wiki-zip-colorful-icon.tsx +0 -21
  189. package/template-nextjs-static/src/components/ui/image.tsx +0 -183
  190. package/template-nextjs-static/src/components/ui/input-group.tsx +0 -166
  191. package/template-nextjs-static/src/components/ui/input.tsx +0 -21
  192. package/template-nextjs-static/src/components/ui/item.tsx +0 -193
  193. package/template-nextjs-static/src/components/ui/kbd.tsx +0 -28
  194. package/template-nextjs-static/src/components/ui/label.tsx +0 -24
  195. package/template-nextjs-static/src/components/ui/menubar.tsx +0 -348
  196. package/template-nextjs-static/src/components/ui/native-select.tsx +0 -48
  197. package/template-nextjs-static/src/components/ui/navigation-menu.tsx +0 -168
  198. package/template-nextjs-static/src/components/ui/popover.tsx +0 -48
  199. package/template-nextjs-static/src/components/ui/progress.tsx +0 -31
  200. package/template-nextjs-static/src/components/ui/radio-group.tsx +0 -45
  201. package/template-nextjs-static/src/components/ui/resizable.tsx +0 -56
  202. package/template-nextjs-static/src/components/ui/scroll-area.tsx +0 -58
  203. package/template-nextjs-static/src/components/ui/select.tsx +0 -243
  204. package/template-nextjs-static/src/components/ui/separator.tsx +0 -28
  205. package/template-nextjs-static/src/components/ui/sheet.tsx +0 -139
  206. package/template-nextjs-static/src/components/ui/sidebar.tsx +0 -727
  207. package/template-nextjs-static/src/components/ui/slider.tsx +0 -87
  208. package/template-nextjs-static/src/components/ui/sonner.tsx +0 -67
  209. package/template-nextjs-static/src/components/ui/spinner.tsx +0 -16
  210. package/template-nextjs-static/src/components/ui/streamdown.tsx +0 -186
  211. package/template-nextjs-static/src/components/ui/switch.tsx +0 -31
  212. package/template-nextjs-static/src/components/ui/table.tsx +0 -116
  213. package/template-nextjs-static/src/components/ui/tabs.tsx +0 -66
  214. package/template-nextjs-static/src/components/ui/textarea.tsx +0 -18
  215. package/template-nextjs-static/src/components/ui/toggle-group.tsx +0 -83
  216. package/template-nextjs-static/src/components/ui/toggle.tsx +0 -47
  217. package/template-nextjs-static/src/components/ui/tooltip.tsx +0 -61
  218. package/template-nextjs-static/src/hooks/use-mobile.ts +0 -19
  219. package/template-nextjs-static/src/lib/utils.ts +0 -6
  220. package/template-nextjs-static/src/pages/_app.tsx +0 -11
  221. package/template-nextjs-static/src/pages/_document.tsx +0 -13
  222. package/template-nextjs-static/src/pages/hello.tsx +0 -32
  223. package/template-nextjs-static/src/pages/index.tsx +0 -76
  224. package/template-nextjs-static/src/styles/globals.css +0 -143
  225. package/template-nextjs-static/tailwind.config.ts +0 -10
  226. package/template-nextjs-static/tsconfig.json +0 -34
  227. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/button-group.tsx +0 -0
  228. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/empty.tsx +0 -0
  229. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/field.tsx +0 -0
  230. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/form.tsx +0 -0
  231. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-ae-colorful-icon.tsx +0 -0
  232. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-ai-colorful-icon.tsx +0 -0
  233. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-android-colorful-icon.tsx +0 -0
  234. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-audio-colorful-icon.tsx +0 -0
  235. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-code-colorful-icon.tsx +0 -0
  236. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-csv-colorful-icon.tsx +0 -0
  237. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-eml-colorful-icon.tsx +0 -0
  238. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-ios-colorful-icon.tsx +0 -0
  239. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-keynote-colorful-icon.tsx +0 -0
  240. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-pages-colorful-icon.tsx +0 -0
  241. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-ps-colorful-icon.tsx +0 -0
  242. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-sketch-colorful-icon.tsx +0 -0
  243. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-slide-colorful-icon.tsx +0 -0
  244. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-vcf-colorful-icon.tsx +0 -0
  245. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-wiki-excel-colorful-icon.tsx +0 -0
  246. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-wiki-image-colorful-icon.tsx +0 -0
  247. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-wiki-pdf-colorful-icon.tsx +0 -0
  248. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-wiki-ppt-colorful-icon.tsx +0 -0
  249. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-wiki-text-colorful-icon.tsx +0 -0
  250. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-wiki-unknown-colorful-icon.tsx +0 -0
  251. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-wiki-video-colorful-icon.tsx +0 -0
  252. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-wiki-word-colorful-icon.tsx +0 -0
  253. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/icons/file-wiki-zip-colorful-icon.tsx +0 -0
  254. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/image.tsx +0 -0
  255. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/item.tsx +0 -0
  256. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/kbd.tsx +0 -0
  257. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/native-select.tsx +0 -0
  258. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/spinner.tsx +0 -0
  259. /package/{template-nextjs-fullstack → template-vite-react/client}/src/components/ui/streamdown.tsx +0 -0
  260. /package/{template-nextjs-fullstack → template-vite-react/client}/src/hooks/use-mobile.ts +0 -0
  261. /package/{template-nextjs-fullstack → template-vite-react/client}/src/lib/utils.ts +0 -0
@@ -1,12 +1,10 @@
1
- "use client"
2
-
3
1
  import * as React from "react"
4
- import { Slot } from "@radix-ui/react-slot"
2
+ import { mergeProps } from "@base-ui/react/merge-props"
3
+ import { useRender } from "@base-ui/react/use-render"
5
4
  import { cva, type VariantProps } from "class-variance-authority"
6
- import { PanelLeftIcon } from "lucide-react"
7
5
 
8
- import { cn } from "@/lib/utils"
9
6
  import { useIsMobile } from "@/hooks/use-mobile"
7
+ import { cn } from "@/lib/utils"
10
8
  import { Button } from "@/components/ui/button"
11
9
  import { Input } from "@/components/ui/input"
12
10
  import { Separator } from "@/components/ui/separator"
@@ -21,9 +19,9 @@ import { Skeleton } from "@/components/ui/skeleton"
21
19
  import {
22
20
  Tooltip,
23
21
  TooltipContent,
24
- TooltipProvider,
25
22
  TooltipTrigger,
26
23
  } from "@/components/ui/tooltip"
24
+ import { PanelLeftIcon } from "lucide-react"
27
25
 
28
26
  const SIDEBAR_COOKIE_NAME = "sidebar_state"
29
27
  const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
@@ -128,25 +126,23 @@ function SidebarProvider({
128
126
 
129
127
  return (
130
128
  <SidebarContext.Provider value={contextValue}>
131
- <TooltipProvider delayDuration={0}>
132
- <div
133
- data-slot="sidebar-wrapper"
134
- style={
135
- {
136
- "--sidebar-width": SIDEBAR_WIDTH,
137
- "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
138
- ...style,
139
- } as React.CSSProperties
140
- }
141
- className={cn(
142
- "group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full",
143
- className
144
- )}
145
- {...props}
146
- >
147
- {children}
148
- </div>
149
- </TooltipProvider>
129
+ <div
130
+ data-slot="sidebar-wrapper"
131
+ style={
132
+ {
133
+ "--sidebar-width": SIDEBAR_WIDTH,
134
+ "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
135
+ ...style,
136
+ } as React.CSSProperties
137
+ }
138
+ className={cn(
139
+ "group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar",
140
+ className
141
+ )}
142
+ {...props}
143
+ >
144
+ {children}
145
+ </div>
150
146
  </SidebarContext.Provider>
151
147
  )
152
148
  }
@@ -157,6 +153,7 @@ function Sidebar({
157
153
  collapsible = "offcanvas",
158
154
  className,
159
155
  children,
156
+ dir,
160
157
  ...props
161
158
  }: React.ComponentProps<"div"> & {
162
159
  side?: "left" | "right"
@@ -170,7 +167,7 @@ function Sidebar({
170
167
  <div
171
168
  data-slot="sidebar"
172
169
  className={cn(
173
- "bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col",
170
+ "flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground",
174
171
  className
175
172
  )}
176
173
  {...props}
@@ -184,10 +181,11 @@ function Sidebar({
184
181
  return (
185
182
  <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
186
183
  <SheetContent
184
+ dir={dir}
187
185
  data-sidebar="sidebar"
188
186
  data-slot="sidebar"
189
187
  data-mobile="true"
190
- className="bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden"
188
+ className="w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
191
189
  style={
192
190
  {
193
191
  "--sidebar-width": SIDEBAR_WIDTH_MOBILE,
@@ -207,7 +205,7 @@ function Sidebar({
207
205
 
208
206
  return (
209
207
  <div
210
- className="group peer text-sidebar-foreground hidden md:block"
208
+ className="group peer hidden text-sidebar-foreground md:block"
211
209
  data-state={state}
212
210
  data-collapsible={state === "collapsed" ? collapsible : ""}
213
211
  data-variant={variant}
@@ -228,11 +226,9 @@ function Sidebar({
228
226
  />
229
227
  <div
230
228
  data-slot="sidebar-container"
229
+ data-side={side}
231
230
  className={cn(
232
- "fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex",
233
- side === "left"
234
- ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]"
235
- : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
231
+ "fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex",
236
232
  // Adjust the padding for floating and inset variants.
237
233
  variant === "floating" || variant === "inset"
238
234
  ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]"
@@ -244,7 +240,7 @@ function Sidebar({
244
240
  <div
245
241
  data-sidebar="sidebar"
246
242
  data-slot="sidebar-inner"
247
- className="bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"
243
+ className="flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 group-data-[variant=floating]:ring-sidebar-border"
248
244
  >
249
245
  {children}
250
246
  </div>
@@ -265,8 +261,8 @@ function SidebarTrigger({
265
261
  data-sidebar="trigger"
266
262
  data-slot="sidebar-trigger"
267
263
  variant="ghost"
268
- size="icon"
269
- className={cn("size-7", className)}
264
+ size="icon-sm"
265
+ className={cn(className)}
270
266
  onClick={(event) => {
271
267
  onClick?.(event)
272
268
  toggleSidebar()
@@ -291,10 +287,10 @@ function SidebarRail({ className, ...props }: React.ComponentProps<"button">) {
291
287
  onClick={toggleSidebar}
292
288
  title="Toggle Sidebar"
293
289
  className={cn(
294
- "hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex",
290
+ "absolute inset-y-0 z-20 hidden w-4 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2",
295
291
  "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize",
296
292
  "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
297
- "hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full",
293
+ "group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar",
298
294
  "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
299
295
  "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
300
296
  className
@@ -309,8 +305,7 @@ function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
309
305
  <main
310
306
  data-slot="sidebar-inset"
311
307
  className={cn(
312
- "bg-background relative flex w-full flex-1 flex-col",
313
- "md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2",
308
+ "relative flex w-full flex-1 flex-col bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2",
314
309
  className
315
310
  )}
316
311
  {...props}
@@ -326,7 +321,7 @@ function SidebarInput({
326
321
  <Input
327
322
  data-slot="sidebar-input"
328
323
  data-sidebar="input"
329
- className={cn("bg-background h-8 w-full shadow-none", className)}
324
+ className={cn("h-8 w-full bg-background shadow-none", className)}
330
325
  {...props}
331
326
  />
332
327
  )
@@ -362,7 +357,7 @@ function SidebarSeparator({
362
357
  <Separator
363
358
  data-slot="sidebar-separator"
364
359
  data-sidebar="separator"
365
- className={cn("bg-sidebar-border mx-2 w-auto", className)}
360
+ className={cn("mx-2 w-auto bg-sidebar-border", className)}
366
361
  {...props}
367
362
  />
368
363
  )
@@ -374,7 +369,7 @@ function SidebarContent({ className, ...props }: React.ComponentProps<"div">) {
374
369
  data-slot="sidebar-content"
375
370
  data-sidebar="content"
376
371
  className={cn(
377
- "flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
372
+ "no-scrollbar flex min-h-0 flex-1 flex-col gap-0 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
378
373
  className
379
374
  )}
380
375
  {...props}
@@ -395,46 +390,50 @@ function SidebarGroup({ className, ...props }: React.ComponentProps<"div">) {
395
390
 
396
391
  function SidebarGroupLabel({
397
392
  className,
398
- asChild = false,
393
+ render,
399
394
  ...props
400
- }: React.ComponentProps<"div"> & { asChild?: boolean }) {
401
- const Comp = asChild ? Slot : "div"
402
-
403
- return (
404
- <Comp
405
- data-slot="sidebar-group-label"
406
- data-sidebar="group-label"
407
- className={cn(
408
- "text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
409
- "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
410
- className
411
- )}
412
- {...props}
413
- />
414
- )
395
+ }: useRender.ComponentProps<"div"> & React.ComponentProps<"div">) {
396
+ return useRender({
397
+ defaultTagName: "div",
398
+ props: mergeProps<"div">(
399
+ {
400
+ className: cn(
401
+ "flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
402
+ className
403
+ ),
404
+ },
405
+ props
406
+ ),
407
+ render,
408
+ state: {
409
+ slot: "sidebar-group-label",
410
+ sidebar: "group-label",
411
+ },
412
+ })
415
413
  }
416
414
 
417
415
  function SidebarGroupAction({
418
416
  className,
419
- asChild = false,
417
+ render,
420
418
  ...props
421
- }: React.ComponentProps<"button"> & { asChild?: boolean }) {
422
- const Comp = asChild ? Slot : "button"
423
-
424
- return (
425
- <Comp
426
- data-slot="sidebar-group-action"
427
- data-sidebar="group-action"
428
- className={cn(
429
- "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
430
- // Increases the hit area of the button on mobile.
431
- "after:absolute after:-inset-2 md:after:hidden",
432
- "group-data-[collapsible=icon]:hidden",
433
- className
434
- )}
435
- {...props}
436
- />
437
- )
419
+ }: useRender.ComponentProps<"button"> & React.ComponentProps<"button">) {
420
+ return useRender({
421
+ defaultTagName: "button",
422
+ props: mergeProps<"button">(
423
+ {
424
+ className: cn(
425
+ "absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
426
+ className
427
+ ),
428
+ },
429
+ props
430
+ ),
431
+ render,
432
+ state: {
433
+ slot: "sidebar-group-action",
434
+ sidebar: "group-action",
435
+ },
436
+ })
438
437
  }
439
438
 
440
439
  function SidebarGroupContent({
@@ -456,7 +455,7 @@ function SidebarMenu({ className, ...props }: React.ComponentProps<"ul">) {
456
455
  <ul
457
456
  data-slot="sidebar-menu"
458
457
  data-sidebar="menu"
459
- className={cn("flex w-full min-w-0 flex-col gap-1", className)}
458
+ className={cn("flex w-full min-w-0 flex-col gap-0", className)}
460
459
  {...props}
461
460
  />
462
461
  )
@@ -474,14 +473,13 @@ function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
474
473
  }
475
474
 
476
475
  const sidebarMenuButtonVariants = cva(
477
- "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] not-disabled:hover:bg-sidebar-accent not-disabled:hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:cursor-not-allowed disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground not-disabled:data-[state=open]:hover:bg-sidebar-accent not-disabled:data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
476
+ "peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate",
478
477
  {
479
478
  variants: {
480
479
  variant: {
481
- default:
482
- "not-disabled:hover:bg-sidebar-accent not-disabled:hover:text-sidebar-accent-foreground",
480
+ default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
483
481
  outline:
484
- "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] not-disabled:hover:bg-sidebar-accent not-disabled:hover:text-sidebar-accent-foreground not-disabled:hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
482
+ "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]",
485
483
  },
486
484
  size: {
487
485
  default: "h-8 text-sm",
@@ -497,34 +495,38 @@ const sidebarMenuButtonVariants = cva(
497
495
  )
498
496
 
499
497
  function SidebarMenuButton({
500
- asChild = false,
498
+ render,
501
499
  isActive = false,
502
500
  variant = "default",
503
501
  size = "default",
504
502
  tooltip,
505
503
  className,
506
504
  ...props
507
- }: React.ComponentProps<"button"> & {
508
- asChild?: boolean
509
- isActive?: boolean
510
- tooltip?: string | React.ComponentProps<typeof TooltipContent>
511
- } & VariantProps<typeof sidebarMenuButtonVariants>) {
512
- const Comp = asChild ? Slot : "button"
505
+ }: useRender.ComponentProps<"button"> &
506
+ React.ComponentProps<"button"> & {
507
+ isActive?: boolean
508
+ tooltip?: string | React.ComponentProps<typeof TooltipContent>
509
+ } & VariantProps<typeof sidebarMenuButtonVariants>) {
513
510
  const { isMobile, state } = useSidebar()
514
-
515
- const button = (
516
- <Comp
517
- data-slot="sidebar-menu-button"
518
- data-sidebar="menu-button"
519
- data-size={size}
520
- data-active={isActive}
521
- className={cn(sidebarMenuButtonVariants({ variant, size }), className)}
522
- {...props}
523
- />
524
- )
511
+ const comp = useRender({
512
+ defaultTagName: "button",
513
+ props: mergeProps<"button">(
514
+ {
515
+ className: cn(sidebarMenuButtonVariants({ variant, size }), className),
516
+ },
517
+ props
518
+ ),
519
+ render: !tooltip ? render : <TooltipTrigger render={render} />,
520
+ state: {
521
+ slot: "sidebar-menu-button",
522
+ sidebar: "menu-button",
523
+ size,
524
+ active: isActive,
525
+ },
526
+ })
525
527
 
526
528
  if (!tooltip) {
527
- return button
529
+ return comp
528
530
  }
529
531
 
530
532
  if (typeof tooltip === "string") {
@@ -535,7 +537,7 @@ function SidebarMenuButton({
535
537
 
536
538
  return (
537
539
  <Tooltip>
538
- <TooltipTrigger asChild>{button}</TooltipTrigger>
540
+ {comp}
539
541
  <TooltipContent
540
542
  side="right"
541
543
  align="center"
@@ -548,34 +550,32 @@ function SidebarMenuButton({
548
550
 
549
551
  function SidebarMenuAction({
550
552
  className,
551
- asChild = false,
553
+ render,
552
554
  showOnHover = false,
553
555
  ...props
554
- }: React.ComponentProps<"button"> & {
555
- asChild?: boolean
556
- showOnHover?: boolean
557
- }) {
558
- const Comp = asChild ? Slot : "button"
559
-
560
- return (
561
- <Comp
562
- data-slot="sidebar-menu-action"
563
- data-sidebar="menu-action"
564
- className={cn(
565
- "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
566
- // Increases the hit area of the button on mobile.
567
- "after:absolute after:-inset-2 md:after:hidden",
568
- "peer-data-[size=sm]/menu-button:top-1",
569
- "peer-data-[size=default]/menu-button:top-1.5",
570
- "peer-data-[size=lg]/menu-button:top-2.5",
571
- "group-data-[collapsible=icon]:hidden",
572
- showOnHover &&
573
- "peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0",
574
- className
575
- )}
576
- {...props}
577
- />
578
- )
556
+ }: useRender.ComponentProps<"button"> &
557
+ React.ComponentProps<"button"> & {
558
+ showOnHover?: boolean
559
+ }) {
560
+ return useRender({
561
+ defaultTagName: "button",
562
+ props: mergeProps<"button">(
563
+ {
564
+ className: cn(
565
+ "absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0",
566
+ showOnHover &&
567
+ "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-active/menu-button:text-sidebar-accent-foreground aria-expanded:opacity-100 md:opacity-0",
568
+ className
569
+ ),
570
+ },
571
+ props
572
+ ),
573
+ render,
574
+ state: {
575
+ slot: "sidebar-menu-action",
576
+ sidebar: "menu-action",
577
+ },
578
+ })
579
579
  }
580
580
 
581
581
  function SidebarMenuBadge({
@@ -587,12 +587,7 @@ function SidebarMenuBadge({
587
587
  data-slot="sidebar-menu-badge"
588
588
  data-sidebar="menu-badge"
589
589
  className={cn(
590
- "text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none",
591
- "peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
592
- "peer-data-[size=sm]/menu-button:top-1",
593
- "peer-data-[size=default]/menu-button:top-1.5",
594
- "peer-data-[size=lg]/menu-button:top-2.5",
595
- "group-data-[collapsible=icon]:hidden",
590
+ "pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 peer-data-active/menu-button:text-sidebar-accent-foreground",
596
591
  className
597
592
  )}
598
593
  {...props}
@@ -608,9 +603,9 @@ function SidebarMenuSkeleton({
608
603
  showIcon?: boolean
609
604
  }) {
610
605
  // Random width between 50 to 90%.
611
- const width = React.useMemo(() => {
606
+ const [width] = React.useState(() => {
612
607
  return `${Math.floor(Math.random() * 40) + 50}%`
613
- }, [])
608
+ })
614
609
 
615
610
  return (
616
611
  <div
@@ -644,8 +639,7 @@ function SidebarMenuSub({ className, ...props }: React.ComponentProps<"ul">) {
644
639
  data-slot="sidebar-menu-sub"
645
640
  data-sidebar="menu-sub"
646
641
  className={cn(
647
- "border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5",
648
- "group-data-[collapsible=icon]:hidden",
642
+ "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5 group-data-[collapsible=icon]:hidden",
649
643
  className
650
644
  )}
651
645
  {...props}
@@ -668,35 +662,35 @@ function SidebarMenuSubItem({
668
662
  }
669
663
 
670
664
  function SidebarMenuSubButton({
671
- asChild = false,
665
+ render,
672
666
  size = "md",
673
667
  isActive = false,
674
668
  className,
675
669
  ...props
676
- }: React.ComponentProps<"a"> & {
677
- asChild?: boolean
678
- size?: "sm" | "md"
679
- isActive?: boolean
680
- }) {
681
- const Comp = asChild ? Slot : "a"
682
-
683
- return (
684
- <Comp
685
- data-slot="sidebar-menu-sub-button"
686
- data-sidebar="menu-sub-button"
687
- data-size={size}
688
- data-active={isActive}
689
- className={cn(
690
- "text-sidebar-foreground ring-sidebar-ring not-disabled:hover:bg-sidebar-accent not-disabled:hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
691
- "data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground",
692
- size === "sm" && "text-xs",
693
- size === "md" && "text-sm",
694
- "group-data-[collapsible=icon]:hidden",
695
- className
696
- )}
697
- {...props}
698
- />
699
- )
670
+ }: useRender.ComponentProps<"a"> &
671
+ React.ComponentProps<"a"> & {
672
+ size?: "sm" | "md"
673
+ isActive?: boolean
674
+ }) {
675
+ return useRender({
676
+ defaultTagName: "a",
677
+ props: mergeProps<"a">(
678
+ {
679
+ className: cn(
680
+ "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[size=md]:text-sm data-[size=sm]:text-xs data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
681
+ className
682
+ ),
683
+ },
684
+ props
685
+ ),
686
+ render,
687
+ state: {
688
+ slot: "sidebar-menu-sub-button",
689
+ sidebar: "menu-sub-button",
690
+ size,
691
+ active: isActive,
692
+ },
693
+ })
700
694
  }
701
695
 
702
696
  export {
@@ -4,7 +4,7 @@ function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
4
4
  return (
5
5
  <div
6
6
  data-slot="skeleton"
7
- className={cn("bg-accent animate-pulse rounded-md", className)}
7
+ className={cn("animate-pulse rounded-md bg-muted", className)}
8
8
  {...props}
9
9
  />
10
10
  )
@@ -0,0 +1,57 @@
1
+ import * as React from "react"
2
+ import { Slider as SliderPrimitive } from "@base-ui/react/slider"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ function Slider({
7
+ className,
8
+ defaultValue,
9
+ value,
10
+ min = 0,
11
+ max = 100,
12
+ ...props
13
+ }: SliderPrimitive.Root.Props) {
14
+ const _values = React.useMemo(
15
+ () =>
16
+ Array.isArray(value)
17
+ ? value
18
+ : Array.isArray(defaultValue)
19
+ ? defaultValue
20
+ : [min, max],
21
+ [value, defaultValue, min, max]
22
+ )
23
+
24
+ return (
25
+ <SliderPrimitive.Root
26
+ className={cn("data-horizontal:w-full data-vertical:h-full", className)}
27
+ data-slot="slider"
28
+ defaultValue={defaultValue}
29
+ value={value}
30
+ min={min}
31
+ max={max}
32
+ thumbAlignment="edge"
33
+ {...props}
34
+ >
35
+ <SliderPrimitive.Control className="relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col">
36
+ <SliderPrimitive.Track
37
+ data-slot="slider-track"
38
+ className="relative grow overflow-hidden rounded-full bg-muted select-none data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1"
39
+ >
40
+ <SliderPrimitive.Indicator
41
+ data-slot="slider-range"
42
+ className="bg-primary select-none data-horizontal:h-full data-vertical:w-full"
43
+ />
44
+ </SliderPrimitive.Track>
45
+ {Array.from({ length: _values.length }, (_, index) => (
46
+ <SliderPrimitive.Thumb
47
+ data-slot="slider-thumb"
48
+ key={index}
49
+ className="relative block size-3 shrink-0 rounded-full border border-ring bg-white ring-ring/50 transition-[color,box-shadow] select-none after:absolute after:-inset-2 hover:ring-3 focus-visible:ring-3 focus-visible:outline-hidden active:ring-3 disabled:pointer-events-none disabled:opacity-50"
50
+ />
51
+ ))}
52
+ </SliderPrimitive.Control>
53
+ </SliderPrimitive.Root>
54
+ )
55
+ }
56
+
57
+ export { Slider }
@@ -0,0 +1,49 @@
1
+ "use client"
2
+
3
+ import { useTheme } from "next-themes"
4
+ import { Toaster as Sonner, type ToasterProps } from "sonner"
5
+ import { CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon, Loader2Icon } from "lucide-react"
6
+
7
+ const Toaster = ({ ...props }: ToasterProps) => {
8
+ const { theme = "system" } = useTheme()
9
+
10
+ return (
11
+ <Sonner
12
+ theme={theme as ToasterProps["theme"]}
13
+ className="toaster group"
14
+ icons={{
15
+ success: (
16
+ <CircleCheckIcon className="size-4" />
17
+ ),
18
+ info: (
19
+ <InfoIcon className="size-4" />
20
+ ),
21
+ warning: (
22
+ <TriangleAlertIcon className="size-4" />
23
+ ),
24
+ error: (
25
+ <OctagonXIcon className="size-4" />
26
+ ),
27
+ loading: (
28
+ <Loader2Icon className="size-4 animate-spin" />
29
+ ),
30
+ }}
31
+ style={
32
+ {
33
+ "--normal-bg": "var(--popover)",
34
+ "--normal-text": "var(--popover-foreground)",
35
+ "--normal-border": "var(--border)",
36
+ "--border-radius": "var(--radius)",
37
+ } as React.CSSProperties
38
+ }
39
+ toastOptions={{
40
+ classNames: {
41
+ toast: "cn-toast",
42
+ },
43
+ }}
44
+ {...props}
45
+ />
46
+ )
47
+ }
48
+
49
+ export { Toaster }