kaze 1.4.0 → 2.0.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 (261) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -1
  3. data/README.md +1 -1
  4. data/lib/kaze/commands/app/hotwire_stack.rb +2 -0
  5. data/lib/kaze/commands/app/inertia_react_stack.rb +5 -1
  6. data/lib/kaze/commands/app/inertia_vue_stack.rb +5 -1
  7. data/lib/kaze/commands/app.rb +9 -2
  8. data/lib/kaze/version.rb +1 -1
  9. data/stubs/default/config/routes.rb +11 -4
  10. data/stubs/default/test/integration/appearance_test.rb +11 -0
  11. data/stubs/default/test/integration/password_update_test.rb +9 -1
  12. data/stubs/hotwire/app/assets/tailwind/application.css +119 -1
  13. data/stubs/hotwire/app/components/breadcrumbs_component.rb +32 -0
  14. data/stubs/hotwire/app/components/danger_button_component.rb +1 -1
  15. data/stubs/hotwire/app/components/dropdown_component.html.erb +2 -2
  16. data/stubs/hotwire/app/components/dropdown_component.rb +5 -1
  17. data/stubs/hotwire/app/components/dropdown_link_component.rb +1 -1
  18. data/stubs/hotwire/app/components/heading_component.rb +19 -0
  19. data/stubs/hotwire/app/components/icon_component.rb +30 -0
  20. data/stubs/hotwire/app/components/input_error_component.rb +1 -1
  21. data/stubs/hotwire/app/components/input_label_component.rb +3 -3
  22. data/stubs/hotwire/app/components/modal_component.html.erb +2 -2
  23. data/stubs/hotwire/app/components/primary_button_component.rb +1 -1
  24. data/stubs/hotwire/app/components/secondary_button_component.rb +1 -1
  25. data/stubs/hotwire/app/components/sidebar_menu_button_component.rb +25 -0
  26. data/stubs/hotwire/app/components/text_input_component.rb +1 -1
  27. data/stubs/hotwire/app/components/user_avatar_component.rb +27 -0
  28. data/stubs/hotwire/app/controllers/application_controller.rb +1 -0
  29. data/stubs/hotwire/app/controllers/concerns/sidebar_state.rb +14 -0
  30. data/stubs/hotwire/app/controllers/settings/appearance_controller.rb +7 -0
  31. data/stubs/hotwire/app/controllers/settings/password_controller.rb +19 -0
  32. data/stubs/hotwire/app/controllers/{profile_controller.rb → settings/profile_controller.rb} +3 -4
  33. data/stubs/hotwire/app/views/auth/login.html.erb +1 -1
  34. data/stubs/hotwire/app/views/dashboard/index.html.erb +6 -11
  35. data/stubs/hotwire/app/views/layouts/_settings.html.erb +26 -0
  36. data/stubs/hotwire/app/views/layouts/_sidebar.html.erb +56 -0
  37. data/stubs/hotwire/app/views/layouts/_sidebar_header.html.erb +11 -0
  38. data/stubs/hotwire/app/views/layouts/_sidebar_user.html.erb +34 -0
  39. data/stubs/hotwire/app/views/layouts/application.html.erb +24 -15
  40. data/stubs/hotwire/app/views/settings/appearance/_update_appearance_form.html.erb +28 -0
  41. data/stubs/hotwire/app/views/settings/appearance/edit.html.erb +10 -0
  42. data/stubs/hotwire/app/views/{profile/partials → settings/password}/_update_password_form.html.erb +2 -10
  43. data/stubs/hotwire/app/views/settings/password/edit.html.erb +10 -0
  44. data/stubs/hotwire/app/views/{profile/partials → settings/profile}/_confirm_user_deletion_modal.html.erb +2 -2
  45. data/stubs/hotwire/app/views/settings/profile/_delete_user_form.html.erb +6 -0
  46. data/stubs/hotwire/app/views/{profile/partials → settings/profile}/_update_profile_information_form.html.erb +4 -12
  47. data/stubs/hotwire/app/views/{profile → settings/profile}/destroy.turbo_stream.erb +1 -1
  48. data/stubs/hotwire/app/views/settings/profile/edit.html.erb +14 -0
  49. data/stubs/inertia-common/app/controllers/concerns/handle_inertia_requests.rb +4 -1
  50. data/stubs/inertia-common/app/controllers/settings/appearance_controller.rb +7 -0
  51. data/stubs/inertia-common/app/controllers/settings/password_controller.rb +17 -0
  52. data/stubs/inertia-common/app/controllers/{profile_controller.rb → settings/profile_controller.rb} +2 -2
  53. data/stubs/inertia-common/test/integration/appearance_test.rb +11 -0
  54. data/stubs/inertia-common/test/integration/password_update_test.rb +10 -2
  55. data/stubs/inertia-react-ts/app/assets/tailwind/application.css +120 -1
  56. data/stubs/inertia-react-ts/app/javascript/Components/AppLogo.tsx +17 -0
  57. data/stubs/inertia-react-ts/app/javascript/Components/AppShell.tsx +9 -0
  58. data/stubs/inertia-react-ts/app/javascript/Components/AppSidebar.tsx +65 -0
  59. data/stubs/inertia-react-ts/app/javascript/Components/AppSidebarHeader.tsx +14 -0
  60. data/stubs/inertia-react-ts/app/javascript/Components/Breadcrumbs.tsx +43 -0
  61. data/stubs/inertia-react-ts/app/javascript/Components/Heading.tsx +19 -0
  62. data/stubs/inertia-react-ts/app/javascript/Components/InputError.tsx +1 -1
  63. data/stubs/inertia-react-ts/app/javascript/Components/NavFooter.tsx +32 -0
  64. data/stubs/inertia-react-ts/app/javascript/Components/NavMain.tsx +32 -0
  65. data/stubs/inertia-react-ts/app/javascript/Components/NavUser.tsx +39 -0
  66. data/stubs/inertia-react-ts/app/javascript/Components/UserInfo.tsx +23 -0
  67. data/stubs/inertia-react-ts/app/javascript/Components/UserMenuContent.tsx +57 -0
  68. data/stubs/inertia-react-ts/app/javascript/Components/ui/avatar.tsx +51 -0
  69. data/stubs/inertia-react-ts/app/javascript/Components/ui/breadcrumb.tsx +109 -0
  70. data/stubs/inertia-react-ts/app/javascript/Components/ui/button.tsx +49 -0
  71. data/stubs/inertia-react-ts/app/javascript/Components/ui/checkbox.tsx +27 -0
  72. data/stubs/inertia-react-ts/app/javascript/Components/ui/dialog.tsx +109 -0
  73. data/stubs/inertia-react-ts/app/javascript/Components/ui/dropdown-menu.tsx +217 -0
  74. data/stubs/inertia-react-ts/app/javascript/Components/ui/input.tsx +21 -0
  75. data/stubs/inertia-react-ts/app/javascript/Components/ui/label.tsx +19 -0
  76. data/stubs/inertia-react-ts/app/javascript/Components/ui/separator.tsx +26 -0
  77. data/stubs/inertia-react-ts/app/javascript/Components/ui/sheet.tsx +137 -0
  78. data/stubs/inertia-react-ts/app/javascript/Components/ui/sidebar.tsx +719 -0
  79. data/stubs/inertia-react-ts/app/javascript/Components/ui/skeleton.tsx +13 -0
  80. data/stubs/inertia-react-ts/app/javascript/Components/ui/tooltip.tsx +55 -0
  81. data/stubs/inertia-react-ts/app/javascript/Layouts/AuthenticatedLayout.tsx +19 -127
  82. data/stubs/inertia-react-ts/app/javascript/Layouts/GuestLayout.tsx +1 -1
  83. data/stubs/inertia-react-ts/app/javascript/Layouts/SettingsLayout.tsx +57 -0
  84. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ForgotPassword.tsx +6 -6
  85. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Login.tsx +17 -12
  86. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/Register.tsx +14 -14
  87. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/ResetPassword.tsx +10 -10
  88. data/stubs/inertia-react-ts/app/javascript/Pages/Auth/VerifyEmail.tsx +2 -2
  89. data/stubs/inertia-react-ts/app/javascript/Pages/Dashboard.tsx +13 -8
  90. data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Appearance.tsx +33 -0
  91. data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Partials/DeleteUserForm.tsx +107 -0
  92. data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Partials/UpdateAppearanceForm.tsx +41 -0
  93. data/stubs/inertia-react-ts/app/javascript/Pages/{Profile → Settings}/Partials/UpdatePasswordForm.tsx +12 -20
  94. data/stubs/inertia-react-ts/app/javascript/Pages/{Profile → Settings}/Partials/UpdateProfileInformationForm.tsx +13 -21
  95. data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Password.tsx +33 -0
  96. data/stubs/inertia-react-ts/app/javascript/Pages/Settings/Profile.tsx +35 -0
  97. data/stubs/inertia-react-ts/app/javascript/entrypoints/application.tsx +6 -1
  98. data/stubs/inertia-react-ts/app/javascript/hooks/use-initials.tsx +23 -0
  99. data/stubs/inertia-react-ts/app/javascript/hooks/use-mobile-navigation.tsx +11 -0
  100. data/stubs/inertia-react-ts/app/javascript/hooks/use-mobile.tsx +36 -0
  101. data/stubs/inertia-react-ts/app/javascript/lib/appearance.ts +1 -2
  102. data/stubs/inertia-react-ts/app/javascript/lib/utils.ts +6 -0
  103. data/stubs/inertia-react-ts/app/javascript/types/global.d.ts +2 -2
  104. data/stubs/inertia-react-ts/app/javascript/types/index.d.ts +14 -0
  105. data/stubs/inertia-react-ts/components.json +21 -0
  106. data/stubs/inertia-react-ts/package.json +13 -0
  107. data/stubs/inertia-vue-ts/app/assets/tailwind/application.css +120 -1
  108. data/stubs/inertia-vue-ts/app/javascript/Components/AppLogo.vue +17 -0
  109. data/stubs/inertia-vue-ts/app/javascript/Components/AppShell.vue +12 -0
  110. data/stubs/inertia-vue-ts/app/javascript/Components/AppSidebar.vue +65 -0
  111. data/stubs/inertia-vue-ts/app/javascript/Components/AppSidebarHeader.vue +20 -0
  112. data/stubs/inertia-vue-ts/app/javascript/Components/Breadcrumbs.vue +32 -0
  113. data/stubs/inertia-vue-ts/app/javascript/Components/Heading.vue +15 -0
  114. data/stubs/inertia-vue-ts/app/javascript/Components/InputError.vue +1 -1
  115. data/stubs/inertia-vue-ts/app/javascript/Components/NavFooter.vue +33 -0
  116. data/stubs/inertia-vue-ts/app/javascript/Components/NavMain.vue +32 -0
  117. data/stubs/inertia-vue-ts/app/javascript/Components/NavUser.vue +40 -0
  118. data/stubs/inertia-vue-ts/app/javascript/Components/UserInfo.vue +25 -0
  119. data/stubs/inertia-vue-ts/app/javascript/Components/UserMenuContent.vue +47 -0
  120. data/stubs/inertia-vue-ts/app/javascript/Components/ui/avatar/Avatar.vue +18 -0
  121. data/stubs/inertia-vue-ts/app/javascript/Components/ui/avatar/AvatarFallback.vue +21 -0
  122. data/stubs/inertia-vue-ts/app/javascript/Components/ui/avatar/AvatarImage.vue +16 -0
  123. data/stubs/inertia-vue-ts/app/javascript/Components/ui/avatar/index.ts +3 -0
  124. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/Breadcrumb.vue +17 -0
  125. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbEllipsis.vue +23 -0
  126. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbItem.vue +17 -0
  127. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbLink.vue +21 -0
  128. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbList.vue +17 -0
  129. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbPage.vue +20 -0
  130. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/BreadcrumbSeparator.vue +22 -0
  131. data/stubs/inertia-vue-ts/app/javascript/Components/ui/breadcrumb/index.ts +7 -0
  132. data/stubs/inertia-vue-ts/app/javascript/Components/ui/button/Button.vue +31 -0
  133. data/stubs/inertia-vue-ts/app/javascript/Components/ui/button/index.ts +34 -0
  134. data/stubs/inertia-vue-ts/app/javascript/Components/ui/checkbox/Checkbox.vue +35 -0
  135. data/stubs/inertia-vue-ts/app/javascript/Components/ui/checkbox/index.ts +1 -0
  136. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/Dialog.vue +15 -0
  137. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogClose.vue +12 -0
  138. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogContent.vue +52 -0
  139. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogDescription.vue +23 -0
  140. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogFooter.vue +25 -0
  141. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogHeader.vue +14 -0
  142. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogOverlay.vue +26 -0
  143. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogTitle.vue +23 -0
  144. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/DialogTrigger.vue +12 -0
  145. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dialog/index.ts +9 -0
  146. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenu.vue +15 -0
  147. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuContent.vue +37 -0
  148. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuGroup.vue +12 -0
  149. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuItem.vue +41 -0
  150. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuLabel.vue +23 -0
  151. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuSeparator.vue +23 -0
  152. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/DropdownMenuTrigger.vue +14 -0
  153. data/stubs/inertia-vue-ts/app/javascript/Components/ui/dropdown-menu/index.ts +7 -0
  154. data/stubs/inertia-vue-ts/app/javascript/Components/ui/input/Input.vue +50 -0
  155. data/stubs/inertia-vue-ts/app/javascript/Components/ui/input/index.ts +1 -0
  156. data/stubs/inertia-vue-ts/app/javascript/Components/ui/label/Label.vue +26 -0
  157. data/stubs/inertia-vue-ts/app/javascript/Components/ui/label/index.ts +1 -0
  158. data/stubs/inertia-vue-ts/app/javascript/Components/ui/separator/Separator.vue +29 -0
  159. data/stubs/inertia-vue-ts/app/javascript/Components/ui/separator/index.ts +1 -0
  160. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/Sheet.vue +19 -0
  161. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetClose.vue +15 -0
  162. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetContent.vue +62 -0
  163. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetDescription.vue +21 -0
  164. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetFooter.vue +16 -0
  165. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetHeader.vue +15 -0
  166. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetOverlay.vue +21 -0
  167. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetTitle.vue +21 -0
  168. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/SheetTrigger.vue +15 -0
  169. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sheet/index.ts +8 -0
  170. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/Sidebar.vue +96 -0
  171. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarContent.vue +18 -0
  172. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarFooter.vue +18 -0
  173. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarGroup.vue +18 -0
  174. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarGroupAction.vue +27 -0
  175. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarGroupContent.vue +18 -0
  176. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarGroupLabel.vue +25 -0
  177. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarHeader.vue +18 -0
  178. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarInput.vue +22 -0
  179. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarInset.vue +21 -0
  180. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenu.vue +18 -0
  181. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuAction.vue +35 -0
  182. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuBadge.vue +26 -0
  183. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuButton.vue +48 -0
  184. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuButtonChild.vue +36 -0
  185. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuItem.vue +18 -0
  186. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuSkeleton.vue +35 -0
  187. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuSub.vue +22 -0
  188. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuSubButton.vue +36 -0
  189. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarMenuSubItem.vue +18 -0
  190. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarProvider.vue +82 -0
  191. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarRail.vue +33 -0
  192. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarSeparator.vue +19 -0
  193. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/SidebarTrigger.vue +28 -0
  194. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/index.ts +60 -0
  195. data/stubs/inertia-vue-ts/app/javascript/Components/ui/sidebar/utils.ts +19 -0
  196. data/stubs/inertia-vue-ts/app/javascript/Components/ui/skeleton/Skeleton.vue +17 -0
  197. data/stubs/inertia-vue-ts/app/javascript/Components/ui/skeleton/index.ts +1 -0
  198. data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/Tooltip.vue +19 -0
  199. data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/TooltipContent.vue +34 -0
  200. data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/TooltipProvider.vue +14 -0
  201. data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/TooltipTrigger.vue +15 -0
  202. data/stubs/inertia-vue-ts/app/javascript/Components/ui/tooltip/index.ts +4 -0
  203. data/stubs/inertia-vue-ts/app/javascript/Layouts/AuthenticatedLayout.vue +17 -147
  204. data/stubs/inertia-vue-ts/app/javascript/Layouts/SettingsLayout.vue +57 -0
  205. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ForgotPassword.vue +7 -7
  206. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Login.vue +10 -12
  207. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/Register.vue +12 -14
  208. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/ResetPassword.vue +8 -10
  209. data/stubs/inertia-vue-ts/app/javascript/Pages/Auth/VerifyEmail.vue +3 -3
  210. data/stubs/inertia-vue-ts/app/javascript/Pages/Dashboard.vue +15 -10
  211. data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Appearance.vue +33 -0
  212. data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Partials/DeleteUserForm.vue +96 -0
  213. data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Partials/UpdateAppearanceForm.vue +42 -0
  214. data/stubs/inertia-vue-ts/app/javascript/Pages/{Profile → Settings}/Partials/UpdatePasswordForm.vue +12 -20
  215. data/stubs/inertia-vue-ts/app/javascript/Pages/{Profile → Settings}/Partials/UpdateProfileInformationForm.vue +12 -20
  216. data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Password.vue +33 -0
  217. data/stubs/inertia-vue-ts/app/javascript/Pages/Settings/Profile.vue +40 -0
  218. data/stubs/inertia-vue-ts/app/javascript/composables/useInitials.ts +29 -0
  219. data/stubs/inertia-vue-ts/app/javascript/lib/appearance.ts +1 -2
  220. data/stubs/inertia-vue-ts/app/javascript/lib/utils.ts +6 -0
  221. data/stubs/inertia-vue-ts/app/javascript/types/index.d.ts +14 -0
  222. data/stubs/inertia-vue-ts/app/javascript/types/vue-shims.d.ts +10 -0
  223. data/stubs/inertia-vue-ts/components.json +20 -0
  224. data/stubs/inertia-vue-ts/package.json +8 -1
  225. data/stubs/inertia-vue-ts/vite.config.ts +25 -1
  226. metadata +171 -46
  227. data/stubs/hotwire/app/components/nav_link_component.rb +0 -15
  228. data/stubs/hotwire/app/components/responsive_nav_link_component.rb +0 -15
  229. data/stubs/hotwire/app/controllers/password_controller.rb +0 -13
  230. data/stubs/hotwire/app/views/layouts/_navigation.html.erb +0 -82
  231. data/stubs/hotwire/app/views/profile/edit.html.erb +0 -29
  232. data/stubs/hotwire/app/views/profile/partials/_delete_user_form.html.erb +0 -14
  233. data/stubs/hotwire/app/views/profile/partials/_update_appearance_form.html.erb +0 -39
  234. data/stubs/inertia-common/app/controllers/password_controller.rb +0 -13
  235. data/stubs/inertia-react-ts/app/javascript/Components/Checkbox.tsx +0 -11
  236. data/stubs/inertia-react-ts/app/javascript/Components/DangerButton.tsx +0 -20
  237. data/stubs/inertia-react-ts/app/javascript/Components/Dropdown.tsx +0 -100
  238. data/stubs/inertia-react-ts/app/javascript/Components/InputLabel.tsx +0 -14
  239. data/stubs/inertia-react-ts/app/javascript/Components/Modal.tsx +0 -66
  240. data/stubs/inertia-react-ts/app/javascript/Components/NavLink.tsx +0 -21
  241. data/stubs/inertia-react-ts/app/javascript/Components/PrimaryButton.tsx +0 -20
  242. data/stubs/inertia-react-ts/app/javascript/Components/ResponsiveNavLink.tsx +0 -21
  243. data/stubs/inertia-react-ts/app/javascript/Components/SecondaryButton.tsx +0 -22
  244. data/stubs/inertia-react-ts/app/javascript/Components/TextInput.tsx +0 -32
  245. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Edit.tsx +0 -37
  246. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.tsx +0 -102
  247. data/stubs/inertia-react-ts/app/javascript/Pages/Profile/Partials/UpdateAppearanceForm.tsx +0 -47
  248. data/stubs/inertia-vue-ts/app/javascript/Components/Checkbox.vue +0 -29
  249. data/stubs/inertia-vue-ts/app/javascript/Components/DangerButton.vue +0 -7
  250. data/stubs/inertia-vue-ts/app/javascript/Components/Dropdown.vue +0 -75
  251. data/stubs/inertia-vue-ts/app/javascript/Components/DropdownLink.vue +0 -16
  252. data/stubs/inertia-vue-ts/app/javascript/Components/InputLabel.vue +0 -12
  253. data/stubs/inertia-vue-ts/app/javascript/Components/Modal.vue +0 -109
  254. data/stubs/inertia-vue-ts/app/javascript/Components/NavLink.vue +0 -21
  255. data/stubs/inertia-vue-ts/app/javascript/Components/PrimaryButton.vue +0 -7
  256. data/stubs/inertia-vue-ts/app/javascript/Components/ResponsiveNavLink.vue +0 -21
  257. data/stubs/inertia-vue-ts/app/javascript/Components/SecondaryButton.vue +0 -19
  258. data/stubs/inertia-vue-ts/app/javascript/Components/TextInput.vue +0 -23
  259. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Edit.vue +0 -43
  260. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/DeleteUserForm.vue +0 -99
  261. data/stubs/inertia-vue-ts/app/javascript/Pages/Profile/Partials/UpdateAppearanceForm.vue +0 -47
@@ -0,0 +1,49 @@
1
+ import { Slot } from '@radix-ui/react-slot'
2
+ import { cva, type VariantProps } from 'class-variance-authority'
3
+ import * as React from 'react'
4
+
5
+ import { cn } from '@/lib/utils'
6
+
7
+ const buttonVariants = cva(
8
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',
13
+ destructive:
14
+ 'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40',
15
+ outline: 'border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground',
16
+ secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',
17
+ ghost: 'hover:bg-accent hover:text-accent-foreground',
18
+ link: 'text-primary underline-offset-4 hover:underline',
19
+ },
20
+ size: {
21
+ default: 'h-9 px-4 py-2 has-[>svg]:px-3',
22
+ sm: 'h-8 rounded-md px-3 has-[>svg]:px-2.5',
23
+ lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
24
+ icon: 'size-9',
25
+ },
26
+ },
27
+ defaultVariants: {
28
+ variant: 'default',
29
+ size: 'default',
30
+ },
31
+ },
32
+ )
33
+
34
+ function Button({
35
+ className,
36
+ variant,
37
+ size,
38
+ asChild = false,
39
+ ...props
40
+ }: React.ComponentProps<'button'> &
41
+ VariantProps<typeof buttonVariants> & {
42
+ asChild?: boolean
43
+ }) {
44
+ const Comp = asChild ? Slot : 'button'
45
+
46
+ return <Comp data-slot="button" className={cn(buttonVariants({ variant, size, className }))} {...props} />
47
+ }
48
+
49
+ export { Button, buttonVariants }
@@ -0,0 +1,27 @@
1
+ import * as CheckboxPrimitive from '@radix-ui/react-checkbox'
2
+ import { CheckIcon } from 'lucide-react'
3
+ import * as React from 'react'
4
+
5
+ import { cn } from '@/lib/utils'
6
+
7
+ function Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) {
8
+ return (
9
+ <CheckboxPrimitive.Root
10
+ data-slot="checkbox"
11
+ className={cn(
12
+ 'peer border-input data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',
13
+ className,
14
+ )}
15
+ {...props}
16
+ >
17
+ <CheckboxPrimitive.Indicator
18
+ data-slot="checkbox-indicator"
19
+ className="flex items-center justify-center text-current transition-none"
20
+ >
21
+ <CheckIcon className="size-3.5" />
22
+ </CheckboxPrimitive.Indicator>
23
+ </CheckboxPrimitive.Root>
24
+ )
25
+ }
26
+
27
+ export { Checkbox }
@@ -0,0 +1,109 @@
1
+ import * as DialogPrimitive from '@radix-ui/react-dialog'
2
+ import { XIcon } from 'lucide-react'
3
+ import * as React from 'react'
4
+
5
+ import { cn } from '@/lib/utils'
6
+
7
+ function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {
8
+ return <DialogPrimitive.Root data-slot="dialog" {...props} />
9
+ }
10
+
11
+ function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
12
+ return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
13
+ }
14
+
15
+ function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
16
+ return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
17
+ }
18
+
19
+ function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {
20
+ return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
21
+ }
22
+
23
+ function DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
24
+ return (
25
+ <DialogPrimitive.Overlay
26
+ data-slot="dialog-overlay"
27
+ className={cn(
28
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80',
29
+ className,
30
+ )}
31
+ {...props}
32
+ />
33
+ )
34
+ }
35
+
36
+ function DialogContent({ className, children, ...props }: React.ComponentProps<typeof DialogPrimitive.Content>) {
37
+ return (
38
+ <DialogPortal data-slot="dialog-portal">
39
+ <DialogOverlay />
40
+ <DialogPrimitive.Content
41
+ data-slot="dialog-content"
42
+ className={cn(
43
+ 'bg-background 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 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
44
+ className,
45
+ )}
46
+ {...props}
47
+ >
48
+ {children}
49
+ <DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4">
50
+ <XIcon />
51
+ <span className="sr-only">Close</span>
52
+ </DialogPrimitive.Close>
53
+ </DialogPrimitive.Content>
54
+ </DialogPortal>
55
+ )
56
+ }
57
+
58
+ function DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
59
+ return (
60
+ <div
61
+ data-slot="dialog-header"
62
+ className={cn('flex flex-col gap-2 text-center sm:text-left', className)}
63
+ {...props}
64
+ />
65
+ )
66
+ }
67
+
68
+ function DialogFooter({ className, ...props }: React.ComponentProps<'div'>) {
69
+ return (
70
+ <div
71
+ data-slot="dialog-footer"
72
+ className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}
73
+ {...props}
74
+ />
75
+ )
76
+ }
77
+
78
+ function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {
79
+ return (
80
+ <DialogPrimitive.Title
81
+ data-slot="dialog-title"
82
+ className={cn('text-lg leading-none font-semibold', className)}
83
+ {...props}
84
+ />
85
+ )
86
+ }
87
+
88
+ function DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {
89
+ return (
90
+ <DialogPrimitive.Description
91
+ data-slot="dialog-description"
92
+ className={cn('text-muted-foreground text-sm', className)}
93
+ {...props}
94
+ />
95
+ )
96
+ }
97
+
98
+ export {
99
+ Dialog,
100
+ DialogClose,
101
+ DialogContent,
102
+ DialogDescription,
103
+ DialogFooter,
104
+ DialogHeader,
105
+ DialogOverlay,
106
+ DialogPortal,
107
+ DialogTitle,
108
+ DialogTrigger,
109
+ }
@@ -0,0 +1,217 @@
1
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'
2
+ import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react'
3
+ import * as React from 'react'
4
+
5
+ import { cn } from '@/lib/utils'
6
+
7
+ function DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
8
+ return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
9
+ }
10
+
11
+ function DropdownMenuPortal({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
12
+ return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
13
+ }
14
+
15
+ function DropdownMenuTrigger({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
16
+ return <DropdownMenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />
17
+ }
18
+
19
+ function DropdownMenuContent({
20
+ className,
21
+ sideOffset = 4,
22
+ ...props
23
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
24
+ return (
25
+ <DropdownMenuPrimitive.Portal>
26
+ <DropdownMenuPrimitive.Content
27
+ data-slot="dropdown-menu-content"
28
+ sideOffset={sideOffset}
29
+ className={cn(
30
+ '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] overflow-hidden rounded-md border p-1 shadow-md',
31
+ className,
32
+ )}
33
+ {...props}
34
+ />
35
+ </DropdownMenuPrimitive.Portal>
36
+ )
37
+ }
38
+
39
+ function DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
40
+ return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
41
+ }
42
+
43
+ function DropdownMenuItem({
44
+ className,
45
+ inset,
46
+ variant = 'default',
47
+ ...props
48
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
49
+ inset?: boolean
50
+ variant?: 'default' | 'destructive'
51
+ }) {
52
+ return (
53
+ <DropdownMenuPrimitive.Item
54
+ data-slot="dropdown-menu-item"
55
+ data-inset={inset}
56
+ data-variant={variant}
57
+ className={cn(
58
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive-foreground data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/40 data-[variant=destructive]:focus:text-destructive-foreground data-[variant=destructive]:*:[svg]:!text-destructive-foreground [&_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",
59
+ className,
60
+ )}
61
+ {...props}
62
+ />
63
+ )
64
+ }
65
+
66
+ function DropdownMenuCheckboxItem({
67
+ className,
68
+ children,
69
+ checked,
70
+ ...props
71
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
72
+ return (
73
+ <DropdownMenuPrimitive.CheckboxItem
74
+ data-slot="dropdown-menu-checkbox-item"
75
+ className={cn(
76
+ "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]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
77
+ className,
78
+ )}
79
+ checked={checked}
80
+ {...props}
81
+ >
82
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
83
+ <DropdownMenuPrimitive.ItemIndicator>
84
+ <CheckIcon className="size-4" />
85
+ </DropdownMenuPrimitive.ItemIndicator>
86
+ </span>
87
+ {children}
88
+ </DropdownMenuPrimitive.CheckboxItem>
89
+ )
90
+ }
91
+
92
+ function DropdownMenuRadioGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
93
+ return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />
94
+ }
95
+
96
+ function DropdownMenuRadioItem({
97
+ className,
98
+ children,
99
+ ...props
100
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
101
+ return (
102
+ <DropdownMenuPrimitive.RadioItem
103
+ data-slot="dropdown-menu-radio-item"
104
+ className={cn(
105
+ "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]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
106
+ className,
107
+ )}
108
+ {...props}
109
+ >
110
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
111
+ <DropdownMenuPrimitive.ItemIndicator>
112
+ <CircleIcon className="size-2 fill-current" />
113
+ </DropdownMenuPrimitive.ItemIndicator>
114
+ </span>
115
+ {children}
116
+ </DropdownMenuPrimitive.RadioItem>
117
+ )
118
+ }
119
+
120
+ function DropdownMenuLabel({
121
+ className,
122
+ inset,
123
+ ...props
124
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
125
+ inset?: boolean
126
+ }) {
127
+ return (
128
+ <DropdownMenuPrimitive.Label
129
+ data-slot="dropdown-menu-label"
130
+ data-inset={inset}
131
+ className={cn('px-2 py-1.5 text-sm font-medium data-[inset]:pl-8', className)}
132
+ {...props}
133
+ />
134
+ )
135
+ }
136
+
137
+ function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
138
+ return (
139
+ <DropdownMenuPrimitive.Separator
140
+ data-slot="dropdown-menu-separator"
141
+ className={cn('bg-border -mx-1 my-1 h-px', className)}
142
+ {...props}
143
+ />
144
+ )
145
+ }
146
+
147
+ function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {
148
+ return (
149
+ <span
150
+ data-slot="dropdown-menu-shortcut"
151
+ className={cn('text-muted-foreground ml-auto text-xs tracking-widest', className)}
152
+ {...props}
153
+ />
154
+ )
155
+ }
156
+
157
+ function DropdownMenuSub({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
158
+ return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
159
+ }
160
+
161
+ function DropdownMenuSubTrigger({
162
+ className,
163
+ inset,
164
+ children,
165
+ ...props
166
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
167
+ inset?: boolean
168
+ }) {
169
+ return (
170
+ <DropdownMenuPrimitive.SubTrigger
171
+ data-slot="dropdown-menu-sub-trigger"
172
+ data-inset={inset}
173
+ className={cn(
174
+ '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-hidden select-none data-[inset]:pl-8',
175
+ className,
176
+ )}
177
+ {...props}
178
+ >
179
+ {children}
180
+ <ChevronRightIcon className="ml-auto size-4" />
181
+ </DropdownMenuPrimitive.SubTrigger>
182
+ )
183
+ }
184
+
185
+ function DropdownMenuSubContent({
186
+ className,
187
+ ...props
188
+ }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
189
+ return (
190
+ <DropdownMenuPrimitive.SubContent
191
+ data-slot="dropdown-menu-sub-content"
192
+ className={cn(
193
+ '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] overflow-hidden rounded-md border p-1 shadow-lg',
194
+ className,
195
+ )}
196
+ {...props}
197
+ />
198
+ )
199
+ }
200
+
201
+ export {
202
+ DropdownMenu,
203
+ DropdownMenuPortal,
204
+ DropdownMenuTrigger,
205
+ DropdownMenuContent,
206
+ DropdownMenuGroup,
207
+ DropdownMenuLabel,
208
+ DropdownMenuItem,
209
+ DropdownMenuCheckboxItem,
210
+ DropdownMenuRadioGroup,
211
+ DropdownMenuRadioItem,
212
+ DropdownMenuSeparator,
213
+ DropdownMenuShortcut,
214
+ DropdownMenuSub,
215
+ DropdownMenuSubTrigger,
216
+ DropdownMenuSubContent,
217
+ }
@@ -0,0 +1,21 @@
1
+ import * as React from 'react'
2
+
3
+ import { cn } from '@/lib/utils'
4
+
5
+ function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
6
+ return (
7
+ <input
8
+ type={type}
9
+ data-slot="input"
10
+ className={cn(
11
+ 'border-input file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
12
+ 'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
13
+ 'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
14
+ className,
15
+ )}
16
+ {...props}
17
+ />
18
+ )
19
+ }
20
+
21
+ export { Input }
@@ -0,0 +1,19 @@
1
+ import * as LabelPrimitive from '@radix-ui/react-label'
2
+ import * as React from 'react'
3
+
4
+ import { cn } from '@/lib/utils'
5
+
6
+ function Label({ className, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) {
7
+ return (
8
+ <LabelPrimitive.Root
9
+ data-slot="label"
10
+ className={cn(
11
+ 'text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50',
12
+ className,
13
+ )}
14
+ {...props}
15
+ />
16
+ )
17
+ }
18
+
19
+ export { Label }
@@ -0,0 +1,26 @@
1
+ import * as SeparatorPrimitive from "@radix-ui/react-separator"
2
+ import * as React from "react"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ function Separator({
7
+ className,
8
+ orientation = "horizontal",
9
+ decorative = true,
10
+ ...props
11
+ }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
12
+ return (
13
+ <SeparatorPrimitive.Root
14
+ data-slot="separator-root"
15
+ decorative={decorative}
16
+ orientation={orientation}
17
+ className={cn(
18
+ "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
19
+ className
20
+ )}
21
+ {...props}
22
+ />
23
+ )
24
+ }
25
+
26
+ export { Separator }
@@ -0,0 +1,137 @@
1
+ import * as SheetPrimitive from "@radix-ui/react-dialog"
2
+ import { XIcon } from "lucide-react"
3
+ import * as React from "react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
8
+ return <SheetPrimitive.Root data-slot="sheet" {...props} />
9
+ }
10
+
11
+ function SheetTrigger({
12
+ ...props
13
+ }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
14
+ return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
15
+ }
16
+
17
+ function SheetClose({
18
+ ...props
19
+ }: React.ComponentProps<typeof SheetPrimitive.Close>) {
20
+ return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
21
+ }
22
+
23
+ function SheetPortal({
24
+ ...props
25
+ }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
26
+ return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
27
+ }
28
+
29
+ function SheetOverlay({
30
+ className,
31
+ ...props
32
+ }: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
33
+ return (
34
+ <SheetPrimitive.Overlay
35
+ data-slot="sheet-overlay"
36
+ className={cn(
37
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80",
38
+ className
39
+ )}
40
+ {...props}
41
+ />
42
+ )
43
+ }
44
+
45
+ function SheetContent({
46
+ className,
47
+ children,
48
+ side = "right",
49
+ ...props
50
+ }: React.ComponentProps<typeof SheetPrimitive.Content> & {
51
+ side?: "top" | "right" | "bottom" | "left"
52
+ }) {
53
+ return (
54
+ <SheetPortal>
55
+ <SheetOverlay />
56
+ <SheetPrimitive.Content
57
+ data-slot="sheet-content"
58
+ className={cn(
59
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
60
+ side === "right" &&
61
+ "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm",
62
+ side === "left" &&
63
+ "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm",
64
+ side === "top" &&
65
+ "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b",
66
+ side === "bottom" &&
67
+ "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t",
68
+ className
69
+ )}
70
+ {...props}
71
+ >
72
+ {children}
73
+ <SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
74
+ <XIcon className="size-4" />
75
+ <span className="sr-only">Close</span>
76
+ </SheetPrimitive.Close>
77
+ </SheetPrimitive.Content>
78
+ </SheetPortal>
79
+ )
80
+ }
81
+
82
+ function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
83
+ return (
84
+ <div
85
+ data-slot="sheet-header"
86
+ className={cn("flex flex-col gap-1.5 p-4", className)}
87
+ {...props}
88
+ />
89
+ )
90
+ }
91
+
92
+ function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
93
+ return (
94
+ <div
95
+ data-slot="sheet-footer"
96
+ className={cn("mt-auto flex flex-col gap-2 p-4", className)}
97
+ {...props}
98
+ />
99
+ )
100
+ }
101
+
102
+ function SheetTitle({
103
+ className,
104
+ ...props
105
+ }: React.ComponentProps<typeof SheetPrimitive.Title>) {
106
+ return (
107
+ <SheetPrimitive.Title
108
+ data-slot="sheet-title"
109
+ className={cn("text-foreground font-semibold", className)}
110
+ {...props}
111
+ />
112
+ )
113
+ }
114
+
115
+ function SheetDescription({
116
+ className,
117
+ ...props
118
+ }: React.ComponentProps<typeof SheetPrimitive.Description>) {
119
+ return (
120
+ <SheetPrimitive.Description
121
+ data-slot="sheet-description"
122
+ className={cn("text-muted-foreground text-sm", className)}
123
+ {...props}
124
+ />
125
+ )
126
+ }
127
+
128
+ export {
129
+ Sheet,
130
+ SheetTrigger,
131
+ SheetClose,
132
+ SheetContent,
133
+ SheetHeader,
134
+ SheetFooter,
135
+ SheetTitle,
136
+ SheetDescription,
137
+ }