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,48 @@
1
+ <script setup lang="ts">
2
+ import type { Component } from "vue"
3
+ import type { SidebarMenuButtonProps } from "./SidebarMenuButtonChild.vue"
4
+ import { reactiveOmit } from "@vueuse/core"
5
+ import { Tooltip, TooltipContent, TooltipTrigger } from '@/Components/ui/tooltip'
6
+ import SidebarMenuButtonChild from "./SidebarMenuButtonChild.vue"
7
+ import { useSidebar } from "./utils"
8
+
9
+ defineOptions({
10
+ inheritAttrs: false,
11
+ })
12
+
13
+ const props = withDefaults(defineProps<SidebarMenuButtonProps & {
14
+ tooltip?: string | Component
15
+ }>(), {
16
+ as: "button",
17
+ variant: "default",
18
+ size: "default",
19
+ })
20
+
21
+ const { isMobile, state } = useSidebar()
22
+
23
+ const delegatedProps = reactiveOmit(props, "tooltip")
24
+ </script>
25
+
26
+ <template>
27
+ <SidebarMenuButtonChild v-if="!tooltip" v-bind="{ ...delegatedProps, ...$attrs }">
28
+ <slot />
29
+ </SidebarMenuButtonChild>
30
+
31
+ <Tooltip v-else>
32
+ <TooltipTrigger as-child>
33
+ <SidebarMenuButtonChild v-bind="{ ...delegatedProps, ...$attrs }">
34
+ <slot />
35
+ </SidebarMenuButtonChild>
36
+ </TooltipTrigger>
37
+ <TooltipContent
38
+ side="right"
39
+ align="center"
40
+ :hidden="state !== 'collapsed' || isMobile"
41
+ >
42
+ <template v-if="typeof tooltip === 'string'">
43
+ {{ tooltip }}
44
+ </template>
45
+ <component :is="tooltip" v-else />
46
+ </TooltipContent>
47
+ </Tooltip>
48
+ </template>
@@ -0,0 +1,36 @@
1
+ <script setup lang="ts">
2
+ import type { PrimitiveProps } from "reka-ui"
3
+ import type { HTMLAttributes } from "vue"
4
+ import type { SidebarMenuButtonVariants } from "."
5
+ import { Primitive } from "reka-ui"
6
+ import { cn } from "@/lib/utils"
7
+ import { sidebarMenuButtonVariants } from "."
8
+
9
+ export interface SidebarMenuButtonProps extends PrimitiveProps {
10
+ variant?: SidebarMenuButtonVariants["variant"]
11
+ size?: SidebarMenuButtonVariants["size"]
12
+ isActive?: boolean
13
+ class?: HTMLAttributes["class"]
14
+ }
15
+
16
+ const props = withDefaults(defineProps<SidebarMenuButtonProps>(), {
17
+ as: "button",
18
+ variant: "default",
19
+ size: "default",
20
+ })
21
+ </script>
22
+
23
+ <template>
24
+ <Primitive
25
+ data-slot="sidebar-menu-button"
26
+ data-sidebar="menu-button"
27
+ :data-size="size"
28
+ :data-active="isActive"
29
+ :class="cn(sidebarMenuButtonVariants({ variant, size }), props.class)"
30
+ :as="as"
31
+ :as-child="asChild"
32
+ v-bind="$attrs"
33
+ >
34
+ <slot />
35
+ </Primitive>
36
+ </template>
@@ -0,0 +1,18 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const props = defineProps<{
6
+ class?: HTMLAttributes["class"]
7
+ }>()
8
+ </script>
9
+
10
+ <template>
11
+ <li
12
+ data-slot="sidebar-menu-item"
13
+ data-sidebar="menu-item"
14
+ :class="cn('group/menu-item relative', props.class)"
15
+ >
16
+ <slot />
17
+ </li>
18
+ </template>
@@ -0,0 +1,35 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { computed } from "vue"
4
+ import { cn } from "@/lib/utils"
5
+ import { Skeleton } from '@/Components/ui/skeleton'
6
+
7
+ const props = defineProps<{
8
+ showIcon?: boolean
9
+ class?: HTMLAttributes["class"]
10
+ }>()
11
+
12
+ const width = computed(() => {
13
+ return `${Math.floor(Math.random() * 40) + 50}%`
14
+ })
15
+ </script>
16
+
17
+ <template>
18
+ <div
19
+ data-slot="sidebar-menu-skeleton"
20
+ data-sidebar="menu-skeleton"
21
+ :class="cn('flex h-8 items-center gap-2 rounded-md px-2', props.class)"
22
+ >
23
+ <Skeleton
24
+ v-if="showIcon"
25
+ class="size-4 rounded-md"
26
+ data-sidebar="menu-skeleton-icon"
27
+ />
28
+
29
+ <Skeleton
30
+ class="h-4 max-w-(--skeleton-width) flex-1"
31
+ data-sidebar="menu-skeleton-text"
32
+ :style="{ '--skeleton-width': width }"
33
+ />
34
+ </div>
35
+ </template>
@@ -0,0 +1,22 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const props = defineProps<{
6
+ class?: HTMLAttributes["class"]
7
+ }>()
8
+ </script>
9
+
10
+ <template>
11
+ <ul
12
+ data-slot="sidebar-menu-sub"
13
+ data-sidebar="menu-badge"
14
+ :class="cn(
15
+ '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',
16
+ 'group-data-[collapsible=icon]:hidden',
17
+ props.class,
18
+ )"
19
+ >
20
+ <slot />
21
+ </ul>
22
+ </template>
@@ -0,0 +1,36 @@
1
+ <script setup lang="ts">
2
+ import type { PrimitiveProps } from "reka-ui"
3
+ import type { HTMLAttributes } from "vue"
4
+ import { Primitive } from "reka-ui"
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const props = withDefaults(defineProps<PrimitiveProps & {
8
+ size?: "sm" | "md"
9
+ isActive?: boolean
10
+ class?: HTMLAttributes["class"]
11
+ }>(), {
12
+ as: "a",
13
+ size: "md",
14
+ })
15
+ </script>
16
+
17
+ <template>
18
+ <Primitive
19
+ data-slot="sidebar-menu-sub-button"
20
+ data-sidebar="menu-sub-button"
21
+ :as="as"
22
+ :as-child="asChild"
23
+ :data-size="size"
24
+ :data-active="isActive"
25
+ :class="cn(
26
+ 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent 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:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
27
+ 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',
28
+ size === 'sm' && 'text-xs',
29
+ size === 'md' && 'text-sm',
30
+ 'group-data-[collapsible=icon]:hidden',
31
+ props.class,
32
+ )"
33
+ >
34
+ <slot />
35
+ </Primitive>
36
+ </template>
@@ -0,0 +1,18 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const props = defineProps<{
6
+ class?: HTMLAttributes["class"]
7
+ }>()
8
+ </script>
9
+
10
+ <template>
11
+ <li
12
+ data-slot="sidebar-menu-sub-item"
13
+ data-sidebar="menu-sub-item"
14
+ :class="cn('group/menu-sub-item relative', props.class)"
15
+ >
16
+ <slot />
17
+ </li>
18
+ </template>
@@ -0,0 +1,82 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes, Ref } from "vue"
3
+ import { defaultDocument, useEventListener, useMediaQuery, useVModel } from "@vueuse/core"
4
+ import { TooltipProvider } from "reka-ui"
5
+ import { computed, ref } from "vue"
6
+ import { cn } from "@/lib/utils"
7
+ import { provideSidebarContext, SIDEBAR_COOKIE_MAX_AGE, SIDEBAR_COOKIE_NAME, SIDEBAR_KEYBOARD_SHORTCUT, SIDEBAR_WIDTH, SIDEBAR_WIDTH_ICON } from "./utils"
8
+
9
+ const props = withDefaults(defineProps<{
10
+ defaultOpen?: boolean
11
+ open?: boolean
12
+ class?: HTMLAttributes["class"]
13
+ }>(), {
14
+ defaultOpen: !defaultDocument?.cookie.includes(`${SIDEBAR_COOKIE_NAME}=false`),
15
+ open: undefined,
16
+ })
17
+
18
+ const emits = defineEmits<{
19
+ "update:open": [open: boolean]
20
+ }>()
21
+
22
+ const isMobile = useMediaQuery("(max-width: 768px)")
23
+ const openMobile = ref(false)
24
+
25
+ const open = useVModel(props, "open", emits, {
26
+ defaultValue: props.defaultOpen ?? false,
27
+ passive: (props.open === undefined) as false,
28
+ }) as Ref<boolean>
29
+
30
+ function setOpen(value: boolean) {
31
+ open.value = value // emits('update:open', value)
32
+
33
+ // This sets the cookie to keep the sidebar state.
34
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${open.value}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`
35
+ }
36
+
37
+ function setOpenMobile(value: boolean) {
38
+ openMobile.value = value
39
+ }
40
+
41
+ // Helper to toggle the sidebar.
42
+ function toggleSidebar() {
43
+ return isMobile.value ? setOpenMobile(!openMobile.value) : setOpen(!open.value)
44
+ }
45
+
46
+ useEventListener("keydown", (event: KeyboardEvent) => {
47
+ if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
48
+ event.preventDefault()
49
+ toggleSidebar()
50
+ }
51
+ })
52
+
53
+ // We add a state so that we can do data-state="expanded" or "collapsed".
54
+ // This makes it easier to style the sidebar with Tailwind classes.
55
+ const state = computed(() => open.value ? "expanded" : "collapsed")
56
+
57
+ provideSidebarContext({
58
+ state,
59
+ open,
60
+ setOpen,
61
+ isMobile,
62
+ openMobile,
63
+ setOpenMobile,
64
+ toggleSidebar,
65
+ })
66
+ </script>
67
+
68
+ <template>
69
+ <TooltipProvider :delay-duration="0">
70
+ <div
71
+ data-slot="sidebar-wrapper"
72
+ :style="{
73
+ '--sidebar-width': SIDEBAR_WIDTH,
74
+ '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,
75
+ }"
76
+ :class="cn('group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full', props.class)"
77
+ v-bind="$attrs"
78
+ >
79
+ <slot />
80
+ </div>
81
+ </TooltipProvider>
82
+ </template>
@@ -0,0 +1,33 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+ import { useSidebar } from "./utils"
5
+
6
+ const props = defineProps<{
7
+ class?: HTMLAttributes["class"]
8
+ }>()
9
+
10
+ const { toggleSidebar } = useSidebar()
11
+ </script>
12
+
13
+ <template>
14
+ <button
15
+ data-sidebar="rail"
16
+ data-slot="sidebar-rail"
17
+ aria-label="Toggle Sidebar"
18
+ :tabindex="-1"
19
+ title="Toggle Sidebar"
20
+ :class="cn(
21
+ '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',
22
+ 'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',
23
+ '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',
24
+ 'hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full',
25
+ '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',
26
+ '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',
27
+ props.class,
28
+ )"
29
+ @click="toggleSidebar"
30
+ >
31
+ <slot />
32
+ </button>
33
+ </template>
@@ -0,0 +1,19 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+ import { Separator } from '@/Components/ui/separator'
5
+
6
+ const props = defineProps<{
7
+ class?: HTMLAttributes["class"]
8
+ }>()
9
+ </script>
10
+
11
+ <template>
12
+ <Separator
13
+ data-slot="sidebar-separator"
14
+ data-sidebar="separator"
15
+ :class="cn('bg-sidebar-border mx-2 w-auto', props.class)"
16
+ >
17
+ <slot />
18
+ </Separator>
19
+ </template>
@@ -0,0 +1,28 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { PanelLeftClose, PanelLeftOpen } from "@lucide/vue"
4
+ import { cn } from "@/lib/utils"
5
+ import { Button } from '@/Components/ui/button'
6
+ import { useSidebar } from "./utils"
7
+
8
+ const props = defineProps<{
9
+ class?: HTMLAttributes["class"]
10
+ }>()
11
+
12
+ const { isMobile, state, toggleSidebar } = useSidebar()
13
+ </script>
14
+
15
+ <template>
16
+ <Button
17
+ data-sidebar="trigger"
18
+ data-slot="sidebar-trigger"
19
+ variant="ghost"
20
+ size="icon"
21
+ :class="cn('h-7 w-7', props.class)"
22
+ @click="toggleSidebar"
23
+ >
24
+ <PanelLeftOpen v-if="isMobile || state === 'collapsed'" />
25
+ <PanelLeftClose v-else />
26
+ <span class="sr-only">Toggle sidebar</span>
27
+ </Button>
28
+ </template>
@@ -0,0 +1,60 @@
1
+ import type { VariantProps } from "class-variance-authority"
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cva } from "class-variance-authority"
4
+
5
+ export interface SidebarProps {
6
+ side?: "left" | "right"
7
+ variant?: "sidebar" | "floating" | "inset"
8
+ collapsible?: "offcanvas" | "icon" | "none"
9
+ class?: HTMLAttributes["class"]
10
+ }
11
+
12
+ export { default as Sidebar } from "./Sidebar.vue"
13
+ export { default as SidebarContent } from "./SidebarContent.vue"
14
+ export { default as SidebarFooter } from "./SidebarFooter.vue"
15
+ export { default as SidebarGroup } from "./SidebarGroup.vue"
16
+ export { default as SidebarGroupAction } from "./SidebarGroupAction.vue"
17
+ export { default as SidebarGroupContent } from "./SidebarGroupContent.vue"
18
+ export { default as SidebarGroupLabel } from "./SidebarGroupLabel.vue"
19
+ export { default as SidebarHeader } from "./SidebarHeader.vue"
20
+ export { default as SidebarInput } from "./SidebarInput.vue"
21
+ export { default as SidebarInset } from "./SidebarInset.vue"
22
+ export { default as SidebarMenu } from "./SidebarMenu.vue"
23
+ export { default as SidebarMenuAction } from "./SidebarMenuAction.vue"
24
+ export { default as SidebarMenuBadge } from "./SidebarMenuBadge.vue"
25
+ export { default as SidebarMenuButton } from "./SidebarMenuButton.vue"
26
+ export { default as SidebarMenuItem } from "./SidebarMenuItem.vue"
27
+ export { default as SidebarMenuSkeleton } from "./SidebarMenuSkeleton.vue"
28
+ export { default as SidebarMenuSub } from "./SidebarMenuSub.vue"
29
+ export { default as SidebarMenuSubButton } from "./SidebarMenuSubButton.vue"
30
+ export { default as SidebarMenuSubItem } from "./SidebarMenuSubItem.vue"
31
+ export { default as SidebarProvider } from "./SidebarProvider.vue"
32
+ export { default as SidebarRail } from "./SidebarRail.vue"
33
+ export { default as SidebarSeparator } from "./SidebarSeparator.vue"
34
+ export { default as SidebarTrigger } from "./SidebarTrigger.vue"
35
+
36
+ export { useSidebar } from "./utils"
37
+
38
+ export const sidebarMenuButtonVariants = cva(
39
+ "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] 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 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent 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",
40
+ {
41
+ variants: {
42
+ variant: {
43
+ default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
44
+ outline:
45
+ "bg-background shadow-[0_0_0_1px_var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_var(--sidebar-accent)]",
46
+ },
47
+ size: {
48
+ default: "h-8 text-sm",
49
+ sm: "h-7 text-xs",
50
+ lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!",
51
+ },
52
+ },
53
+ defaultVariants: {
54
+ variant: "default",
55
+ size: "default",
56
+ },
57
+ },
58
+ )
59
+
60
+ export type SidebarMenuButtonVariants = VariantProps<typeof sidebarMenuButtonVariants>
@@ -0,0 +1,19 @@
1
+ import type { ComputedRef, Ref } from "vue"
2
+ import { createContext } from "reka-ui"
3
+
4
+ export const SIDEBAR_COOKIE_NAME = "sidebar_state"
5
+ export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
6
+ export const SIDEBAR_WIDTH = "16rem"
7
+ export const SIDEBAR_WIDTH_MOBILE = "18rem"
8
+ export const SIDEBAR_WIDTH_ICON = "3rem"
9
+ export const SIDEBAR_KEYBOARD_SHORTCUT = "b"
10
+
11
+ export const [useSidebar, provideSidebarContext] = createContext<{
12
+ state: ComputedRef<"expanded" | "collapsed">
13
+ open: Ref<boolean>
14
+ setOpen: (value: boolean) => void
15
+ isMobile: Ref<boolean>
16
+ openMobile: Ref<boolean>
17
+ setOpenMobile: (value: boolean) => void
18
+ toggleSidebar: () => void
19
+ }>("Sidebar")
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ import type { HTMLAttributes } from "vue"
3
+ import { cn } from "@/lib/utils"
4
+
5
+ interface SkeletonProps {
6
+ class?: HTMLAttributes["class"]
7
+ }
8
+
9
+ const props = defineProps<SkeletonProps>()
10
+ </script>
11
+
12
+ <template>
13
+ <div
14
+ data-slot="skeleton"
15
+ :class="cn('animate-pulse rounded-md bg-primary/10', props.class)"
16
+ />
17
+ </template>
@@ -0,0 +1 @@
1
+ export { default as Skeleton } from "./Skeleton.vue"
@@ -0,0 +1,19 @@
1
+ <script setup lang="ts">
2
+ import type { TooltipRootEmits, TooltipRootProps } from "reka-ui"
3
+ import { TooltipRoot, useForwardPropsEmits } from "reka-ui"
4
+
5
+ const props = defineProps<TooltipRootProps>()
6
+ const emits = defineEmits<TooltipRootEmits>()
7
+
8
+ const forwarded = useForwardPropsEmits(props, emits)
9
+ </script>
10
+
11
+ <template>
12
+ <TooltipRoot
13
+ v-slot="slotProps"
14
+ data-slot="tooltip"
15
+ v-bind="forwarded"
16
+ >
17
+ <slot v-bind="slotProps" />
18
+ </TooltipRoot>
19
+ </template>
@@ -0,0 +1,34 @@
1
+ <script setup lang="ts">
2
+ import type { TooltipContentEmits, TooltipContentProps } from "reka-ui"
3
+ import type { HTMLAttributes } from "vue"
4
+ import { reactiveOmit } from "@vueuse/core"
5
+ import { TooltipArrow, TooltipContent, TooltipPortal, useForwardPropsEmits } from "reka-ui"
6
+ import { cn } from "@/lib/utils"
7
+
8
+ defineOptions({
9
+ inheritAttrs: false,
10
+ })
11
+
12
+ const props = withDefaults(defineProps<TooltipContentProps & { class?: HTMLAttributes["class"] }>(), {
13
+ sideOffset: 4,
14
+ })
15
+
16
+ const emits = defineEmits<TooltipContentEmits>()
17
+
18
+ const delegatedProps = reactiveOmit(props, "class")
19
+ const forwarded = useForwardPropsEmits(delegatedProps, emits)
20
+ </script>
21
+
22
+ <template>
23
+ <TooltipPortal>
24
+ <TooltipContent
25
+ data-slot="tooltip-content"
26
+ v-bind="{ ...forwarded, ...$attrs }"
27
+ :class="cn('bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-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 w-fit rounded-md px-3 py-1.5 text-xs text-balance', props.class)"
28
+ >
29
+ <slot />
30
+
31
+ <TooltipArrow class="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
32
+ </TooltipContent>
33
+ </TooltipPortal>
34
+ </template>
@@ -0,0 +1,14 @@
1
+ <script setup lang="ts">
2
+ import type { TooltipProviderProps } from "reka-ui"
3
+ import { TooltipProvider } from "reka-ui"
4
+
5
+ const props = withDefaults(defineProps<TooltipProviderProps>(), {
6
+ delayDuration: 0,
7
+ })
8
+ </script>
9
+
10
+ <template>
11
+ <TooltipProvider v-bind="props">
12
+ <slot />
13
+ </TooltipProvider>
14
+ </template>
@@ -0,0 +1,15 @@
1
+ <script setup lang="ts">
2
+ import type { TooltipTriggerProps } from "reka-ui"
3
+ import { TooltipTrigger } from "reka-ui"
4
+
5
+ const props = defineProps<TooltipTriggerProps>()
6
+ </script>
7
+
8
+ <template>
9
+ <TooltipTrigger
10
+ data-slot="tooltip-trigger"
11
+ v-bind="props"
12
+ >
13
+ <slot />
14
+ </TooltipTrigger>
15
+ </template>
@@ -0,0 +1,4 @@
1
+ export { default as Tooltip } from "./Tooltip.vue"
2
+ export { default as TooltipContent } from "./TooltipContent.vue"
3
+ export { default as TooltipProvider } from "./TooltipProvider.vue"
4
+ export { default as TooltipTrigger } from "./TooltipTrigger.vue"