ruby_ui 1.0.0.pre.alpha.4

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 (166) hide show
  1. checksums.yaml +7 -0
  2. data/lib/generators/rbui/base_generator.rb +17 -0
  3. data/lib/generators/rbui/component_generator.rb +137 -0
  4. data/lib/generators/rbui/install/install_generator.rb +194 -0
  5. data/lib/rbui/accordion/accordion.rb +17 -0
  6. data/lib/rbui/accordion/accordion_content.rb +21 -0
  7. data/lib/rbui/accordion/accordion_default_content.rb +17 -0
  8. data/lib/rbui/accordion/accordion_default_trigger.rb +19 -0
  9. data/lib/rbui/accordion/accordion_icon.rb +38 -0
  10. data/lib/rbui/accordion/accordion_item.rb +28 -0
  11. data/lib/rbui/accordion/accordion_trigger.rb +16 -0
  12. data/lib/rbui/alert/alert.rb +36 -0
  13. data/lib/rbui/alert/alert_description.rb +17 -0
  14. data/lib/rbui/alert/alert_title.rb +17 -0
  15. data/lib/rbui/alert_dialog/alert_dialog.rb +26 -0
  16. data/lib/rbui/alert_dialog/alert_dialog_action.rb +17 -0
  17. data/lib/rbui/alert_dialog/alert_dialog_cancel.rb +21 -0
  18. data/lib/rbui/alert_dialog/alert_dialog_content.rb +45 -0
  19. data/lib/rbui/alert_dialog/alert_dialog_description.rb +17 -0
  20. data/lib/rbui/alert_dialog/alert_dialog_footer.rb +17 -0
  21. data/lib/rbui/alert_dialog/alert_dialog_header.rb +17 -0
  22. data/lib/rbui/alert_dialog/alert_dialog_title.rb +17 -0
  23. data/lib/rbui/alert_dialog/alert_dialog_trigger.rb +18 -0
  24. data/lib/rbui/aspect_ratio/aspect_ratio.rb +33 -0
  25. data/lib/rbui/avatar/avatar.rb +31 -0
  26. data/lib/rbui/avatar/avatar_fallback.rb +17 -0
  27. data/lib/rbui/avatar/avatar_image.rb +26 -0
  28. data/lib/rbui/badge/badge.rb +60 -0
  29. data/lib/rbui/base.rb +29 -0
  30. data/lib/rbui/button/button.rb +97 -0
  31. data/lib/rbui/calendar/calendar.rb +39 -0
  32. data/lib/rbui/calendar/calendar_body.rb +19 -0
  33. data/lib/rbui/calendar/calendar_days.rb +104 -0
  34. data/lib/rbui/calendar/calendar_header.rb +17 -0
  35. data/lib/rbui/calendar/calendar_next.rb +43 -0
  36. data/lib/rbui/calendar/calendar_prev.rb +43 -0
  37. data/lib/rbui/calendar/calendar_title.rb +27 -0
  38. data/lib/rbui/calendar/calendar_weekdays.rb +33 -0
  39. data/lib/rbui/card/card.rb +17 -0
  40. data/lib/rbui/card/card_content.rb +17 -0
  41. data/lib/rbui/card/card_description.rb +17 -0
  42. data/lib/rbui/card/card_footer.rb +17 -0
  43. data/lib/rbui/card/card_header.rb +17 -0
  44. data/lib/rbui/card/card_title.rb +17 -0
  45. data/lib/rbui/chart/chart.rb +23 -0
  46. data/lib/rbui/checkbox/checkbox.rb +23 -0
  47. data/lib/rbui/checkbox/checkbox_group.rb +20 -0
  48. data/lib/rbui/clipboard/clipboard.rb +42 -0
  49. data/lib/rbui/clipboard/clipboard_popover.rb +40 -0
  50. data/lib/rbui/clipboard/clipboard_source.rb +19 -0
  51. data/lib/rbui/clipboard/clipboard_trigger.rb +20 -0
  52. data/lib/rbui/codeblock/codeblock.rb +105 -0
  53. data/lib/rbui/collapsible/collapsible.rb +25 -0
  54. data/lib/rbui/collapsible/collapsible_content.rb +18 -0
  55. data/lib/rbui/collapsible/collapsible_trigger.rb +19 -0
  56. data/lib/rbui/combobox/combobox.rb +24 -0
  57. data/lib/rbui/combobox/combobox_content.rb +31 -0
  58. data/lib/rbui/combobox/combobox_empty.rb +21 -0
  59. data/lib/rbui/combobox/combobox_group.rb +38 -0
  60. data/lib/rbui/combobox/combobox_input.rb +22 -0
  61. data/lib/rbui/combobox/combobox_item.rb +53 -0
  62. data/lib/rbui/combobox/combobox_list.rb +29 -0
  63. data/lib/rbui/combobox/combobox_search_input.rb +56 -0
  64. data/lib/rbui/combobox/combobox_separator.rb +15 -0
  65. data/lib/rbui/combobox/combobox_trigger.rb +52 -0
  66. data/lib/rbui/combobox/combobox_value.rb +27 -0
  67. data/lib/rbui/command/command.rb +9 -0
  68. data/lib/rbui/command/command_dialog.rb +17 -0
  69. data/lib/rbui/command/command_dialog_content.rb +48 -0
  70. data/lib/rbui/command/command_dialog_trigger.rb +29 -0
  71. data/lib/rbui/command/command_empty.rb +19 -0
  72. data/lib/rbui/command/command_group.rb +40 -0
  73. data/lib/rbui/command/command_input.rb +56 -0
  74. data/lib/rbui/command/command_item.rb +32 -0
  75. data/lib/rbui/command/command_list.rb +17 -0
  76. data/lib/rbui/context_menu/context_menu.rb +26 -0
  77. data/lib/rbui/context_menu/context_menu_content.rb +25 -0
  78. data/lib/rbui/context_menu/context_menu_item.rb +66 -0
  79. data/lib/rbui/context_menu/context_menu_label.rb +24 -0
  80. data/lib/rbui/context_menu/context_menu_separator.rb +19 -0
  81. data/lib/rbui/context_menu/context_menu_trigger.rb +20 -0
  82. data/lib/rbui/dialog/dialog.rb +25 -0
  83. data/lib/rbui/dialog/dialog_content.rb +78 -0
  84. data/lib/rbui/dialog/dialog_description.rb +17 -0
  85. data/lib/rbui/dialog/dialog_footer.rb +17 -0
  86. data/lib/rbui/dialog/dialog_header.rb +17 -0
  87. data/lib/rbui/dialog/dialog_middle.rb +17 -0
  88. data/lib/rbui/dialog/dialog_title.rb +17 -0
  89. data/lib/rbui/dialog/dialog_trigger.rb +20 -0
  90. data/lib/rbui/dropdown_menu/dropdown_menu.rb +26 -0
  91. data/lib/rbui/dropdown_menu/dropdown_menu_content.rb +22 -0
  92. data/lib/rbui/dropdown_menu/dropdown_menu_item.rb +28 -0
  93. data/lib/rbui/dropdown_menu/dropdown_menu_label.rb +17 -0
  94. data/lib/rbui/dropdown_menu/dropdown_menu_separator.rb +19 -0
  95. data/lib/rbui/dropdown_menu/dropdown_menu_trigger.rb +18 -0
  96. data/lib/rbui/form/form.rb +15 -0
  97. data/lib/rbui/form/form_field.rb +20 -0
  98. data/lib/rbui/form/form_field_error.rb +20 -0
  99. data/lib/rbui/form/form_field_hint.rb +15 -0
  100. data/lib/rbui/form/form_field_label.rb +15 -0
  101. data/lib/rbui/hover_card/hover_card.rb +27 -0
  102. data/lib/rbui/hover_card/hover_card_content.rb +22 -0
  103. data/lib/rbui/hover_card/hover_card_trigger.rb +20 -0
  104. data/lib/rbui/input/input.rb +26 -0
  105. data/lib/rbui/link/link.rb +97 -0
  106. data/lib/rbui/pagination/pagination.rb +19 -0
  107. data/lib/rbui/pagination/pagination_content.rb +17 -0
  108. data/lib/rbui/pagination/pagination_ellipsis.rb +42 -0
  109. data/lib/rbui/pagination/pagination_item.rb +28 -0
  110. data/lib/rbui/popover/popover.rb +26 -0
  111. data/lib/rbui/popover/popover_content.rb +27 -0
  112. data/lib/rbui/popover/popover_trigger.rb +20 -0
  113. data/lib/rbui/radio_button/radio_button.rb +22 -0
  114. data/lib/rbui/railtie.rb +52 -0
  115. data/lib/rbui/select/select.rb +23 -0
  116. data/lib/rbui/select/select_content.rb +32 -0
  117. data/lib/rbui/select/select_group.rb +15 -0
  118. data/lib/rbui/select/select_input.rb +22 -0
  119. data/lib/rbui/select/select_item.rb +52 -0
  120. data/lib/rbui/select/select_label.rb +17 -0
  121. data/lib/rbui/select/select_trigger.rb +54 -0
  122. data/lib/rbui/select/select_value.rb +27 -0
  123. data/lib/rbui/sheet/sheet.rb +17 -0
  124. data/lib/rbui/sheet/sheet_content.rb +77 -0
  125. data/lib/rbui/sheet/sheet_description.rb +17 -0
  126. data/lib/rbui/sheet/sheet_footer.rb +17 -0
  127. data/lib/rbui/sheet/sheet_header.rb +17 -0
  128. data/lib/rbui/sheet/sheet_middle.rb +17 -0
  129. data/lib/rbui/sheet/sheet_title.rb +17 -0
  130. data/lib/rbui/sheet/sheet_trigger.rb +17 -0
  131. data/lib/rbui/shortcut_key/shortcut_key.rb +17 -0
  132. data/lib/rbui/table/table.rb +19 -0
  133. data/lib/rbui/table/table_body.rb +17 -0
  134. data/lib/rbui/table/table_caption.rb +17 -0
  135. data/lib/rbui/table/table_cell.rb +17 -0
  136. data/lib/rbui/table/table_footer.rb +17 -0
  137. data/lib/rbui/table/table_head.rb +17 -0
  138. data/lib/rbui/table/table_header.rb +17 -0
  139. data/lib/rbui/table/table_row.rb +17 -0
  140. data/lib/rbui/tabs/tabs.rb +25 -0
  141. data/lib/rbui/tabs/tabs_content.rb +26 -0
  142. data/lib/rbui/tabs/tabs_list.rb +17 -0
  143. data/lib/rbui/tabs/tabs_trigger.rb +28 -0
  144. data/lib/rbui/textarea/textarea.rb +26 -0
  145. data/lib/rbui/theme_toggle/theme_toggle.rb +41 -0
  146. data/lib/rbui/tooltip/tooltip.rb +26 -0
  147. data/lib/rbui/tooltip/tooltip_content.rb +26 -0
  148. data/lib/rbui/tooltip/tooltip_trigger.rb +19 -0
  149. data/lib/rbui/typography/typography_blockquote.rb +17 -0
  150. data/lib/rbui/typography/typography_h1.rb +17 -0
  151. data/lib/rbui/typography/typography_h2.rb +17 -0
  152. data/lib/rbui/typography/typography_h3.rb +17 -0
  153. data/lib/rbui/typography/typography_h4.rb +17 -0
  154. data/lib/rbui/typography/typography_inline_code.rb +17 -0
  155. data/lib/rbui/typography/typography_inline_link.rb +22 -0
  156. data/lib/rbui/typography/typography_large.rb +17 -0
  157. data/lib/rbui/typography/typography_lead.rb +17 -0
  158. data/lib/rbui/typography/typography_list.rb +47 -0
  159. data/lib/rbui/typography/typography_list_item.rb +17 -0
  160. data/lib/rbui/typography/typography_muted.rb +17 -0
  161. data/lib/rbui/typography/typography_p.rb +17 -0
  162. data/lib/rbui/typography/typography_small.rb +17 -0
  163. data/lib/rbui/version.rb +5 -0
  164. data/lib/rbui.rb +57 -0
  165. data/lib/ruby_ui.rb +1 -0
  166. metadata +291 -0
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CalendarPrev < Base
5
+ def view_template(&block)
6
+ button(**attrs) do
7
+ icon
8
+ end
9
+ end
10
+
11
+ private
12
+
13
+ def icon
14
+ svg(
15
+ width: "15",
16
+ height: "15",
17
+ viewbox: "0 0 15 15",
18
+ fill: "none",
19
+ xmlns: "http://www.w3.org/2000/svg",
20
+ class: "h-4 w-4"
21
+ ) do |s|
22
+ s.path(
23
+ d:
24
+ "M8.84182 3.13514C9.04327 3.32401 9.05348 3.64042 8.86462 3.84188L5.43521 7.49991L8.86462 11.1579C9.05348 11.3594 9.04327 11.6758 8.84182 11.8647C8.64036 12.0535 8.32394 12.0433 8.13508 11.8419L4.38508 7.84188C4.20477 7.64955 4.20477 7.35027 4.38508 7.15794L8.13508 3.15794C8.32394 2.95648 8.64036 2.94628 8.84182 3.13514Z",
25
+ fill: "currentColor",
26
+ fill_rule: "evenodd",
27
+ clip_rule: "evenodd"
28
+ )
29
+ end
30
+ end
31
+
32
+ def default_attrs
33
+ {
34
+ name: "previous-month",
35
+ aria_label: "Go to previous month",
36
+ class:
37
+ "rdp-button_reset rdp-button inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 border border-input hover:bg-accent hover:text-accent-foreground h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute left-1",
38
+ type: "button",
39
+ data_action: "click->rbui--calendar#prevMonth"
40
+ }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CalendarTitle < Base
5
+ def initialize(default: "Month Year", **attrs)
6
+ @default = default
7
+ super(**attrs)
8
+ end
9
+
10
+ def view_template
11
+ div(**attrs) { @default }
12
+ end
13
+
14
+ private
15
+
16
+ def default_attrs
17
+ {
18
+ class: "text-sm font-medium",
19
+ aria_live: "polite",
20
+ role: "presentation",
21
+ data: {
22
+ rbui__calendar_target: "title"
23
+ }
24
+ }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CalendarWeekdays < Base
5
+ DAYS = %w[Monday Tuesday Wednesday Thursday Friday Saturday Sunday].freeze
6
+
7
+ def view_template
8
+ template_tag(data: {rbui__calendar_target: "weekdaysTemplate"}) do
9
+ thead(**attrs) do
10
+ tr(class: "flex") do
11
+ DAYS.each do |day|
12
+ render_day(day)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def render_day(day)
22
+ th(
23
+ scope: "col",
24
+ class: "text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]",
25
+ aria_label: day
26
+ ) { day[0..1] }
27
+ end
28
+
29
+ def default_attrs
30
+ {}
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class Card < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "rounded-xl border bg-background shadow"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CardContent < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "p-6 pt-0"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CardDescription < Base
5
+ def view_template(&)
6
+ p(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "text-sm text-muted-foreground"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CardFooter < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "items-center p-6 pt-0"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CardHeader < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "flex flex-col space-y-1.5 p-6"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CardTitle < Base
5
+ def view_template(&)
6
+ h3(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "font-semibold leading-none tracking-tight"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class Chart < Base
5
+ def initialize(options: {}, **attrs)
6
+ @options = options.to_json
7
+ super(**attrs)
8
+ end
9
+
10
+ def view_template(&)
11
+ canvas(**attrs, &)
12
+ end
13
+
14
+ private
15
+
16
+ def default_attrs
17
+ {
18
+ data_controller: "rbui--chart",
19
+ data_rbui__chart_options_value: @options
20
+ }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class Checkbox < Base
5
+ def view_template
6
+ input(**attrs)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ type: "checkbox",
14
+ data: {
15
+ rbui__form_field_target: "input",
16
+ rbui__checkbox_group_target: "checkbox",
17
+ action: "input->rbui--form-field#onInput invalid->rbui--form-field#onInvalid change->rbui--checkbox-group#onChange"
18
+ },
19
+ class: "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 accent-primary"
20
+ }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CheckboxGroup < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ role: "group",
14
+ data: {
15
+ controller: "rbui--checkbox-group"
16
+ }
17
+ }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class Clipboard < Base
5
+ def initialize(options: {}, success: "Copied!", error: "Copy Failed!", **attrs)
6
+ @options = options
7
+ @success = success
8
+ @error = error
9
+ super(**attrs)
10
+ end
11
+
12
+ def view_template(&block)
13
+ div(**attrs) do
14
+ div(&block)
15
+ success_popover
16
+ error_popover
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def success_popover
23
+ ClipboardPopover(type: :success) { @success }
24
+ end
25
+
26
+ def error_popover
27
+ ClipboardPopover(type: :error) { @error }
28
+ end
29
+
30
+ def default_attrs
31
+ {
32
+ data: {
33
+ controller: "rbui--clipboard",
34
+ action: "click@window->rbui--clipboard#onClickOutside",
35
+ rbui__clipboard_success_value: @success,
36
+ rbui__clipboard_error_value: @error,
37
+ rbui__clipboard_options_value: @options.to_json
38
+ }
39
+ }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class ClipboardPopover < Base
5
+ def initialize(type:, **attrs)
6
+ @type = type
7
+ super(**attrs)
8
+ end
9
+
10
+ def view_template(&block)
11
+ div(
12
+ class: "hidden",
13
+ style: "width: max-content; position: absolute; top: 0; left: 0;",
14
+ data: {rbui__clipboard_target: clipboard_target}
15
+ ) do
16
+ div(**attrs, &block)
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def clipboard_target
23
+ case @type
24
+ when :success
25
+ "successPopover"
26
+ when :error
27
+ "errorPopover"
28
+ end
29
+ end
30
+
31
+ def default_attrs
32
+ {
33
+ data: {
34
+ state: :open
35
+ },
36
+ class: "z-50 rounded-md text-sm border bg-background px-2 py-0.5 text-foreground shadow-md outline-none 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-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
37
+ }
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class ClipboardSource < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {
14
+ rbui__clipboard_target: "source"
15
+ }
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class ClipboardTrigger < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {
14
+ rbui__clipboard_target: "trigger",
15
+ action: "click->rbui--clipboard#copy"
16
+ }
17
+ }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rouge"
4
+
5
+ module RBUI
6
+ class Codeblock < Base
7
+ FORMATTER = ::Rouge::Formatters::HTML.new
8
+ ROUGE_CSS = Rouge::Themes::Github.mode(:dark).render(scope: ".highlight") # See themes here: https://rouge-ruby.github.io/docs/Rouge/CSSTheme.html
9
+
10
+ def initialize(code, syntax:, clipboard: true, clipboard_success: "Copied!", clipboard_error: "Copy failed!", **attrs)
11
+ @code = code
12
+ @syntax = syntax.to_sym
13
+ @clipboard = clipboard
14
+ @clipboard_success = clipboard_success
15
+ @clipboard_error = clipboard_error
16
+
17
+ if @syntax == :ruby || @syntax == :html
18
+ @code = @code.gsub(/(?:^|\G) {2}/m, " ")
19
+ end
20
+
21
+ super(**attrs)
22
+ end
23
+
24
+ def view_template
25
+ style { ROUGE_CSS } # For faster load times, move this to the head of your document. (Also move ROUGE_CSS value to head of document)
26
+ if @clipboard
27
+ with_clipboard
28
+ else
29
+ codeblock
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def default_attrs
36
+ {
37
+ class: "highlight text-sm max-h-[350px] after:content-none flex font-mono overflow-auto overflow-x rounded-md border !bg-stone-900 [&_pre]:p-4"
38
+ }
39
+ end
40
+
41
+ def with_clipboard
42
+ RBUI.Clipboard(success: @clipboard_success, error: @clipboard_error, class: "relative") do
43
+ RBUI.ClipboardSource do
44
+ codeblock
45
+ end
46
+ div(class: "absolute top-2 right-2") do
47
+ RBUI.ClipboardTrigger do
48
+ RBUI.Button(variant: :ghost, size: :sm, icon: true, class: "text-white hover:text-white hover:bg-white/20") { clipboard_icon }
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def codeblock
55
+ div(**attrs) do
56
+ div(class: "after:content-none") do
57
+ pre do
58
+ unsafe_raw FORMATTER.format(
59
+ lexer.lex(@code)
60
+ )
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ def lexer
67
+ Rouge::Lexer.find(@syntax)
68
+ end
69
+
70
+ def clipboard_icon
71
+ svg(
72
+ xmlns: "http://www.w3.org/2000/svg",
73
+ fill: "none",
74
+ viewbox: "0 0 24 24",
75
+ stroke_width: "1.5",
76
+ stroke: "currentColor",
77
+ class: "w-4 h-4"
78
+ ) do |s|
79
+ s.path(
80
+ stroke_linecap: "round",
81
+ stroke_linejoin: "round",
82
+ d:
83
+ "M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"
84
+ )
85
+ end
86
+ end
87
+
88
+ def check_icon
89
+ svg(
90
+ xmlns: "http://www.w3.org/2000/svg",
91
+ fill: "none",
92
+ viewbox: "0 0 24 24",
93
+ stroke_width: "1.5",
94
+ stroke: "currentColor",
95
+ class: "w-4 h-4"
96
+ ) do |s|
97
+ s.path(
98
+ stroke_linecap: "round",
99
+ stroke_linejoin: "round",
100
+ d: "M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
101
+ )
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class Collapsible < Base
5
+ def initialize(open: false, **attrs)
6
+ @open = open
7
+ super(**attrs)
8
+ end
9
+
10
+ def view_template(&)
11
+ div(**attrs, &)
12
+ end
13
+
14
+ private
15
+
16
+ def default_attrs
17
+ {
18
+ data: {
19
+ controller: "rbui--collapsible",
20
+ rbui__collapsible_open_value: @open
21
+ }
22
+ }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CollapsibleContent < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {rbui__collapsible_target: "content"},
14
+ class: "overflow-y-hidden"
15
+ }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CollapsibleTrigger < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {
14
+ action: "click->rbui--collapsible#toggle"
15
+ }
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class Combobox < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {
14
+ controller: "rbui--combobox",
15
+ rbui__combobox_open_value: "false",
16
+ action: "click@window->rbui--combobox#onClickOutside",
17
+ rbui__combobox_rbui__combobox_content_outlet: ".combobox-content",
18
+ rbui__combobox_rbui__combobox_item_outlet: ".combobox-item"
19
+ },
20
+ class: "group/combobox w-full relative"
21
+ }
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class ComboboxContent < Base
5
+ def initialize(**attrs)
6
+ @id = "content#{SecureRandom.hex(4)}"
7
+ super
8
+ end
9
+
10
+ def view_template(&)
11
+ div(**attrs) do
12
+ div(class: "min-w-max max-h-[300px] overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md outline-none animate-out group-data-[rbui--combobox-open-value=true]/combobox:animate-in fade-out-0 group-data-[rbui--combobox-open-value=true]/combobox:fade-in-0 zoom-out-95 group-data-[rbui--combobox-open-value=true]/combobox:zoom-in-95 slide-in-from-top-2", &)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def default_attrs
19
+ {
20
+ id: @id,
21
+ role: "listbox",
22
+ data: {
23
+ controller: "rbui--combobox-content",
24
+ rbui__combobox_target: "content",
25
+ action: "keydown.enter->rbui--combobox#onKeyEnter keydown.esc->rbui--combobox#onEscKey keydown.down->rbui--combobox#onKeyDown keydown.up->rbui--combobox#onKeyUp"
26
+ },
27
+ class: "combobox-content hidden w-full absolute top-0 left-0 z-50"
28
+ }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class ComboboxEmpty < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ role: "presentation",
14
+ class: "hidden py-6 text-center text-sm",
15
+ data: {
16
+ rbui__combobox_content_target: "empty"
17
+ }
18
+ }
19
+ end
20
+ end
21
+ end