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,8 @@
1
+ <%= render(Shadcn::Item::Component.new(variant: :outline, class: "w-full max-w-md")) do %>
2
+ <%= render(Shadcn::Item::Media::Component.new(variant: :image)) do %>
3
+ <img src="https://placehold.co/40" alt="">
4
+ <% end %>
5
+ <%= render(Shadcn::Item::Content::Component.new) do %>
6
+ <%= render(Shadcn::Item::Title::Component.new) { "Outline, with an image" } %>
7
+ <% end %>
8
+ <% end %>
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Item
5
+ module Separator
6
+ # ItemSeparator renders a Separator with its own `data-slot` and one class
7
+ # on top, the way ButtonGroupSeparator does. Upstream pins the orientation
8
+ # to horizontal rather than defaulting it, so it is not a keyword here.
9
+ class Component < Shadcn::Separator::Component
10
+ slot_name :"item-separator"
11
+
12
+ EXTRA_CLASSES = "my-0"
13
+
14
+ def initialize(**attributes)
15
+ super(orientation: :horizontal, **attributes)
16
+ end
17
+
18
+ def css_classes(extra = nil)
19
+ super([ EXTRA_CLASSES, extra ].compact.join(" "))
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ # The parts of the Item family that are just an element with a `data-slot`
5
+ # and a fixed set of classes. `Item`, `ItemGroup`, `ItemMedia` and
6
+ # `ItemSeparator` each need more than that, so they keep their own
7
+ # `component.rb`.
8
+ #
9
+ # `ItemDescription` really is a `<p>` here — unlike Empty's, which upstream
10
+ # types as `"p"` while rendering a `<div>`.
11
+ module Item
12
+ extend Parts
13
+
14
+ part :content, slot: "item-content",
15
+ classes: "flex flex-1 flex-col gap-1 " \
16
+ "[&+[data-slot=item-content]]:flex-none"
17
+
18
+ part :title, slot: "item-title",
19
+ classes: "flex w-fit items-center gap-2 text-sm leading-snug font-medium"
20
+
21
+ part :description, slot: "item-description", tag: :p,
22
+ classes: "line-clamp-2 text-sm leading-normal font-normal " \
23
+ "text-balance text-muted-foreground [&>a]:underline " \
24
+ "[&>a]:underline-offset-4 [&>a:hover]:text-primary"
25
+
26
+ part :actions, slot: "item-actions", classes: "flex items-center gap-2"
27
+
28
+ part :header, slot: "item-header",
29
+ classes: "flex basis-full items-center justify-between gap-2"
30
+
31
+ part :footer, slot: "item-footer",
32
+ classes: "flex basis-full items-center justify-between gap-2"
33
+ end
34
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Kbd
5
+ # Port of registry/new-york-v4/ui/kbd.tsx
6
+ class Component < ApplicationViewComponent
7
+ default_tag :kbd
8
+ slot_name :kbd
9
+
10
+ style do
11
+ base {
12
+ "pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center " \
13
+ "gap-1 rounded-sm bg-muted px-1 font-sans text-xs font-medium " \
14
+ "text-muted-foreground select-none " \
15
+ "[&_svg:not([class*='size-'])]:size-3 " \
16
+ "[[data-slot=tooltip-content]_&]:bg-background/20 " \
17
+ "[[data-slot=tooltip-content]_&]:text-background " \
18
+ "dark:[[data-slot=tooltip-content]_&]:bg-background/10"
19
+ }
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Kbd
5
+ module Group
6
+ # KbdGroup — note shadcn types it as a div but renders a <kbd>.
7
+ class Component < ApplicationViewComponent
8
+ default_tag :kbd
9
+ slot_name :"kbd-group"
10
+
11
+ style do
12
+ base { "inline-flex items-center gap-1" }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Kbd
5
+ class Preview < ApplicationViewComponentPreview
6
+ def default
7
+ render_with_template
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ <%= render(Shadcn::Kbd::Group::Component.new) do %>
2
+ <%= render(Shadcn::Kbd::Component.new) { "\u2318" } %>
3
+ <%= render(Shadcn::Kbd::Component.new) { "K" } %>
4
+ <% end %>
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Label
5
+ # Port of registry/new-york-v4/ui/label.tsx
6
+ class Component < ApplicationViewComponent
7
+ default_tag :label
8
+ slot_name :label
9
+
10
+ style do
11
+ base {
12
+ "flex items-center gap-2 text-sm leading-none font-medium select-none " \
13
+ "group-data-[disabled=true]:pointer-events-none " \
14
+ "group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed " \
15
+ "peer-disabled:opacity-50"
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Label
5
+ class Preview < ApplicationViewComponentPreview
6
+ def default
7
+ render_with_template
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ <div class="flex items-center gap-2">
2
+ <%= render(Shadcn::Checkbox::Component.new(id: "terms")) %>
3
+ <%= render(Shadcn::Label::Component.new(for: "terms")) { "Accept terms and conditions" } %>
4
+ </div>
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Marker
5
+ # Port of registry/new-york-v4/ui/marker.tsx
6
+ class Component < ApplicationViewComponent
7
+ slot_name :marker
8
+
9
+ style do
10
+ base {
11
+ "group/marker relative flex min-h-4 w-full items-center gap-2 text-left text-sm " \
12
+ "text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [a]:underline " \
13
+ "[a]:underline-offset-3 [a]:hover:text-foreground"
14
+ }
15
+
16
+ variants {
17
+ variant {
18
+ default { "" }
19
+ separator {
20
+ "before:mr-1 before:h-px before:min-w-0 before:flex-1 before:bg-border " \
21
+ "after:ml-1 after:h-px after:min-w-0 after:flex-1 after:bg-border"
22
+ }
23
+ border { "border-b border-border pb-2" }
24
+ }
25
+ }
26
+
27
+ defaults { { variant: :default } }
28
+ end
29
+
30
+ attr_reader :variant
31
+
32
+ def initialize(variant: :default, **attributes)
33
+ @variant = variant&.to_sym || :default
34
+ super(**attributes)
35
+ end
36
+
37
+ def style_variants
38
+ { variant: }
39
+ end
40
+
41
+ def element_attributes(**defaults)
42
+ super(**{ "data-variant" => variant }.merge(defaults))
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Marker
5
+ module Icon
6
+ # MarkerIcon. Its own file rather than a `part` declaration for one
7
+ # reason: upstream stamps `aria-hidden` on it (marker.tsx:46), and `part`
8
+ # declares a slot, classes and a tag and deliberately no other attribute.
9
+ class Component < ApplicationViewComponent
10
+ default_tag :span
11
+ slot_name :"marker-icon"
12
+
13
+ style do
14
+ base { "size-4 shrink-0 [&_svg:not([class*='size-'])]:size-4" }
15
+ end
16
+
17
+ def element_attributes(**defaults)
18
+ super(**{ "aria-hidden" => "true" }.merge(defaults))
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Marker
5
+ class Preview < ApplicationViewComponentPreview
6
+ def default
7
+ render_with_template
8
+ end
9
+
10
+ # Upstream's "Status" and "Shimmer" — and the only place in the gallery
11
+ # that renders the `shimmer` utility.
12
+ def status
13
+ render_with_template
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ <%# The three variants, which is all this family has: a row of muted text with
2
+ an optional icon, ruled off in one of three ways. %>
3
+ <div class="flex w-[420px] flex-col gap-4">
4
+ <%= render(Shadcn::Marker::Component.new) do %>
5
+ <%= render(Shadcn::Marker::Icon::Component.new) do %>
6
+ <%= render(Shadcn::Icon::Component.new("check")) %>
7
+ <% end %>
8
+ <%= render(Shadcn::Marker::Content::Component.new) { "Delivered · 9:41 AM" } %>
9
+ <% end %>
10
+
11
+ <%= render(Shadcn::Marker::Component.new(variant: :separator)) do %>
12
+ <%= render(Shadcn::Marker::Content::Component.new) { "Today" } %>
13
+ <% end %>
14
+
15
+ <%= render(Shadcn::Marker::Component.new(variant: :border)) do %>
16
+ <%= render(Shadcn::Marker::Content::Component.new) { "Unread messages" } %>
17
+ <% end %>
18
+ </div>
@@ -0,0 +1,32 @@
1
+ <%# Upstream's "Status" and "Shimmer": a marker saying what is happening right
2
+ now, with the text lit by a band that travels across it.
3
+
4
+ `shimmer` is one of the six utilities in `shadcn.css` that are shadcn's own
5
+ CSS rather than Tailwind's — they were read from the stylesheet
6
+ ui.shadcn.com serves, because no vendored source here defines them, and
7
+ until this preview nothing in the gallery rendered one. A utility nobody
8
+ looks at is a utility nobody notices breaking. %>
9
+ <div class="flex w-[420px] flex-col gap-4">
10
+ <%= render(Shadcn::Marker::Component.new) do %>
11
+ <%= render(Shadcn::Marker::Icon::Component.new) do %>
12
+ <%= render(Shadcn::Icon::Component.new("loader-circle", class: "animate-spin")) %>
13
+ <% end %>
14
+ <%= render(Shadcn::Marker::Content::Component.new(class: "shimmer")) { "Thinking…" } %>
15
+ <% end %>
16
+
17
+ <%= render(Shadcn::Marker::Component.new) do %>
18
+ <%= render(Shadcn::Marker::Icon::Component.new) do %>
19
+ <%= render(Shadcn::Icon::Component.new("search")) %>
20
+ <% end %>
21
+ <%= render(Shadcn::Marker::Content::Component.new(class: "shimmer")) { "Searching the archive" } %>
22
+ <% end %>
23
+
24
+ <%# And the same row once it is over, which is what the shimmer is the
25
+ absence of. %>
26
+ <%= render(Shadcn::Marker::Component.new) do %>
27
+ <%= render(Shadcn::Marker::Icon::Component.new) do %>
28
+ <%= render(Shadcn::Icon::Component.new("check")) %>
29
+ <% end %>
30
+ <%= render(Shadcn::Marker::Content::Component.new) { "Found 12 matches" } %>
31
+ <% end %>
32
+ </div>
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ # The parts of the Marker 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 Marker
8
+ extend Parts
9
+
10
+ part :content, slot: "marker-content", tag: :span,
11
+ classes: "min-w-0 wrap-break-word " \
12
+ "group-data-[variant=separator]/marker:flex-none " \
13
+ "group-data-[variant=separator]/marker:text-center " \
14
+ "*:[a]:underline *:[a]:underline-offset-3 " \
15
+ "*:[a]:hover:text-foreground"
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Menubar
5
+ # Port of registry/new-york-v4/ui/menubar.tsx — the bar itself.
6
+ #
7
+ # Each menu inside it is a `shadcn--dropdown-menu`, as the context menu's
8
+ # submenus are: what this controller adds is the *bar* — one menu open at a
9
+ # time, arrows moving between the triggers, and a menu already open turning
10
+ # the rest into things you merely hover to reach.
11
+ class Component < ApplicationViewComponent
12
+ slot_name :menubar
13
+
14
+ style do
15
+ base { "flex h-9 items-center gap-1 rounded-md border bg-background p-1 shadow-xs" }
16
+ end
17
+
18
+ attr_reader :loop
19
+
20
+ # Radix's `loop` defaults to **true** here (menubar.tsx:76), unlike the
21
+ # dropdown's, where it is false. A bar is a ring; a list is not.
22
+ def initialize(loop: true, **attributes)
23
+ @loop = loop
24
+ super(**attributes)
25
+ end
26
+
27
+ def element_attributes(**defaults)
28
+ super(**{
29
+ role: "menubar",
30
+ "data-controller" => "shadcn--menubar",
31
+ "data-shadcn--menubar-loop-value" => loop
32
+ }.merge(defaults))
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Menubar
5
+ module Content
6
+ # A menu's panel. Wider than the dropdown's (`min-w-[12rem]` against
7
+ # `min-w-[8rem]`), and it reads `--radix-menubar-*`, which is why it is
8
+ # written out rather than inherited.
9
+ #
10
+ # It carries no `data-[state=closed]:animate-out`, which the dropdown's
11
+ # does. That is upstream's string as vendored, not an omission here.
12
+ class Component < ApplicationViewComponent
13
+ slot_name :"menubar-content"
14
+
15
+ style do
16
+ base {
17
+ "z-50 min-w-[12rem] origin-(--radix-menubar-content-transform-origin) " \
18
+ "overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground " \
19
+ "shadow-md data-[side=bottom]:slide-in-from-top-2 " \
20
+ "data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 " \
21
+ "data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:fade-out-0 " \
22
+ "data-[state=closed]:zoom-out-95 data-[state=open]:animate-in " \
23
+ "data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95"
24
+ }
25
+ end
26
+
27
+ def element_attributes(**defaults)
28
+ super(**{
29
+ role: "menu",
30
+ # Neither is upstream's markup — Radix's FocusScope and Menu add
31
+ # them at runtime, which is why they are in the dropdown's content
32
+ # and not in either vendored file. The `tabindex` is load-bearing:
33
+ # without it `focus()` on the panel is silently a no-op, so the
34
+ # panel never holds the focus, and Escape, the typeahead and the
35
+ # arrow keys are all left listening on an element nothing types
36
+ # into.
37
+ tabindex: "-1",
38
+ "aria-orientation" => "vertical",
39
+ hidden: true,
40
+ "data-state" => "closed",
41
+ "data-shadcn--dropdown-menu-target" => "content",
42
+ "data-action" => "keydown->shadcn--dropdown-menu#contentKeydown " \
43
+ "keydown->shadcn--menubar#contentKeydown"
44
+ }.merge(defaults))
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Menubar
5
+ module Menu
6
+ # One menu in the bar: its trigger and its panel. Upstream gives it no
7
+ # classes (menubar.tsx:28) — it is a grouping, not a box.
8
+ #
9
+ # A `shadcn--dropdown-menu` of its own, carrying the prefix so `popper.js`
10
+ # writes the `--radix-menubar-*` properties the panel reads.
11
+ class Component < ApplicationViewComponent
12
+ renders_one :trigger, "Shadcn::Menubar::Trigger::Component"
13
+ renders_one :menu_content, "Shadcn::Menubar::Content::Component"
14
+
15
+ slot_name :"menubar-menu"
16
+
17
+ def element_attributes(**defaults)
18
+ super(**{
19
+ style: merged_style(CONTENTS_STYLE),
20
+ "data-controller" => "shadcn--dropdown-menu",
21
+ "data-shadcn--dropdown-menu-prefix-value" => "menubar",
22
+ "data-shadcn--menubar-target" => "menu",
23
+ # Upstream's own defaults for a menubar panel (menubar.tsx:68-70):
24
+ # it hangs below the bar, aligned to its trigger's left edge and
25
+ # pulled back by the bar's own padding.
26
+ "data-shadcn--dropdown-menu-side-value" => "bottom",
27
+ "data-shadcn--dropdown-menu-align-value" => "start",
28
+ "data-shadcn--dropdown-menu-side-offset-value" => 8,
29
+ "data-shadcn--dropdown-menu-align-offset-value" => -4
30
+ }.merge(defaults))
31
+ end
32
+
33
+ def call
34
+ render_element(body: safe_join([ trigger, menu_content, content ].compact))
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Menubar
5
+ class Preview < ApplicationViewComponentPreview
6
+ def default
7
+ render_with_template
8
+ end
9
+
10
+ # Upstream's "Radio" and "With Icons".
11
+ def items
12
+ render_with_template
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,52 @@
1
+ <%# Three menus, which is the smallest number at which the bar behaves like one:
2
+ with two, "next" and "previous" land on the same name and neither the arrows
3
+ nor the wrap-around can be told apart.
4
+
5
+ Everything inside a menu is the dropdown's — items, submenu, checkbox and
6
+ radio — and the bar is what this component adds on top. %>
7
+ <div class="flex h-72 items-start justify-center pt-6">
8
+ <%= render(Shadcn::Menubar::Component.new) do %>
9
+ <%= render(Shadcn::Menubar::Menu::Component.new) do |menu| %>
10
+ <% menu.with_trigger { "File" } %>
11
+ <% menu.with_menu_content do %>
12
+ <%= render(Shadcn::Menubar::Item::Component.new) do %>
13
+ New tab
14
+ <%= render(Shadcn::Menubar::Shortcut::Component.new) { "⌘T" } %>
15
+ <% end %>
16
+ <%= render(Shadcn::Menubar::Item::Component.new) { "New window" } %>
17
+ <%= render(Shadcn::Menubar::Separator::Component.new) %>
18
+ <%= render(Shadcn::Menubar::Sub::Component.new) do |sub| %>
19
+ <% sub.with_trigger { "Share" } %>
20
+ <% sub.with_menu_content do %>
21
+ <%= render(Shadcn::Menubar::Item::Component.new) { "Email link" } %>
22
+ <%= render(Shadcn::Menubar::Item::Component.new) { "Messages" } %>
23
+ <% end %>
24
+ <% end %>
25
+ <%= render(Shadcn::Menubar::Separator::Component.new) %>
26
+ <%= render(Shadcn::Menubar::Item::Component.new) do %>
27
+ Print
28
+ <%= render(Shadcn::Menubar::Shortcut::Component.new) { "⌘P" } %>
29
+ <% end %>
30
+ <% end %>
31
+ <% end %>
32
+
33
+ <%= render(Shadcn::Menubar::Menu::Component.new) do |menu| %>
34
+ <% menu.with_trigger { "Edit" } %>
35
+ <% menu.with_menu_content do %>
36
+ <%= render(Shadcn::Menubar::Item::Component.new) do %>
37
+ Undo
38
+ <%= render(Shadcn::Menubar::Shortcut::Component.new) { "⌘Z" } %>
39
+ <% end %>
40
+ <%= render(Shadcn::Menubar::Item::Component.new) { "Redo" } %>
41
+ <% end %>
42
+ <% end %>
43
+
44
+ <%= render(Shadcn::Menubar::Menu::Component.new) do |menu| %>
45
+ <% menu.with_trigger { "View" } %>
46
+ <% menu.with_menu_content do %>
47
+ <%= render(Shadcn::Menubar::CheckboxItem::Component.new(checked: true)) { "Always show bookmarks" } %>
48
+ <%= render(Shadcn::Menubar::CheckboxItem::Component.new) { "Always show full URLs" } %>
49
+ <% end %>
50
+ <% end %>
51
+ <% end %>
52
+ </div>
@@ -0,0 +1,38 @@
1
+ <%# Upstream's "Radio" and "With Icons": the two kinds of item the default
2
+ preview leaves out, which has the plain items, the shortcuts, a submenu and
3
+ the checkboxes.
4
+
5
+ Both are the dropdown's, restamped — the bar's own behaviour is in the
6
+ default preview, which is where three menus are needed to see it. %>
7
+ <%= render(Shadcn::Menubar::Component.new) do %>
8
+ <%= render(Shadcn::Menubar::Menu::Component.new) do |menu| %>
9
+ <% menu.with_trigger { "View" } %>
10
+ <% menu.with_menu_content do %>
11
+ <%= render(Shadcn::Menubar::Label::Component.new) { "Sort by" } %>
12
+ <%= render(Shadcn::Menubar::RadioGroup::Component.new) do %>
13
+ <% %w[Name Date Size].each do |option| %>
14
+ <%= render(Shadcn::Menubar::RadioItem::Component.new(value: option.downcase, checked: option == "Date")) { option } %>
15
+ <% end %>
16
+ <% end %>
17
+ <% end %>
18
+ <% end %>
19
+
20
+ <%= render(Shadcn::Menubar::Menu::Component.new) do |menu| %>
21
+ <% menu.with_trigger { "Go" } %>
22
+ <% menu.with_menu_content do %>
23
+ <%= render(Shadcn::Menubar::Item::Component.new) do %>
24
+ <%= render(Shadcn::Icon::Component.new("chevron-left")) %>
25
+ Back
26
+ <% end %>
27
+ <%= render(Shadcn::Menubar::Item::Component.new) do %>
28
+ <%= render(Shadcn::Icon::Component.new("chevron-right")) %>
29
+ Forward
30
+ <% end %>
31
+ <%= render(Shadcn::Menubar::Separator::Component.new) %>
32
+ <%= render(Shadcn::Menubar::Item::Component.new) do %>
33
+ <%= render(Shadcn::Icon::Component.new("search")) %>
34
+ Find…
35
+ <% end %>
36
+ <% end %>
37
+ <% end %>
38
+ <% end %>
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Menubar
5
+ module Sub
6
+ # A nested menu. Written out rather than subclassed, because ViewComponent
7
+ # refuses to redeclare an inherited slot and this one holds *this*
8
+ # family's sub-content.
9
+ class Component < ApplicationViewComponent
10
+ renders_one :trigger, "Shadcn::Menubar::SubTrigger::Component"
11
+ renders_one :menu_content, "Shadcn::Menubar::SubContent::Component"
12
+
13
+ slot_name :"menubar-sub"
14
+
15
+ attr_reader :open, :side, :align, :side_offset
16
+
17
+ def initialize(open: false, side: :right, align: :start, side_offset: 0, **attributes)
18
+ @open = open
19
+ @side = side&.to_sym || :right
20
+ @align = align&.to_sym || :start
21
+ @side_offset = side_offset
22
+ super(**attributes)
23
+ end
24
+
25
+ def element_attributes(**defaults)
26
+ super(**{
27
+ style: merged_style(CONTENTS_STYLE),
28
+ "data-controller" => "shadcn--dropdown-menu",
29
+ "data-shadcn--dropdown-menu-prefix-value" => "menubar",
30
+ "data-shadcn--dropdown-menu-open-value" => open,
31
+ "data-shadcn--dropdown-menu-side-value" => side,
32
+ "data-shadcn--dropdown-menu-align-value" => align,
33
+ "data-shadcn--dropdown-menu-side-offset-value" => side_offset
34
+ }.merge(defaults))
35
+ end
36
+
37
+ def call
38
+ render_element(body: safe_join([ trigger, menu_content, content ].compact))
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module Menubar
5
+ module SubContent
6
+ # A submenu's panel. Byte-identical to the dropdown's but for the
7
+ # `--radix-*` prefix, which is exactly why it cannot be inherited: those
8
+ # are the properties `popper.js` writes under the controller's prefix, and
9
+ # borrowing the dropdown's string would leave this reading variables
10
+ # nothing sets. `parity_spec` would not catch it — it asks whether a token
11
+ # appears anywhere in the family, not whether it appears on the right
12
+ # element.
13
+ class Component < Shadcn::DropdownMenu::SubContent::Component
14
+ slot_name :"menubar-sub-content"
15
+
16
+ style do
17
+ base {
18
+ "z-50 min-w-[8rem] origin-(--radix-menubar-content-transform-origin) " \
19
+ "overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground " \
20
+ "shadow-lg data-[side=bottom]:slide-in-from-top-2 " \
21
+ "data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 " \
22
+ "data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out " \
23
+ "data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 " \
24
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 " \
25
+ "data-[state=open]:zoom-in-95"
26
+ }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end