shadcn_phlexcomponents 0.1.5 → 0.1.11

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 (249) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -0
  3. data/app/javascript/controllers/accordion_controller.ts +133 -0
  4. data/app/javascript/controllers/{avatar_controller.js → avatar_controller.ts} +4 -0
  5. data/app/javascript/controllers/checkbox_controller.ts +34 -0
  6. data/app/javascript/controllers/collapsible_controller.ts +45 -0
  7. data/app/javascript/controllers/combobox_controller.ts +145 -0
  8. data/app/javascript/controllers/command_controller.ts +129 -0
  9. data/app/javascript/controllers/command_root_controller.ts +355 -0
  10. data/app/javascript/controllers/date_picker_controller.ts +274 -0
  11. data/app/javascript/controllers/date_range_picker_controller.ts +243 -0
  12. data/app/javascript/controllers/dialog_controller.ts +113 -0
  13. data/app/javascript/controllers/dropdown_menu_controller.ts +133 -0
  14. data/app/javascript/controllers/dropdown_menu_root_controller.ts +234 -0
  15. data/app/javascript/controllers/dropdown_menu_sub_controller.ts +150 -0
  16. data/app/javascript/controllers/form_field_controller.ts +22 -0
  17. data/app/javascript/controllers/hover_card_controller.ts +93 -0
  18. data/app/javascript/controllers/{loading_button_controller.js → loading_button_controller.ts} +2 -2
  19. data/app/javascript/controllers/popover_controller.ts +141 -0
  20. data/app/javascript/controllers/progress_controller.ts +17 -0
  21. data/app/javascript/controllers/radio_group_controller.ts +106 -0
  22. data/app/javascript/controllers/select_controller.ts +200 -0
  23. data/app/javascript/controllers/{sidebar_controller.js → sidebar_controller.ts} +6 -2
  24. data/app/javascript/controllers/sidebar_trigger_controller.ts +21 -0
  25. data/app/javascript/controllers/slider_controller.ts +107 -0
  26. data/app/javascript/controllers/switch_controller.ts +30 -0
  27. data/app/javascript/controllers/tabs_controller.ts +79 -0
  28. data/app/javascript/controllers/{theme_switcher_controller.js → theme_switcher_controller.ts} +12 -9
  29. data/app/javascript/controllers/toast_container_controller.ts +62 -0
  30. data/app/javascript/controllers/toast_controller.ts +28 -0
  31. data/app/javascript/controllers/tooltip_controller.ts +98 -0
  32. data/app/javascript/shadcn_phlexcomponents.ts +57 -0
  33. data/app/javascript/utils.ts +437 -0
  34. data/app/stylesheets/date_picker.css +74 -0
  35. data/app/stylesheets/nouislider.css +173 -0
  36. data/app/stylesheets/tw-animate.css +486 -0
  37. data/lib/install/install_shadcn_phlexcomponents.rb +22 -9
  38. data/lib/shadcn_phlexcomponents/alias.rb +3 -1
  39. data/lib/shadcn_phlexcomponents/components/accordion.rb +129 -0
  40. data/lib/shadcn_phlexcomponents/components/alert.rb +59 -0
  41. data/lib/shadcn_phlexcomponents/components/alert_dialog.rb +276 -0
  42. data/lib/{components → shadcn_phlexcomponents/components}/aspect_ratio.rb +2 -2
  43. data/lib/shadcn_phlexcomponents/components/avatar.rb +63 -0
  44. data/lib/shadcn_phlexcomponents/components/badge.rb +35 -0
  45. data/lib/{components → shadcn_phlexcomponents/components}/base.rb +44 -7
  46. data/lib/shadcn_phlexcomponents/components/breadcrumb.rb +150 -0
  47. data/lib/shadcn_phlexcomponents/components/button.rb +49 -0
  48. data/lib/shadcn_phlexcomponents/components/card.rb +88 -0
  49. data/lib/{components → shadcn_phlexcomponents/components}/checkbox.rb +21 -17
  50. data/lib/{components → shadcn_phlexcomponents/components}/checkbox_group.rb +27 -16
  51. data/lib/shadcn_phlexcomponents/components/collapsible.rb +91 -0
  52. data/lib/shadcn_phlexcomponents/components/combobox.rb +398 -0
  53. data/lib/shadcn_phlexcomponents/components/command.rb +351 -0
  54. data/lib/shadcn_phlexcomponents/components/date_picker.rb +264 -0
  55. data/lib/shadcn_phlexcomponents/components/date_range_picker.rb +126 -0
  56. data/lib/shadcn_phlexcomponents/components/dialog.rb +234 -0
  57. data/lib/shadcn_phlexcomponents/components/dropdown_menu.rb +282 -0
  58. data/lib/shadcn_phlexcomponents/components/dropdown_menu_sub.rb +135 -0
  59. data/lib/shadcn_phlexcomponents/components/form/form_checkbox.rb +82 -0
  60. data/lib/shadcn_phlexcomponents/components/form/form_checkbox_group.rb +116 -0
  61. data/lib/shadcn_phlexcomponents/components/form/form_date_picker.rb +46 -0
  62. data/lib/shadcn_phlexcomponents/components/form/form_date_range_picker.rb +82 -0
  63. data/lib/{components → shadcn_phlexcomponents/components/form}/form_error.rb +7 -3
  64. data/lib/shadcn_phlexcomponents/components/form/form_helpers.rb +143 -0
  65. data/lib/shadcn_phlexcomponents/components/form/form_hint.rb +21 -0
  66. data/lib/{components → shadcn_phlexcomponents/components/form}/form_input.rb +3 -4
  67. data/lib/shadcn_phlexcomponents/components/form/form_radio_group.rb +106 -0
  68. data/lib/shadcn_phlexcomponents/components/form/form_select.rb +64 -0
  69. data/lib/shadcn_phlexcomponents/components/form/form_slider.rb +91 -0
  70. data/lib/shadcn_phlexcomponents/components/form/form_switch.rb +67 -0
  71. data/lib/shadcn_phlexcomponents/components/form/form_textarea.rb +59 -0
  72. data/lib/shadcn_phlexcomponents/components/form.rb +157 -0
  73. data/lib/shadcn_phlexcomponents/components/hover_card.rb +110 -0
  74. data/lib/shadcn_phlexcomponents/components/input.rb +31 -0
  75. data/lib/shadcn_phlexcomponents/components/label.rb +16 -0
  76. data/lib/{components → shadcn_phlexcomponents/components}/link.rb +10 -3
  77. data/lib/shadcn_phlexcomponents/components/loading_button.rb +28 -0
  78. data/lib/shadcn_phlexcomponents/components/pagination.rb +166 -0
  79. data/lib/shadcn_phlexcomponents/components/popover.rb +116 -0
  80. data/lib/{components → shadcn_phlexcomponents/components}/progress.rb +5 -5
  81. data/lib/shadcn_phlexcomponents/components/radio_group.rb +155 -0
  82. data/lib/shadcn_phlexcomponents/components/select.rb +421 -0
  83. data/lib/{components → shadcn_phlexcomponents/components}/separator.rb +9 -8
  84. data/lib/shadcn_phlexcomponents/components/sheet.rb +239 -0
  85. data/lib/{components → shadcn_phlexcomponents/components}/skeleton.rb +1 -1
  86. data/lib/shadcn_phlexcomponents/components/slider.rb +72 -0
  87. data/lib/shadcn_phlexcomponents/components/switch.rb +75 -0
  88. data/lib/shadcn_phlexcomponents/components/table.rb +140 -0
  89. data/lib/shadcn_phlexcomponents/components/tabs.rb +135 -0
  90. data/lib/shadcn_phlexcomponents/components/textarea.rb +24 -0
  91. data/lib/{components → shadcn_phlexcomponents/components}/theme_switcher.rb +2 -2
  92. data/lib/shadcn_phlexcomponents/components/toast.rb +153 -0
  93. data/lib/{components → shadcn_phlexcomponents/components}/toast_container.rb +24 -5
  94. data/lib/shadcn_phlexcomponents/components/tooltip.rb +131 -0
  95. data/lib/shadcn_phlexcomponents/initializers/shadcn_phlexcomponents.rb +25 -0
  96. data/lib/shadcn_phlexcomponents/version.rb +1 -1
  97. data/lib/tasks/install.rake +1 -1
  98. metadata +92 -168
  99. data/app/assets/tailwind/choices.css +0 -324
  100. data/app/assets/tailwind/tailwindcss-animate.css +0 -318
  101. data/app/assets/tailwind/vanilla-calendar-pro.css +0 -466
  102. data/app/javascript/controllers/accordion_controller.js +0 -133
  103. data/app/javascript/controllers/alert_dialog_controller.js +0 -157
  104. data/app/javascript/controllers/checkbox_controller.js +0 -28
  105. data/app/javascript/controllers/collapsible_controller.js +0 -35
  106. data/app/javascript/controllers/combobox_controller.js +0 -34
  107. data/app/javascript/controllers/date_picker_controller.js +0 -118
  108. data/app/javascript/controllers/date_range_picker_controller.js +0 -231
  109. data/app/javascript/controllers/dialog_controller.js +0 -159
  110. data/app/javascript/controllers/dropdown_menu_controller.js +0 -193
  111. data/app/javascript/controllers/hover_card_controller.js +0 -42
  112. data/app/javascript/controllers/popover_controller.js +0 -124
  113. data/app/javascript/controllers/progress_controller.js +0 -14
  114. data/app/javascript/controllers/radio_group_controller.js +0 -90
  115. data/app/javascript/controllers/select_controller.js +0 -294
  116. data/app/javascript/controllers/sheet_controller.js +0 -159
  117. data/app/javascript/controllers/sidebar_trigger_controller.js +0 -15
  118. data/app/javascript/controllers/switch_controller.js +0 -24
  119. data/app/javascript/controllers/tabs_controller.js +0 -73
  120. data/app/javascript/controllers/toast_container_controller.js +0 -22
  121. data/app/javascript/controllers/toast_controller.js +0 -45
  122. data/app/javascript/controllers/tooltip_controller.js +0 -41
  123. data/lib/components/accordion.rb +0 -38
  124. data/lib/components/accordion_content.rb +0 -30
  125. data/lib/components/accordion_item.rb +0 -26
  126. data/lib/components/accordion_trigger.rb +0 -45
  127. data/lib/components/alert.rb +0 -40
  128. data/lib/components/alert_description.rb +0 -11
  129. data/lib/components/alert_dialog.rb +0 -60
  130. data/lib/components/alert_dialog_action.rb +0 -22
  131. data/lib/components/alert_dialog_action_to.rb +0 -40
  132. data/lib/components/alert_dialog_cancel.rb +0 -22
  133. data/lib/components/alert_dialog_content.rb +0 -40
  134. data/lib/components/alert_dialog_description.rb +0 -22
  135. data/lib/components/alert_dialog_footer.rb +0 -11
  136. data/lib/components/alert_dialog_header.rb +0 -11
  137. data/lib/components/alert_dialog_title.rb +0 -22
  138. data/lib/components/alert_dialog_trigger.rb +0 -50
  139. data/lib/components/alert_title.rb +0 -11
  140. data/lib/components/avatar.rb +0 -31
  141. data/lib/components/avatar_fallback.rb +0 -21
  142. data/lib/components/avatar_image.rb +0 -19
  143. data/lib/components/badge.rb +0 -30
  144. data/lib/components/breadcrumb.rb +0 -51
  145. data/lib/components/breadcrumb_ellipsis.rb +0 -23
  146. data/lib/components/breadcrumb_item.rb +0 -11
  147. data/lib/components/breadcrumb_link.rb +0 -7
  148. data/lib/components/breadcrumb_page.rb +0 -21
  149. data/lib/components/breadcrumb_separator.rb +0 -26
  150. data/lib/components/button.rb +0 -53
  151. data/lib/components/card.rb +0 -31
  152. data/lib/components/card_content.rb +0 -11
  153. data/lib/components/card_description.rb +0 -11
  154. data/lib/components/card_footer.rb +0 -11
  155. data/lib/components/card_header.rb +0 -11
  156. data/lib/components/card_title.rb +0 -11
  157. data/lib/components/collapsible.rb +0 -31
  158. data/lib/components/collapsible_content.rb +0 -24
  159. data/lib/components/collapsible_trigger.rb +0 -50
  160. data/lib/components/combobox.rb +0 -57
  161. data/lib/components/combobox_item.rb +0 -9
  162. data/lib/components/date_picker.rb +0 -94
  163. data/lib/components/date_range_picker.rb +0 -113
  164. data/lib/components/dialog.rb +0 -52
  165. data/lib/components/dialog_close.rb +0 -42
  166. data/lib/components/dialog_content.rb +0 -54
  167. data/lib/components/dialog_description.rb +0 -22
  168. data/lib/components/dialog_footer.rb +0 -11
  169. data/lib/components/dialog_header.rb +0 -11
  170. data/lib/components/dialog_title.rb +0 -22
  171. data/lib/components/dialog_trigger.rb +0 -50
  172. data/lib/components/dropdown_menu.rb +0 -50
  173. data/lib/components/dropdown_menu_content.rb +0 -52
  174. data/lib/components/dropdown_menu_item.rb +0 -56
  175. data/lib/components/dropdown_menu_item_to.rb +0 -28
  176. data/lib/components/dropdown_menu_label.rb +0 -11
  177. data/lib/components/dropdown_menu_separator.rb +0 -20
  178. data/lib/components/dropdown_menu_trigger.rb +0 -57
  179. data/lib/components/form.rb +0 -59
  180. data/lib/components/form_hint.rb +0 -17
  181. data/lib/components/hover_card.rb +0 -33
  182. data/lib/components/hover_card_content.rb +0 -32
  183. data/lib/components/hover_card_trigger.rb +0 -44
  184. data/lib/components/input.rb +0 -32
  185. data/lib/components/label.rb +0 -14
  186. data/lib/components/loading_button.rb +0 -21
  187. data/lib/components/pagination.rb +0 -38
  188. data/lib/components/pagination_ellipsis.rb +0 -24
  189. data/lib/components/pagination_link.rb +0 -34
  190. data/lib/components/pagination_next.rb +0 -32
  191. data/lib/components/pagination_previous.rb +0 -32
  192. data/lib/components/popover.rb +0 -34
  193. data/lib/components/popover_content.rb +0 -40
  194. data/lib/components/popover_trigger.rb +0 -51
  195. data/lib/components/radio_group.rb +0 -62
  196. data/lib/components/radio_group_item.rb +0 -66
  197. data/lib/components/select.rb +0 -184
  198. data/lib/components/select_content.rb +0 -64
  199. data/lib/components/select_group.rb +0 -23
  200. data/lib/components/select_item.rb +0 -59
  201. data/lib/components/select_label.rb +0 -24
  202. data/lib/components/select_trigger.rb +0 -56
  203. data/lib/components/sheet.rb +0 -53
  204. data/lib/components/sheet_close.rb +0 -42
  205. data/lib/components/sheet_content.rb +0 -65
  206. data/lib/components/sheet_description.rb +0 -22
  207. data/lib/components/sheet_footer.rb +0 -11
  208. data/lib/components/sheet_header.rb +0 -11
  209. data/lib/components/sheet_title.rb +0 -22
  210. data/lib/components/sheet_trigger.rb +0 -50
  211. data/lib/components/sidebar.rb +0 -108
  212. data/lib/components/sidebar_container.rb +0 -11
  213. data/lib/components/sidebar_content.rb +0 -11
  214. data/lib/components/sidebar_footer.rb +0 -11
  215. data/lib/components/sidebar_group.rb +0 -11
  216. data/lib/components/sidebar_group_content.rb +0 -11
  217. data/lib/components/sidebar_group_label.rb +0 -16
  218. data/lib/components/sidebar_header.rb +0 -11
  219. data/lib/components/sidebar_inset.rb +0 -15
  220. data/lib/components/sidebar_menu.rb +0 -11
  221. data/lib/components/sidebar_menu_button.rb +0 -61
  222. data/lib/components/sidebar_menu_item.rb +0 -9
  223. data/lib/components/sidebar_menu_sub.rb +0 -14
  224. data/lib/components/sidebar_menu_sub_button.rb +0 -48
  225. data/lib/components/sidebar_menu_sub_item.rb +0 -9
  226. data/lib/components/sidebar_trigger.rb +0 -40
  227. data/lib/components/switch.rb +0 -66
  228. data/lib/components/table.rb +0 -75
  229. data/lib/components/table_body.rb +0 -11
  230. data/lib/components/table_caption.rb +0 -11
  231. data/lib/components/table_cell.rb +0 -11
  232. data/lib/components/table_footer.rb +0 -11
  233. data/lib/components/table_head.rb +0 -14
  234. data/lib/components/table_header.rb +0 -11
  235. data/lib/components/table_row.rb +0 -11
  236. data/lib/components/tabs.rb +0 -38
  237. data/lib/components/tabs_content.rb +0 -35
  238. data/lib/components/tabs_list.rb +0 -23
  239. data/lib/components/tabs_trigger.rb +0 -45
  240. data/lib/components/textarea.rb +0 -28
  241. data/lib/components/toast.rb +0 -101
  242. data/lib/components/toast_action.rb +0 -39
  243. data/lib/components/toast_action_to.rb +0 -28
  244. data/lib/components/toast_content.rb +0 -11
  245. data/lib/components/toast_description.rb +0 -11
  246. data/lib/components/toast_title.rb +0 -11
  247. data/lib/components/tooltip.rb +0 -34
  248. data/lib/components/tooltip_content.rb +0 -39
  249. data/lib/components/tooltip_trigger.rb +0 -48
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShadcnPhlexcomponents
4
+ class Slider < Base
5
+ def initialize(name: nil, value: nil, id: nil, range: false, orientation: :horizontal, step: 1, min: 0, max: 100, disabled: false, options: false, **attributes)
6
+ if range
7
+ if name && !name.is_a?(Array)
8
+ raise ArgumentError, "Expected an array for \"name\", got #{name.class}"
9
+ end
10
+
11
+ if value && !value.is_a?(Array)
12
+ raise ArgumentError, "Expected an array for \"value\", got #{value.class}"
13
+ end
14
+ end
15
+ @range = range
16
+ @name = range && name ? name[0] : name
17
+ @end_name = range && name ? name[1] : nil
18
+ @value = range && value ? value[0] : value
19
+ @end_value = range && value ? value[1] : nil
20
+ @id = id
21
+ @orientation = orientation
22
+ @step = step
23
+ @min = min
24
+ @max = max
25
+ @disabled = disabled
26
+ @options = options
27
+ super(**attributes)
28
+ end
29
+
30
+ def default_attributes
31
+ {
32
+ data: {
33
+ controller: "slider",
34
+ range: @range.to_s,
35
+ options: @options.to_json,
36
+ value: @value,
37
+ end_value: @end_value,
38
+ orientation: @orientation,
39
+ step: @step,
40
+ min: @min,
41
+ max: @max,
42
+ disabled: @disabled.to_s,
43
+ id: @id,
44
+ },
45
+ }
46
+ end
47
+
48
+ def view_template
49
+ div(class: "py-[6px]") do
50
+ div(**@attributes) do
51
+ input(
52
+ type: :hidden,
53
+ name: @name,
54
+ value: @value,
55
+ data: { slider_target: "hiddenInput" },
56
+ )
57
+
58
+ if @range
59
+ input(
60
+ type: :hidden,
61
+ name: @end_name,
62
+ value: @end_value,
63
+ data: { slider_target: "endHiddenInput" },
64
+ )
65
+ end
66
+
67
+ div(data: { slider_target: "slider" })
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShadcnPhlexcomponents
4
+ class Switch < Base
5
+ class_variants(
6
+ base: <<~HEREDOC,
7
+ peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring
8
+ focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem]
9
+ w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all
10
+ outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 relative
11
+ HEREDOC
12
+ )
13
+
14
+ def initialize(name: nil, value: "1", unchecked_value: "0", checked: false, include_hidden: true, disabled: false, **attributes)
15
+ @name = name
16
+ @value = value
17
+ @unchecked_value = unchecked_value
18
+ @checked = checked
19
+ @include_hidden = include_hidden
20
+ @disabled = disabled
21
+ super(**attributes)
22
+ end
23
+
24
+ def view_template(&)
25
+ button(**@attributes) do
26
+ span(
27
+ class: <<~HEREDOC,
28
+ bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground
29
+ pointer-events-none block size-4 rounded-full ring-0 transition-transform
30
+ data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0
31
+ HEREDOC
32
+ data: {
33
+ switch_target: "thumb",
34
+ state: @checked ? "checked" : "unchecked",
35
+ },
36
+ )
37
+
38
+ if @include_hidden
39
+ input(name: @name, type: "hidden", value: @unchecked_value, autocomplete: "off")
40
+ end
41
+
42
+ input(
43
+ type: "checkbox",
44
+ value: @value,
45
+ class: "-translate-x-full pointer-events-none absolute m-0 top-0 left-0 size-4 opacity-0",
46
+ name: @name,
47
+ disabled: @disabled,
48
+ tabindex: -1,
49
+ checked: @checked,
50
+ aria: { hidden: "true" },
51
+ data: {
52
+ switch_target: "input",
53
+ },
54
+ )
55
+ end
56
+ end
57
+
58
+ def default_attributes
59
+ {
60
+ type: "button",
61
+ role: "switch",
62
+ disabled: @disabled,
63
+ aria: {
64
+ checked: @checked.to_s,
65
+ },
66
+ data: {
67
+ state: @checked ? "checked" : "unchecked",
68
+ controller: "switch",
69
+ action: "click->switch#toggle",
70
+ switch_is_checked_value: @checked.to_s,
71
+ },
72
+ }
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShadcnPhlexcomponents
4
+ class Table < Base
5
+ class_variants(base: "w-full caption-bottom text-sm")
6
+
7
+ def initialize(**attributes)
8
+ @columns = []
9
+ super(**attributes)
10
+ end
11
+
12
+ def view_template(&)
13
+ div(class: "relative w-full overflow-x-auto", data: { shadcn_phlexcomponents: "table-container" }) do
14
+ table(**@attributes, &)
15
+ end
16
+ end
17
+
18
+ def caption(**attributes, &)
19
+ TableCaption(**attributes, &)
20
+ end
21
+
22
+ def header(**attributes, &)
23
+ TableHeader(**attributes, &)
24
+ end
25
+
26
+ def row(**attributes, &)
27
+ TableRow(**attributes, &)
28
+ end
29
+
30
+ def head(**attributes, &)
31
+ TableHead(**attributes, &)
32
+ end
33
+
34
+ def body(**attributes, &)
35
+ TableBody(**attributes, &)
36
+ end
37
+
38
+ def cell(**attributes, &)
39
+ TableCell(**attributes, &)
40
+ end
41
+
42
+ def footer(**attributes, &)
43
+ TableFooter(**attributes, &)
44
+ end
45
+
46
+ def rows(rows, &)
47
+ @rows = rows
48
+
49
+ vanish(&)
50
+
51
+ thead(class: TableHeader.new.class_variants) do
52
+ tr(class: TableRow.new.class_variants) do
53
+ @columns.each do |column|
54
+ th(class: TAILWIND_MERGER.merge("#{TableHead.new.class_variants} #{column[:head_class]}")) { column[:header] }
55
+ end
56
+ end
57
+ end
58
+
59
+ tbody(class: TableBody.new.class_variants) do
60
+ @rows.each do |row|
61
+ tr(class: TableRow.new.class_variants) do
62
+ @columns.each do |column|
63
+ td(class: TAILWIND_MERGER.merge("#{TableCell.new.class_variants} #{column[:cell_class]}")) do
64
+ column[:content].call(row)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ def column(header, head_class: nil, cell_class: nil, &content)
73
+ @columns << { header:, head_class:, cell_class:, content: }
74
+ nil
75
+ end
76
+ end
77
+
78
+ class TableCaption < Base
79
+ class_variants(base: "text-muted-foreground mt-4 text-sm")
80
+
81
+ def view_template(&)
82
+ caption(**@attributes, &)
83
+ end
84
+ end
85
+
86
+ class TableHeader < Base
87
+ class_variants(base: "[&_tr]:border-b")
88
+
89
+ def view_template(&)
90
+ thead(**@attributes, &)
91
+ end
92
+ end
93
+
94
+ class TableRow < Base
95
+ class_variants(base: "hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors")
96
+
97
+ def view_template(&)
98
+ tr(**@attributes, &)
99
+ end
100
+ end
101
+
102
+ class TableHead < Base
103
+ class_variants(
104
+ base: <<~HEREDOC,
105
+ text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0
106
+ [&>[role=checkbox]]:translate-y-[2px]"
107
+ HEREDOC
108
+ )
109
+
110
+ def view_template(&)
111
+ th(**@attributes, &)
112
+ end
113
+ end
114
+
115
+ class TableBody < Base
116
+ class_variants(base: "[&_tr:last-child]:border-0")
117
+
118
+ def view_template(&)
119
+ tbody(**@attributes, &)
120
+ end
121
+ end
122
+
123
+ class TableCell < Base
124
+ class_variants(
125
+ base: "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
126
+ )
127
+
128
+ def view_template(&)
129
+ td(**@attributes, &)
130
+ end
131
+ end
132
+
133
+ class TableFooter < Base
134
+ class_variants(base: "bg-muted/50 border-t font-medium [&>tr]:last:border-b-0")
135
+
136
+ def view_template(&)
137
+ tfoot(**@attributes, &)
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShadcnPhlexcomponents
4
+ class Tabs < Base
5
+ class_variants(base: "flex flex-col gap-2")
6
+
7
+ def initialize(value: nil, dir: "ltr", **attributes)
8
+ @dir = dir
9
+ @value = value
10
+ @aria_id = "tabs-#{SecureRandom.hex(5)}"
11
+ super(**attributes)
12
+ end
13
+
14
+ def list(**attributes, &)
15
+ TabsList(**attributes, &)
16
+ end
17
+
18
+ def trigger(**attributes, &)
19
+ TabsTrigger(aria_id: @aria_id, **attributes, &)
20
+ end
21
+
22
+ def content(**attributes, &)
23
+ TabsContent(aria_id: @aria_id, **attributes, &)
24
+ end
25
+
26
+ def default_attributes
27
+ {
28
+ dir: @dir,
29
+ data: {
30
+ controller: "tabs",
31
+ tabs_active_value: @value,
32
+ },
33
+ }
34
+ end
35
+
36
+ def view_template(&)
37
+ div(**@attributes, &)
38
+ end
39
+ end
40
+
41
+ class TabsList < Base
42
+ class_variants(
43
+ base: "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
44
+ )
45
+
46
+ def view_template(&)
47
+ div(**@attributes, &)
48
+ end
49
+
50
+ def default_attributes
51
+ {
52
+ role: "tablist",
53
+ tabindex: "-1",
54
+ aria: {
55
+ orientation: "horizontal",
56
+ },
57
+ }
58
+ end
59
+ end
60
+
61
+ class TabsTrigger < Base
62
+ class_variants(
63
+ base: <<~HEREDOC,
64
+ data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring
65
+ focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input
66
+ dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)]
67
+ flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm
68
+ font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1
69
+ disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none
70
+ [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4
71
+ HEREDOC
72
+ )
73
+
74
+ def initialize(value: nil, aria_id: nil, **attributes)
75
+ @value = value
76
+ @aria_id = aria_id
77
+ super(**attributes)
78
+ end
79
+
80
+ def view_template(&)
81
+ button(**@attributes, &)
82
+ end
83
+
84
+ def default_attributes
85
+ {
86
+ id: "#{@aria_id}-trigger-#{@value}",
87
+ role: "tab",
88
+ tabindex: "-1",
89
+ aria: {
90
+ controls: "#{@aria_id}-content-#{@value}",
91
+ selected: false,
92
+ },
93
+ data: {
94
+ tabs_target: "trigger",
95
+ value: @value,
96
+ state: "inactive",
97
+ action: <<~HEREDOC,
98
+ click->tabs#setActiveTab
99
+ keydown.left->tabs#setActiveTab:prevent
100
+ keydown.right->tabs#setActiveToNext:prevent
101
+ HEREDOC
102
+ },
103
+ }
104
+ end
105
+ end
106
+
107
+ class TabsContent < Base
108
+ class_variants(base: "flex-1 outline-none")
109
+
110
+ def initialize(value: nil, aria_id: nil, **attributes)
111
+ @value = value
112
+ @aria_id = aria_id
113
+ super(**attributes)
114
+ end
115
+
116
+ def view_template(&)
117
+ div(**@attributes, &)
118
+ end
119
+
120
+ def default_attributes
121
+ {
122
+ id: "#{@aria_id}-content-#{@value}",
123
+ role: "tabpanel",
124
+ tabindex: "0",
125
+ aria: {
126
+ labelledby: "#{@aria_id}-trigger-#{@value}",
127
+ },
128
+ data: {
129
+ value: @value,
130
+ tabs_target: "content",
131
+ },
132
+ }
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShadcnPhlexcomponents
4
+ class Textarea < Base
5
+ class_variants(
6
+ base: <<~HEREDOC,
7
+ border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50
8
+ aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive
9
+ dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2
10
+ text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px]
11
+ disabled:cursor-not-allowed disabled:opacity-50 md:text-sm
12
+ HEREDOC
13
+ )
14
+
15
+ def initialize(value: nil, **attributes)
16
+ @value = value
17
+ super(**attributes)
18
+ end
19
+
20
+ def view_template(&)
21
+ textarea(**@attributes) { @value }
22
+ end
23
+ end
24
+ end
@@ -12,8 +12,8 @@ module ShadcnPhlexcomponents
12
12
  def default_attributes
13
13
  {
14
14
  data: {
15
- controller: "shadcn-phlexcomponents--theme-switcher",
16
- action: "shadcn-phlexcomponents--theme-switcher#toggle",
15
+ controller: "theme-switcher",
16
+ action: "theme-switcher#toggle",
17
17
  },
18
18
  }
19
19
  end
@@ -0,0 +1,153 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShadcnPhlexcomponents
4
+ class Toast < Base
5
+ class_variants(
6
+ base: <<~HEREDOC,
7
+ p-4 border shadow-lg text-[0.8rem] flex gap-1.5 items-center w-full sm:w-90 rounded-lg duration-200
8
+ data-[state=open]:animate-in data-[state=closed]:animate-out [&_svg]:size-4 [&_svg]:mr-1 [&_svg]:self-start [&_svg]:translate-y-0.5
9
+ HEREDOC
10
+ variants: {
11
+ variant: {
12
+ default: "bg-popover text-popover-foreground",
13
+ destructive: "bg-card text-destructive [&>svg]:text-current *:data-[shadcn-phlexcomponents=toast-description]:text-destructive/90",
14
+ },
15
+ side: {
16
+ top: "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
17
+ bottom: "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
18
+ },
19
+ },
20
+ defaults: {
21
+ variant: :default,
22
+ },
23
+ )
24
+
25
+ def initialize(variant: :default, side: :top, duration: 5000, **attributes)
26
+ @class_variants = { variant: variant, side: side }
27
+ @duration = duration
28
+ super(**attributes)
29
+ end
30
+
31
+ def content(**attributes, &)
32
+ ToastContent(**attributes, &)
33
+ end
34
+
35
+ def title(**attributes, &)
36
+ ToastTitle(**attributes, &)
37
+ end
38
+
39
+ def description(**attributes, &)
40
+ ToastDescription(**attributes, &)
41
+ end
42
+
43
+ def action(**attributes, &)
44
+ ToastAction(**attributes, &)
45
+ end
46
+
47
+ def action_to(name = nil, options = nil, html_options = nil, &)
48
+ ToastActionTo(name, options, html_options, &)
49
+ end
50
+
51
+ def default_attributes
52
+ {
53
+ role: "status",
54
+ tabindex: 0,
55
+ aria: {
56
+ live: "off",
57
+ atomic: "true",
58
+ },
59
+ data: {
60
+ duration: @duration,
61
+ state: "open",
62
+ controller: "toast",
63
+ action: <<~HEREDOC,
64
+ focus->toast#cancelClose
65
+ blur->toast#close
66
+ mouseover->toast#cancelClose
67
+ mouseout->toast#close
68
+ HEREDOC
69
+ },
70
+ }
71
+ end
72
+
73
+ def view_template(&)
74
+ li(**@attributes, &)
75
+ end
76
+ end
77
+
78
+ class ToastContent < Base
79
+ class_variants(base: "flex flex-col gap-0.5")
80
+
81
+ def view_template(&)
82
+ div(**@attributes, &)
83
+ end
84
+ end
85
+
86
+ class ToastTitle < Base
87
+ class_variants(base: "font-medium leading-[1.5]")
88
+
89
+ def view_template(&)
90
+ div(**@attributes, &)
91
+ end
92
+ end
93
+
94
+ class ToastDescription < Base
95
+ class_variants(base: "leading-[1.4] opacity-90")
96
+
97
+ def view_template(&)
98
+ div(**@attributes, &)
99
+ end
100
+ end
101
+
102
+ class ToastAction < Base
103
+ def initialize(as_child: false, **attributes)
104
+ @as_child = as_child
105
+ super(**attributes)
106
+ end
107
+
108
+ def class_variants(**args)
109
+ Button.new.class_variants(variant: :default, size: :sm, class: "text-xs h-6 py-0 px-2 rounded-sm ml-auto #{args[:class]}")
110
+ end
111
+
112
+ def view_template(&)
113
+ if @as_child
114
+ content = capture(&)
115
+ element = find_as_child(content.to_s)
116
+ vanish(&)
117
+ merged_attributes = merged_as_child_attributes(element, @attributes)
118
+
119
+ send(element.name, **merged_attributes) do
120
+ sanitize_as_child(element.children.to_s)
121
+ end
122
+ else
123
+ button(**@attributes, &)
124
+ end
125
+ end
126
+ end
127
+
128
+ class ToastActionTo < ToastAction
129
+ def initialize(name = nil, options = nil, html_options = nil)
130
+ @name = name
131
+ @options = options
132
+ @html_options = html_options
133
+ end
134
+
135
+ def view_template(&)
136
+ if block_given?
137
+ @html_options = @options
138
+ @options = @name
139
+ end
140
+
141
+ merge_default_attributes({})
142
+ @html_options ||= {}
143
+ @html_options = mix(@attributes, @html_options)
144
+ @html_options[:form_class] = TAILWIND_MERGER.merge("inline-flex ml-auto #{@html_options[:form_class]}")
145
+
146
+ if block_given?
147
+ button_to(@options, @html_options, &)
148
+ else
149
+ button_to(@name, @options, @html_options)
150
+ end
151
+ end
152
+ end
153
+ end
@@ -2,16 +2,33 @@
2
2
 
3
3
  module ShadcnPhlexcomponents
4
4
  class ToastContainer < Base
5
- STYLES = <<~HEREDOC
6
- fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4
7
- sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]
8
- HEREDOC
5
+ class_variants(
6
+ base: "fixed z-[100] hidden has-[li]:flex flex-col gap-2",
7
+ variants: {
8
+ side: {
9
+ top_center: "top-6 left-1/2 -translate-x-1/2",
10
+ top_left: "top-6 left-6",
11
+ top_right: "top-6 right-6",
12
+ bottom_center: "bottom-6 left-1/2 -translate-x-1/2",
13
+ bottom_left: "bottom-6 left-6",
14
+ bottom_right: "right-6 bottom-6",
15
+ },
16
+ },
17
+ defaults: {
18
+ side: :top_center,
19
+ },
20
+ )
21
+
22
+ def initialize(side: :top_center, **attributes)
23
+ @class_variants = { side: side }
24
+ super(**attributes)
25
+ end
9
26
 
10
27
  def default_attributes
11
28
  {
12
29
  tabindex: -1,
13
30
  data: {
14
- controller: "shadcn-phlexcomponents--toast-container",
31
+ controller: "toast-container",
15
32
  },
16
33
  }
17
34
  end
@@ -38,6 +55,8 @@ module ShadcnPhlexcomponents
38
55
  t.title { "" }
39
56
  t.description { "" }
40
57
  end
58
+
59
+ t.action { "" }
41
60
  end
42
61
  end
43
62
  end