ruby_ui 1.0.0.pre.alpha.4

Sign up to get free protection for your applications and to get access to all the features.
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,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class ContextMenuItem < Base
5
+ def initialize(href: "#", checked: false, shortcut: nil, disabled: false, **attrs)
6
+ @href = href
7
+ @checked = checked
8
+ @shortcut = shortcut
9
+ @disabled = disabled
10
+
11
+ super(**attrs)
12
+ end
13
+
14
+ def view_template(&block)
15
+ a(**attrs) do
16
+ render_checkmark if @checked
17
+ yield
18
+ render_shortcut if @shortcut
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def render_checkmark
25
+ span(class: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center") do
26
+ span(data_state: "checked") do
27
+ svg(
28
+ width: "15",
29
+ height: "15",
30
+ viewbox: "0 0 15 15",
31
+ fill: "none",
32
+ xmlns: "http://www.w3.org/2000/svg",
33
+ class: "h-4 w-4"
34
+ ) do |s|
35
+ s.path(
36
+ d:
37
+ "M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z",
38
+ fill: "currentColor",
39
+ fill_rule: "evenodd",
40
+ clip_rule: "evenodd"
41
+ )
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ def render_shortcut
48
+ span(class: "ml-auto text-xs tracking-widest text-muted-foreground") { @shortcut }
49
+ end
50
+
51
+ def default_attrs
52
+ {
53
+ href: @href,
54
+ role: "menuitem",
55
+ class:
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
+ tabindex: "-1",
58
+ data_orientation: "vertical",
59
+ data_action: "click->rbui--context-menu#close",
60
+ data_rbui__context_menu_target: "menuItem",
61
+ data_disabled: @disabled,
62
+ disabled: @disabled
63
+ }
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class ContextMenuLabel < Base
5
+ def initialize(inset: false, **attrs)
6
+ @inset = inset
7
+ super(**attrs)
8
+ end
9
+
10
+ def view_template(&)
11
+ div(**attrs, &)
12
+ end
13
+
14
+ private
15
+
16
+ def inset? = @inset
17
+
18
+ def default_attrs
19
+ {
20
+ class: tokens("px-2 py-1.5 text-sm font-semibold text-foreground", inset?: "pl-8")
21
+ }
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class ContextMenuSeparator < Base
5
+ def view_template
6
+ div(**attrs)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ role: "separator",
14
+ aria_orientation: "horizontal",
15
+ class: "-mx-1 my-1 h-px bg-border"
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class ContextMenuTrigger < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {
14
+ rbui__context_menu_target: "trigger",
15
+ action: "contextmenu->rbui--context-menu#handleContextMenu"
16
+ }
17
+ }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class Dialog < 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--dialog",
20
+ rbui__dialog_open_value: @open
21
+ }
22
+ }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class DialogContent < Base
5
+ SIZES = {
6
+ xs: "max-w-sm",
7
+ sm: "max-w-md",
8
+ md: "max-w-lg",
9
+ lg: "max-w-2xl",
10
+ xl: "max-w-4xl",
11
+ full: "max-w-full"
12
+ }
13
+
14
+ def initialize(size: :md, **attrs)
15
+ @size = size
16
+ super(**attrs)
17
+ end
18
+
19
+ def view_template
20
+ template_tag(data: {rbui__dialog_target: "content"}) do
21
+ div(data_controller: "rbui--dialog") do
22
+ backdrop
23
+ div(**attrs) do
24
+ yield
25
+ close_button
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def default_attrs
34
+ {
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",
38
+ SIZES[@size]
39
+ )
40
+ }
41
+ end
42
+
43
+ def close_button
44
+ button(
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"
48
+ ) do
49
+ svg(
50
+ width: "15",
51
+ height: "15",
52
+ viewbox: "0 0 15 15",
53
+ fill: "none",
54
+ xmlns: "http://www.w3.org/2000/svg",
55
+ class: "h-4 w-4"
56
+ ) do |s|
57
+ s.path(
58
+ d:
59
+ "M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z",
60
+ fill: "currentColor",
61
+ fill_rule: "evenodd",
62
+ clip_rule: "evenodd"
63
+ )
64
+ end
65
+ span(class: "sr-only") { "Close" }
66
+ end
67
+ end
68
+
69
+ def backdrop
70
+ div(
71
+ data_state: "open",
72
+ data_action: "click->rbui--dialog#dismiss esc->rbui--dialog#dismiss",
73
+ class:
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
+ )
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class DialogDescription < 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 DialogFooter < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 gap-y-2 sm:gap-y-0"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class DialogHeader < 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 text-center sm:text-left"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class DialogMiddle < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "py-4"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class DialogTitle < Base
5
+ def view_template(&)
6
+ h3(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "text-lg font-semibold leading-none tracking-tight"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class DialogTrigger < 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--dialog#open"
15
+ },
16
+ class: "inline-block"
17
+ }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class DropdownMenu < Base
5
+ def initialize(options: {}, **attrs)
6
+ @options = options
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--dropdown-menu",
20
+ action: "click@window->rbui--dropdown-menu#onClickOutside",
21
+ rbui__dropdown_menu_options_value: @options.to_json
22
+ }
23
+ }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class DropdownMenuContent < Base
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
7
+ div(**attrs, &block)
8
+ end
9
+ end
10
+
11
+ private
12
+
13
+ def default_attrs
14
+ {
15
+ data: {
16
+ state: :open
17
+ },
18
+ class: "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-background p-1 text-foreground shadow-md 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 w-56"
19
+ }
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class DropdownMenuItem < Base
5
+ def initialize(href: "#", **attrs)
6
+ @href = href
7
+ super(**attrs)
8
+ end
9
+
10
+ def view_template(&)
11
+ a(**attrs, &)
12
+ end
13
+
14
+ private
15
+
16
+ def default_attrs
17
+ {
18
+ href: @href,
19
+ role: "menuitem",
20
+ class: "relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors 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",
21
+ data_action: "click->rbui--dropdown-menu#close",
22
+ data_rbui__dropdown_menu_target: "menuItem",
23
+ tabindex: "-1",
24
+ data_orientation: "vertical"
25
+ }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class DropdownMenuLabel < Base
5
+ def view_template(&)
6
+ h3(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "px-2 py-1.5 text-sm font-semibold"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class DropdownMenuSeparator < Base
5
+ def view_template
6
+ div(**attrs)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ role: "separator",
14
+ aria_orientation: "horizontal",
15
+ class: "-mx-1 my-1 h-px bg-muted"
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class DropdownMenuTrigger < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {rbui__dropdown_menu_target: "trigger", action: "click->rbui--dropdown-menu#toggle"},
14
+ class: "inline-block"
15
+ }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class Form < Base
5
+ def view_template(&)
6
+ form(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {}
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class FormField < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {
14
+ controller: "rbui--form-field"
15
+ },
16
+ class: "space-y-2"
17
+ }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class FormFieldError < Base
5
+ def view_template(&)
6
+ p(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {
14
+ rbui__form_field_target: "error"
15
+ },
16
+ class: "text-sm font-medium text-destructive"
17
+ }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class FormFieldHint < Base
5
+ def view_template(&)
6
+ p(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {class: "text-sm text-muted-foreground"}
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class FormFieldLabel < Base
5
+ def view_template(&)
6
+ label(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {class: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"}
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class HoverCard < Base
5
+ def initialize(option: {}, **attrs)
6
+ @options = option
7
+ @options[:delay] ||= [500, 250]
8
+ @options[:trigger] ||= "mouseenter focus click"
9
+ super(**attrs)
10
+ end
11
+
12
+ def view_template(&)
13
+ div(**attrs, &)
14
+ end
15
+
16
+ private
17
+
18
+ def default_attrs
19
+ {
20
+ data: {
21
+ controller: "rbui--hover-card",
22
+ rbui__hover_card_options_value: @options.to_json
23
+ }
24
+ }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class HoverCardContent < Base
5
+ def view_template(&block)
6
+ template_tag(data: {rbui__hover_card_target: "content"}) do
7
+ div(**attrs, &block)
8
+ end
9
+ end
10
+
11
+ private
12
+
13
+ def default_attrs
14
+ {
15
+ data: {
16
+ state: :open
17
+ },
18
+ class: "z-50 rounded-md border bg-background p-4 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"
19
+ }
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class HoverCardTrigger < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {
14
+ rbui__hover_card_target: "trigger"
15
+ },
16
+ class: "inline-block"
17
+ }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class Input < Base
5
+ def initialize(type: :string, **attrs)
6
+ @type = type.to_sym
7
+ super(**attrs)
8
+ end
9
+
10
+ def view_template
11
+ input(type: @type, **attrs)
12
+ end
13
+
14
+ private
15
+
16
+ def default_attrs
17
+ {
18
+ data: {
19
+ rbui__form_field_target: "input",
20
+ action: "input->rbui--form-field#onInput invalid->rbui--form-field#onInvalid"
21
+ },
22
+ class: "flex h-9 w-full rounded-md border bg-background px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50 border-border focus-visible:ring-ring placeholder:text-muted-foreground"
23
+ }
24
+ end
25
+ end
26
+ end