shadcn-rails 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +40 -0
  3. data/CHANGELOG.md +54 -0
  4. data/CLAUDE.md +463 -0
  5. data/PROGRESS.md +485 -0
  6. data/README.md +1483 -0
  7. data/Rakefile +29 -0
  8. data/__tests__/controllers/__snapshots__/calendar_controller.test.js.snap +13 -0
  9. data/__tests__/controllers/__snapshots__/popover_controller.test.js.snap +46 -0
  10. data/__tests__/controllers/__snapshots__/sheet_controller.test.js.snap +111 -0
  11. data/__tests__/controllers/__snapshots__/tabs_controller.test.js.snap +27 -0
  12. data/__tests__/controllers/accordion_controller.test.js +904 -0
  13. data/__tests__/controllers/calendar_controller.test.js +1370 -0
  14. data/__tests__/controllers/carousel_controller.test.js +912 -0
  15. data/__tests__/controllers/checkbox_controller.test.js +454 -0
  16. data/__tests__/controllers/collapsible_controller.test.js +407 -0
  17. data/__tests__/controllers/combobox_controller.test.js +966 -0
  18. data/__tests__/controllers/context_menu_controller.test.js +627 -0
  19. data/__tests__/controllers/date_picker_controller.test.js +636 -0
  20. data/__tests__/controllers/dialog_controller.test.js +878 -0
  21. data/__tests__/controllers/drawer_controller.test.js +995 -0
  22. data/__tests__/controllers/menubar_controller.test.js +736 -0
  23. data/__tests__/controllers/navigation_menu_controller.test.js +598 -0
  24. data/__tests__/controllers/popover_controller.test.js +1007 -0
  25. data/__tests__/controllers/radio_group_controller.test.js +640 -0
  26. data/__tests__/controllers/resizable_controller.test.js +680 -0
  27. data/__tests__/controllers/select_controller.test.js +674 -0
  28. data/__tests__/controllers/sheet_controller.test.js +986 -0
  29. data/__tests__/controllers/slider_controller.test.js +1036 -0
  30. data/__tests__/controllers/switch_controller.test.js +424 -0
  31. data/__tests__/controllers/tabs_controller.test.js +907 -0
  32. data/__tests__/controllers/toggle_group_controller.test.js +839 -0
  33. data/__tests__/controllers/tooltip_controller.test.js +808 -0
  34. data/__tests__/helpers/stimulus-test-helper.js +203 -0
  35. data/app/assets/config/manifest.js +1 -0
  36. data/app/assets/javascripts/shadcn/controllers/accordion_controller.d.ts +53 -0
  37. data/app/assets/javascripts/shadcn/controllers/accordion_controller.js +140 -0
  38. data/app/assets/javascripts/shadcn/controllers/avatar_controller.d.ts +22 -0
  39. data/app/assets/javascripts/shadcn/controllers/avatar_controller.js +26 -0
  40. data/app/assets/javascripts/shadcn/controllers/calendar_controller.js +592 -0
  41. data/app/assets/javascripts/shadcn/controllers/carousel_controller.js +263 -0
  42. data/app/assets/javascripts/shadcn/controllers/checkbox_controller.d.ts +31 -0
  43. data/app/assets/javascripts/shadcn/controllers/checkbox_controller.js +48 -0
  44. data/app/assets/javascripts/shadcn/controllers/collapsible_controller.d.ts +43 -0
  45. data/app/assets/javascripts/shadcn/controllers/collapsible_controller.js +73 -0
  46. data/app/assets/javascripts/shadcn/controllers/combobox_controller.js +234 -0
  47. data/app/assets/javascripts/shadcn/controllers/command_controller.js +141 -0
  48. data/app/assets/javascripts/shadcn/controllers/command_dialog_controller.js +162 -0
  49. data/app/assets/javascripts/shadcn/controllers/context_menu_controller.js +202 -0
  50. data/app/assets/javascripts/shadcn/controllers/date_picker_controller.js +282 -0
  51. data/app/assets/javascripts/shadcn/controllers/dialog_controller.d.ts +67 -0
  52. data/app/assets/javascripts/shadcn/controllers/dialog_controller.js +187 -0
  53. data/app/assets/javascripts/shadcn/controllers/drawer_controller.d.ts +58 -0
  54. data/app/assets/javascripts/shadcn/controllers/drawer_controller.js +112 -0
  55. data/app/assets/javascripts/shadcn/controllers/dropdown_controller.d.ts +83 -0
  56. data/app/assets/javascripts/shadcn/controllers/dropdown_controller.js +225 -0
  57. data/app/assets/javascripts/shadcn/controllers/hover_card_controller.d.ts +59 -0
  58. data/app/assets/javascripts/shadcn/controllers/hover_card_controller.js +143 -0
  59. data/app/assets/javascripts/shadcn/controllers/input_otp_controller.d.ts +44 -0
  60. data/app/assets/javascripts/shadcn/controllers/input_otp_controller.js +206 -0
  61. data/app/assets/javascripts/shadcn/controllers/menubar_controller.js +323 -0
  62. data/app/assets/javascripts/shadcn/controllers/navigation_menu_controller.js +251 -0
  63. data/app/assets/javascripts/shadcn/controllers/popover_controller.d.ts +56 -0
  64. data/app/assets/javascripts/shadcn/controllers/popover_controller.js +141 -0
  65. data/app/assets/javascripts/shadcn/controllers/radio_group_controller.d.ts +47 -0
  66. data/app/assets/javascripts/shadcn/controllers/radio_group_controller.js +108 -0
  67. data/app/assets/javascripts/shadcn/controllers/resizable_controller.js +272 -0
  68. data/app/assets/javascripts/shadcn/controllers/scroll_area_controller.d.ts +44 -0
  69. data/app/assets/javascripts/shadcn/controllers/scroll_area_controller.js +74 -0
  70. data/app/assets/javascripts/shadcn/controllers/select_controller.d.ts +84 -0
  71. data/app/assets/javascripts/shadcn/controllers/select_controller.js +222 -0
  72. data/app/assets/javascripts/shadcn/controllers/sheet_controller.d.ts +60 -0
  73. data/app/assets/javascripts/shadcn/controllers/sheet_controller.js +151 -0
  74. data/app/assets/javascripts/shadcn/controllers/sidebar_controller.js +148 -0
  75. data/app/assets/javascripts/shadcn/controllers/slider_controller.d.ts +102 -0
  76. data/app/assets/javascripts/shadcn/controllers/slider_controller.js +364 -0
  77. data/app/assets/javascripts/shadcn/controllers/switch_controller.d.ts +46 -0
  78. data/app/assets/javascripts/shadcn/controllers/switch_controller.js +78 -0
  79. data/app/assets/javascripts/shadcn/controllers/tabs_controller.d.ts +51 -0
  80. data/app/assets/javascripts/shadcn/controllers/tabs_controller.js +126 -0
  81. data/app/assets/javascripts/shadcn/controllers/toast_controller.d.ts +37 -0
  82. data/app/assets/javascripts/shadcn/controllers/toast_controller.js +58 -0
  83. data/app/assets/javascripts/shadcn/controllers/toggle_controller.d.ts +27 -0
  84. data/app/assets/javascripts/shadcn/controllers/toggle_controller.js +42 -0
  85. data/app/assets/javascripts/shadcn/controllers/toggle_group_controller.d.ts +44 -0
  86. data/app/assets/javascripts/shadcn/controllers/toggle_group_controller.js +68 -0
  87. data/app/assets/javascripts/shadcn/controllers/tooltip_controller.d.ts +56 -0
  88. data/app/assets/javascripts/shadcn/controllers/tooltip_controller.js +117 -0
  89. data/app/assets/javascripts/shadcn/index.d.ts +74 -0
  90. data/app/assets/javascripts/shadcn/index.js +133 -0
  91. data/app/assets/stylesheets/.keep +0 -0
  92. data/app/assets/stylesheets/shadcn/base.css +445 -0
  93. data/app/assets/stylesheets/shadcn/components.css +513 -0
  94. data/app/assets/stylesheets/shadcn/index.css +18 -0
  95. data/app/assets/stylesheets/shadcn/themes/gray.css +68 -0
  96. data/app/assets/stylesheets/shadcn/themes/slate.css +68 -0
  97. data/app/assets/stylesheets/shadcn/themes/stone.css +68 -0
  98. data/app/assets/stylesheets/shadcn/themes/zinc.css +68 -0
  99. data/app/components/shadcn/accordion_component.rb +63 -0
  100. data/app/components/shadcn/accordion_content_component.rb +29 -0
  101. data/app/components/shadcn/accordion_item_component.rb +40 -0
  102. data/app/components/shadcn/accordion_trigger_component.rb +49 -0
  103. data/app/components/shadcn/alert_component.rb +75 -0
  104. data/app/components/shadcn/alert_description_component.rb +12 -0
  105. data/app/components/shadcn/alert_dialog_action_component.rb +24 -0
  106. data/app/components/shadcn/alert_dialog_cancel_component.rb +24 -0
  107. data/app/components/shadcn/alert_dialog_component.rb +71 -0
  108. data/app/components/shadcn/alert_dialog_content_component.rb +57 -0
  109. data/app/components/shadcn/alert_dialog_description_component.rb +12 -0
  110. data/app/components/shadcn/alert_dialog_footer_component.rb +19 -0
  111. data/app/components/shadcn/alert_dialog_header_component.rb +19 -0
  112. data/app/components/shadcn/alert_dialog_title_component.rb +12 -0
  113. data/app/components/shadcn/alert_title_component.rb +12 -0
  114. data/app/components/shadcn/aspect_ratio_component.rb +49 -0
  115. data/app/components/shadcn/avatar_component.rb +107 -0
  116. data/app/components/shadcn/avatar_fallback_component.rb +17 -0
  117. data/app/components/shadcn/badge_component.rb +49 -0
  118. data/app/components/shadcn/base_component.rb +100 -0
  119. data/app/components/shadcn/breadcrumb_component.rb +70 -0
  120. data/app/components/shadcn/breadcrumb_item_component.rb +50 -0
  121. data/app/components/shadcn/button_component.rb +141 -0
  122. data/app/components/shadcn/button_group_component.rb +69 -0
  123. data/app/components/shadcn/calendar_component.rb +337 -0
  124. data/app/components/shadcn/card_action_component.rb +10 -0
  125. data/app/components/shadcn/card_component.rb +63 -0
  126. data/app/components/shadcn/card_content_component.rb +19 -0
  127. data/app/components/shadcn/card_description_component.rb +12 -0
  128. data/app/components/shadcn/card_footer_component.rb +12 -0
  129. data/app/components/shadcn/card_header_component.rb +24 -0
  130. data/app/components/shadcn/card_title_component.rb +18 -0
  131. data/app/components/shadcn/carousel_component.rb +275 -0
  132. data/app/components/shadcn/checkbox_component.rb +103 -0
  133. data/app/components/shadcn/collapsible_component.rb +66 -0
  134. data/app/components/shadcn/collapsible_content_component.rb +28 -0
  135. data/app/components/shadcn/combobox_component.rb +322 -0
  136. data/app/components/shadcn/command_component.rb +52 -0
  137. data/app/components/shadcn/command_dialog_component.rb +76 -0
  138. data/app/components/shadcn/command_empty_component.rb +12 -0
  139. data/app/components/shadcn/command_group_component.rb +34 -0
  140. data/app/components/shadcn/command_input_component.rb +59 -0
  141. data/app/components/shadcn/command_item_component.rb +48 -0
  142. data/app/components/shadcn/command_list_component.rb +38 -0
  143. data/app/components/shadcn/command_separator_component.rb +12 -0
  144. data/app/components/shadcn/command_shortcut_component.rb +12 -0
  145. data/app/components/shadcn/context_menu_component.rb +64 -0
  146. data/app/components/shadcn/context_menu_content_component.rb +44 -0
  147. data/app/components/shadcn/context_menu_item_component.rb +63 -0
  148. data/app/components/shadcn/context_menu_label_component.rb +18 -0
  149. data/app/components/shadcn/context_menu_separator_component.rb +12 -0
  150. data/app/components/shadcn/context_menu_shortcut_component.rb +12 -0
  151. data/app/components/shadcn/date_picker_component.rb +368 -0
  152. data/app/components/shadcn/dialog_component.rb +77 -0
  153. data/app/components/shadcn/dialog_content_component.rb +91 -0
  154. data/app/components/shadcn/dialog_description_component.rb +12 -0
  155. data/app/components/shadcn/dialog_footer_component.rb +12 -0
  156. data/app/components/shadcn/dialog_header_component.rb +19 -0
  157. data/app/components/shadcn/dialog_title_component.rb +12 -0
  158. data/app/components/shadcn/drawer_component.rb +72 -0
  159. data/app/components/shadcn/drawer_content_component.rb +76 -0
  160. data/app/components/shadcn/drawer_description_component.rb +12 -0
  161. data/app/components/shadcn/drawer_footer_component.rb +12 -0
  162. data/app/components/shadcn/drawer_header_component.rb +19 -0
  163. data/app/components/shadcn/drawer_title_component.rb +12 -0
  164. data/app/components/shadcn/dropdown_menu_component.rb +75 -0
  165. data/app/components/shadcn/dropdown_menu_content_component.rb +49 -0
  166. data/app/components/shadcn/dropdown_menu_group_component.rb +10 -0
  167. data/app/components/shadcn/dropdown_menu_item_component.rb +63 -0
  168. data/app/components/shadcn/dropdown_menu_label_component.rb +18 -0
  169. data/app/components/shadcn/dropdown_menu_separator_component.rb +12 -0
  170. data/app/components/shadcn/dropdown_menu_shortcut_component.rb +12 -0
  171. data/app/components/shadcn/empty_component.rb +48 -0
  172. data/app/components/shadcn/empty_content_component.rb +12 -0
  173. data/app/components/shadcn/empty_description_component.rb +12 -0
  174. data/app/components/shadcn/empty_header_component.rb +29 -0
  175. data/app/components/shadcn/empty_media_component.rb +21 -0
  176. data/app/components/shadcn/empty_title_component.rb +12 -0
  177. data/app/components/shadcn/field_component.rb +113 -0
  178. data/app/components/shadcn/hover_card_component.rb +64 -0
  179. data/app/components/shadcn/hover_card_content_component.rb +36 -0
  180. data/app/components/shadcn/input_component.rb +108 -0
  181. data/app/components/shadcn/input_group_component.rb +70 -0
  182. data/app/components/shadcn/input_otp_component.rb +183 -0
  183. data/app/components/shadcn/item_actions_component.rb +12 -0
  184. data/app/components/shadcn/item_component.rb +98 -0
  185. data/app/components/shadcn/item_content_component.rb +24 -0
  186. data/app/components/shadcn/item_description_component.rb +12 -0
  187. data/app/components/shadcn/item_footer_component.rb +12 -0
  188. data/app/components/shadcn/item_group_component.rb +24 -0
  189. data/app/components/shadcn/item_header_component.rb +12 -0
  190. data/app/components/shadcn/item_media_component.rb +22 -0
  191. data/app/components/shadcn/item_separator_component.rb +12 -0
  192. data/app/components/shadcn/item_title_component.rb +12 -0
  193. data/app/components/shadcn/kbd_component.rb +36 -0
  194. data/app/components/shadcn/label_component.rb +49 -0
  195. data/app/components/shadcn/menubar_checkbox_item_component.rb +76 -0
  196. data/app/components/shadcn/menubar_component.rb +56 -0
  197. data/app/components/shadcn/menubar_content_component.rb +64 -0
  198. data/app/components/shadcn/menubar_item_component.rb +65 -0
  199. data/app/components/shadcn/menubar_label_component.rb +27 -0
  200. data/app/components/shadcn/menubar_menu_component.rb +34 -0
  201. data/app/components/shadcn/menubar_radio_group_component.rb +42 -0
  202. data/app/components/shadcn/menubar_radio_item_component.rb +76 -0
  203. data/app/components/shadcn/menubar_separator_component.rb +22 -0
  204. data/app/components/shadcn/menubar_shortcut_component.rb +21 -0
  205. data/app/components/shadcn/menubar_sub_component.rb +38 -0
  206. data/app/components/shadcn/menubar_sub_content_component.rb +45 -0
  207. data/app/components/shadcn/menubar_sub_trigger_component.rb +59 -0
  208. data/app/components/shadcn/menubar_trigger_component.rb +31 -0
  209. data/app/components/shadcn/native_select_component.rb +150 -0
  210. data/app/components/shadcn/navigation_menu_component.rb +76 -0
  211. data/app/components/shadcn/navigation_menu_content_component.rb +30 -0
  212. data/app/components/shadcn/navigation_menu_item_component.rb +39 -0
  213. data/app/components/shadcn/navigation_menu_link_component.rb +38 -0
  214. data/app/components/shadcn/navigation_menu_list_component.rb +29 -0
  215. data/app/components/shadcn/navigation_menu_trigger_component.rb +59 -0
  216. data/app/components/shadcn/pagination_component.rb +195 -0
  217. data/app/components/shadcn/pagination_content_component.rb +47 -0
  218. data/app/components/shadcn/pagination_ellipsis_component.rb +30 -0
  219. data/app/components/shadcn/pagination_item_component.rb +53 -0
  220. data/app/components/shadcn/pagination_next_component.rb +48 -0
  221. data/app/components/shadcn/pagination_previous_component.rb +48 -0
  222. data/app/components/shadcn/popover_component.rb +76 -0
  223. data/app/components/shadcn/popover_content_component.rb +25 -0
  224. data/app/components/shadcn/progress_component.rb +77 -0
  225. data/app/components/shadcn/radio_group_component.rb +129 -0
  226. data/app/components/shadcn/radio_group_item_component.rb +109 -0
  227. data/app/components/shadcn/resizable_handle_component.rb +98 -0
  228. data/app/components/shadcn/resizable_panel_component.rb +56 -0
  229. data/app/components/shadcn/resizable_panel_group_component.rb +94 -0
  230. data/app/components/shadcn/scroll_area_component.rb +110 -0
  231. data/app/components/shadcn/select_component.rb +151 -0
  232. data/app/components/shadcn/select_group_component.rb +32 -0
  233. data/app/components/shadcn/select_item_component.rb +59 -0
  234. data/app/components/shadcn/select_separator_component.rb +12 -0
  235. data/app/components/shadcn/separator_component.rb +54 -0
  236. data/app/components/shadcn/sheet_component.rb +82 -0
  237. data/app/components/shadcn/sheet_content_component.rb +95 -0
  238. data/app/components/shadcn/sheet_description_component.rb +12 -0
  239. data/app/components/shadcn/sheet_footer_component.rb +12 -0
  240. data/app/components/shadcn/sheet_header_component.rb +19 -0
  241. data/app/components/shadcn/sheet_title_component.rb +12 -0
  242. data/app/components/shadcn/sidebar_component.rb +180 -0
  243. data/app/components/shadcn/sidebar_content_component.rb +32 -0
  244. data/app/components/shadcn/sidebar_footer_component.rb +24 -0
  245. data/app/components/shadcn/sidebar_group_action_component.rb +26 -0
  246. data/app/components/shadcn/sidebar_group_component.rb +38 -0
  247. data/app/components/shadcn/sidebar_group_content_component.rb +32 -0
  248. data/app/components/shadcn/sidebar_group_label_component.rb +25 -0
  249. data/app/components/shadcn/sidebar_header_component.rb +24 -0
  250. data/app/components/shadcn/sidebar_inset_component.rb +25 -0
  251. data/app/components/shadcn/sidebar_menu_action_component.rb +37 -0
  252. data/app/components/shadcn/sidebar_menu_badge_component.rb +25 -0
  253. data/app/components/shadcn/sidebar_menu_button_component.rb +52 -0
  254. data/app/components/shadcn/sidebar_menu_component.rb +32 -0
  255. data/app/components/shadcn/sidebar_menu_item_component.rb +41 -0
  256. data/app/components/shadcn/sidebar_menu_skeleton_component.rb +46 -0
  257. data/app/components/shadcn/sidebar_menu_sub_button_component.rb +43 -0
  258. data/app/components/shadcn/sidebar_menu_sub_component.rb +33 -0
  259. data/app/components/shadcn/sidebar_menu_sub_item_component.rb +30 -0
  260. data/app/components/shadcn/sidebar_provider_component.rb +57 -0
  261. data/app/components/shadcn/sidebar_rail_component.rb +30 -0
  262. data/app/components/shadcn/sidebar_separator_component.rb +24 -0
  263. data/app/components/shadcn/sidebar_trigger_component.rb +51 -0
  264. data/app/components/shadcn/skeleton_component.rb +29 -0
  265. data/app/components/shadcn/slider_component.rb +76 -0
  266. data/app/components/shadcn/spinner_component.rb +67 -0
  267. data/app/components/shadcn/switch_component.rb +147 -0
  268. data/app/components/shadcn/table_body_component.rb +16 -0
  269. data/app/components/shadcn/table_caption_component.rb +12 -0
  270. data/app/components/shadcn/table_cell_component.rb +12 -0
  271. data/app/components/shadcn/table_component.rb +57 -0
  272. data/app/components/shadcn/table_footer_component.rb +16 -0
  273. data/app/components/shadcn/table_head_component.rb +12 -0
  274. data/app/components/shadcn/table_header_component.rb +16 -0
  275. data/app/components/shadcn/table_row_component.rb +40 -0
  276. data/app/components/shadcn/tabs_component.rb +78 -0
  277. data/app/components/shadcn/tabs_content_component.rb +32 -0
  278. data/app/components/shadcn/tabs_list_component.rb +30 -0
  279. data/app/components/shadcn/tabs_trigger_component.rb +37 -0
  280. data/app/components/shadcn/textarea_component.rb +84 -0
  281. data/app/components/shadcn/toast_action_component.rb +18 -0
  282. data/app/components/shadcn/toast_component.rb +114 -0
  283. data/app/components/shadcn/toast_description_component.rb +12 -0
  284. data/app/components/shadcn/toast_title_component.rb +12 -0
  285. data/app/components/shadcn/toast_viewport_component.rb +12 -0
  286. data/app/components/shadcn/toggle_component.rb +77 -0
  287. data/app/components/shadcn/toggle_group_component.rb +96 -0
  288. data/app/components/shadcn/toggle_group_item_component.rb +62 -0
  289. data/app/components/shadcn/tooltip_component.rb +89 -0
  290. data/app/components/shadcn/typography_component.rb +112 -0
  291. data/babel.config.cjs +5 -0
  292. data/bin/console +11 -0
  293. data/bin/setup +8 -0
  294. data/config/importmap.rb +5 -0
  295. data/fly.toml +26 -0
  296. data/jest.config.js +19 -0
  297. data/jest.setup.js +8 -0
  298. data/lib/generators/shadcn/component/component_generator.rb +188 -0
  299. data/lib/generators/shadcn/install/install_generator.rb +140 -0
  300. data/lib/generators/shadcn/install/templates/initializer.rb.tt +35 -0
  301. data/lib/generators/shadcn/install/templates/shadcn.yml.tt +35 -0
  302. data/lib/generators/shadcn/theme/theme_generator.rb +128 -0
  303. data/lib/shadcn/rails/class_merger.rb +228 -0
  304. data/lib/shadcn/rails/configuration.rb +341 -0
  305. data/lib/shadcn/rails/engine.rb +59 -0
  306. data/lib/shadcn/rails/helpers/class_name_helper.rb +35 -0
  307. data/lib/shadcn/rails/helpers/component_helper.rb +60 -0
  308. data/lib/shadcn/rails/helpers/pagination_helper.rb +187 -0
  309. data/lib/shadcn/rails/version.rb +7 -0
  310. data/lib/shadcn/rails.rb +179 -0
  311. data/package-lock.json +7415 -0
  312. data/package.json +68 -0
  313. data/rollup.config.js +29 -0
  314. data/sig/shadcn/rails.rbs +6 -0
  315. metadata +526 -0
@@ -0,0 +1,58 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ /**
4
+ * Toast controller for notification toasts
5
+ */
6
+ export default class extends Controller {
7
+ static values = {
8
+ duration: { type: Number, default: 5000 },
9
+ open: { type: Boolean, default: true }
10
+ }
11
+
12
+ connect() {
13
+ if (this.openValue && this.durationValue > 0) {
14
+ this.startDismissTimer()
15
+ }
16
+ }
17
+
18
+ disconnect() {
19
+ this.clearDismissTimer()
20
+ }
21
+
22
+ close() {
23
+ this.openValue = false
24
+ this.element.dataset.state = "closed"
25
+
26
+ // Remove after animation
27
+ setTimeout(() => {
28
+ this.element.remove()
29
+ this.dispatch("closed")
30
+ }, 200)
31
+ }
32
+
33
+ startDismissTimer() {
34
+ this.clearDismissTimer()
35
+ this.dismissTimeout = setTimeout(() => {
36
+ this.close()
37
+ }, this.durationValue)
38
+ }
39
+
40
+ clearDismissTimer() {
41
+ if (this.dismissTimeout) {
42
+ clearTimeout(this.dismissTimeout)
43
+ this.dismissTimeout = null
44
+ }
45
+ }
46
+
47
+ // Pause timer on hover
48
+ pause() {
49
+ this.clearDismissTimer()
50
+ }
51
+
52
+ // Resume timer when hover ends
53
+ resume() {
54
+ if (this.openValue && this.durationValue > 0) {
55
+ this.startDismissTimer()
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,27 @@
1
+ import { Controller } from "@hotwired/stimulus";
2
+
3
+ /**
4
+ * Toggle Controller
5
+ * Handles toggle button state management
6
+ */
7
+ export default class ToggleController extends Controller {
8
+ static values: {
9
+ pressed: { type: "Boolean"; default: false };
10
+ };
11
+
12
+ /** Whether the toggle is pressed */
13
+ pressedValue: boolean;
14
+ readonly hasPressedValue: boolean;
15
+
16
+ /** Toggle the pressed state */
17
+ toggle(): void;
18
+
19
+ /** Update visual state */
20
+ updateState(): void;
21
+
22
+ /** Dispatch change event */
23
+ dispatchChange(): void;
24
+
25
+ /** Called when pressedValue changes */
26
+ pressedValueChanged(): void;
27
+ }
@@ -0,0 +1,42 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ /**
4
+ * Toggle Controller
5
+ *
6
+ * Handles toggle button state management
7
+ *
8
+ * Values:
9
+ * - pressed: Boolean indicating if toggle is pressed
10
+ */
11
+ export default class extends Controller {
12
+ static values = {
13
+ pressed: { type: Boolean, default: false }
14
+ }
15
+
16
+ connect() {
17
+ this.updateState()
18
+ }
19
+
20
+ toggle() {
21
+ if (this.element.disabled) return
22
+
23
+ this.pressedValue = !this.pressedValue
24
+ this.updateState()
25
+ this.dispatchChange()
26
+ }
27
+
28
+ updateState() {
29
+ this.element.setAttribute("aria-pressed", this.pressedValue.toString())
30
+ this.element.dataset.state = this.pressedValue ? "on" : "off"
31
+ }
32
+
33
+ dispatchChange() {
34
+ this.dispatch("change", {
35
+ detail: { pressed: this.pressedValue }
36
+ })
37
+ }
38
+
39
+ pressedValueChanged() {
40
+ this.updateState()
41
+ }
42
+ }
@@ -0,0 +1,44 @@
1
+ import { Controller } from "@hotwired/stimulus";
2
+
3
+ /**
4
+ * Toggle Group Controller
5
+ * Handles single or multiple selection of toggle items
6
+ */
7
+ export default class ToggleGroupController extends Controller {
8
+ static targets: ["item", "input"];
9
+ static values: {
10
+ type: { type: "String"; default: "single" };
11
+ value: { type: "String"; default: "" };
12
+ };
13
+
14
+ /** Toggle item targets */
15
+ readonly itemTargets: HTMLElement[];
16
+ readonly hasItemTarget: boolean;
17
+
18
+ /** Hidden input target */
19
+ readonly inputTarget: HTMLInputElement;
20
+ readonly hasInputTarget: boolean;
21
+
22
+ /** Selection type: "single" or "multiple" */
23
+ typeValue: "single" | "multiple";
24
+ readonly hasTypeValue: boolean;
25
+
26
+ /** Current value(s) as comma-separated string */
27
+ valueValue: string;
28
+ readonly hasValueValue: boolean;
29
+
30
+ /** Toggle an item's selection */
31
+ toggle(event: Event): void;
32
+
33
+ /** Get current values as array */
34
+ getValues(): string[];
35
+
36
+ /** Update visual states of all items */
37
+ updateStates(): void;
38
+
39
+ /** Update hidden input value */
40
+ updateInput(): void;
41
+
42
+ /** Called when valueValue changes */
43
+ valueValueChanged(): void;
44
+ }
@@ -0,0 +1,68 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ /**
4
+ * Toggle Group Controller
5
+ * Handles single or multiple selection of toggle items
6
+ */
7
+ export default class extends Controller {
8
+ static targets = ["item", "input"]
9
+ static values = {
10
+ type: { type: String, default: "single" }, // "single" or "multiple"
11
+ value: { type: String, default: "" }
12
+ }
13
+
14
+ connect() {
15
+ this.updateStates()
16
+ }
17
+
18
+ toggle(event) {
19
+ const item = event.currentTarget
20
+ const value = item.dataset.value
21
+ const currentValues = this.getValues()
22
+
23
+ if (this.typeValue === "single") {
24
+ // Single selection - toggle or select new
25
+ if (currentValues.includes(value)) {
26
+ this.valueValue = ""
27
+ } else {
28
+ this.valueValue = value
29
+ }
30
+ } else {
31
+ // Multiple selection - toggle individual item
32
+ if (currentValues.includes(value)) {
33
+ this.valueValue = currentValues.filter(v => v !== value).join(",")
34
+ } else {
35
+ this.valueValue = [...currentValues, value].filter(Boolean).join(",")
36
+ }
37
+ }
38
+
39
+ this.updateStates()
40
+ this.updateInput()
41
+ this.dispatch("change", { detail: { value: this.getValues() } })
42
+ }
43
+
44
+ getValues() {
45
+ return this.valueValue.split(",").filter(Boolean)
46
+ }
47
+
48
+ updateStates() {
49
+ const values = this.getValues()
50
+
51
+ this.itemTargets.forEach(item => {
52
+ const isOn = values.includes(item.dataset.value)
53
+ item.setAttribute("data-state", isOn ? "on" : "off")
54
+ item.setAttribute("aria-pressed", isOn.toString())
55
+ })
56
+ }
57
+
58
+ updateInput() {
59
+ if (this.hasInputTarget) {
60
+ this.inputTarget.value = this.valueValue
61
+ }
62
+ }
63
+
64
+ valueValueChanged() {
65
+ this.updateStates()
66
+ this.updateInput()
67
+ }
68
+ }
@@ -0,0 +1,56 @@
1
+ import { Controller } from "@hotwired/stimulus";
2
+
3
+ /**
4
+ * Tooltip controller for contextual information
5
+ */
6
+ export default class TooltipController extends Controller {
7
+ static targets: ["trigger", "content"];
8
+ static values: {
9
+ side: { type: "String"; default: "top" };
10
+ align: { type: "String"; default: "center" };
11
+ delay: { type: "Number"; default: 200 };
12
+ skipDelay: { type: "Number"; default: 300 };
13
+ };
14
+
15
+ /** Tooltip trigger target */
16
+ readonly triggerTarget: HTMLElement;
17
+ readonly hasTriggerTarget: boolean;
18
+
19
+ /** Tooltip content target */
20
+ readonly contentTarget: HTMLElement;
21
+ readonly hasContentTarget: boolean;
22
+
23
+ /** Side to display: "top", "bottom", "left", "right" */
24
+ sideValue: "top" | "bottom" | "left" | "right";
25
+ readonly hasSideValue: boolean;
26
+
27
+ /** Alignment: "start", "center", "end" */
28
+ alignValue: "start" | "center" | "end";
29
+ readonly hasAlignValue: boolean;
30
+
31
+ /** Delay before showing tooltip (ms) */
32
+ delayValue: number;
33
+ readonly hasDelayValue: boolean;
34
+
35
+ /** Skip delay threshold (ms) */
36
+ skipDelayValue: number;
37
+ readonly hasSkipDelayValue: boolean;
38
+
39
+ /** Show timeout handle */
40
+ showTimeout: ReturnType<typeof setTimeout> | null;
41
+
42
+ /** Hide timeout handle */
43
+ hideTimeout: ReturnType<typeof setTimeout> | null;
44
+
45
+ /** Show the tooltip */
46
+ show(): void;
47
+
48
+ /** Hide the tooltip */
49
+ hide(): void;
50
+
51
+ /** Clear all timeouts */
52
+ clearTimeouts(): void;
53
+
54
+ /** Position the tooltip */
55
+ positionTooltip(): void;
56
+ }
@@ -0,0 +1,117 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ /**
4
+ * Tooltip controller for contextual information
5
+ */
6
+ export default class extends Controller {
7
+ static targets = ["trigger", "content"]
8
+ static values = {
9
+ side: { type: String, default: "top" },
10
+ align: { type: String, default: "center" },
11
+ delay: { type: Number, default: 200 },
12
+ skipDelay: { type: Number, default: 300 }
13
+ }
14
+
15
+ connect() {
16
+ this.showTimeout = null
17
+ this.hideTimeout = null
18
+ }
19
+
20
+ disconnect() {
21
+ this.clearTimeouts()
22
+ }
23
+
24
+ show() {
25
+ this.clearTimeouts()
26
+
27
+ this.showTimeout = setTimeout(() => {
28
+ if (this.hasContentTarget) {
29
+ this.contentTarget.hidden = false
30
+ this.contentTarget.dataset.state = "open"
31
+ this.positionTooltip()
32
+ }
33
+ }, this.delayValue)
34
+ }
35
+
36
+ hide() {
37
+ this.clearTimeouts()
38
+
39
+ this.hideTimeout = setTimeout(() => {
40
+ if (this.hasContentTarget) {
41
+ this.contentTarget.dataset.state = "closed"
42
+ setTimeout(() => {
43
+ this.contentTarget.hidden = true
44
+ }, 100)
45
+ }
46
+ }, 0)
47
+ }
48
+
49
+ clearTimeouts() {
50
+ if (this.showTimeout) {
51
+ clearTimeout(this.showTimeout)
52
+ this.showTimeout = null
53
+ }
54
+ if (this.hideTimeout) {
55
+ clearTimeout(this.hideTimeout)
56
+ this.hideTimeout = null
57
+ }
58
+ }
59
+
60
+ positionTooltip() {
61
+ if (!this.hasContentTarget || !this.hasTriggerTarget) return
62
+
63
+ const trigger = this.triggerTarget.getBoundingClientRect()
64
+ const tooltip = this.contentTarget
65
+ const tooltipRect = tooltip.getBoundingClientRect()
66
+
67
+ // Reset positioning
68
+ tooltip.style.position = "absolute"
69
+ tooltip.style.top = ""
70
+ tooltip.style.bottom = ""
71
+ tooltip.style.left = ""
72
+ tooltip.style.right = ""
73
+ tooltip.style.transform = ""
74
+
75
+ const gap = 8
76
+
77
+ switch (this.sideValue) {
78
+ case "top":
79
+ tooltip.style.bottom = "100%"
80
+ tooltip.style.marginBottom = `${gap}px`
81
+ break
82
+ case "bottom":
83
+ tooltip.style.top = "100%"
84
+ tooltip.style.marginTop = `${gap}px`
85
+ break
86
+ case "left":
87
+ tooltip.style.right = "100%"
88
+ tooltip.style.marginRight = `${gap}px`
89
+ tooltip.style.top = "50%"
90
+ tooltip.style.transform = "translateY(-50%)"
91
+ break
92
+ case "right":
93
+ tooltip.style.left = "100%"
94
+ tooltip.style.marginLeft = `${gap}px`
95
+ tooltip.style.top = "50%"
96
+ tooltip.style.transform = "translateY(-50%)"
97
+ break
98
+ }
99
+
100
+ if (this.sideValue === "top" || this.sideValue === "bottom") {
101
+ switch (this.alignValue) {
102
+ case "start":
103
+ tooltip.style.left = "0"
104
+ break
105
+ case "center":
106
+ tooltip.style.left = "50%"
107
+ tooltip.style.transform = "translateX(-50%)"
108
+ break
109
+ case "end":
110
+ tooltip.style.right = "0"
111
+ break
112
+ }
113
+ }
114
+
115
+ tooltip.dataset.side = this.sideValue
116
+ }
117
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * shadcn-rails Stimulus Controllers - TypeScript Type Definitions
3
+ *
4
+ * This file provides TypeScript type definitions for all shadcn-rails
5
+ * Stimulus controllers without requiring TypeScript compilation.
6
+ */
7
+
8
+ import { Application } from "@hotwired/stimulus";
9
+
10
+ // Re-export individual controllers
11
+ export { default as AccordionController } from "./controllers/accordion_controller";
12
+ export { default as AvatarController } from "./controllers/avatar_controller";
13
+ export { default as CheckboxController } from "./controllers/checkbox_controller";
14
+ export { default as CollapsibleController } from "./controllers/collapsible_controller";
15
+ export { default as DialogController } from "./controllers/dialog_controller";
16
+ export { default as DrawerController } from "./controllers/drawer_controller";
17
+ export { default as DropdownController } from "./controllers/dropdown_controller";
18
+ export { default as HoverCardController } from "./controllers/hover_card_controller";
19
+ export { default as InputOtpController } from "./controllers/input_otp_controller";
20
+ export { default as PopoverController } from "./controllers/popover_controller";
21
+ export { default as RadioGroupController } from "./controllers/radio_group_controller";
22
+ export { default as ScrollAreaController } from "./controllers/scroll_area_controller";
23
+ export { default as SelectController } from "./controllers/select_controller";
24
+ export { default as SheetController } from "./controllers/sheet_controller";
25
+ export { default as SliderController } from "./controllers/slider_controller";
26
+ export { default as SwitchController } from "./controllers/switch_controller";
27
+ export { default as TabsController } from "./controllers/tabs_controller";
28
+ export { default as ToastController } from "./controllers/toast_controller";
29
+ export { default as ToggleController } from "./controllers/toggle_controller";
30
+ export { default as ToggleGroupController } from "./controllers/toggle_group_controller";
31
+ export { default as TooltipController } from "./controllers/tooltip_controller";
32
+
33
+ /**
34
+ * Controller name to controller class mapping
35
+ */
36
+ export const controllers: {
37
+ "shadcn--accordion": typeof AccordionController;
38
+ "shadcn--avatar": typeof AvatarController;
39
+ "shadcn--checkbox": typeof CheckboxController;
40
+ "shadcn--collapsible": typeof CollapsibleController;
41
+ "shadcn--dialog": typeof DialogController;
42
+ "shadcn--drawer": typeof DrawerController;
43
+ "shadcn--dropdown": typeof DropdownController;
44
+ "shadcn--hover-card": typeof HoverCardController;
45
+ "shadcn--input-otp": typeof InputOtpController;
46
+ "shadcn--popover": typeof PopoverController;
47
+ "shadcn--radio-group": typeof RadioGroupController;
48
+ "shadcn--scroll-area": typeof ScrollAreaController;
49
+ "shadcn--select": typeof SelectController;
50
+ "shadcn--sheet": typeof SheetController;
51
+ "shadcn--slider": typeof SliderController;
52
+ "shadcn--switch": typeof SwitchController;
53
+ "shadcn--tabs": typeof TabsController;
54
+ "shadcn--toast": typeof ToastController;
55
+ "shadcn--toggle": typeof ToggleController;
56
+ "shadcn--toggle-group": typeof ToggleGroupController;
57
+ "shadcn--tooltip": typeof TooltipController;
58
+ };
59
+
60
+ /**
61
+ * Register all shadcn controllers with a Stimulus application
62
+ * @param application - The Stimulus application instance
63
+ */
64
+ export function registerShadcnControllers(application: Application): void;
65
+
66
+ /**
67
+ * Default export containing controllers and registration function
68
+ */
69
+ declare const _default: {
70
+ controllers: typeof controllers;
71
+ registerShadcnControllers: typeof registerShadcnControllers;
72
+ };
73
+
74
+ export default _default;
@@ -0,0 +1,133 @@
1
+ /**
2
+ * shadcn-rails Stimulus Controllers
3
+ *
4
+ * This file exports all Stimulus controllers for the shadcn-rails gem.
5
+ * Import this file to register all controllers with your Stimulus application.
6
+ *
7
+ * Usage with importmaps:
8
+ * import { registerShadcnControllers } from "shadcn"
9
+ * registerShadcnControllers(application)
10
+ *
11
+ * Usage with esbuild/webpack:
12
+ * import { registerShadcnControllers } from "shadcn-rails"
13
+ * registerShadcnControllers(application)
14
+ */
15
+
16
+ // Import all controllers
17
+ import AccordionController from "./controllers/accordion_controller"
18
+ import AvatarController from "./controllers/avatar_controller"
19
+ import CalendarController from "./controllers/calendar_controller"
20
+ import CarouselController from "./controllers/carousel_controller"
21
+ import DatePickerController from "./controllers/date_picker_controller"
22
+ import CheckboxController from "./controllers/checkbox_controller"
23
+ import CollapsibleController from "./controllers/collapsible_controller"
24
+ import ComboboxController from "./controllers/combobox_controller"
25
+ import CommandController from "./controllers/command_controller"
26
+ import CommandDialogController from "./controllers/command_dialog_controller"
27
+ import ContextMenuController from "./controllers/context_menu_controller"
28
+ import DialogController from "./controllers/dialog_controller"
29
+ import DrawerController from "./controllers/drawer_controller"
30
+ import DropdownController from "./controllers/dropdown_controller"
31
+ import HoverCardController from "./controllers/hover_card_controller"
32
+ import MenubarController from "./controllers/menubar_controller"
33
+ import NavigationMenuController from "./controllers/navigation_menu_controller"
34
+ import PopoverController from "./controllers/popover_controller"
35
+ import ResizableController from "./controllers/resizable_controller"
36
+ import RadioGroupController from "./controllers/radio_group_controller"
37
+ import ScrollAreaController from "./controllers/scroll_area_controller"
38
+ import SelectController from "./controllers/select_controller"
39
+ import SheetController from "./controllers/sheet_controller"
40
+ import SliderController from "./controllers/slider_controller"
41
+ import SwitchController from "./controllers/switch_controller"
42
+ import TabsController from "./controllers/tabs_controller"
43
+ import ToastController from "./controllers/toast_controller"
44
+ import ToggleController from "./controllers/toggle_controller"
45
+ import ToggleGroupController from "./controllers/toggle_group_controller"
46
+ import TooltipController from "./controllers/tooltip_controller"
47
+ import InputOtpController from "./controllers/input_otp_controller"
48
+ import SidebarController from "./controllers/sidebar_controller"
49
+
50
+ // Export individual controllers
51
+ export {
52
+ AccordionController,
53
+ AvatarController,
54
+ CalendarController,
55
+ CarouselController,
56
+ DatePickerController,
57
+ CheckboxController,
58
+ CollapsibleController,
59
+ ComboboxController,
60
+ CommandController,
61
+ CommandDialogController,
62
+ ContextMenuController,
63
+ DialogController,
64
+ DrawerController,
65
+ DropdownController,
66
+ HoverCardController,
67
+ InputOtpController,
68
+ MenubarController,
69
+ NavigationMenuController,
70
+ PopoverController,
71
+ RadioGroupController,
72
+ ResizableController,
73
+ ScrollAreaController,
74
+ SelectController,
75
+ SheetController,
76
+ SliderController,
77
+ SwitchController,
78
+ TabsController,
79
+ ToastController,
80
+ ToggleController,
81
+ ToggleGroupController,
82
+ TooltipController,
83
+ SidebarController
84
+ }
85
+
86
+ // Controller definitions for registration
87
+ export const controllers = {
88
+ "shadcn--accordion": AccordionController,
89
+ "shadcn--avatar": AvatarController,
90
+ "shadcn--calendar": CalendarController,
91
+ "shadcn--carousel": CarouselController,
92
+ "shadcn--date-picker": DatePickerController,
93
+ "shadcn--checkbox": CheckboxController,
94
+ "shadcn--collapsible": CollapsibleController,
95
+ "shadcn--combobox": ComboboxController,
96
+ "shadcn--command": CommandController,
97
+ "shadcn--command-dialog": CommandDialogController,
98
+ "shadcn--context-menu": ContextMenuController,
99
+ "shadcn--dialog": DialogController,
100
+ "shadcn--drawer": DrawerController,
101
+ "shadcn--dropdown": DropdownController,
102
+ "shadcn--hover-card": HoverCardController,
103
+ "shadcn--input-otp": InputOtpController,
104
+ "shadcn--menubar": MenubarController,
105
+ "shadcn--navigation-menu": NavigationMenuController,
106
+ "shadcn--popover": PopoverController,
107
+ "shadcn--radio-group": RadioGroupController,
108
+ "shadcn--resizable": ResizableController,
109
+ "shadcn--scroll-area": ScrollAreaController,
110
+ "shadcn--select": SelectController,
111
+ "shadcn--sheet": SheetController,
112
+ "shadcn--slider": SliderController,
113
+ "shadcn--switch": SwitchController,
114
+ "shadcn--tabs": TabsController,
115
+ "shadcn--toast": ToastController,
116
+ "shadcn--toggle": ToggleController,
117
+ "shadcn--toggle-group": ToggleGroupController,
118
+ "shadcn--tooltip": TooltipController,
119
+ "shadcn--sidebar": SidebarController
120
+ }
121
+
122
+ /**
123
+ * Register all shadcn controllers with a Stimulus application
124
+ * @param {Application} application - The Stimulus application instance
125
+ */
126
+ export function registerShadcnControllers(application) {
127
+ for (const [name, controller] of Object.entries(controllers)) {
128
+ application.register(name, controller)
129
+ }
130
+ }
131
+
132
+ // Default export for convenience
133
+ export default { controllers, registerShadcnControllers }
File without changes