shadcn_phlexcomponents 0.1.9 → 0.1.14

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 (256) hide show
  1. checksums.yaml +4 -4
  2. data/app/javascript/controllers/accordion_controller.ts +136 -0
  3. data/app/javascript/controllers/alert_dialog_controller.ts +12 -0
  4. data/app/javascript/controllers/avatar_controller.ts +24 -0
  5. data/app/javascript/controllers/checkbox_controller.ts +41 -0
  6. data/app/javascript/controllers/collapsible_controller.ts +52 -0
  7. data/app/javascript/controllers/combobox_controller.ts +376 -0
  8. data/app/javascript/controllers/command_controller.ts +301 -0
  9. data/app/javascript/controllers/date_picker_controller.ts +334 -0
  10. data/app/javascript/controllers/date_range_picker_controller.ts +253 -0
  11. data/app/javascript/controllers/dialog_controller.ts +115 -0
  12. data/app/javascript/controllers/dropdown_menu_controller.ts +309 -0
  13. data/app/javascript/controllers/dropdown_menu_sub_controller.ts +152 -0
  14. data/app/javascript/controllers/form_field_controller.ts +27 -0
  15. data/app/javascript/controllers/hover_card_controller.ts +103 -0
  16. data/app/javascript/controllers/{loading_button_controller.js → loading_button_controller.ts} +7 -2
  17. data/app/javascript/controllers/popover_controller.ts +118 -0
  18. data/app/javascript/controllers/progress_controller.ts +23 -0
  19. data/app/javascript/controllers/radio_group_controller.ts +113 -0
  20. data/app/javascript/controllers/select_controller.ts +341 -0
  21. data/app/javascript/controllers/{sidebar_controller.js → sidebar_controller.ts} +6 -2
  22. data/app/javascript/controllers/sidebar_trigger_controller.ts +21 -0
  23. data/app/javascript/controllers/slider_controller.ts +114 -0
  24. data/app/javascript/controllers/switch_controller.ts +37 -0
  25. data/app/javascript/controllers/tabs_controller.ts +87 -0
  26. data/app/javascript/controllers/theme_switcher_controller.ts +40 -0
  27. data/app/javascript/controllers/toast_container_controller.ts +67 -0
  28. data/app/javascript/controllers/toast_controller.ts +34 -0
  29. data/app/javascript/controllers/toggle_controller.ts +28 -0
  30. data/app/javascript/controllers/toggle_group_controller.ts +28 -0
  31. data/app/javascript/controllers/tooltip_controller.ts +110 -0
  32. data/app/javascript/shadcn_phlexcomponents.ts +61 -0
  33. data/app/javascript/utils/command.ts +544 -0
  34. data/app/javascript/utils/floating_ui.ts +196 -0
  35. data/app/javascript/utils/index.ts +417 -0
  36. data/app/stylesheets/date_picker.css +81 -101
  37. data/app/stylesheets/nouislider.css +173 -0
  38. data/app/stylesheets/tw-animate.css +486 -0
  39. data/lib/install/install_shadcn_phlexcomponents.rb +16 -3
  40. data/lib/shadcn_phlexcomponents/alias.rb +6 -1
  41. data/lib/shadcn_phlexcomponents/components/accordion.rb +130 -0
  42. data/lib/shadcn_phlexcomponents/components/alert.rb +59 -0
  43. data/lib/shadcn_phlexcomponents/components/alert_dialog.rb +279 -0
  44. data/lib/shadcn_phlexcomponents/components/{aspect_ratio/aspect_ratio.rb → aspect_ratio.rb} +2 -2
  45. data/lib/shadcn_phlexcomponents/components/avatar.rb +63 -0
  46. data/lib/shadcn_phlexcomponents/components/badge.rb +35 -0
  47. data/lib/shadcn_phlexcomponents/components/base.rb +48 -7
  48. data/lib/shadcn_phlexcomponents/components/breadcrumb.rb +150 -0
  49. data/lib/shadcn_phlexcomponents/components/button.rb +49 -0
  50. data/lib/shadcn_phlexcomponents/components/card.rb +88 -0
  51. data/lib/shadcn_phlexcomponents/components/{checkbox/checkbox.rb → checkbox.rb} +18 -14
  52. data/lib/shadcn_phlexcomponents/components/{checkbox_group/checkbox_group.rb → checkbox_group.rb} +7 -8
  53. data/lib/shadcn_phlexcomponents/components/collapsible.rb +90 -0
  54. data/lib/shadcn_phlexcomponents/components/combobox.rb +428 -0
  55. data/lib/shadcn_phlexcomponents/components/command.rb +381 -0
  56. data/lib/shadcn_phlexcomponents/components/date_picker.rb +208 -0
  57. data/lib/shadcn_phlexcomponents/components/date_range_picker.rb +143 -0
  58. data/lib/shadcn_phlexcomponents/components/dialog.rb +236 -0
  59. data/lib/shadcn_phlexcomponents/components/dropdown_menu.rb +283 -0
  60. data/lib/shadcn_phlexcomponents/components/dropdown_menu_sub.rb +136 -0
  61. data/lib/shadcn_phlexcomponents/components/form/form_checkbox.rb +6 -7
  62. data/lib/shadcn_phlexcomponents/components/form/form_checkbox_group.rb +2 -2
  63. data/lib/shadcn_phlexcomponents/components/form/form_combobox.rb +64 -0
  64. data/lib/shadcn_phlexcomponents/components/form/form_date_picker.rb +3 -4
  65. data/lib/shadcn_phlexcomponents/components/form/form_date_range_picker.rb +27 -41
  66. data/lib/shadcn_phlexcomponents/components/form/form_error.rb +1 -1
  67. data/lib/shadcn_phlexcomponents/components/form/form_helpers.rb +43 -8
  68. data/lib/shadcn_phlexcomponents/components/form/form_hint.rb +1 -1
  69. data/lib/shadcn_phlexcomponents/components/form/form_input.rb +3 -4
  70. data/lib/shadcn_phlexcomponents/components/form/form_radio_group.rb +4 -5
  71. data/lib/shadcn_phlexcomponents/components/form/form_select.rb +3 -4
  72. data/lib/shadcn_phlexcomponents/components/form/form_slider.rb +91 -0
  73. data/lib/shadcn_phlexcomponents/components/form/form_switch.rb +7 -6
  74. data/lib/shadcn_phlexcomponents/components/form/form_textarea.rb +3 -4
  75. data/lib/shadcn_phlexcomponents/components/{form/form.rb → form.rb} +36 -4
  76. data/lib/shadcn_phlexcomponents/components/hover_card.rb +111 -0
  77. data/lib/shadcn_phlexcomponents/components/input.rb +31 -0
  78. data/lib/shadcn_phlexcomponents/components/label.rb +16 -0
  79. data/lib/shadcn_phlexcomponents/components/{link/link.rb → link.rb} +10 -3
  80. data/lib/shadcn_phlexcomponents/components/{loading_button/loading_button.rb → loading_button.rb} +9 -2
  81. data/lib/shadcn_phlexcomponents/components/pagination.rb +166 -0
  82. data/lib/shadcn_phlexcomponents/components/popover.rb +116 -0
  83. data/lib/shadcn_phlexcomponents/components/{progress/progress.rb → progress.rb} +4 -4
  84. data/lib/shadcn_phlexcomponents/components/radio_group.rb +155 -0
  85. data/lib/shadcn_phlexcomponents/components/select.rb +406 -0
  86. data/lib/shadcn_phlexcomponents/components/{separator/separator.rb → separator.rb} +9 -8
  87. data/lib/shadcn_phlexcomponents/components/sheet.rb +243 -0
  88. data/lib/shadcn_phlexcomponents/components/{skeleton/skeleton.rb → skeleton.rb} +1 -1
  89. data/lib/shadcn_phlexcomponents/components/slider.rb +72 -0
  90. data/lib/shadcn_phlexcomponents/components/switch.rb +75 -0
  91. data/lib/shadcn_phlexcomponents/components/table.rb +140 -0
  92. data/lib/shadcn_phlexcomponents/components/tabs.rb +135 -0
  93. data/lib/shadcn_phlexcomponents/components/textarea.rb +24 -0
  94. data/lib/shadcn_phlexcomponents/components/toast.rb +153 -0
  95. data/lib/shadcn_phlexcomponents/components/{toast/toast_container.rb → toast_container.rb} +23 -4
  96. data/lib/shadcn_phlexcomponents/components/toggle.rb +54 -0
  97. data/lib/shadcn_phlexcomponents/components/tooltip.rb +132 -0
  98. data/lib/shadcn_phlexcomponents/engine.rb +1 -5
  99. data/lib/shadcn_phlexcomponents/initializers/shadcn_phlexcomponents.rb +25 -0
  100. data/lib/shadcn_phlexcomponents/version.rb +1 -1
  101. data/lib/tasks/install.rake +1 -1
  102. metadata +83 -167
  103. data/app/javascript/controllers/accordion_controller.js +0 -124
  104. data/app/javascript/controllers/alert_dialog_controller.js +0 -21
  105. data/app/javascript/controllers/avatar_controller.js +0 -15
  106. data/app/javascript/controllers/checkbox_controller.js +0 -28
  107. data/app/javascript/controllers/collapsible_controller.js +0 -35
  108. data/app/javascript/controllers/combobox_controller.js +0 -54
  109. data/app/javascript/controllers/date_picker_controller.js +0 -253
  110. data/app/javascript/controllers/date_range_picker_controller.js +0 -344
  111. data/app/javascript/controllers/dialog_controller.js +0 -114
  112. data/app/javascript/controllers/dropdown_menu_controller.js +0 -171
  113. data/app/javascript/controllers/form_field_controller.js +0 -24
  114. data/app/javascript/controllers/hover_card_controller.js +0 -21
  115. data/app/javascript/controllers/popover_controller.js +0 -113
  116. data/app/javascript/controllers/progress_controller.js +0 -14
  117. data/app/javascript/controllers/radio_group_controller.js +0 -90
  118. data/app/javascript/controllers/select_controller.js +0 -274
  119. data/app/javascript/controllers/sidebar_trigger_controller.js +0 -15
  120. data/app/javascript/controllers/switch_controller.js +0 -24
  121. data/app/javascript/controllers/tabs_controller.js +0 -73
  122. data/app/javascript/controllers/theme_switcher_controller.js +0 -32
  123. data/app/javascript/controllers/toast_container_controller.js +0 -22
  124. data/app/javascript/controllers/toast_controller.js +0 -45
  125. data/app/javascript/controllers/tooltip_controller.js +0 -40
  126. data/app/javascript/shadcn_phlexcomponents.js +0 -53
  127. data/app/javascript/utils.js +0 -184
  128. data/app/stylesheets/choices.css +0 -324
  129. data/app/stylesheets/tailwindcss-animate.css +0 -318
  130. data/lib/shadcn_phlexcomponents/components/accordion/accordion.rb +0 -38
  131. data/lib/shadcn_phlexcomponents/components/accordion/accordion_content.rb +0 -30
  132. data/lib/shadcn_phlexcomponents/components/accordion/accordion_item.rb +0 -26
  133. data/lib/shadcn_phlexcomponents/components/accordion/accordion_trigger.rb +0 -46
  134. data/lib/shadcn_phlexcomponents/components/alert/alert.rb +0 -40
  135. data/lib/shadcn_phlexcomponents/components/alert/alert_description.rb +0 -11
  136. data/lib/shadcn_phlexcomponents/components/alert/alert_title.rb +0 -11
  137. data/lib/shadcn_phlexcomponents/components/alert_dialog/alert_dialog.rb +0 -60
  138. data/lib/shadcn_phlexcomponents/components/alert_dialog/alert_dialog_action.rb +0 -22
  139. data/lib/shadcn_phlexcomponents/components/alert_dialog/alert_dialog_action_to.rb +0 -40
  140. data/lib/shadcn_phlexcomponents/components/alert_dialog/alert_dialog_cancel.rb +0 -22
  141. data/lib/shadcn_phlexcomponents/components/alert_dialog/alert_dialog_content.rb +0 -40
  142. data/lib/shadcn_phlexcomponents/components/alert_dialog/alert_dialog_description.rb +0 -22
  143. data/lib/shadcn_phlexcomponents/components/alert_dialog/alert_dialog_footer.rb +0 -11
  144. data/lib/shadcn_phlexcomponents/components/alert_dialog/alert_dialog_header.rb +0 -11
  145. data/lib/shadcn_phlexcomponents/components/alert_dialog/alert_dialog_title.rb +0 -22
  146. data/lib/shadcn_phlexcomponents/components/alert_dialog/alert_dialog_trigger.rb +0 -50
  147. data/lib/shadcn_phlexcomponents/components/avatar/avatar.rb +0 -31
  148. data/lib/shadcn_phlexcomponents/components/avatar/avatar_fallback.rb +0 -21
  149. data/lib/shadcn_phlexcomponents/components/avatar/avatar_image.rb +0 -19
  150. data/lib/shadcn_phlexcomponents/components/badge/badge.rb +0 -30
  151. data/lib/shadcn_phlexcomponents/components/breadcrumb/breadcrumb.rb +0 -53
  152. data/lib/shadcn_phlexcomponents/components/breadcrumb/breadcrumb_ellipsis.rb +0 -23
  153. data/lib/shadcn_phlexcomponents/components/breadcrumb/breadcrumb_item.rb +0 -11
  154. data/lib/shadcn_phlexcomponents/components/breadcrumb/breadcrumb_link.rb +0 -7
  155. data/lib/shadcn_phlexcomponents/components/breadcrumb/breadcrumb_page.rb +0 -21
  156. data/lib/shadcn_phlexcomponents/components/breadcrumb/breadcrumb_separator.rb +0 -26
  157. data/lib/shadcn_phlexcomponents/components/button/button.rb +0 -53
  158. data/lib/shadcn_phlexcomponents/components/card/card.rb +0 -31
  159. data/lib/shadcn_phlexcomponents/components/card/card_content.rb +0 -11
  160. data/lib/shadcn_phlexcomponents/components/card/card_description.rb +0 -11
  161. data/lib/shadcn_phlexcomponents/components/card/card_footer.rb +0 -11
  162. data/lib/shadcn_phlexcomponents/components/card/card_header.rb +0 -11
  163. data/lib/shadcn_phlexcomponents/components/card/card_title.rb +0 -11
  164. data/lib/shadcn_phlexcomponents/components/collapsible/collapsible.rb +0 -31
  165. data/lib/shadcn_phlexcomponents/components/collapsible/collapsible_content.rb +0 -24
  166. data/lib/shadcn_phlexcomponents/components/collapsible/collapsible_trigger.rb +0 -50
  167. data/lib/shadcn_phlexcomponents/components/date_picker/date_picker.rb +0 -87
  168. data/lib/shadcn_phlexcomponents/components/date_picker/date_picker_content.rb +0 -45
  169. data/lib/shadcn_phlexcomponents/components/date_picker/date_picker_trigger.rb +0 -64
  170. data/lib/shadcn_phlexcomponents/components/date_range_picker/date_range_picker.rb +0 -105
  171. data/lib/shadcn_phlexcomponents/components/date_range_picker/date_range_picker_content.rb +0 -9
  172. data/lib/shadcn_phlexcomponents/components/date_range_picker/date_range_picker_trigger.rb +0 -9
  173. data/lib/shadcn_phlexcomponents/components/dialog/dialog.rb +0 -52
  174. data/lib/shadcn_phlexcomponents/components/dialog/dialog_close.rb +0 -42
  175. data/lib/shadcn_phlexcomponents/components/dialog/dialog_content.rb +0 -54
  176. data/lib/shadcn_phlexcomponents/components/dialog/dialog_description.rb +0 -22
  177. data/lib/shadcn_phlexcomponents/components/dialog/dialog_footer.rb +0 -11
  178. data/lib/shadcn_phlexcomponents/components/dialog/dialog_header.rb +0 -11
  179. data/lib/shadcn_phlexcomponents/components/dialog/dialog_title.rb +0 -22
  180. data/lib/shadcn_phlexcomponents/components/dialog/dialog_trigger.rb +0 -50
  181. data/lib/shadcn_phlexcomponents/components/dropdown_menu/dropdown_menu.rb +0 -50
  182. data/lib/shadcn_phlexcomponents/components/dropdown_menu/dropdown_menu_content.rb +0 -52
  183. data/lib/shadcn_phlexcomponents/components/dropdown_menu/dropdown_menu_item.rb +0 -56
  184. data/lib/shadcn_phlexcomponents/components/dropdown_menu/dropdown_menu_item_to.rb +0 -28
  185. data/lib/shadcn_phlexcomponents/components/dropdown_menu/dropdown_menu_label.rb +0 -11
  186. data/lib/shadcn_phlexcomponents/components/dropdown_menu/dropdown_menu_separator.rb +0 -20
  187. data/lib/shadcn_phlexcomponents/components/dropdown_menu/dropdown_menu_trigger.rb +0 -57
  188. data/lib/shadcn_phlexcomponents/components/hover_card/hover_card.rb +0 -33
  189. data/lib/shadcn_phlexcomponents/components/hover_card/hover_card_content.rb +0 -32
  190. data/lib/shadcn_phlexcomponents/components/hover_card/hover_card_trigger.rb +0 -44
  191. data/lib/shadcn_phlexcomponents/components/input/input.rb +0 -32
  192. data/lib/shadcn_phlexcomponents/components/label/label.rb +0 -14
  193. data/lib/shadcn_phlexcomponents/components/pagination/pagination.rb +0 -38
  194. data/lib/shadcn_phlexcomponents/components/pagination/pagination_ellipsis.rb +0 -24
  195. data/lib/shadcn_phlexcomponents/components/pagination/pagination_link.rb +0 -34
  196. data/lib/shadcn_phlexcomponents/components/pagination/pagination_next.rb +0 -32
  197. data/lib/shadcn_phlexcomponents/components/pagination/pagination_previous.rb +0 -32
  198. data/lib/shadcn_phlexcomponents/components/popover/popover.rb +0 -34
  199. data/lib/shadcn_phlexcomponents/components/popover/popover_content.rb +0 -40
  200. data/lib/shadcn_phlexcomponents/components/popover/popover_trigger.rb +0 -50
  201. data/lib/shadcn_phlexcomponents/components/radio_group/radio_group.rb +0 -88
  202. data/lib/shadcn_phlexcomponents/components/radio_group/radio_group_item.rb +0 -66
  203. data/lib/shadcn_phlexcomponents/components/select/select.rb +0 -194
  204. data/lib/shadcn_phlexcomponents/components/select/select_content.rb +0 -64
  205. data/lib/shadcn_phlexcomponents/components/select/select_group.rb +0 -23
  206. data/lib/shadcn_phlexcomponents/components/select/select_item.rb +0 -59
  207. data/lib/shadcn_phlexcomponents/components/select/select_label.rb +0 -24
  208. data/lib/shadcn_phlexcomponents/components/select/select_trigger.rb +0 -56
  209. data/lib/shadcn_phlexcomponents/components/sheet/sheet.rb +0 -53
  210. data/lib/shadcn_phlexcomponents/components/sheet/sheet_close.rb +0 -42
  211. data/lib/shadcn_phlexcomponents/components/sheet/sheet_content.rb +0 -65
  212. data/lib/shadcn_phlexcomponents/components/sheet/sheet_description.rb +0 -22
  213. data/lib/shadcn_phlexcomponents/components/sheet/sheet_footer.rb +0 -11
  214. data/lib/shadcn_phlexcomponents/components/sheet/sheet_header.rb +0 -11
  215. data/lib/shadcn_phlexcomponents/components/sheet/sheet_title.rb +0 -22
  216. data/lib/shadcn_phlexcomponents/components/sheet/sheet_trigger.rb +0 -50
  217. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar.rb +0 -108
  218. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_container.rb +0 -11
  219. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_content.rb +0 -11
  220. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_footer.rb +0 -11
  221. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_group.rb +0 -11
  222. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_group_content.rb +0 -11
  223. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_group_label.rb +0 -16
  224. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_header.rb +0 -11
  225. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_inset.rb +0 -15
  226. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_menu.rb +0 -11
  227. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_menu_button.rb +0 -61
  228. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_menu_item.rb +0 -9
  229. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_menu_sub.rb +0 -14
  230. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_menu_sub_button.rb +0 -48
  231. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_menu_sub_item.rb +0 -9
  232. data/lib/shadcn_phlexcomponents/components/sidebar/sidebar_trigger.rb +0 -40
  233. data/lib/shadcn_phlexcomponents/components/switch/switch.rb +0 -66
  234. data/lib/shadcn_phlexcomponents/components/table/table.rb +0 -75
  235. data/lib/shadcn_phlexcomponents/components/table/table_body.rb +0 -11
  236. data/lib/shadcn_phlexcomponents/components/table/table_caption.rb +0 -11
  237. data/lib/shadcn_phlexcomponents/components/table/table_cell.rb +0 -11
  238. data/lib/shadcn_phlexcomponents/components/table/table_footer.rb +0 -11
  239. data/lib/shadcn_phlexcomponents/components/table/table_head.rb +0 -14
  240. data/lib/shadcn_phlexcomponents/components/table/table_header.rb +0 -11
  241. data/lib/shadcn_phlexcomponents/components/table/table_row.rb +0 -11
  242. data/lib/shadcn_phlexcomponents/components/tabs/tabs.rb +0 -38
  243. data/lib/shadcn_phlexcomponents/components/tabs/tabs_content.rb +0 -35
  244. data/lib/shadcn_phlexcomponents/components/tabs/tabs_list.rb +0 -23
  245. data/lib/shadcn_phlexcomponents/components/tabs/tabs_trigger.rb +0 -45
  246. data/lib/shadcn_phlexcomponents/components/textarea/textarea.rb +0 -29
  247. data/lib/shadcn_phlexcomponents/components/toast/toast.rb +0 -101
  248. data/lib/shadcn_phlexcomponents/components/toast/toast_action.rb +0 -39
  249. data/lib/shadcn_phlexcomponents/components/toast/toast_action_to.rb +0 -28
  250. data/lib/shadcn_phlexcomponents/components/toast/toast_content.rb +0 -11
  251. data/lib/shadcn_phlexcomponents/components/toast/toast_description.rb +0 -11
  252. data/lib/shadcn_phlexcomponents/components/toast/toast_title.rb +0 -11
  253. data/lib/shadcn_phlexcomponents/components/tooltip/tooltip.rb +0 -34
  254. data/lib/shadcn_phlexcomponents/components/tooltip/tooltip_content.rb +0 -39
  255. data/lib/shadcn_phlexcomponents/components/tooltip/tooltip_trigger.rb +0 -48
  256. /data/lib/shadcn_phlexcomponents/components/{theme_switcher/theme_switcher.rb → theme_switcher.rb} +0 -0
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShadcnPhlexcomponents
4
+ class Alert < Base
5
+ class_variants(
6
+ base: <<~HEREDOC,
7
+ relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr]
8
+ grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5
9
+ [&>svg]:text-current
10
+ HEREDOC
11
+ variants: {
12
+ variant: {
13
+ default: "bg-card text-card-foreground",
14
+ destructive: "text-destructive bg-card [&>svg]:text-current *:data-[shadcn-phlexcomponents=alert-description]:text-destructive/90",
15
+ },
16
+ },
17
+ defaults: {
18
+ variant: :default,
19
+ },
20
+ )
21
+
22
+ def initialize(variant: :default, **attributes)
23
+ @class_variants = { variant: variant }
24
+ super(**attributes)
25
+ end
26
+
27
+ def title(**attributes, &)
28
+ AlertTitle(**attributes, &)
29
+ end
30
+
31
+ def description(**attributes, &)
32
+ AlertDescription(**attributes, &)
33
+ end
34
+
35
+ def default_attributes
36
+ { role: "alert" }
37
+ end
38
+
39
+ def view_template(&)
40
+ div(**@attributes, &)
41
+ end
42
+ end
43
+
44
+ class AlertTitle < Base
45
+ class_variants(base: "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight")
46
+
47
+ def view_template(&)
48
+ div(**@attributes, &)
49
+ end
50
+ end
51
+
52
+ class AlertDescription < Base
53
+ class_variants(base: "text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed")
54
+
55
+ def view_template(&)
56
+ div(**@attributes, &)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,279 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShadcnPhlexcomponents
4
+ class AlertDialog < Base
5
+ class_variants(base: "inline-flex max-w-fit")
6
+
7
+ def initialize(open: false, **attributes)
8
+ @open = open
9
+ @aria_id = "alert-dialog-#{SecureRandom.hex(5)}"
10
+ super(**attributes)
11
+ end
12
+
13
+ def trigger(**attributes, &)
14
+ AlertDialogTrigger(aria_id: @aria_id, **attributes, &)
15
+ end
16
+
17
+ def content(**attributes, &)
18
+ AlertDialogContent(aria_id: @aria_id, **attributes, &)
19
+ end
20
+
21
+ def header(**attributes, &)
22
+ AlertDialogHeader(**attributes, &)
23
+ end
24
+
25
+ def title(**attributes, &)
26
+ AlertDialogTitle(aria_id: @aria_id, **attributes, &)
27
+ end
28
+
29
+ def description(**attributes, &)
30
+ AlertDialogDescription(aria_id: @aria_id, **attributes, &)
31
+ end
32
+
33
+ def footer(**attributes, &)
34
+ AlertDialogFooter(**attributes, &)
35
+ end
36
+
37
+ def cancel(**attributes, &)
38
+ AlertDialogCancel(**attributes, &)
39
+ end
40
+
41
+ def action(**attributes, &)
42
+ AlertDialogAction(**attributes, &)
43
+ end
44
+
45
+ def action_to(name = nil, options = nil, html_options = nil, &)
46
+ AlertDialogActionTo(name, options, html_options, &)
47
+ end
48
+
49
+ def default_attributes
50
+ {
51
+ data: {
52
+ controller: "alert-dialog",
53
+ alert_dialog_is_open_value: @open.to_s
54
+ }
55
+ }
56
+ end
57
+
58
+ def view_template(&)
59
+ div(**@attributes) do
60
+ overlay("alert-dialog")
61
+
62
+ yield
63
+ end
64
+ end
65
+ end
66
+
67
+ class AlertDialogTrigger < Base
68
+ def initialize(as_child: false, aria_id: nil, **attributes)
69
+ @as_child = as_child
70
+ @aria_id = aria_id
71
+ super(**attributes)
72
+ end
73
+
74
+ def default_attributes
75
+ {
76
+ role: "button",
77
+ aria: {
78
+ haspopup: "dialog",
79
+ expanded: "false",
80
+ controls: "#{@aria_id}-content",
81
+ },
82
+ data: {
83
+ as_child: @as_child.to_s,
84
+ alert_dialog_target: "trigger",
85
+ action: "click->alert-dialog#open"
86
+ },
87
+ }
88
+ end
89
+
90
+ def view_template(&)
91
+ if @as_child
92
+ content = capture(&)
93
+ element = find_as_child(content.to_s)
94
+ vanish(&)
95
+ merged_attributes = merged_as_child_attributes(element, @attributes)
96
+
97
+ send(element.name, **merged_attributes) do
98
+ sanitize_as_child(element.children.to_s)
99
+ end
100
+ else
101
+ div(**@attributes, &)
102
+ end
103
+ end
104
+ end
105
+
106
+ class AlertDialogContent < Base
107
+ class_variants(
108
+ base: <<~HEREDOC,
109
+ bg-background data-[state=open]:animate-in data-[state=closed]:animate-out
110
+ data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95
111
+ data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)]
112
+ translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg
113
+ pointer-events-auto outline-none
114
+ HEREDOC
115
+ )
116
+
117
+ def initialize(aria_id: nil, **attributes)
118
+ @aria_id = aria_id
119
+ super(**attributes)
120
+ end
121
+
122
+ def default_attributes
123
+ {
124
+ id: "#{@aria_id}-content",
125
+ tabindex: -1,
126
+ role: "alertdialog",
127
+ aria: {
128
+ describedby: "#{@aria_id}-description",
129
+ labelledby: "#{@aria_id}-title",
130
+ },
131
+ data: {
132
+ state: "closed",
133
+ alert_dialog_target: "content"
134
+ },
135
+ }
136
+ end
137
+
138
+ def view_template(&)
139
+ div(style: { display: "none" }, **@attributes, &)
140
+ end
141
+ end
142
+
143
+ class AlertDialogHeader < Base
144
+ class_variants(base: "flex flex-col gap-2 text-center sm:text-left")
145
+
146
+ def view_template(&)
147
+ div(**@attributes, &)
148
+ end
149
+ end
150
+
151
+ class AlertDialogTitle < Base
152
+ class_variants(base: "text-lg font-semibold")
153
+
154
+ def initialize(aria_id: nil, **attributes)
155
+ @aria_id = aria_id
156
+ super(**attributes)
157
+ end
158
+
159
+ def default_attributes
160
+ {
161
+ id: "#{@aria_id}-title",
162
+ }
163
+ end
164
+
165
+ def view_template(&)
166
+ h2(**@attributes, &)
167
+ end
168
+ end
169
+
170
+ class AlertDialogDescription < Base
171
+ class_variants(base: "text-sm text-muted-foreground")
172
+
173
+ def initialize(aria_id: nil, **attributes)
174
+ @aria_id = aria_id
175
+ super(**attributes)
176
+ end
177
+
178
+ def default_attributes
179
+ {
180
+ id: "#{@aria_id}-description",
181
+ }
182
+ end
183
+
184
+ def view_template(&)
185
+ p(**@attributes, &)
186
+ end
187
+ end
188
+
189
+ class AlertDialogFooter < Base
190
+ class_variants(base: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end")
191
+
192
+ def view_template(&)
193
+ div(**@attributes, &)
194
+ end
195
+ end
196
+
197
+ class AlertDialogCancel < Base
198
+ def initialize(variant: :outline, size: :default, **attributes)
199
+ @variant = variant
200
+ @size = size
201
+ super(**attributes)
202
+ end
203
+
204
+ def default_attributes
205
+ {
206
+ data: {
207
+ action: "click->alert-dialog#close",
208
+ },
209
+ }
210
+ end
211
+
212
+ def view_template(&)
213
+ Button(variant: @variant, size: @size, **@attributes, &)
214
+ end
215
+ end
216
+
217
+ class AlertDialogAction < Base
218
+ def initialize(variant: :default, size: :default, as_child: false, **attributes)
219
+ @variant = variant
220
+ @size = size
221
+ @as_child = as_child
222
+ super(**attributes)
223
+ end
224
+
225
+ def default_attributes
226
+ {
227
+ data: {
228
+ action: "click->alert-dialog#close",
229
+ },
230
+ }
231
+ end
232
+
233
+ def class_variants(**args)
234
+ Button.new.class_variants(variant: @variant, size: @size, class: args[:class])
235
+ end
236
+
237
+ def view_template(&)
238
+ if @as_child
239
+ content = capture(&)
240
+ element = find_as_child(content.to_s)
241
+ vanish(&)
242
+ merged_attributes = merged_as_child_attributes(element, @attributes)
243
+
244
+ send(element.name, **merged_attributes) do
245
+ sanitize_as_child(element.children.to_s)
246
+ end
247
+ else
248
+ button(**@attributes, &)
249
+ end
250
+ end
251
+ end
252
+
253
+ class AlertDialogActionTo < AlertDialogAction
254
+ def initialize(name = nil, options = nil, html_options = nil)
255
+ @name = name
256
+ @options = options
257
+ @html_options = html_options
258
+ end
259
+
260
+ def view_template(&)
261
+ if block_given?
262
+ @html_options = @options
263
+ @options = @name
264
+ end
265
+
266
+ @html_options ||= {}
267
+ @variant = @html_options.delete(:variant) || :default
268
+ @size = @html_options.delete(:size) || :default
269
+ merge_default_attributes({})
270
+ @html_options = mix(@attributes, @html_options)
271
+
272
+ if block_given?
273
+ button_to(@options, @html_options, &)
274
+ else
275
+ button_to(@name, @options, @html_options)
276
+ end
277
+ end
278
+ end
279
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ShadcnPhlexcomponents
4
4
  class AspectRatio < Base
5
- STYLES = "absolute inset-0"
5
+ class_variants(base: "absolute inset-0")
6
6
 
7
7
  def initialize(ratio: "1/1", **attributes)
8
8
  ratio_arr = ratio.split("/").map(&:to_f)
@@ -11,7 +11,7 @@ module ShadcnPhlexcomponents
11
11
  end
12
12
 
13
13
  def view_template(&)
14
- div(style: { position: "relative", width: "100%", "padding-bottom": "#{100 / @ratio}%" }) do
14
+ div(class: "relative w-full", style: { "padding-bottom": "#{100 / @ratio}%" }) do
15
15
  div(**@attributes, &)
16
16
  end
17
17
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShadcnPhlexcomponents
4
+ class Avatar < Base
5
+ class_variants(base: "relative flex size-8 shrink-0 overflow-hidden rounded-full")
6
+
7
+ def initialize(**attributes)
8
+ super(**attributes)
9
+ end
10
+
11
+ def image(**attributes, &)
12
+ AvatarImage(**attributes, &)
13
+ end
14
+
15
+ def fallback(**attributes, &)
16
+ AvatarFallback(**attributes, &)
17
+ end
18
+
19
+ def default_attributes
20
+ {
21
+ data: {
22
+ controller: "avatar",
23
+ },
24
+ }
25
+ end
26
+
27
+ def view_template(&)
28
+ span(**@attributes, &)
29
+ end
30
+ end
31
+
32
+ class AvatarImage < Base
33
+ class_variants(base: "aspect-square size-full")
34
+
35
+ def default_attributes
36
+ {
37
+ data: {
38
+ avatar_target: "image",
39
+ },
40
+ }
41
+ end
42
+
43
+ def view_template(&)
44
+ img(**@attributes, &)
45
+ end
46
+ end
47
+
48
+ class AvatarFallback < Base
49
+ class_variants(base: "bg-muted flex size-full items-center justify-center rounded-full")
50
+
51
+ def default_attributes
52
+ {
53
+ data: {
54
+ avatar_target: "fallback",
55
+ },
56
+ }
57
+ end
58
+
59
+ def view_template(&)
60
+ span(**@attributes, &)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShadcnPhlexcomponents
4
+ class Badge < Base
5
+ class_variants(
6
+ base: <<~HEREDOC,
7
+ inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium
8
+ w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none
9
+ focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]
10
+ aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive
11
+ transition-[color,box-shadow] overflow-hidden
12
+ HEREDOC
13
+ variants: {
14
+ variant: {
15
+ default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
16
+ secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
17
+ destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
18
+ outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
19
+ },
20
+ },
21
+ defaults: {
22
+ variant: :default,
23
+ },
24
+ )
25
+
26
+ def initialize(variant: :default, **attributes)
27
+ @class_variants = { variant: variant }
28
+ super(**attributes)
29
+ end
30
+
31
+ def view_template(&)
32
+ span(**@attributes, &)
33
+ end
34
+ end
35
+ end
@@ -2,13 +2,12 @@
2
2
 
3
3
  module ShadcnPhlexcomponents
4
4
  class Base < Phlex::HTML
5
- # Include any helpers you want to be available across all components
5
+ include ClassVariants::Helper
6
6
  include Phlex::Rails::Helpers::Sanitize
7
7
  include Phlex::Rails::Helpers::LinkTo
8
8
  include Phlex::Rails::Helpers::ButtonTo
9
9
 
10
10
  TAILWIND_MERGER = ::TailwindMerge::Merger.new.freeze
11
- STYLES = ""
12
11
 
13
12
  SANITIZER_ALLOWED_TAGS = (Rails::HTML::SafeListSanitizer.allowed_tags.to_a +
14
13
  ["svg", "path", "polygon", "polyline", "circle", "ellipse", "rect", "line", "use", "defs", "g"]).freeze
@@ -33,11 +32,29 @@ module ShadcnPhlexcomponents
33
32
  "stroke-linecap",
34
33
  "aria-hidden",
35
34
  "class",
35
+ "x1",
36
+ "x2",
37
+ "y1",
38
+ "y2",
36
39
  ]).freeze
37
40
 
38
41
  def initialize(**attributes)
42
+ merge_default_attributes(attributes)
43
+ end
44
+
45
+ def merge_default_attributes(attributes)
39
46
  @attributes = mix(default_attributes, attributes)
40
- @attributes[:class] = TAILWIND_MERGER.merge("#{default_styles} #{@attributes[:class]}")
47
+ @attributes = mix(@attributes, {
48
+ data: {
49
+ shadcn_phlexcomponents: self.class.name.demodulize.underscore.dasherize,
50
+ },
51
+ })
52
+
53
+ @attributes[:class] = class_variants(class: @attributes[:class], **@class_variants&.compact)
54
+
55
+ if @attributes[:class].blank?
56
+ @attributes.delete(:class)
57
+ end
41
58
  end
42
59
 
43
60
  if Rails.env.development?
@@ -51,10 +68,6 @@ module ShadcnPhlexcomponents
51
68
  {}
52
69
  end
53
70
 
54
- def default_styles
55
- self.class::STYLES
56
- end
57
-
58
71
  def nokogiri_attributes_to_hash(element)
59
72
  hash = {}
60
73
 
@@ -86,6 +99,20 @@ module ShadcnPhlexcomponents
86
99
  element
87
100
  end
88
101
 
102
+ def merged_as_child_attributes(element, component_attributes)
103
+ element_attributes = nokogiri_attributes_to_hash(element)
104
+ merged_attributes = mix(component_attributes, element_attributes)
105
+ merged_attributes[:class] = TAILWIND_MERGER.merge("#{component_attributes[:class]} #{element_attributes[:class]}")
106
+
107
+ # some components are divs that have role="button",
108
+ # we should remove it if the child element is a button
109
+ if component_attributes[:role].present? && component_attributes[:role].to_sym == :button && element.name == "button"
110
+ merged_attributes.delete(:role)
111
+ end
112
+
113
+ merged_attributes
114
+ end
115
+
89
116
  # https://github.com/heyvito/lucide-rails/blob/master/lib/lucide-rails/rails_helper.rb
90
117
  def icon(named, **options)
91
118
  options = options.with_indifferent_access
@@ -114,5 +141,19 @@ module ShadcnPhlexcomponents
114
141
  disabled
115
142
  end
116
143
  end
144
+
145
+ def overlay(component)
146
+ div(
147
+ style: { display: "none" },
148
+ class: "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50 pointer-events-auto",
149
+ aria: {
150
+ hidden: true,
151
+ },
152
+ data: {
153
+ state: "closed",
154
+ "#{component}-target" => "overlay"
155
+ }
156
+ )
157
+ end
117
158
  end
118
159
  end
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShadcnPhlexcomponents
4
+ class Breadcrumb < Base
5
+ class_variants(
6
+ base: "text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5",
7
+ )
8
+
9
+ def item(**attributes, &)
10
+ BreadcrumbItem(**attributes, &)
11
+ end
12
+
13
+ def link(name = nil, options = nil, html_options = nil, &)
14
+ BreadcrumbLink(name, options, html_options, &)
15
+ end
16
+
17
+ def separator(**attributes, &)
18
+ BreadcrumbSeparator(**attributes, &)
19
+ end
20
+
21
+ def page(**attributes, &)
22
+ BreadcrumbPage(**attributes, &)
23
+ end
24
+
25
+ def ellipsis(**attributes)
26
+ BreadcrumbEllipsis(**attributes)
27
+ end
28
+
29
+ def links(collection)
30
+ collection.each_with_index do |link, index|
31
+ if index == collection.size - 1
32
+ item do
33
+ page { link[:name] }
34
+ end
35
+ else
36
+ item do
37
+ link(link[:name], link[:path])
38
+ end
39
+ end
40
+
41
+ if index < collection.size - 1
42
+ separator
43
+ end
44
+ end
45
+
46
+ nil
47
+ end
48
+
49
+ def view_template(&)
50
+ nav(aria: { label: "breadcrumb" }) do
51
+ ol(**@attributes, &)
52
+ end
53
+ end
54
+ end
55
+
56
+ class BreadcrumbItem < Base
57
+ class_variants(base: "inline-flex items-center gap-1.5")
58
+
59
+ def view_template(&)
60
+ li(**@attributes, &)
61
+ end
62
+ end
63
+
64
+ class BreadcrumbLink < Base
65
+ class_variants(base: "transition-colors hover:text-foreground")
66
+
67
+ def initialize(name = nil, options = nil, html_options = nil)
68
+ @name = name
69
+ @options = options
70
+ @html_options = html_options
71
+ end
72
+
73
+ def view_template(&)
74
+ if block_given?
75
+ @html_options = @options
76
+ @options = @name
77
+ end
78
+
79
+ @html_options ||= {}
80
+ @html_options[:class] = class_variants(class: @html_options[:class])
81
+
82
+ if block_given?
83
+ link_to(@options, @html_options, &)
84
+ else
85
+ link_to(@name, @options, @html_options)
86
+ end
87
+ end
88
+ end
89
+
90
+ class BreadcrumbSeparator < Base
91
+ class_variants(base: "[&>svg]:size-3.5")
92
+
93
+ def default_attributes
94
+ {
95
+ role: "presentation",
96
+ aria: {
97
+ hidden: "true",
98
+ },
99
+ }
100
+ end
101
+
102
+ def view_template(&)
103
+ li(**@attributes) do
104
+ if block_given?
105
+ yield
106
+ else
107
+ icon("chevron-right")
108
+ end
109
+ end
110
+ end
111
+ end
112
+
113
+ class BreadcrumbPage < Base
114
+ class_variants(base: "font-normal text-foreground")
115
+
116
+ def default_attributes
117
+ {
118
+ role: "link",
119
+ aria: {
120
+ disabled: "true",
121
+ current: "page",
122
+ },
123
+ }
124
+ end
125
+
126
+ def view_template(&)
127
+ span(**@attributes, &)
128
+ end
129
+ end
130
+
131
+ class BreadcrumbEllipsis < Base
132
+ class_variants(base: "flex size-9 items-center justify-center")
133
+
134
+ def default_attributes
135
+ {
136
+ role: "presentation",
137
+ aria: {
138
+ hidden: "true",
139
+ },
140
+ }
141
+ end
142
+
143
+ def view_template
144
+ span(**@attributes) do
145
+ icon("ellipsis", class: "size-4")
146
+ span(class: "sr-only") { "More" }
147
+ end
148
+ end
149
+ end
150
+ end