shadcn_view_component 0.3.3

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 (507) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +255 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +604 -0
  5. data/app/assets/stylesheets/shadcn-themes.css +1075 -0
  6. data/app/assets/stylesheets/shadcn.css +853 -0
  7. data/app/components/shadcn/accordion/component.rb +44 -0
  8. data/app/components/shadcn/accordion/content/component.rb +44 -0
  9. data/app/components/shadcn/accordion/item/component.rb +41 -0
  10. data/app/components/shadcn/accordion/preview.rb +16 -0
  11. data/app/components/shadcn/accordion/previews/default.html.erb +10 -0
  12. data/app/components/shadcn/accordion/previews/multiple.html.erb +13 -0
  13. data/app/components/shadcn/accordion/trigger/component.rb +52 -0
  14. data/app/components/shadcn/alert/component.rb +52 -0
  15. data/app/components/shadcn/alert/preview.rb +11 -0
  16. data/app/components/shadcn/alert/previews/default.html.erb +8 -0
  17. data/app/components/shadcn/alert.rb +17 -0
  18. data/app/components/shadcn/alert_dialog/action/component.rb +35 -0
  19. data/app/components/shadcn/alert_dialog/cancel/component.rb +16 -0
  20. data/app/components/shadcn/alert_dialog/component.rb +20 -0
  21. data/app/components/shadcn/alert_dialog/content/component.rb +55 -0
  22. data/app/components/shadcn/alert_dialog/header/component.rb +33 -0
  23. data/app/components/shadcn/alert_dialog/preview.rb +16 -0
  24. data/app/components/shadcn/alert_dialog/previews/default.html.erb +13 -0
  25. data/app/components/shadcn/alert_dialog/previews/small_with_media.html.erb +38 -0
  26. data/app/components/shadcn/alert_dialog.rb +32 -0
  27. data/app/components/shadcn/application_view_component.rb +225 -0
  28. data/app/components/shadcn/application_view_component_preview.rb +8 -0
  29. data/app/components/shadcn/aspect_ratio/component.rb +34 -0
  30. data/app/components/shadcn/aspect_ratio/preview.rb +16 -0
  31. data/app/components/shadcn/aspect_ratio/previews/default.html.erb +5 -0
  32. data/app/components/shadcn/aspect_ratio/previews/ratios.html.erb +12 -0
  33. data/app/components/shadcn/attachment/action/component.rb +19 -0
  34. data/app/components/shadcn/attachment/component.rb +76 -0
  35. data/app/components/shadcn/attachment/media/component.rb +56 -0
  36. data/app/components/shadcn/attachment/preview.rb +11 -0
  37. data/app/components/shadcn/attachment/previews/default.html.erb +80 -0
  38. data/app/components/shadcn/attachment/trigger/component.rb +31 -0
  39. data/app/components/shadcn/attachment.rb +42 -0
  40. data/app/components/shadcn/avatar/component.rb +43 -0
  41. data/app/components/shadcn/avatar/fallback/component.rb +23 -0
  42. data/app/components/shadcn/avatar/image/component.rb +20 -0
  43. data/app/components/shadcn/avatar/preview.rb +11 -0
  44. data/app/components/shadcn/avatar/previews/default.html.erb +13 -0
  45. data/app/components/shadcn/avatar.rb +32 -0
  46. data/app/components/shadcn/badge/component.rb +57 -0
  47. data/app/components/shadcn/badge/preview.rb +11 -0
  48. data/app/components/shadcn/badge/previews/default.html.erb +5 -0
  49. data/app/components/shadcn/breadcrumb/component.rb +15 -0
  50. data/app/components/shadcn/breadcrumb/ellipsis/component.rb +28 -0
  51. data/app/components/shadcn/breadcrumb/page/component.rb +25 -0
  52. data/app/components/shadcn/breadcrumb/preview.rb +16 -0
  53. data/app/components/shadcn/breadcrumb/previews/custom_separator.html.erb +17 -0
  54. data/app/components/shadcn/breadcrumb/previews/default.html.erb +15 -0
  55. data/app/components/shadcn/breadcrumb/separator/component.rb +31 -0
  56. data/app/components/shadcn/breadcrumb.rb +18 -0
  57. data/app/components/shadcn/bubble/component.rb +90 -0
  58. data/app/components/shadcn/bubble/preview.rb +16 -0
  59. data/app/components/shadcn/bubble/previews/alignment.html.erb +33 -0
  60. data/app/components/shadcn/bubble/previews/default.html.erb +22 -0
  61. data/app/components/shadcn/bubble/reactions/component.rb +54 -0
  62. data/app/components/shadcn/bubble.rb +24 -0
  63. data/app/components/shadcn/button/component.rb +85 -0
  64. data/app/components/shadcn/button/preview.rb +31 -0
  65. data/app/components/shadcn/button/previews/default.html.erb +8 -0
  66. data/app/components/shadcn/button/previews/sizes.html.erb +5 -0
  67. data/app/components/shadcn/button/previews/variants.html.erb +5 -0
  68. data/app/components/shadcn/button_group/component.rb +53 -0
  69. data/app/components/shadcn/button_group/preview.rb +15 -0
  70. data/app/components/shadcn/button_group/previews/default.html.erb +18 -0
  71. data/app/components/shadcn/button_group/previews/vertical.html.erb +5 -0
  72. data/app/components/shadcn/button_group/separator/component.rb +30 -0
  73. data/app/components/shadcn/button_group/text/component.rb +20 -0
  74. data/app/components/shadcn/calendar/component.rb +558 -0
  75. data/app/components/shadcn/calendar/month.rb +74 -0
  76. data/app/components/shadcn/calendar/preview.rb +64 -0
  77. data/app/components/shadcn/calendar/previews/booked.html.erb +18 -0
  78. data/app/components/shadcn/calendar/previews/custom_cell_size.html.erb +11 -0
  79. data/app/components/shadcn/calendar/previews/date_and_time.html.erb +31 -0
  80. data/app/components/shadcn/calendar/previews/default.html.erb +8 -0
  81. data/app/components/shadcn/calendar/previews/dropdown_caption.html.erb +11 -0
  82. data/app/components/shadcn/calendar/previews/in_a_form.html.erb +8 -0
  83. data/app/components/shadcn/calendar/previews/presets.html.erb +20 -0
  84. data/app/components/shadcn/calendar/previews/range.html.erb +10 -0
  85. data/app/components/shadcn/calendar/previews/week_numbers.html.erb +8 -0
  86. data/app/components/shadcn/card/component.rb +24 -0
  87. data/app/components/shadcn/card/header/component.rb +26 -0
  88. data/app/components/shadcn/card/preview.rb +16 -0
  89. data/app/components/shadcn/card/previews/default.html.erb +18 -0
  90. data/app/components/shadcn/card/previews/image.html.erb +37 -0
  91. data/app/components/shadcn/card.rb +21 -0
  92. data/app/components/shadcn/carousel/component.rb +61 -0
  93. data/app/components/shadcn/carousel/content/component.rb +86 -0
  94. data/app/components/shadcn/carousel/item/component.rb +42 -0
  95. data/app/components/shadcn/carousel/next/component.rb +59 -0
  96. data/app/components/shadcn/carousel/preview.rb +22 -0
  97. data/app/components/shadcn/carousel/previews/default.html.erb +22 -0
  98. data/app/components/shadcn/carousel/previews/sizes.html.erb +42 -0
  99. data/app/components/shadcn/carousel/previews/vertical.html.erb +27 -0
  100. data/app/components/shadcn/carousel/previous/component.rb +59 -0
  101. data/app/components/shadcn/chart/area/component.rb +43 -0
  102. data/app/components/shadcn/chart/bar/component.rb +75 -0
  103. data/app/components/shadcn/chart/cartesian/component.rb +152 -0
  104. data/app/components/shadcn/chart/component.rb +124 -0
  105. data/app/components/shadcn/chart/focusable.rb +38 -0
  106. data/app/components/shadcn/chart/legend/component.rb +55 -0
  107. data/app/components/shadcn/chart/line/component.rb +50 -0
  108. data/app/components/shadcn/chart/pie/component.rb +169 -0
  109. data/app/components/shadcn/chart/plot.rb +147 -0
  110. data/app/components/shadcn/chart/preview.rb +45 -0
  111. data/app/components/shadcn/chart/previews/area.html.erb +31 -0
  112. data/app/components/shadcn/chart/previews/bar.html.erb +32 -0
  113. data/app/components/shadcn/chart/previews/bar_stacked.html.erb +30 -0
  114. data/app/components/shadcn/chart/previews/default.html.erb +30 -0
  115. data/app/components/shadcn/chart/previews/donut.html.erb +16 -0
  116. data/app/components/shadcn/chart/previews/line.html.erb +30 -0
  117. data/app/components/shadcn/chart/previews/percentages.html.erb +17 -0
  118. data/app/components/shadcn/chart/table/component.rb +75 -0
  119. data/app/components/shadcn/chart/tooltip/component.rb +111 -0
  120. data/app/components/shadcn/checkbox/component.rb +109 -0
  121. data/app/components/shadcn/checkbox/preview.rb +16 -0
  122. data/app/components/shadcn/checkbox/previews/default.html.erb +14 -0
  123. data/app/components/shadcn/checkbox/previews/states.html.erb +23 -0
  124. data/app/components/shadcn/collapsible/component.rb +35 -0
  125. data/app/components/shadcn/collapsible/content/component.rb +20 -0
  126. data/app/components/shadcn/collapsible/preview.rb +11 -0
  127. data/app/components/shadcn/collapsible/previews/default.html.erb +9 -0
  128. data/app/components/shadcn/collapsible/trigger/component.rb +23 -0
  129. data/app/components/shadcn/combobox/chip/component.rb +60 -0
  130. data/app/components/shadcn/combobox/chip_input/component.rb +43 -0
  131. data/app/components/shadcn/combobox/chips/component.rb +54 -0
  132. data/app/components/shadcn/combobox/clear/component.rb +32 -0
  133. data/app/components/shadcn/combobox/component.rb +113 -0
  134. data/app/components/shadcn/combobox/content/component.rb +59 -0
  135. data/app/components/shadcn/combobox/empty/component.rb +23 -0
  136. data/app/components/shadcn/combobox/input/component.rb +85 -0
  137. data/app/components/shadcn/combobox/item/component.rb +69 -0
  138. data/app/components/shadcn/combobox/list/component.rb +27 -0
  139. data/app/components/shadcn/combobox/preview.rb +31 -0
  140. data/app/components/shadcn/combobox/previews/default.html.erb +20 -0
  141. data/app/components/shadcn/combobox/previews/grouped.html.erb +25 -0
  142. data/app/components/shadcn/combobox/previews/multiple.html.erb +28 -0
  143. data/app/components/shadcn/combobox/previews/with_clear.html.erb +16 -0
  144. data/app/components/shadcn/combobox/trigger/component.rb +54 -0
  145. data/app/components/shadcn/combobox.rb +16 -0
  146. data/app/components/shadcn/command/component.rb +67 -0
  147. data/app/components/shadcn/command/dialog/component.rb +72 -0
  148. data/app/components/shadcn/command/empty/component.rb +29 -0
  149. data/app/components/shadcn/command/group/component.rb +63 -0
  150. data/app/components/shadcn/command/input/component.rb +66 -0
  151. data/app/components/shadcn/command/item/component.rb +62 -0
  152. data/app/components/shadcn/command/list/component.rb +36 -0
  153. data/app/components/shadcn/command/preview.rb +26 -0
  154. data/app/components/shadcn/command/previews/default.html.erb +41 -0
  155. data/app/components/shadcn/command/previews/dialog.html.erb +33 -0
  156. data/app/components/shadcn/command/previews/ranking.html.erb +16 -0
  157. data/app/components/shadcn/command/separator/component.rb +33 -0
  158. data/app/components/shadcn/command.rb +14 -0
  159. data/app/components/shadcn/concerns/modal_root.rb +43 -0
  160. data/app/components/shadcn/concerns/submits_value.rb +81 -0
  161. data/app/components/shadcn/context_menu/component.rb +45 -0
  162. data/app/components/shadcn/context_menu/content/component.rb +40 -0
  163. data/app/components/shadcn/context_menu/preview.rb +16 -0
  164. data/app/components/shadcn/context_menu/previews/default.html.erb +34 -0
  165. data/app/components/shadcn/context_menu/previews/items.html.erb +35 -0
  166. data/app/components/shadcn/context_menu/sub/component.rb +47 -0
  167. data/app/components/shadcn/context_menu/sub_content/component.rb +31 -0
  168. data/app/components/shadcn/context_menu/trigger/component.rb +50 -0
  169. data/app/components/shadcn/context_menu.rb +43 -0
  170. data/app/components/shadcn/dialog/close/component.rb +20 -0
  171. data/app/components/shadcn/dialog/component.rb +20 -0
  172. data/app/components/shadcn/dialog/content/component.rb +78 -0
  173. data/app/components/shadcn/dialog/header/component.rb +23 -0
  174. data/app/components/shadcn/dialog/overlay/component.rb +28 -0
  175. data/app/components/shadcn/dialog/preview.rb +28 -0
  176. data/app/components/shadcn/dialog/previews/default.html.erb +17 -0
  177. data/app/components/shadcn/dialog/previews/inside_stacking_context.html.erb +25 -0
  178. data/app/components/shadcn/dialog/previews/no_close_button.html.erb +15 -0
  179. data/app/components/shadcn/dialog/previews/scrollable_content.html.erb +29 -0
  180. data/app/components/shadcn/dialog/trigger/component.rb +24 -0
  181. data/app/components/shadcn/dialog.rb +17 -0
  182. data/app/components/shadcn/drawer/component.rb +33 -0
  183. data/app/components/shadcn/drawer/content/component.rb +95 -0
  184. data/app/components/shadcn/drawer/header/component.rb +34 -0
  185. data/app/components/shadcn/drawer/preview.rb +29 -0
  186. data/app/components/shadcn/drawer/previews/default.html.erb +21 -0
  187. data/app/components/shadcn/drawer/previews/scrollable.html.erb +20 -0
  188. data/app/components/shadcn/drawer/previews/scrollable_side.html.erb +21 -0
  189. data/app/components/shadcn/drawer/previews/sides.html.erb +17 -0
  190. data/app/components/shadcn/drawer.rb +27 -0
  191. data/app/components/shadcn/dropdown_menu/checkbox_item/component.rb +61 -0
  192. data/app/components/shadcn/dropdown_menu/component.rb +48 -0
  193. data/app/components/shadcn/dropdown_menu/content/component.rb +49 -0
  194. data/app/components/shadcn/dropdown_menu/group/component.rb +16 -0
  195. data/app/components/shadcn/dropdown_menu/item/component.rb +50 -0
  196. data/app/components/shadcn/dropdown_menu/preview.rb +16 -0
  197. data/app/components/shadcn/dropdown_menu/previews/checkboxes_and_radio.html.erb +34 -0
  198. data/app/components/shadcn/dropdown_menu/previews/default.html.erb +23 -0
  199. data/app/components/shadcn/dropdown_menu/radio_group/component.rb +16 -0
  200. data/app/components/shadcn/dropdown_menu/radio_item/component.rb +63 -0
  201. data/app/components/shadcn/dropdown_menu/sub/component.rb +44 -0
  202. data/app/components/shadcn/dropdown_menu/sub_content/component.rb +45 -0
  203. data/app/components/shadcn/dropdown_menu/sub_trigger/component.rb +58 -0
  204. data/app/components/shadcn/dropdown_menu/trigger/component.rb +25 -0
  205. data/app/components/shadcn/dropdown_menu.rb +18 -0
  206. data/app/components/shadcn/empty/component.rb +17 -0
  207. data/app/components/shadcn/empty/media/component.rb +48 -0
  208. data/app/components/shadcn/empty/preview.rb +16 -0
  209. data/app/components/shadcn/empty/previews/default.html.erb +15 -0
  210. data/app/components/shadcn/empty/previews/media.html.erb +32 -0
  211. data/app/components/shadcn/empty.rb +26 -0
  212. data/app/components/shadcn/field/component.rb +61 -0
  213. data/app/components/shadcn/field/error/component.rb +49 -0
  214. data/app/components/shadcn/field/legend/component.rb +30 -0
  215. data/app/components/shadcn/field/preview.rb +17 -0
  216. data/app/components/shadcn/field/previews/default.html.erb +29 -0
  217. data/app/components/shadcn/field/previews/form_builder.html.erb +38 -0
  218. data/app/components/shadcn/field/separator/component.rb +35 -0
  219. data/app/components/shadcn/field.rb +44 -0
  220. data/app/components/shadcn/hover_card/component.rb +51 -0
  221. data/app/components/shadcn/hover_card/content/component.rb +45 -0
  222. data/app/components/shadcn/hover_card/preview.rb +16 -0
  223. data/app/components/shadcn/hover_card/previews/default.html.erb +36 -0
  224. data/app/components/shadcn/hover_card/previews/sides.html.erb +15 -0
  225. data/app/components/shadcn/hover_card/trigger/component.rb +33 -0
  226. data/app/components/shadcn/icon/component.rb +76 -0
  227. data/app/components/shadcn/icon.rb +43 -0
  228. data/app/components/shadcn/input/component.rb +26 -0
  229. data/app/components/shadcn/input/preview.rb +16 -0
  230. data/app/components/shadcn/input/previews/default.html.erb +5 -0
  231. data/app/components/shadcn/input/previews/states.html.erb +20 -0
  232. data/app/components/shadcn/input_group/addon/component.rb +65 -0
  233. data/app/components/shadcn/input_group/button/component.rb +40 -0
  234. data/app/components/shadcn/input_group/component.rb +43 -0
  235. data/app/components/shadcn/input_group/input/component.rb +25 -0
  236. data/app/components/shadcn/input_group/preview.rb +17 -0
  237. data/app/components/shadcn/input_group/previews/addons.html.erb +53 -0
  238. data/app/components/shadcn/input_group/previews/default.html.erb +25 -0
  239. data/app/components/shadcn/input_group/text/component.rb +20 -0
  240. data/app/components/shadcn/input_group/textarea/component.rb +21 -0
  241. data/app/components/shadcn/input_otp/component.rb +95 -0
  242. data/app/components/shadcn/input_otp/preview.rb +17 -0
  243. data/app/components/shadcn/input_otp/previews/default.html.erb +19 -0
  244. data/app/components/shadcn/input_otp/previews/variations.html.erb +33 -0
  245. data/app/components/shadcn/input_otp/separator/component.rb +21 -0
  246. data/app/components/shadcn/input_otp/slot/component.rb +60 -0
  247. data/app/components/shadcn/input_otp.rb +11 -0
  248. data/app/components/shadcn/item/component.rb +56 -0
  249. data/app/components/shadcn/item/group/component.rb +53 -0
  250. data/app/components/shadcn/item/media/component.rb +53 -0
  251. data/app/components/shadcn/item/preview.rb +20 -0
  252. data/app/components/shadcn/item/previews/default.html.erb +32 -0
  253. data/app/components/shadcn/item/previews/link.html.erb +39 -0
  254. data/app/components/shadcn/item/previews/outline.html.erb +8 -0
  255. data/app/components/shadcn/item/separator/component.rb +24 -0
  256. data/app/components/shadcn/item.rb +34 -0
  257. data/app/components/shadcn/kbd/component.rb +23 -0
  258. data/app/components/shadcn/kbd/group/component.rb +17 -0
  259. data/app/components/shadcn/kbd/preview.rb +11 -0
  260. data/app/components/shadcn/kbd/previews/default.html.erb +4 -0
  261. data/app/components/shadcn/label/component.rb +20 -0
  262. data/app/components/shadcn/label/preview.rb +11 -0
  263. data/app/components/shadcn/label/previews/default.html.erb +4 -0
  264. data/app/components/shadcn/marker/component.rb +46 -0
  265. data/app/components/shadcn/marker/icon/component.rb +23 -0
  266. data/app/components/shadcn/marker/preview.rb +17 -0
  267. data/app/components/shadcn/marker/previews/default.html.erb +18 -0
  268. data/app/components/shadcn/marker/previews/status.html.erb +32 -0
  269. data/app/components/shadcn/marker.rb +17 -0
  270. data/app/components/shadcn/menubar/component.rb +36 -0
  271. data/app/components/shadcn/menubar/content/component.rb +49 -0
  272. data/app/components/shadcn/menubar/menu/component.rb +39 -0
  273. data/app/components/shadcn/menubar/preview.rb +16 -0
  274. data/app/components/shadcn/menubar/previews/default.html.erb +52 -0
  275. data/app/components/shadcn/menubar/previews/items.html.erb +38 -0
  276. data/app/components/shadcn/menubar/sub/component.rb +43 -0
  277. data/app/components/shadcn/menubar/sub_content/component.rb +31 -0
  278. data/app/components/shadcn/menubar/sub_trigger/component.rb +31 -0
  279. data/app/components/shadcn/menubar/trigger/component.rb +41 -0
  280. data/app/components/shadcn/menubar.rb +47 -0
  281. data/app/components/shadcn/message/component.rb +33 -0
  282. data/app/components/shadcn/message/preview.rb +16 -0
  283. data/app/components/shadcn/message/previews/actions.html.erb +51 -0
  284. data/app/components/shadcn/message/previews/default.html.erb +35 -0
  285. data/app/components/shadcn/message.rb +35 -0
  286. data/app/components/shadcn/message_scroller/button/component.rb +78 -0
  287. data/app/components/shadcn/message_scroller/component.rb +59 -0
  288. data/app/components/shadcn/message_scroller/content/component.rb +50 -0
  289. data/app/components/shadcn/message_scroller/item/component.rb +45 -0
  290. data/app/components/shadcn/message_scroller/preview.rb +11 -0
  291. data/app/components/shadcn/message_scroller/previews/default.html.erb +72 -0
  292. data/app/components/shadcn/message_scroller/viewport/component.rb +41 -0
  293. data/app/components/shadcn/mode_switcher/component.rb +67 -0
  294. data/app/components/shadcn/mode_switcher/preview.rb +11 -0
  295. data/app/components/shadcn/mode_switcher/previews/default.html.erb +5 -0
  296. data/app/components/shadcn/mode_toggle/component.rb +75 -0
  297. data/app/components/shadcn/mode_toggle/preview.rb +11 -0
  298. data/app/components/shadcn/mode_toggle/previews/default.html.erb +20 -0
  299. data/app/components/shadcn/native_select/component.rb +59 -0
  300. data/app/components/shadcn/native_select/preview.rb +16 -0
  301. data/app/components/shadcn/native_select/previews/default.html.erb +9 -0
  302. data/app/components/shadcn/native_select/previews/groups.html.erb +26 -0
  303. data/app/components/shadcn/native_select.rb +16 -0
  304. data/app/components/shadcn/navigation_menu/component.rb +51 -0
  305. data/app/components/shadcn/navigation_menu/content/component.rb +58 -0
  306. data/app/components/shadcn/navigation_menu/preview.rb +11 -0
  307. data/app/components/shadcn/navigation_menu/previews/default.html.erb +49 -0
  308. data/app/components/shadcn/navigation_menu/trigger/component.rb +59 -0
  309. data/app/components/shadcn/navigation_menu.rb +28 -0
  310. data/app/components/shadcn/pagination/component.rb +19 -0
  311. data/app/components/shadcn/pagination/ellipsis/component.rb +28 -0
  312. data/app/components/shadcn/pagination/link/component.rb +37 -0
  313. data/app/components/shadcn/pagination/next/component.rb +31 -0
  314. data/app/components/shadcn/pagination/preview.rb +16 -0
  315. data/app/components/shadcn/pagination/previews/default.html.erb +18 -0
  316. data/app/components/shadcn/pagination/previews/simple.html.erb +39 -0
  317. data/app/components/shadcn/pagination/previous/component.rb +31 -0
  318. data/app/components/shadcn/pagination.rb +14 -0
  319. data/app/components/shadcn/parts.rb +38 -0
  320. data/app/components/shadcn/popover/anchor/component.rb +17 -0
  321. data/app/components/shadcn/popover/component.rb +42 -0
  322. data/app/components/shadcn/popover/content/component.rb +40 -0
  323. data/app/components/shadcn/popover/preview.rb +28 -0
  324. data/app/components/shadcn/popover/previews/align.html.erb +13 -0
  325. data/app/components/shadcn/popover/previews/default.html.erb +9 -0
  326. data/app/components/shadcn/popover/previews/inside_containing_block.html.erb +41 -0
  327. data/app/components/shadcn/popover/previews/inside_stacking_context.html.erb +30 -0
  328. data/app/components/shadcn/popover/trigger/component.rb +24 -0
  329. data/app/components/shadcn/popover.rb +16 -0
  330. data/app/components/shadcn/progress/component.rb +62 -0
  331. data/app/components/shadcn/progress/preview.rb +11 -0
  332. data/app/components/shadcn/progress/previews/default.html.erb +5 -0
  333. data/app/components/shadcn/radio_group/component.rb +51 -0
  334. data/app/components/shadcn/radio_group/item/component.rb +74 -0
  335. data/app/components/shadcn/radio_group/preview.rb +16 -0
  336. data/app/components/shadcn/radio_group/previews/default.html.erb +15 -0
  337. data/app/components/shadcn/radio_group/previews/states.html.erb +41 -0
  338. data/app/components/shadcn/resizable/component.rb +59 -0
  339. data/app/components/shadcn/resizable/handle/component.rb +70 -0
  340. data/app/components/shadcn/resizable/panel/component.rb +53 -0
  341. data/app/components/shadcn/resizable/preview.rb +23 -0
  342. data/app/components/shadcn/resizable/previews/default.html.erb +25 -0
  343. data/app/components/shadcn/resizable/previews/vertical.html.erb +19 -0
  344. data/app/components/shadcn/resizable/previews/with_handle.html.erb +17 -0
  345. data/app/components/shadcn/scroll_area/component.rb +84 -0
  346. data/app/components/shadcn/scroll_area/preview.rb +11 -0
  347. data/app/components/shadcn/scroll_area/previews/default.html.erb +36 -0
  348. data/app/components/shadcn/scroll_area/scrollbar/component.rb +72 -0
  349. data/app/components/shadcn/scroll_area/viewport/component.rb +70 -0
  350. data/app/components/shadcn/scroll_area.rb +14 -0
  351. data/app/components/shadcn/select/component.rb +67 -0
  352. data/app/components/shadcn/select/content/component.rb +157 -0
  353. data/app/components/shadcn/select/empty/component.rb +38 -0
  354. data/app/components/shadcn/select/group/component.rb +16 -0
  355. data/app/components/shadcn/select/item/component.rb +71 -0
  356. data/app/components/shadcn/select/list/component.rb +41 -0
  357. data/app/components/shadcn/select/preview.rb +24 -0
  358. data/app/components/shadcn/select/previews/default.html.erb +17 -0
  359. data/app/components/shadcn/select/previews/scrollable.html.erb +19 -0
  360. data/app/components/shadcn/select/previews/searchable.html.erb +18 -0
  361. data/app/components/shadcn/select/previews/states.html.erb +25 -0
  362. data/app/components/shadcn/select/search/component.rb +54 -0
  363. data/app/components/shadcn/select/trigger/component.rb +78 -0
  364. data/app/components/shadcn/select/value/component.rb +28 -0
  365. data/app/components/shadcn/select.rb +15 -0
  366. data/app/components/shadcn/separator/component.rb +41 -0
  367. data/app/components/shadcn/separator/preview.rb +11 -0
  368. data/app/components/shadcn/separator/previews/default.html.erb +9 -0
  369. data/app/components/shadcn/sheet/component.rb +16 -0
  370. data/app/components/shadcn/sheet/content/component.rb +98 -0
  371. data/app/components/shadcn/sheet/header/component.rb +23 -0
  372. data/app/components/shadcn/sheet/preview.rb +16 -0
  373. data/app/components/shadcn/sheet/previews/default.html.erb +16 -0
  374. data/app/components/shadcn/sheet/previews/no_close_button.html.erb +14 -0
  375. data/app/components/shadcn/sheet.rb +22 -0
  376. data/app/components/shadcn/sidebar/component.rb +232 -0
  377. data/app/components/shadcn/sidebar/input/component.rb +25 -0
  378. data/app/components/shadcn/sidebar/menu_action/component.rb +58 -0
  379. data/app/components/shadcn/sidebar/menu_button/component.rb +100 -0
  380. data/app/components/shadcn/sidebar/menu_skeleton/component.rb +51 -0
  381. data/app/components/shadcn/sidebar/menu_sub_button/component.rb +60 -0
  382. data/app/components/shadcn/sidebar/preview.rb +22 -0
  383. data/app/components/shadcn/sidebar/previews/default.html.erb +189 -0
  384. data/app/components/shadcn/sidebar/previews/floating.html.erb +39 -0
  385. data/app/components/shadcn/sidebar/previews/inset.html.erb +48 -0
  386. data/app/components/shadcn/sidebar/provider/component.rb +53 -0
  387. data/app/components/shadcn/sidebar/rail/component.rb +43 -0
  388. data/app/components/shadcn/sidebar/separator/component.rb +23 -0
  389. data/app/components/shadcn/sidebar/trigger/component.rb +39 -0
  390. data/app/components/shadcn/sidebar.rb +98 -0
  391. data/app/components/shadcn/skeleton/component.rb +14 -0
  392. data/app/components/shadcn/skeleton/preview.rb +11 -0
  393. data/app/components/shadcn/skeleton/previews/default.html.erb +7 -0
  394. data/app/components/shadcn/slider/component.rb +145 -0
  395. data/app/components/shadcn/slider/preview.rb +16 -0
  396. data/app/components/shadcn/slider/previews/default.html.erb +17 -0
  397. data/app/components/shadcn/slider/previews/vertical.html.erb +7 -0
  398. data/app/components/shadcn/slider/range/component.rb +51 -0
  399. data/app/components/shadcn/slider/thumb/component.rb +58 -0
  400. data/app/components/shadcn/slider/track/component.rb +32 -0
  401. data/app/components/shadcn/spinner/component.rb +21 -0
  402. data/app/components/shadcn/spinner/preview.rb +11 -0
  403. data/app/components/shadcn/spinner/previews/default.html.erb +7 -0
  404. data/app/components/shadcn/switch/component.rb +104 -0
  405. data/app/components/shadcn/switch/preview.rb +11 -0
  406. data/app/components/shadcn/switch/previews/default.html.erb +24 -0
  407. data/app/components/shadcn/table/component.rb +26 -0
  408. data/app/components/shadcn/table/preview.rb +16 -0
  409. data/app/components/shadcn/table/previews/default.html.erb +19 -0
  410. data/app/components/shadcn/table/previews/footer.html.erb +25 -0
  411. data/app/components/shadcn/table.rb +33 -0
  412. data/app/components/shadcn/tabs/component.rb +40 -0
  413. data/app/components/shadcn/tabs/content/component.rb +34 -0
  414. data/app/components/shadcn/tabs/list/component.rb +51 -0
  415. data/app/components/shadcn/tabs/preview.rb +16 -0
  416. data/app/components/shadcn/tabs/previews/default.html.erb +21 -0
  417. data/app/components/shadcn/tabs/previews/line.html.erb +23 -0
  418. data/app/components/shadcn/tabs/trigger/component.rb +66 -0
  419. data/app/components/shadcn/textarea/component.rb +24 -0
  420. data/app/components/shadcn/textarea/preview.rb +16 -0
  421. data/app/components/shadcn/textarea/previews/default.html.erb +3 -0
  422. data/app/components/shadcn/textarea/previews/states.html.erb +18 -0
  423. data/app/components/shadcn/theme_selector/component.rb +88 -0
  424. data/app/components/shadcn/theme_selector/preview.rb +17 -0
  425. data/app/components/shadcn/theme_selector/previews/all_themes.html.erb +20 -0
  426. data/app/components/shadcn/theme_selector/previews/default.html.erb +18 -0
  427. data/app/components/shadcn/toaster/component.rb +139 -0
  428. data/app/components/shadcn/toaster/preview.rb +16 -0
  429. data/app/components/shadcn/toaster/previews/default.html.erb +19 -0
  430. data/app/components/shadcn/toaster/previews/from_the_server.html.erb +15 -0
  431. data/app/components/shadcn/toaster/toast/component.rb +134 -0
  432. data/app/components/shadcn/toggle/component.rb +81 -0
  433. data/app/components/shadcn/toggle/preview.rb +11 -0
  434. data/app/components/shadcn/toggle/previews/default.html.erb +6 -0
  435. data/app/components/shadcn/toggle_group/component.rb +62 -0
  436. data/app/components/shadcn/toggle_group/item/component.rb +59 -0
  437. data/app/components/shadcn/toggle_group/preview.rb +16 -0
  438. data/app/components/shadcn/toggle_group/previews/default.html.erb +12 -0
  439. data/app/components/shadcn/toggle_group/previews/sizes.html.erb +37 -0
  440. data/app/components/shadcn/tooltip/component.rb +38 -0
  441. data/app/components/shadcn/tooltip/content/component.rb +62 -0
  442. data/app/components/shadcn/tooltip/preview.rb +21 -0
  443. data/app/components/shadcn/tooltip/previews/default.html.erb +4 -0
  444. data/app/components/shadcn/tooltip/previews/sides.html.erb +19 -0
  445. data/app/components/shadcn/tooltip/previews/with_keyboard_shortcut.html.erb +11 -0
  446. data/app/components/shadcn/tooltip/provider/component.rb +28 -0
  447. data/app/components/shadcn/tooltip/trigger/component.rb +25 -0
  448. data/app/helpers/shadcn_view_component/form_helper.rb +25 -0
  449. data/app/helpers/shadcn_view_component/theme_helper.rb +61 -0
  450. data/app/javascript/shadcn/animation.js +180 -0
  451. data/app/javascript/shadcn/command_score.js +110 -0
  452. data/app/javascript/shadcn/controllers/accordion_controller.js +127 -0
  453. data/app/javascript/shadcn/controllers/avatar_controller.js +32 -0
  454. data/app/javascript/shadcn/controllers/calendar_controller.js +633 -0
  455. data/app/javascript/shadcn/controllers/carousel_controller.js +139 -0
  456. data/app/javascript/shadcn/controllers/chart_controller.js +110 -0
  457. data/app/javascript/shadcn/controllers/checkbox_controller.js +61 -0
  458. data/app/javascript/shadcn/controllers/collapsible_controller.js +55 -0
  459. data/app/javascript/shadcn/controllers/combobox_controller.js +360 -0
  460. data/app/javascript/shadcn/controllers/command_controller.js +199 -0
  461. data/app/javascript/shadcn/controllers/dialog_controller.js +154 -0
  462. data/app/javascript/shadcn/controllers/drawer_controller.js +265 -0
  463. data/app/javascript/shadcn/controllers/dropdown_menu_controller.js +259 -0
  464. data/app/javascript/shadcn/controllers/hover_card_controller.js +85 -0
  465. data/app/javascript/shadcn/controllers/input_group_controller.js +17 -0
  466. data/app/javascript/shadcn/controllers/input_otp_controller.js +80 -0
  467. data/app/javascript/shadcn/controllers/menubar_controller.js +151 -0
  468. data/app/javascript/shadcn/controllers/message_scroller_controller.js +456 -0
  469. data/app/javascript/shadcn/controllers/navigation_menu_controller.js +211 -0
  470. data/app/javascript/shadcn/controllers/popover_controller.js +66 -0
  471. data/app/javascript/shadcn/controllers/radio_group_controller.js +69 -0
  472. data/app/javascript/shadcn/controllers/resizable_controller.js +167 -0
  473. data/app/javascript/shadcn/controllers/scroll_area_controller.js +253 -0
  474. data/app/javascript/shadcn/controllers/select_controller.js +320 -0
  475. data/app/javascript/shadcn/controllers/sidebar_controller.js +273 -0
  476. data/app/javascript/shadcn/controllers/slider_controller.js +230 -0
  477. data/app/javascript/shadcn/controllers/switch_controller.js +39 -0
  478. data/app/javascript/shadcn/controllers/tabs_controller.js +81 -0
  479. data/app/javascript/shadcn/controllers/theme_controller.js +67 -0
  480. data/app/javascript/shadcn/controllers/toaster_controller.js +281 -0
  481. data/app/javascript/shadcn/controllers/toggle_controller.js +24 -0
  482. data/app/javascript/shadcn/controllers/toggle_group_controller.js +73 -0
  483. data/app/javascript/shadcn/controllers/tooltip_controller.js +58 -0
  484. data/app/javascript/shadcn/direction.js +41 -0
  485. data/app/javascript/shadcn/dismiss.js +73 -0
  486. data/app/javascript/shadcn/floating.js +207 -0
  487. data/app/javascript/shadcn/focus.js +86 -0
  488. data/app/javascript/shadcn/id.js +14 -0
  489. data/app/javascript/shadcn/index.js +110 -0
  490. data/app/javascript/shadcn/popper.js +262 -0
  491. data/app/javascript/shadcn/scroll_geometry.js +267 -0
  492. data/app/javascript/shadcn/theme.js +161 -0
  493. data/app/javascript/shadcn/top_layer.js +59 -0
  494. data/app/javascript/shadcn/typeahead.js +99 -0
  495. data/config/importmap.rb +6 -0
  496. data/config/locales/en.yml +62 -0
  497. data/lib/generators/shadcn_view_component/install/install_generator.rb +149 -0
  498. data/lib/shadcn_view_component/engine.rb +73 -0
  499. data/lib/shadcn_view_component/form_builder.rb +264 -0
  500. data/lib/shadcn_view_component/icon_registry.rb +66 -0
  501. data/lib/shadcn_view_component/icons.rb +32 -0
  502. data/lib/shadcn_view_component/themes.rb +1065 -0
  503. data/lib/shadcn_view_component/version.rb +3 -0
  504. data/lib/shadcn_view_component.rb +82 -0
  505. data/lib/tasks/icons.rake +53 -0
  506. data/lib/tasks/themes.rake +171 -0
  507. metadata +608 -0
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Accordion
5
+ # Port of registry/new-york-v4/ui/accordion.tsx
6
+ #
7
+ # Radix's Accordion.Root renders a plain div; the `shadcn--accordion`
8
+ # Stimulus controller supplies the open/close state machine, the roving
9
+ # arrow-key navigation and the ARIA wiring between triggers and panels.
10
+ class Component < ApplicationViewComponent
11
+ renders_many :items, "Shadcn::Accordion::Item::Component"
12
+
13
+ slot_name :accordion
14
+
15
+ attr_reader :type, :collapsible, :value, :orientation
16
+
17
+ # @param type [:single, :multiple]
18
+ # @param collapsible [Boolean] may the open item be closed again (single only)
19
+ # @param value [String, Array] initially open item value(s)
20
+ def initialize(type: :single, collapsible: false, value: nil, orientation: :vertical,
21
+ **attributes)
22
+ @type = type&.to_sym || :single
23
+ @collapsible = collapsible
24
+ @value = Array(value).compact.join(",")
25
+ @orientation = orientation&.to_sym || :vertical
26
+ super(**attributes)
27
+ end
28
+
29
+ def element_attributes(**defaults)
30
+ super(**{
31
+ "data-orientation" => orientation,
32
+ "data-controller" => "shadcn--accordion",
33
+ "data-shadcn--accordion-type-value" => type,
34
+ "data-shadcn--accordion-collapsible-value" => collapsible,
35
+ "data-shadcn--accordion-value-value" => value
36
+ }.merge(defaults))
37
+ end
38
+
39
+ def call
40
+ render_element(body: safe_join([ items, content ].flatten.compact))
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Accordion
5
+ module Content
6
+ # AccordionContent — the animated wrapper carries the classes, the inner
7
+ # div takes the padding, exactly as in the TSX.
8
+ class Component < ApplicationViewComponent
9
+ WRAPPER_CLASSES = "overflow-hidden text-sm data-[state=closed]:animate-accordion-up " \
10
+ "data-[state=open]:animate-accordion-down"
11
+
12
+ slot_name :"accordion-content"
13
+
14
+ style do
15
+ base { "pt-0 pb-4" }
16
+ end
17
+
18
+ def element_attributes(**defaults)
19
+ # The outer element gets no caller classes: shadcn puts them on the
20
+ # inner div instead.
21
+ {
22
+ "data-slot" => "accordion-content",
23
+ "data-state" => "closed",
24
+ "data-orientation" => "vertical",
25
+ role: "region",
26
+ hidden: true,
27
+ class: WRAPPER_CLASSES
28
+ }.merge(defaults).compact
29
+ end
30
+
31
+ def call
32
+ content_tag(:div, inner, element_attributes)
33
+ end
34
+
35
+ private
36
+
37
+ def inner
38
+ inner_attributes = attributes.except(:class)
39
+ content_tag(:div, content, inner_attributes.merge(class: css_classes(attributes[:class])))
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Accordion
5
+ module Item
6
+ # AccordionItem
7
+ class Component < ApplicationViewComponent
8
+ renders_one :trigger, "Shadcn::Accordion::Trigger::Component"
9
+ renders_one :panel, "Shadcn::Accordion::Content::Component"
10
+
11
+ slot_name :"accordion-item"
12
+
13
+ style do
14
+ base { "border-b last:border-b-0" }
15
+ end
16
+
17
+ attr_reader :value, :disabled
18
+
19
+ def initialize(value:, disabled: false, **attributes)
20
+ @value = value.to_s
21
+ @disabled = disabled
22
+ super(**attributes)
23
+ end
24
+
25
+ def element_attributes(**defaults)
26
+ super(**{
27
+ "data-value" => value,
28
+ "data-state" => "closed",
29
+ "data-orientation" => "vertical",
30
+ "data-disabled" => (true if disabled),
31
+ "data-shadcn--accordion-target" => "item"
32
+ }.merge(defaults))
33
+ end
34
+
35
+ def call
36
+ render_element(body: safe_join([ trigger, panel, content ].compact))
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Accordion
5
+ class Preview < ApplicationViewComponentPreview
6
+ def default
7
+ render_with_template
8
+ end
9
+
10
+ # Upstream's "Multiple" and "Disabled".
11
+ def multiple
12
+ render_with_template
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ <%= render(Shadcn::Accordion::Component.new(type: :single, collapsible: true, value: "item-1", class: "w-[420px]")) do |acc| %>
2
+ <% [["item-1", "Is it accessible?", "Yes. It adheres to the WAI-ARIA design pattern."],
3
+ ["item-2", "Is it styled?", "Yes. It comes with default styles that match the other components."],
4
+ ["item-3", "Is it animated?", "Yes. It is animated by default, but you can disable it."]].each do |value, question, answer| %>
5
+ <% acc.with_item(value:) do |item| %>
6
+ <% item.with_trigger { question } %>
7
+ <% item.with_panel { answer } %>
8
+ <% end %>
9
+ <% end %>
10
+ <% end %>
@@ -0,0 +1,13 @@
1
+ <%# Upstream's "Multiple" and "Disabled". Both are arguments rather than
2
+ markup — `type: :multiple` lets more than one panel stay open at a time,
3
+ and a disabled item cannot be opened at all. %>
4
+ <%= render(Shadcn::Accordion::Component.new(type: :multiple, value: %w[shipping returns], class: "w-[420px]")) do |acc| %>
5
+ <% [["shipping", "How long does shipping take?", "Two to five working days.", false],
6
+ ["returns", "Can I return an order?", "Within thirty days, unopened.", false],
7
+ ["wholesale", "Do you sell wholesale?", "Not reachable — this item is disabled.", true]].each do |value, question, answer, disabled| %>
8
+ <% acc.with_item(value:, disabled:) do |item| %>
9
+ <% item.with_trigger { question } %>
10
+ <% item.with_panel { answer } %>
11
+ <% end %>
12
+ <% end %>
13
+ <% end %>
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Accordion
5
+ module Trigger
6
+ # AccordionTrigger — Radix wraps the button in an `<h3>` header, which is
7
+ # where shadcn puts the `flex` class.
8
+ class Component < ApplicationViewComponent
9
+ HEADER_CLASSES = "flex"
10
+
11
+ default_tag :button
12
+ slot_name :"accordion-trigger"
13
+
14
+ style do
15
+ base {
16
+ "flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left " \
17
+ "text-sm font-medium transition-all outline-none hover:underline " \
18
+ "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 " \
19
+ "disabled:pointer-events-none disabled:opacity-50 " \
20
+ "[&[data-state=open]>svg]:rotate-180"
21
+ }
22
+ end
23
+
24
+ CHEVRON_CLASSES = "pointer-events-none size-4 shrink-0 translate-y-0.5 " \
25
+ "text-muted-foreground transition-transform duration-200"
26
+
27
+ def element_attributes(**defaults)
28
+ super(**{
29
+ type: "button",
30
+ "data-state" => "closed",
31
+ "data-orientation" => "vertical",
32
+ "aria-expanded" => "false",
33
+ "data-shadcn--accordion-target" => "trigger",
34
+ "data-action" => "click->shadcn--accordion#toggle keydown->shadcn--accordion#keydown"
35
+ }.merge(defaults))
36
+ end
37
+
38
+ def call
39
+ tag.h3(class: HEADER_CLASSES, "data-slot": "accordion-header") do
40
+ render_element(body: safe_join([ content, chevron ]))
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def chevron
47
+ render(Icon::Component.new("chevron-down", class: CHEVRON_CLASSES))
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Alert
5
+ # Port of registry/new-york-v4/ui/alert.tsx
6
+ class Component < ApplicationViewComponent
7
+ renders_one :title, "Shadcn::Alert::Title::Component"
8
+ renders_one :description, "Shadcn::Alert::Description::Component"
9
+
10
+ slot_name :alert
11
+
12
+ style do
13
+ base {
14
+ "relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border " \
15
+ "px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] " \
16
+ "has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current"
17
+ }
18
+
19
+ variants {
20
+ variant {
21
+ default { "bg-card text-card-foreground" }
22
+ destructive {
23
+ "bg-card text-destructive " \
24
+ "*:data-[slot=alert-description]:text-destructive/90 [&>svg]:text-current"
25
+ }
26
+ }
27
+ }
28
+
29
+ defaults { { variant: :default } }
30
+ end
31
+
32
+ attr_reader :variant
33
+
34
+ def initialize(variant: :default, **attributes)
35
+ @variant = variant&.to_sym || :default
36
+ super(**attributes)
37
+ end
38
+
39
+ def style_variants
40
+ { variant: }
41
+ end
42
+
43
+ def element_attributes(**defaults)
44
+ super(**{ role: "alert" }.merge(defaults))
45
+ end
46
+
47
+ def call
48
+ render_element(body: safe_join([ title, description, content ].compact))
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Alert
5
+ class Preview < ApplicationViewComponentPreview
6
+ def default
7
+ render_with_template
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ <div class="flex max-w-xl flex-col gap-4">
2
+ <% %i[default destructive].each do |variant| %>
3
+ <%= render(Shadcn::Alert::Component.new(variant:)) do |a| %>
4
+ <% a.with_title { "Heads up!" } %>
5
+ <% a.with_description { "You can add components to your app using the CLI." } %>
6
+ <% end %>
7
+ <% end %>
8
+ </div>
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ # The parts of the Alert family that are just an element with a
5
+ # `data-slot` and a fixed set of classes. Anything with variants, slots or
6
+ # markup of its own keeps its own `component.rb`.
7
+ module Alert
8
+ extend Parts
9
+
10
+ part :description, slot: "alert-description",
11
+ classes: "col-start-2 grid justify-items-start gap-1 text-sm " \
12
+ "text-muted-foreground [&_p]:leading-relaxed"
13
+
14
+ part :title, slot: "alert-title",
15
+ classes: "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight"
16
+ end
17
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module AlertDialog
5
+ module Action
6
+ # AlertDialogAction — shadcn wraps it in `<Button asChild>`, so it carries
7
+ # the button's classes while staying the dialog's action element.
8
+ class Component < ApplicationViewComponent
9
+ default_tag :button
10
+ slot_name :"alert-dialog-action"
11
+
12
+ attr_reader :variant, :size
13
+
14
+ def initialize(variant: :default, size: :default, **attributes)
15
+ @variant = variant&.to_sym || :default
16
+ @size = size&.to_sym || :default
17
+ super(**attributes)
18
+ end
19
+
20
+ def element_attributes(**defaults)
21
+ super(**{
22
+ type: "button",
23
+ "data-variant" => variant,
24
+ "data-size" => size,
25
+ "data-action" => "shadcn--dialog#close"
26
+ }.merge(defaults))
27
+ end
28
+
29
+ def css_classes(extra = nil)
30
+ Button::Component.variant_classes(variant:, size:, class: extra)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module AlertDialog
5
+ module Cancel
6
+ # AlertDialogCancel — same as Action but outlined by default.
7
+ class Component < Action::Component
8
+ slot_name :"alert-dialog-cancel"
9
+
10
+ def initialize(variant: :outline, **attributes)
11
+ super(variant:, **attributes)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module AlertDialog
5
+ # Port of registry/new-york-v4/ui/alert-dialog.tsx
6
+ #
7
+ # Same primitive as Dialog, except Radix deliberately refuses to close an
8
+ # alert dialog on an outside click — the user has to pick an action.
9
+ class Component < ApplicationViewComponent
10
+ include Concerns::ModalRoot
11
+
12
+ renders_one :trigger, "Shadcn::AlertDialog::Trigger::Component"
13
+ renders_one :dialog_content, "Shadcn::AlertDialog::Content::Component"
14
+
15
+ slot_name :"alert-dialog"
16
+
17
+ def dismissable? = false
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module AlertDialog
5
+ module Content
6
+ # AlertDialogContent — `role="alertdialog"`, no dismiss button.
7
+ class Component < ApplicationViewComponent
8
+ renders_one :header, "Shadcn::AlertDialog::Header::Component"
9
+ renders_one :footer, "Shadcn::AlertDialog::Footer::Component"
10
+
11
+ slot_name :"alert-dialog-content"
12
+
13
+ style do
14
+ base {
15
+ "group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full " \
16
+ "max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg " \
17
+ "border bg-background p-6 shadow-lg duration-200 data-[size=sm]:max-w-xs " \
18
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 " \
19
+ "data-[state=closed]:zoom-out-95 data-[state=open]:animate-in " \
20
+ "data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 " \
21
+ "data-[size=default]:sm:max-w-lg"
22
+ }
23
+ end
24
+
25
+ attr_reader :size
26
+
27
+ def initialize(size: :default, **attributes)
28
+ @size = size&.to_sym || :default
29
+ super(**attributes)
30
+ end
31
+
32
+ def element_attributes(**defaults)
33
+ super(**{
34
+ role: "alertdialog",
35
+ "aria-modal" => "true",
36
+ tabindex: "-1",
37
+ "data-size" => size,
38
+ "data-state" => "closed",
39
+ hidden: true,
40
+ "data-shadcn--dialog-target" => "content"
41
+ }.merge(defaults))
42
+ end
43
+
44
+ def call
45
+ tag.div("data-slot": "alert-dialog-portal", style: CONTENTS_STYLE) do
46
+ safe_join([
47
+ render(Overlay::Component.new),
48
+ render_element(body: safe_join([ header, content, footer ].compact))
49
+ ])
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module AlertDialog
5
+ module Header
6
+ # AlertDialogHeader
7
+ class Component < ApplicationViewComponent
8
+ renders_one :media, "Shadcn::AlertDialog::Media::Component"
9
+ renders_one :title, "Shadcn::AlertDialog::Title::Component"
10
+ renders_one :description, "Shadcn::AlertDialog::Description::Component"
11
+
12
+ slot_name :"alert-dialog-header"
13
+
14
+ style do
15
+ base {
16
+ # Class names are never split across line continuations: Tailwind
17
+ # scans the source text, so half a token would generate no CSS.
18
+ "grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center " \
19
+ "has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] " \
20
+ "has-data-[slot=alert-dialog-media]:gap-x-6 " \
21
+ "sm:group-data-[size=default]/alert-dialog-content:place-items-start " \
22
+ "sm:group-data-[size=default]/alert-dialog-content:text-left " \
23
+ "sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]"
24
+ }
25
+ end
26
+
27
+ def call
28
+ render_element(body: safe_join([ media, title, description, content ].compact))
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module AlertDialog
5
+ class Preview < ApplicationViewComponentPreview
6
+ def default
7
+ render_with_template
8
+ end
9
+
10
+ # Upstream's "Small", "Media", "Small with Media" and "Destructive".
11
+ def small_with_media
12
+ render_with_template
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ <%= render(Shadcn::AlertDialog::Component.new) do |d| %>
2
+ <% d.with_trigger(class: Shadcn::Button::Component.variant_classes(variant: :destructive)) { "Delete account" } %>
3
+ <% d.with_dialog_content do |c| %>
4
+ <% c.with_header do |h| %>
5
+ <% h.with_title { "Are you absolutely sure?" } %>
6
+ <% h.with_description { "This action cannot be undone. It will permanently delete your account." } %>
7
+ <% end %>
8
+ <% c.with_footer do %>
9
+ <%= render(Shadcn::AlertDialog::Cancel::Component.new) { "Cancel" } %>
10
+ <%= render(Shadcn::AlertDialog::Action::Component.new) { "Continue" } %>
11
+ <% end %>
12
+ <% end %>
13
+ <% end %>
@@ -0,0 +1,38 @@
1
+ <%# Upstream's "Small", "Media" and "Small with Media" — `size: :sm` and the
2
+ `media` slot, which the default preview shows neither of. The action is
3
+ styled destructive, which is upstream's "Destructive": the dialog itself has
4
+ no variant, so the colour is the button's. %>
5
+ <div class="flex items-center gap-2">
6
+ <%= render(Shadcn::AlertDialog::Component.new) do |d| %>
7
+ <% d.with_trigger(class: Shadcn::Button::Component.variant_classes(variant: :outline)) { "Small" } %>
8
+ <% d.with_dialog_content(size: :sm) do |c| %>
9
+ <% c.with_header do |h| %>
10
+ <% h.with_title { "Discard draft?" } %>
11
+ <% h.with_description { "It has not been saved anywhere." } %>
12
+ <% end %>
13
+ <% c.with_footer do %>
14
+ <%= render(Shadcn::AlertDialog::Cancel::Component.new) { "Keep" } %>
15
+ <%= render(Shadcn::AlertDialog::Action::Component.new(class: Shadcn::Button::Component.variant_classes(variant: :destructive))) { "Discard" } %>
16
+ <% end %>
17
+ <% end %>
18
+ <% end %>
19
+
20
+ <%= render(Shadcn::AlertDialog::Component.new) do |d| %>
21
+ <% d.with_trigger(class: Shadcn::Button::Component.variant_classes(variant: :outline)) { "Small with media" } %>
22
+ <% d.with_dialog_content(size: :sm) do |c| %>
23
+ <%# The media sits inside the header, which is where upstream puts it and
24
+ what its `row-span-2` is measured against. %>
25
+ <% c.with_header do |h| %>
26
+ <% h.with_media do %>
27
+ <%= render(Shadcn::Icon::Component.new("circle")) %>
28
+ <% end %>
29
+ <% h.with_title { "Delete this project?" } %>
30
+ <% h.with_description { "Everything in it goes with it." } %>
31
+ <% end %>
32
+ <% c.with_footer do %>
33
+ <%= render(Shadcn::AlertDialog::Cancel::Component.new) { "Cancel" } %>
34
+ <%= render(Shadcn::AlertDialog::Action::Component.new(class: Shadcn::Button::Component.variant_classes(variant: :destructive))) { "Delete" } %>
35
+ <% end %>
36
+ <% end %>
37
+ <% end %>
38
+ </div>
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ # The parts of the AlertDialog family that are just an element with a
5
+ # `data-slot` and a fixed set of classes. Anything with variants, slots or
6
+ # markup of its own keeps its own `component.rb`.
7
+ module AlertDialog
8
+ extend Parts
9
+
10
+ part :description, tag: :p, slot: "alert-dialog-description",
11
+ classes: "text-sm text-muted-foreground"
12
+
13
+ part :footer, slot: "alert-dialog-footer",
14
+ classes: "flex flex-col-reverse gap-2 " \
15
+ "group-data-[size=sm]/alert-dialog-content:grid " \
16
+ "group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row " \
17
+ "sm:justify-end"
18
+
19
+ part :media, slot: "alert-dialog-media",
20
+ classes: "mb-2 inline-flex size-16 items-center justify-center rounded-md " \
21
+ "bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 " \
22
+ "*:[svg:not([class*='size-'])]:size-8"
23
+
24
+ part :overlay, slot: "alert-dialog-overlay", from: Dialog::Overlay::Component
25
+
26
+ part :title, tag: :h2, slot: "alert-dialog-title",
27
+ classes: "text-lg font-semibold " \
28
+ "sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2"
29
+
30
+ part :trigger, slot: "alert-dialog-trigger", from: Dialog::Trigger::Component
31
+ end
32
+ end