ruby_ui 1.0.0.pre.alpha.4 → 1.0.0.rc1

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 (227) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +21 -0
  3. data/README.md +85 -0
  4. data/lib/generators/ruby_ui/component_generator.rb +94 -0
  5. data/lib/generators/ruby_ui/dependencies.yml +74 -0
  6. data/lib/generators/ruby_ui/install/install_generator.rb +89 -0
  7. data/lib/generators/ruby_ui/install/templates/ruby_ui.rb.erb +18 -0
  8. data/lib/generators/ruby_ui/install/templates/tailwind.css.erb +156 -0
  9. data/lib/generators/ruby_ui/javascript_utils.rb +57 -0
  10. data/lib/{rbui → ruby_ui}/accordion/accordion.rb +1 -1
  11. data/lib/{rbui → ruby_ui}/accordion/accordion_content.rb +2 -2
  12. data/lib/ruby_ui/accordion/accordion_controller.js +97 -0
  13. data/lib/{rbui → ruby_ui}/accordion/accordion_default_content.rb +1 -1
  14. data/lib/{rbui → ruby_ui}/accordion/accordion_default_trigger.rb +3 -3
  15. data/lib/{rbui → ruby_ui}/accordion/accordion_icon.rb +2 -2
  16. data/lib/{rbui → ruby_ui}/accordion/accordion_item.rb +4 -4
  17. data/lib/{rbui → ruby_ui}/accordion/accordion_trigger.rb +3 -2
  18. data/lib/{rbui → ruby_ui}/alert/alert.rb +3 -3
  19. data/lib/{rbui → ruby_ui}/alert/alert_description.rb +1 -1
  20. data/lib/{rbui → ruby_ui}/alert/alert_title.rb +1 -1
  21. data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog.rb +3 -3
  22. data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_action.rb +2 -2
  23. data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_cancel.rb +3 -3
  24. data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_content.rb +5 -5
  25. data/lib/ruby_ui/alert_dialog/alert_dialog_controller.js +31 -0
  26. data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_description.rb +1 -1
  27. data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_footer.rb +2 -2
  28. data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_header.rb +2 -2
  29. data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_title.rb +1 -1
  30. data/lib/{rbui → ruby_ui}/alert_dialog/alert_dialog_trigger.rb +2 -2
  31. data/lib/{rbui → ruby_ui}/aspect_ratio/aspect_ratio.rb +1 -1
  32. data/lib/{rbui → ruby_ui}/avatar/avatar.rb +2 -2
  33. data/lib/{rbui → ruby_ui}/avatar/avatar_fallback.rb +1 -1
  34. data/lib/{rbui → ruby_ui}/avatar/avatar_image.rb +1 -1
  35. data/lib/{rbui → ruby_ui}/badge/badge.rb +2 -2
  36. data/lib/{rbui → ruby_ui}/base.rb +1 -8
  37. data/lib/ruby_ui/breadcrumb/breadcrumb.rb +17 -0
  38. data/lib/ruby_ui/breadcrumb/breadcrumb_ellipsis.rb +39 -0
  39. data/lib/{rbui/typography/typography_list_item.rb → ruby_ui/breadcrumb/breadcrumb_item.rb} +3 -3
  40. data/lib/ruby_ui/breadcrumb/breadcrumb_link.rb +22 -0
  41. data/lib/ruby_ui/breadcrumb/breadcrumb_list.rb +17 -0
  42. data/lib/ruby_ui/breadcrumb/breadcrumb_page.rb +19 -0
  43. data/lib/ruby_ui/breadcrumb/breadcrumb_separator.rb +38 -0
  44. data/lib/{rbui → ruby_ui}/button/button.rb +13 -13
  45. data/lib/ruby_ui/calendar/calendar.rb +39 -0
  46. data/lib/{rbui → ruby_ui}/calendar/calendar_body.rb +2 -2
  47. data/lib/ruby_ui/calendar/calendar_controller.js +249 -0
  48. data/lib/{rbui → ruby_ui}/calendar/calendar_days.rb +14 -14
  49. data/lib/{rbui → ruby_ui}/calendar/calendar_header.rb +1 -1
  50. data/lib/ruby_ui/calendar/calendar_input_controller.js +8 -0
  51. data/lib/{rbui → ruby_ui}/calendar/calendar_next.rb +2 -2
  52. data/lib/{rbui → ruby_ui}/calendar/calendar_prev.rb +2 -2
  53. data/lib/{rbui → ruby_ui}/calendar/calendar_title.rb +2 -2
  54. data/lib/{rbui → ruby_ui}/calendar/calendar_weekdays.rb +2 -2
  55. data/lib/{rbui → ruby_ui}/card/card.rb +1 -1
  56. data/lib/{rbui → ruby_ui}/card/card_content.rb +1 -1
  57. data/lib/{rbui → ruby_ui}/card/card_description.rb +1 -1
  58. data/lib/{rbui → ruby_ui}/card/card_footer.rb +1 -1
  59. data/lib/{rbui → ruby_ui}/card/card_header.rb +1 -1
  60. data/lib/{rbui → ruby_ui}/card/card_title.rb +1 -1
  61. data/lib/ruby_ui/carousel/carousel.rb +44 -0
  62. data/lib/ruby_ui/carousel/carousel_content.rb +23 -0
  63. data/lib/ruby_ui/carousel/carousel_controller.js +60 -0
  64. data/lib/ruby_ui/carousel/carousel_item.rb +23 -0
  65. data/lib/ruby_ui/carousel/carousel_next.rb +48 -0
  66. data/lib/ruby_ui/carousel/carousel_previous.rb +49 -0
  67. data/lib/{rbui → ruby_ui}/chart/chart.rb +3 -3
  68. data/lib/ruby_ui/chart/chart_controller.js +103 -0
  69. data/lib/{rbui → ruby_ui}/checkbox/checkbox.rb +4 -4
  70. data/lib/{rbui → ruby_ui}/checkbox/checkbox_group.rb +2 -2
  71. data/lib/ruby_ui/checkbox/checkbox_group_controller.js +21 -0
  72. data/lib/{rbui → ruby_ui}/clipboard/clipboard.rb +6 -6
  73. data/lib/ruby_ui/clipboard/clipboard_controller.js +54 -0
  74. data/lib/{rbui → ruby_ui}/clipboard/clipboard_popover.rb +2 -2
  75. data/lib/{rbui → ruby_ui}/clipboard/clipboard_source.rb +2 -2
  76. data/lib/{rbui → ruby_ui}/clipboard/clipboard_trigger.rb +3 -3
  77. data/lib/{rbui → ruby_ui}/codeblock/codeblock.rb +7 -10
  78. data/lib/{rbui → ruby_ui}/collapsible/collapsible.rb +3 -3
  79. data/lib/{rbui → ruby_ui}/collapsible/collapsible_content.rb +2 -2
  80. data/lib/ruby_ui/collapsible/collapsible_controller.js +47 -0
  81. data/lib/{rbui → ruby_ui}/collapsible/collapsible_trigger.rb +2 -2
  82. data/lib/ruby_ui/combobox/combobox.rb +26 -0
  83. data/lib/ruby_ui/combobox/combobox_checkbox.rb +25 -0
  84. data/lib/ruby_ui/combobox/combobox_controller.js +176 -0
  85. data/lib/{rbui/combobox/combobox_empty.rb → ruby_ui/combobox/combobox_empty_state.rb} +3 -3
  86. data/lib/ruby_ui/combobox/combobox_item.rb +25 -0
  87. data/lib/ruby_ui/combobox/combobox_list.rb +18 -0
  88. data/lib/ruby_ui/combobox/combobox_list_group.rb +20 -0
  89. data/lib/ruby_ui/combobox/combobox_popover.rb +30 -0
  90. data/lib/ruby_ui/combobox/combobox_radio.rb +26 -0
  91. data/lib/{rbui → ruby_ui}/combobox/combobox_search_input.rb +22 -25
  92. data/lib/ruby_ui/combobox/combobox_toggle_all_checkbox.rb +25 -0
  93. data/lib/{rbui → ruby_ui}/combobox/combobox_trigger.rb +26 -21
  94. data/lib/{rbui → ruby_ui}/command/command.rb +1 -1
  95. data/lib/ruby_ui/command/command_controller.js +136 -0
  96. data/lib/{rbui → ruby_ui}/command/command_dialog.rb +2 -2
  97. data/lib/{rbui → ruby_ui}/command/command_dialog_content.rb +6 -6
  98. data/lib/{rbui → ruby_ui}/command/command_dialog_trigger.rb +3 -3
  99. data/lib/{rbui → ruby_ui}/command/command_empty.rb +2 -2
  100. data/lib/{rbui → ruby_ui}/command/command_group.rb +2 -2
  101. data/lib/{rbui → ruby_ui}/command/command_input.rb +3 -3
  102. data/lib/{rbui → ruby_ui}/command/command_item.rb +2 -2
  103. data/lib/{rbui → ruby_ui}/command/command_list.rb +1 -1
  104. data/lib/{rbui → ruby_ui}/context_menu/context_menu.rb +2 -2
  105. data/lib/{rbui → ruby_ui}/context_menu/context_menu_content.rb +2 -2
  106. data/lib/ruby_ui/context_menu/context_menu_controller.js +144 -0
  107. data/lib/{rbui → ruby_ui}/context_menu/context_menu_item.rb +3 -3
  108. data/lib/{rbui → ruby_ui}/context_menu/context_menu_label.rb +2 -2
  109. data/lib/{rbui → ruby_ui}/context_menu/context_menu_separator.rb +1 -1
  110. data/lib/{rbui → ruby_ui}/context_menu/context_menu_trigger.rb +3 -3
  111. data/lib/{rbui → ruby_ui}/dialog/dialog.rb +3 -3
  112. data/lib/{rbui → ruby_ui}/dialog/dialog_content.rb +9 -9
  113. data/lib/ruby_ui/dialog/dialog_controller.js +32 -0
  114. data/lib/{rbui → ruby_ui}/dialog/dialog_description.rb +1 -1
  115. data/lib/{rbui → ruby_ui}/dialog/dialog_footer.rb +2 -2
  116. data/lib/{rbui → ruby_ui}/dialog/dialog_header.rb +2 -2
  117. data/lib/{rbui → ruby_ui}/dialog/dialog_middle.rb +1 -1
  118. data/lib/{rbui → ruby_ui}/dialog/dialog_title.rb +1 -1
  119. data/lib/{rbui → ruby_ui}/dialog/dialog_trigger.rb +2 -2
  120. data/lib/{rbui → ruby_ui}/dropdown_menu/dropdown_menu.rb +4 -4
  121. data/lib/{rbui → ruby_ui}/dropdown_menu/dropdown_menu_content.rb +2 -2
  122. data/lib/ruby_ui/dropdown_menu/dropdown_menu_controller.js +120 -0
  123. data/lib/{rbui → ruby_ui}/dropdown_menu/dropdown_menu_item.rb +3 -3
  124. data/lib/{rbui → ruby_ui}/dropdown_menu/dropdown_menu_label.rb +1 -1
  125. data/lib/{rbui → ruby_ui}/dropdown_menu/dropdown_menu_separator.rb +1 -1
  126. data/lib/{rbui → ruby_ui}/dropdown_menu/dropdown_menu_trigger.rb +2 -2
  127. data/lib/{rbui → ruby_ui}/form/form.rb +1 -1
  128. data/lib/{rbui → ruby_ui}/form/form_field.rb +2 -2
  129. data/lib/ruby_ui/form/form_field_controller.js +61 -0
  130. data/lib/{rbui → ruby_ui}/form/form_field_error.rb +2 -2
  131. data/lib/{rbui → ruby_ui}/form/form_field_hint.rb +1 -1
  132. data/lib/{rbui → ruby_ui}/form/form_field_label.rb +1 -1
  133. data/lib/{rbui → ruby_ui}/hover_card/hover_card.rb +3 -3
  134. data/lib/{rbui → ruby_ui}/hover_card/hover_card_content.rb +2 -2
  135. data/lib/ruby_ui/hover_card/hover_card_controller.js +144 -0
  136. data/lib/{rbui → ruby_ui}/hover_card/hover_card_trigger.rb +2 -2
  137. data/lib/{rbui → ruby_ui}/input/input.rb +3 -3
  138. data/lib/{rbui → ruby_ui}/link/link.rb +13 -13
  139. data/lib/ruby_ui/masked_input/masked_input.rb +15 -0
  140. data/lib/ruby_ui/masked_input/masked_input_controller.js +9 -0
  141. data/lib/{rbui → ruby_ui}/pagination/pagination.rb +1 -1
  142. data/lib/{rbui → ruby_ui}/pagination/pagination_content.rb +1 -1
  143. data/lib/{rbui → ruby_ui}/pagination/pagination_ellipsis.rb +1 -1
  144. data/lib/{rbui → ruby_ui}/pagination/pagination_item.rb +4 -4
  145. data/lib/{rbui → ruby_ui}/popover/popover.rb +4 -4
  146. data/lib/{rbui → ruby_ui}/popover/popover_content.rb +2 -2
  147. data/lib/ruby_ui/popover/popover_controller.js +107 -0
  148. data/lib/{rbui → ruby_ui}/popover/popover_trigger.rb +2 -2
  149. data/lib/ruby_ui/progress/progress.rb +37 -0
  150. data/lib/ruby_ui/radio_button/radio_button.rb +25 -0
  151. data/lib/{rbui → ruby_ui}/select/select.rb +5 -5
  152. data/lib/{rbui → ruby_ui}/select/select_content.rb +3 -3
  153. data/lib/ruby_ui/select/select_controller.js +171 -0
  154. data/lib/{rbui → ruby_ui}/select/select_group.rb +1 -1
  155. data/lib/{rbui → ruby_ui}/select/select_input.rb +4 -4
  156. data/lib/{rbui → ruby_ui}/select/select_item.rb +4 -4
  157. data/lib/ruby_ui/select/select_item_controller.js +11 -0
  158. data/lib/{rbui → ruby_ui}/select/select_label.rb +1 -1
  159. data/lib/{rbui → ruby_ui}/select/select_trigger.rb +3 -3
  160. data/lib/{rbui → ruby_ui}/select/select_value.rb +3 -3
  161. data/lib/ruby_ui/separator/separator.rb +38 -0
  162. data/lib/{rbui → ruby_ui}/sheet/sheet.rb +2 -2
  163. data/lib/{rbui → ruby_ui}/sheet/sheet_content.rb +8 -8
  164. data/lib/ruby_ui/sheet/sheet_content_controller.js +7 -0
  165. data/lib/ruby_ui/sheet/sheet_controller.js +9 -0
  166. data/lib/{rbui → ruby_ui}/sheet/sheet_description.rb +1 -1
  167. data/lib/{rbui → ruby_ui}/sheet/sheet_footer.rb +1 -1
  168. data/lib/{rbui → ruby_ui}/sheet/sheet_header.rb +1 -1
  169. data/lib/{rbui → ruby_ui}/sheet/sheet_middle.rb +1 -1
  170. data/lib/{rbui → ruby_ui}/sheet/sheet_title.rb +1 -1
  171. data/lib/{rbui → ruby_ui}/sheet/sheet_trigger.rb +2 -2
  172. data/lib/{rbui → ruby_ui}/shortcut_key/shortcut_key.rb +1 -1
  173. data/lib/ruby_ui/skeleton/skeleton.rb +17 -0
  174. data/lib/ruby_ui/switch/switch.rb +24 -0
  175. data/lib/{rbui → ruby_ui}/table/table.rb +1 -1
  176. data/lib/{rbui → ruby_ui}/table/table_body.rb +1 -1
  177. data/lib/{rbui → ruby_ui}/table/table_caption.rb +1 -1
  178. data/lib/{rbui → ruby_ui}/table/table_cell.rb +1 -1
  179. data/lib/{rbui → ruby_ui}/table/table_footer.rb +1 -1
  180. data/lib/{rbui → ruby_ui}/table/table_head.rb +1 -1
  181. data/lib/{rbui → ruby_ui}/table/table_header.rb +1 -1
  182. data/lib/{rbui → ruby_ui}/table/table_row.rb +1 -1
  183. data/lib/{rbui → ruby_ui}/tabs/tabs.rb +3 -3
  184. data/lib/{rbui → ruby_ui}/tabs/tabs_content.rb +2 -2
  185. data/lib/ruby_ui/tabs/tabs_controller.js +45 -0
  186. data/lib/{rbui → ruby_ui}/tabs/tabs_list.rb +1 -1
  187. data/lib/{rbui → ruby_ui}/tabs/tabs_trigger.rb +3 -3
  188. data/lib/{rbui → ruby_ui}/textarea/textarea.rb +3 -3
  189. data/lib/{rbui → ruby_ui}/theme_toggle/theme_toggle.rb +4 -4
  190. data/lib/ruby_ui/theme_toggle/theme_toggle_controller.js +30 -0
  191. data/lib/{rbui → ruby_ui}/tooltip/tooltip.rb +3 -3
  192. data/lib/{rbui → ruby_ui}/tooltip/tooltip_content.rb +3 -3
  193. data/lib/ruby_ui/tooltip/tooltip_controller.js +37 -0
  194. data/lib/{rbui → ruby_ui}/tooltip/tooltip_trigger.rb +2 -2
  195. data/lib/ruby_ui/typography/heading.rb +60 -0
  196. data/lib/{rbui/typography/typography_inline_code.rb → ruby_ui/typography/inline_code.rb} +2 -2
  197. data/lib/{rbui/typography/typography_inline_link.rb → ruby_ui/typography/inline_link.rb} +2 -2
  198. data/lib/ruby_ui/typography/text.rb +53 -0
  199. data/lib/{rbui → ruby_ui}/typography/typography_blockquote.rb +1 -1
  200. data/lib/ruby_ui.rb +5 -1
  201. metadata +208 -173
  202. data/lib/generators/rbui/base_generator.rb +0 -17
  203. data/lib/generators/rbui/component_generator.rb +0 -137
  204. data/lib/generators/rbui/install/install_generator.rb +0 -194
  205. data/lib/rbui/calendar/calendar.rb +0 -39
  206. data/lib/rbui/combobox/combobox.rb +0 -24
  207. data/lib/rbui/combobox/combobox_content.rb +0 -31
  208. data/lib/rbui/combobox/combobox_group.rb +0 -38
  209. data/lib/rbui/combobox/combobox_input.rb +0 -22
  210. data/lib/rbui/combobox/combobox_item.rb +0 -53
  211. data/lib/rbui/combobox/combobox_list.rb +0 -29
  212. data/lib/rbui/combobox/combobox_separator.rb +0 -15
  213. data/lib/rbui/combobox/combobox_value.rb +0 -27
  214. data/lib/rbui/radio_button/radio_button.rb +0 -22
  215. data/lib/rbui/railtie.rb +0 -52
  216. data/lib/rbui/typography/typography_h1.rb +0 -17
  217. data/lib/rbui/typography/typography_h2.rb +0 -17
  218. data/lib/rbui/typography/typography_h3.rb +0 -17
  219. data/lib/rbui/typography/typography_h4.rb +0 -17
  220. data/lib/rbui/typography/typography_large.rb +0 -17
  221. data/lib/rbui/typography/typography_lead.rb +0 -17
  222. data/lib/rbui/typography/typography_list.rb +0 -47
  223. data/lib/rbui/typography/typography_muted.rb +0 -17
  224. data/lib/rbui/typography/typography_p.rb +0 -17
  225. data/lib/rbui/typography/typography_small.rb +0 -17
  226. data/lib/rbui/version.rb +0 -5
  227. data/lib/rbui.rb +0 -57
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class CommandDialogContent < Base
5
5
  SIZES = {
6
6
  xs: "max-w-sm",
@@ -17,8 +17,8 @@ module RBUI
17
17
  end
18
18
 
19
19
  def view_template(&block)
20
- template_tag(data: {rbui__command_target: "content"}) do
21
- div(data: {controller: "rbui--command"}) do
20
+ template(data: {ruby_ui__command_target: "content"}) do
21
+ div(data: {controller: "ruby-ui--command"}) do
22
22
  backdrop
23
23
  div(**attrs, &block)
24
24
  end
@@ -30,17 +30,17 @@ module RBUI
30
30
  def default_attrs
31
31
  {
32
32
  data_state: "open",
33
- class: tokens(
33
+ class: [
34
34
  "fixed pointer-events-auto left-[50%] top-[50%] z-50 grid w-full translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full",
35
35
  SIZES[@size]
36
- )
36
+ ]
37
37
  }
38
38
  end
39
39
 
40
40
  def backdrop
41
41
  div(
42
42
  data_state: "open",
43
- data_action: "click->rbui--command#dismiss esc->rbui--command#dismiss",
43
+ data_action: "click->ruby-ui--command#dismiss esc->ruby-ui--command#dismiss",
44
44
  class: "fixed pointer-events-auto inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
45
45
  )
46
46
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class CommandDialogTrigger < Base
5
5
  DEFAULT_KEYBINDINGS = [
6
6
  "keydown.ctrl+k@window",
@@ -8,7 +8,7 @@ module RBUI
8
8
  ].freeze
9
9
 
10
10
  def initialize(keybindings: DEFAULT_KEYBINDINGS, **attrs)
11
- @keybindings = keybindings.map { |kb| "#{kb}->rbui--command#open" }
11
+ @keybindings = keybindings.map { |kb| "#{kb}->ruby-ui--command#open" }
12
12
  super(**attrs)
13
13
  end
14
14
 
@@ -21,7 +21,7 @@ module RBUI
21
21
  def default_attrs
22
22
  {
23
23
  data: {
24
- action: tokens("click->rbui--command#open", @keybindings.join(" "))
24
+ action: ["click->ruby-ui--command#open", @keybindings.join(" ")]
25
25
  }
26
26
  }
27
27
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class CommandEmpty < Base
5
5
  def view_template(&)
6
6
  div(**attrs, &)
@@ -12,7 +12,7 @@ module RBUI
12
12
  {
13
13
  class: "py-6 text-center text-sm",
14
14
  role: "presentation",
15
- data: {rbui__command_target: "empty"}
15
+ data: {ruby_ui__command_target: "empty"}
16
16
  }
17
17
  end
18
18
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class CommandGroup < Base
5
5
  def initialize(title: nil, **attrs)
6
6
  @title = title
@@ -32,7 +32,7 @@ module RBUI
32
32
  role: "presentation",
33
33
  data: {
34
34
  value: @title,
35
- rbui__command_target: "group"
35
+ ruby_ui__command_target: "group"
36
36
  }
37
37
  }
38
38
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class CommandInput < Base
5
5
  def initialize(placeholder: "Type a command or search...", **attrs)
6
6
  @placeholder = placeholder
@@ -40,8 +40,8 @@ module RBUI
40
40
  {
41
41
  class: "flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
42
42
  placeholder: @placeholder,
43
- data_action: "input->rbui--command#filter keydown.down->rbui--command#handleKeydown keydown.up->rbui--command#handleKeydown keydown.enter->rbui--command#handleKeydown keydown.esc->rbui--command#dismiss",
44
- data_rbui__command_target: "input",
43
+ data_action: "input->ruby-ui--command#filter keydown.down->ruby-ui--command#handleKeydown keydown.up->ruby-ui--command#handleKeydown keydown.enter->ruby-ui--command#handleKeydown keydown.esc->ruby-ui--command#dismiss",
44
+ data_ruby_ui__command_target: "input",
45
45
  autocomplete: "off",
46
46
  autocorrect: "off",
47
47
  spellcheck: false,
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class CommandItem < Base
5
5
  def initialize(value:, text: "", href: "#", **attrs)
6
6
  @value = value
@@ -21,7 +21,7 @@ module RBUI
21
21
  href: @href,
22
22
  role: "option",
23
23
  data: {
24
- rbui__command_target: "item",
24
+ ruby_ui__command_target: "item",
25
25
  value: @value,
26
26
  text: @text
27
27
  }
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class CommandList < Base
5
5
  def view_template(&)
6
6
  div(**attrs, &)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class ContextMenu < Base
5
5
  def initialize(options: {}, **attrs)
6
6
  @options = options
@@ -17,7 +17,7 @@ module RBUI
17
17
  def default_attrs
18
18
  {
19
19
  data: {
20
- controller: "rbui--context-menu",
20
+ controller: "ruby-ui--context-menu",
21
21
  popover_options_value: @options.to_json
22
22
  }
23
23
  }
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class ContextMenuContent < Base
5
5
  def view_template(&block)
6
- template_tag(data: {rbui__context_menu_target: "content"}) do
6
+ template(data: {ruby_ui__context_menu_target: "content"}) do
7
7
  div(**attrs, &block)
8
8
  end
9
9
  end
@@ -0,0 +1,144 @@
1
+ import { Controller } from "@hotwired/stimulus";
2
+ import tippy from "tippy.js";
3
+
4
+ export default class extends Controller {
5
+ static targets = ["trigger", "content", "menuItem"];
6
+ static values = {
7
+ options: {
8
+ type: Object,
9
+ default: {},
10
+ },
11
+ // make content width of the trigger element (true/false)
12
+ matchWidth: {
13
+ type: Boolean,
14
+ default: false,
15
+ }
16
+ }
17
+
18
+ connect() {
19
+ this.boundHandleKeydown = this.handleKeydown.bind(this); // Bind the function so we can remove it later
20
+ this.initializeTippy();
21
+ this.selectedIndex = -1;
22
+ }
23
+
24
+ disconnect() {
25
+ this.destroyTippy();
26
+ }
27
+
28
+ initializeTippy() {
29
+ const defaultOptions = {
30
+ content: this.contentTarget.innerHTML,
31
+ allowHTML: true,
32
+ interactive: true,
33
+ onShow: (instance) => {
34
+ this.matchWidthValue && this.setContentWidth(instance); // ensure content width matches trigger width
35
+ this.addEventListeners();
36
+ },
37
+ onHide: () => {
38
+ this.removeEventListeners();
39
+ this.deselectAll();
40
+ },
41
+ popperOptions: {
42
+ modifiers: [
43
+ {
44
+ name: "offset",
45
+ options: {
46
+ offset: [0, 4]
47
+ },
48
+ },
49
+ ],
50
+ }
51
+ };
52
+
53
+ const mergedOptions = { ...this.optionsValue, ...defaultOptions };
54
+ this.tippy = tippy(this.triggerTarget, mergedOptions);
55
+ }
56
+
57
+ destroyTippy() {
58
+ if (this.tippy) {
59
+ this.tippy.destroy();
60
+ }
61
+ }
62
+
63
+ setContentWidth(instance) {
64
+ // box-sizing: border-box
65
+ const content = instance.popper.querySelector('.tippy-content');
66
+ if (content) {
67
+ content.style.width = `${instance.reference.offsetWidth}px`;
68
+ }
69
+ }
70
+
71
+ handleContextMenu(event) {
72
+ event.preventDefault();
73
+ this.open();
74
+ }
75
+
76
+ open() {
77
+ this.tippy.show();
78
+ }
79
+
80
+ close() {
81
+ this.tippy.hide();
82
+ }
83
+
84
+ handleKeydown(e) {
85
+ // return if no menu items (one line fix for)
86
+ if (this.menuItemTargets.length === 0) { return; }
87
+
88
+ if (e.key === 'ArrowDown') {
89
+ e.preventDefault();
90
+ this.updateSelectedItem(1);
91
+ } else if (e.key === 'ArrowUp') {
92
+ e.preventDefault();
93
+ this.updateSelectedItem(-1);
94
+ } else if (e.key === 'Enter' && this.selectedIndex !== -1) {
95
+ e.preventDefault();
96
+ this.menuItemTargets[this.selectedIndex].click();
97
+ }
98
+ }
99
+
100
+ updateSelectedItem(direction) {
101
+ // Check if any of the menuItemTargets have aria-selected="true" and set the selectedIndex to that index
102
+ this.menuItemTargets.forEach((item, index) => {
103
+ if (item.getAttribute('aria-selected') === 'true') {
104
+ this.selectedIndex = index;
105
+ }
106
+ });
107
+
108
+ if (this.selectedIndex >= 0) {
109
+ this.toggleAriaSelected(this.menuItemTargets[this.selectedIndex], false);
110
+ }
111
+
112
+ this.selectedIndex += direction;
113
+
114
+ if (this.selectedIndex < 0) {
115
+ this.selectedIndex = this.menuItemTargets.length - 1;
116
+ } else if (this.selectedIndex >= this.menuItemTargets.length) {
117
+ this.selectedIndex = 0;
118
+ }
119
+
120
+ this.toggleAriaSelected(this.menuItemTargets[this.selectedIndex], true);
121
+ }
122
+
123
+ toggleAriaSelected(element, isSelected) {
124
+ // Add or remove attribute
125
+ if (isSelected) {
126
+ element.setAttribute('aria-selected', 'true');
127
+ } else {
128
+ element.removeAttribute('aria-selected');
129
+ }
130
+ }
131
+
132
+ deselectAll() {
133
+ this.menuItemTargets.forEach(item => this.toggleAriaSelected(item, false));
134
+ this.selectedIndex = -1;
135
+ }
136
+
137
+ addEventListeners() {
138
+ document.addEventListener('keydown', this.boundHandleKeydown);
139
+ }
140
+
141
+ removeEventListeners() {
142
+ document.removeEventListener('keydown', this.boundHandleKeydown);
143
+ }
144
+ }
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class ContextMenuItem < Base
5
5
  def initialize(href: "#", checked: false, shortcut: nil, disabled: false, **attrs)
6
6
  @href = href
@@ -56,8 +56,8 @@ module RBUI
56
56
  "relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 pl-8",
57
57
  tabindex: "-1",
58
58
  data_orientation: "vertical",
59
- data_action: "click->rbui--context-menu#close",
60
- data_rbui__context_menu_target: "menuItem",
59
+ data_action: "click->ruby-ui--context-menu#close",
60
+ data_ruby_ui__context_menu_target: "menuItem",
61
61
  data_disabled: @disabled,
62
62
  disabled: @disabled
63
63
  }
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class ContextMenuLabel < Base
5
5
  def initialize(inset: false, **attrs)
6
6
  @inset = inset
@@ -17,7 +17,7 @@ module RBUI
17
17
 
18
18
  def default_attrs
19
19
  {
20
- class: tokens("px-2 py-1.5 text-sm font-semibold text-foreground", inset?: "pl-8")
20
+ class: ["px-2 py-1.5 text-sm font-semibold text-foreground", inset?: "pl-8"]
21
21
  }
22
22
  end
23
23
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class ContextMenuSeparator < Base
5
5
  def view_template
6
6
  div(**attrs)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class ContextMenuTrigger < Base
5
5
  def view_template(&)
6
6
  div(**attrs, &)
@@ -11,8 +11,8 @@ module RBUI
11
11
  def default_attrs
12
12
  {
13
13
  data: {
14
- rbui__context_menu_target: "trigger",
15
- action: "contextmenu->rbui--context-menu#handleContextMenu"
14
+ ruby_ui__context_menu_target: "trigger",
15
+ action: "contextmenu->ruby-ui--context-menu#handleContextMenu"
16
16
  }
17
17
  }
18
18
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class Dialog < Base
5
5
  def initialize(open: false, **attrs)
6
6
  @open = open
@@ -16,8 +16,8 @@ module RBUI
16
16
  def default_attrs
17
17
  {
18
18
  data: {
19
- controller: "rbui--dialog",
20
- rbui__dialog_open_value: @open
19
+ controller: "ruby-ui--dialog",
20
+ ruby_ui__dialog_open_value: @open
21
21
  }
22
22
  }
23
23
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class DialogContent < Base
5
5
  SIZES = {
6
6
  xs: "max-w-sm",
@@ -17,8 +17,8 @@ module RBUI
17
17
  end
18
18
 
19
19
  def view_template
20
- template_tag(data: {rbui__dialog_target: "content"}) do
21
- div(data_controller: "rbui--dialog") do
20
+ template(data: {ruby_ui__dialog_target: "content"}) do
21
+ div(data_controller: "ruby-ui--dialog") do
22
22
  backdrop
23
23
  div(**attrs) do
24
24
  yield
@@ -33,18 +33,18 @@ module RBUI
33
33
  def default_attrs
34
34
  {
35
35
  data_state: "open",
36
- class: tokens(
37
- "fixed pointer-events-auto left-[50%] top-[50%] z-50 grid w-full translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full",
36
+ class: [
37
+ "fixed flex flex-col pointer-events-auto left-[50%] top-[50%] z-50 w-full max-h-screen overflow-y-auto translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full",
38
38
  SIZES[@size]
39
- )
39
+ ]
40
40
  }
41
41
  end
42
42
 
43
43
  def close_button
44
44
  button(
45
45
  type: "button",
46
- class: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",
47
- data_action: "click->rbui--dialog#dismiss"
46
+ class: "absolute end-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",
47
+ data_action: "click->ruby-ui--dialog#dismiss"
48
48
  ) do
49
49
  svg(
50
50
  width: "15",
@@ -69,7 +69,7 @@ module RBUI
69
69
  def backdrop
70
70
  div(
71
71
  data_state: "open",
72
- data_action: "click->rbui--dialog#dismiss esc->rbui--dialog#dismiss",
72
+ data_action: "click->ruby-ui--dialog#dismiss esc->ruby-ui--dialog#dismiss",
73
73
  class:
74
74
  "fixed pointer-events-auto inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
75
75
  )
@@ -0,0 +1,32 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ // Connects to data-controller="dialog"
4
+ export default class extends Controller {
5
+ static targets = ["content"]
6
+ static values = {
7
+ open: {
8
+ type: Boolean,
9
+ default: false
10
+ },
11
+ }
12
+
13
+ connect() {
14
+ if (this.openValue) {
15
+ this.open()
16
+ }
17
+ }
18
+
19
+ open(e) {
20
+ e.preventDefault()
21
+ document.body.insertAdjacentHTML('beforeend', this.contentTarget.innerHTML)
22
+ // prevent scroll on body
23
+ document.body.classList.add('overflow-hidden')
24
+ }
25
+
26
+ dismiss() {
27
+ // allow scroll on body
28
+ document.body.classList.remove('overflow-hidden')
29
+ // remove the element
30
+ this.element.remove()
31
+ }
32
+ }
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class DialogDescription < Base
5
5
  def view_template(&)
6
6
  p(**attrs, &)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class DialogFooter < Base
5
5
  def view_template(&)
6
6
  div(**attrs, &)
@@ -10,7 +10,7 @@ module RBUI
10
10
 
11
11
  def default_attrs
12
12
  {
13
- class: "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 gap-y-2 sm:gap-y-0"
13
+ class: "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 gap-y-2 sm:gap-y-0 rtl:space-x-reverse"
14
14
  }
15
15
  end
16
16
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class DialogHeader < Base
5
5
  def view_template(&)
6
6
  div(**attrs, &)
@@ -10,7 +10,7 @@ module RBUI
10
10
 
11
11
  def default_attrs
12
12
  {
13
- class: "flex flex-col space-y-1.5 text-center sm:text-left"
13
+ class: "flex flex-col space-y-1.5 text-center sm:text-left rtl:sm:text-right"
14
14
  }
15
15
  end
16
16
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class DialogMiddle < Base
5
5
  def view_template(&)
6
6
  div(**attrs, &)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class DialogTitle < Base
5
5
  def view_template(&)
6
6
  h3(**attrs, &)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class DialogTrigger < Base
5
5
  def view_template(&)
6
6
  div(**attrs, &)
@@ -11,7 +11,7 @@ module RBUI
11
11
  def default_attrs
12
12
  {
13
13
  data: {
14
- action: "click->rbui--dialog#open"
14
+ action: "click->ruby-ui--dialog#open"
15
15
  },
16
16
  class: "inline-block"
17
17
  }
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class DropdownMenu < Base
5
5
  def initialize(options: {}, **attrs)
6
6
  @options = options
@@ -16,9 +16,9 @@ module RBUI
16
16
  def default_attrs
17
17
  {
18
18
  data: {
19
- controller: "rbui--dropdown-menu",
20
- action: "click@window->rbui--dropdown-menu#onClickOutside",
21
- rbui__dropdown_menu_options_value: @options.to_json
19
+ controller: "ruby-ui--dropdown-menu",
20
+ action: "click@window->ruby-ui--dropdown-menu#onClickOutside",
21
+ ruby_ui__dropdown_menu_options_value: @options.to_json
22
22
  }
23
23
  }
24
24
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module RBUI
3
+ module RubyUI
4
4
  class DropdownMenuContent < Base
5
5
  def view_template(&block)
6
- div(data: {rbui__dropdown_menu_target: "content"}, class: "hidden", style: "width: max-content; position: absolute; top: 0; left: 0;") do
6
+ div(data: {ruby_ui__dropdown_menu_target: "content"}, class: "hidden", style: "width: max-content; position: absolute; top: 0; left: 0;") do
7
7
  div(**attrs, &block)
8
8
  end
9
9
  end