rbui 0.0.0 → 1.0.0.pre.alpha.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rbui/accordion/accordion.rb +17 -0
  3. data/lib/rbui/accordion/accordion_content.rb +21 -0
  4. data/lib/rbui/accordion/accordion_default_content.rb +17 -0
  5. data/lib/rbui/accordion/accordion_default_trigger.rb +19 -0
  6. data/lib/rbui/accordion/accordion_icon.rb +38 -0
  7. data/lib/rbui/accordion/accordion_item.rb +28 -0
  8. data/lib/rbui/accordion/accordion_trigger.rb +16 -0
  9. data/lib/rbui/alert/alert.rb +36 -0
  10. data/lib/rbui/alert/alert_description.rb +17 -0
  11. data/lib/rbui/alert/alert_title.rb +17 -0
  12. data/lib/rbui/alert_dialog/alert_dialog.rb +26 -0
  13. data/lib/rbui/alert_dialog/alert_dialog_action.rb +17 -0
  14. data/lib/rbui/alert_dialog/alert_dialog_cancel.rb +21 -0
  15. data/lib/rbui/alert_dialog/alert_dialog_content.rb +45 -0
  16. data/lib/rbui/alert_dialog/alert_dialog_description.rb +17 -0
  17. data/lib/rbui/alert_dialog/alert_dialog_footer.rb +17 -0
  18. data/lib/rbui/alert_dialog/alert_dialog_header.rb +17 -0
  19. data/lib/rbui/alert_dialog/alert_dialog_title.rb +17 -0
  20. data/lib/rbui/alert_dialog/alert_dialog_trigger.rb +18 -0
  21. data/lib/rbui/aspect_ratio/aspect_ratio.rb +33 -0
  22. data/lib/rbui/avatar/avatar.rb +31 -0
  23. data/lib/rbui/avatar/avatar_fallback.rb +17 -0
  24. data/lib/rbui/avatar/avatar_image.rb +26 -0
  25. data/lib/rbui/badge/badge.rb +60 -0
  26. data/lib/rbui/base.rb +27 -0
  27. data/lib/rbui/button/button.rb +97 -0
  28. data/lib/rbui/calendar/calendar.rb +39 -0
  29. data/lib/rbui/calendar/calendar_body.rb +19 -0
  30. data/lib/rbui/calendar/calendar_days.rb +104 -0
  31. data/lib/rbui/calendar/calendar_header.rb +17 -0
  32. data/lib/rbui/calendar/calendar_next.rb +43 -0
  33. data/lib/rbui/calendar/calendar_prev.rb +43 -0
  34. data/lib/rbui/calendar/calendar_title.rb +27 -0
  35. data/lib/rbui/calendar/calendar_weekdays.rb +33 -0
  36. data/lib/rbui/card/card.rb +17 -0
  37. data/lib/rbui/card/card_content.rb +17 -0
  38. data/lib/rbui/card/card_description.rb +17 -0
  39. data/lib/rbui/card/card_footer.rb +17 -0
  40. data/lib/rbui/card/card_header.rb +17 -0
  41. data/lib/rbui/card/card_title.rb +17 -0
  42. data/lib/rbui/chart/chart.rb +23 -0
  43. data/lib/rbui/checkbox/checkbox.rb +23 -0
  44. data/lib/rbui/checkbox/checkbox_group.rb +20 -0
  45. data/lib/rbui/clipboard/clipboard.rb +42 -0
  46. data/lib/rbui/clipboard/clipboard_popover.rb +40 -0
  47. data/lib/rbui/clipboard/clipboard_source.rb +19 -0
  48. data/lib/rbui/clipboard/clipboard_trigger.rb +20 -0
  49. data/lib/rbui/codeblock/codeblock.rb +105 -0
  50. data/lib/rbui/collapsible/collapsible.rb +25 -0
  51. data/lib/rbui/collapsible/collapsible_content.rb +18 -0
  52. data/lib/rbui/collapsible/collapsible_trigger.rb +19 -0
  53. data/lib/rbui/combobox/combobox.rb +24 -0
  54. data/lib/rbui/combobox/combobox_content.rb +31 -0
  55. data/lib/rbui/combobox/combobox_empty.rb +21 -0
  56. data/lib/rbui/combobox/combobox_group.rb +38 -0
  57. data/lib/rbui/combobox/combobox_input.rb +22 -0
  58. data/lib/rbui/combobox/combobox_item.rb +53 -0
  59. data/lib/rbui/combobox/combobox_list.rb +29 -0
  60. data/lib/rbui/combobox/combobox_search_input.rb +56 -0
  61. data/lib/rbui/combobox/combobox_separator.rb +15 -0
  62. data/lib/rbui/combobox/combobox_trigger.rb +52 -0
  63. data/lib/rbui/combobox/combobox_value.rb +27 -0
  64. data/lib/rbui/command/command.rb +9 -0
  65. data/lib/rbui/command/command_dialog.rb +17 -0
  66. data/lib/rbui/command/command_dialog_content.rb +48 -0
  67. data/lib/rbui/command/command_dialog_trigger.rb +29 -0
  68. data/lib/rbui/command/command_empty.rb +19 -0
  69. data/lib/rbui/command/command_group.rb +40 -0
  70. data/lib/rbui/command/command_input.rb +56 -0
  71. data/lib/rbui/command/command_item.rb +32 -0
  72. data/lib/rbui/command/command_list.rb +17 -0
  73. data/lib/rbui/context_menu/context_menu.rb +26 -0
  74. data/lib/rbui/context_menu/context_menu_content.rb +25 -0
  75. data/lib/rbui/context_menu/context_menu_item.rb +66 -0
  76. data/lib/rbui/context_menu/context_menu_label.rb +24 -0
  77. data/lib/rbui/context_menu/context_menu_separator.rb +19 -0
  78. data/lib/rbui/context_menu/context_menu_trigger.rb +20 -0
  79. data/lib/rbui/dialog/dialog.rb +25 -0
  80. data/lib/rbui/dialog/dialog_content.rb +78 -0
  81. data/lib/rbui/dialog/dialog_description.rb +17 -0
  82. data/lib/rbui/dialog/dialog_footer.rb +17 -0
  83. data/lib/rbui/dialog/dialog_header.rb +17 -0
  84. data/lib/rbui/dialog/dialog_middle.rb +17 -0
  85. data/lib/rbui/dialog/dialog_title.rb +17 -0
  86. data/lib/rbui/dialog/dialog_trigger.rb +20 -0
  87. data/lib/rbui/dropdown_menu/dropdown_menu.rb +26 -0
  88. data/lib/rbui/dropdown_menu/dropdown_menu_content.rb +22 -0
  89. data/lib/rbui/dropdown_menu/dropdown_menu_item.rb +28 -0
  90. data/lib/rbui/dropdown_menu/dropdown_menu_label.rb +17 -0
  91. data/lib/rbui/dropdown_menu/dropdown_menu_separator.rb +19 -0
  92. data/lib/rbui/dropdown_menu/dropdown_menu_trigger.rb +18 -0
  93. data/lib/rbui/form/form.rb +15 -0
  94. data/lib/rbui/form/form_field.rb +20 -0
  95. data/lib/rbui/form/form_field_error.rb +20 -0
  96. data/lib/rbui/form/form_field_hint.rb +15 -0
  97. data/lib/rbui/form/form_field_label.rb +15 -0
  98. data/lib/rbui/hover_card/hover_card.rb +27 -0
  99. data/lib/rbui/hover_card/hover_card_content.rb +22 -0
  100. data/lib/rbui/hover_card/hover_card_trigger.rb +20 -0
  101. data/lib/rbui/input/input.rb +26 -0
  102. data/lib/rbui/link/link.rb +97 -0
  103. data/lib/rbui/pagination/pagination.rb +19 -0
  104. data/lib/rbui/pagination/pagination_content.rb +17 -0
  105. data/lib/rbui/pagination/pagination_ellipsis.rb +42 -0
  106. data/lib/rbui/pagination/pagination_item.rb +28 -0
  107. data/lib/rbui/popover/popover.rb +25 -0
  108. data/lib/rbui/popover/popover_content.rb +22 -0
  109. data/lib/rbui/popover/popover_trigger.rb +20 -0
  110. data/lib/rbui/radio_button/radio_button.rb +22 -0
  111. data/lib/rbui/select/select.rb +23 -0
  112. data/lib/rbui/select/select_content.rb +32 -0
  113. data/lib/rbui/select/select_group.rb +15 -0
  114. data/lib/rbui/select/select_input.rb +22 -0
  115. data/lib/rbui/select/select_item.rb +52 -0
  116. data/lib/rbui/select/select_label.rb +17 -0
  117. data/lib/rbui/select/select_trigger.rb +54 -0
  118. data/lib/rbui/select/select_value.rb +27 -0
  119. data/lib/rbui/sheet/sheet.rb +17 -0
  120. data/lib/rbui/sheet/sheet_content.rb +77 -0
  121. data/lib/rbui/sheet/sheet_description.rb +17 -0
  122. data/lib/rbui/sheet/sheet_footer.rb +17 -0
  123. data/lib/rbui/sheet/sheet_header.rb +17 -0
  124. data/lib/rbui/sheet/sheet_middle.rb +17 -0
  125. data/lib/rbui/sheet/sheet_title.rb +17 -0
  126. data/lib/rbui/sheet/sheet_trigger.rb +17 -0
  127. data/lib/rbui/shortcut_key/shortcut_key.rb +17 -0
  128. data/lib/rbui/table/table.rb +19 -0
  129. data/lib/rbui/table/table_body.rb +17 -0
  130. data/lib/rbui/table/table_caption.rb +17 -0
  131. data/lib/rbui/table/table_cell.rb +17 -0
  132. data/lib/rbui/table/table_footer.rb +17 -0
  133. data/lib/rbui/table/table_head.rb +17 -0
  134. data/lib/rbui/table/table_header.rb +17 -0
  135. data/lib/rbui/table/table_row.rb +17 -0
  136. data/lib/rbui/tabs/tabs.rb +25 -0
  137. data/lib/rbui/tabs/tabs_content.rb +26 -0
  138. data/lib/rbui/tabs/tabs_list.rb +17 -0
  139. data/lib/rbui/tabs/tabs_trigger.rb +28 -0
  140. data/lib/rbui/theme_toggle/theme_toggle.rb +41 -0
  141. data/lib/rbui/tooltip/tooltip.rb +26 -0
  142. data/lib/rbui/tooltip/tooltip_content.rb +26 -0
  143. data/lib/rbui/tooltip/tooltip_trigger.rb +19 -0
  144. data/lib/rbui/typography/typography_blockquote.rb +17 -0
  145. data/lib/rbui/typography/typography_h1.rb +17 -0
  146. data/lib/rbui/typography/typography_h2.rb +17 -0
  147. data/lib/rbui/typography/typography_h3.rb +17 -0
  148. data/lib/rbui/typography/typography_h4.rb +17 -0
  149. data/lib/rbui/typography/typography_inline_code.rb +17 -0
  150. data/lib/rbui/typography/typography_inline_link.rb +22 -0
  151. data/lib/rbui/typography/typography_large.rb +17 -0
  152. data/lib/rbui/typography/typography_lead.rb +17 -0
  153. data/lib/rbui/typography/typography_list.rb +47 -0
  154. data/lib/rbui/typography/typography_list_item.rb +17 -0
  155. data/lib/rbui/typography/typography_muted.rb +17 -0
  156. data/lib/rbui/typography/typography_p.rb +17 -0
  157. data/lib/rbui/typography/typography_small.rb +17 -0
  158. data/lib/rbui/version.rb +5 -0
  159. data/lib/rbui.rb +42 -3
  160. metadata +254 -12
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CommandDialogTrigger < Base
5
+ DEFAULT_KEYBINDINGS = [
6
+ "keydown.ctrl+k@window",
7
+ "keydown.meta+k@window"
8
+ ].freeze
9
+
10
+ def initialize(keybindings: DEFAULT_KEYBINDINGS, **attrs)
11
+ @keybindings = keybindings.map { |kb| "#{kb}->rbui--command#open" }
12
+ super(**attrs)
13
+ end
14
+
15
+ def view_template(&)
16
+ div(**attrs, &)
17
+ end
18
+
19
+ private
20
+
21
+ def default_attrs
22
+ {
23
+ data: {
24
+ action: tokens("click->rbui--command#open", @keybindings.join(" "))
25
+ }
26
+ }
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CommandEmpty < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "py-6 text-center text-sm",
14
+ role: "presentation",
15
+ data: {rbui__command_target: "empty"}
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CommandGroup < Base
5
+ def initialize(title: nil, **attrs)
6
+ @title = title
7
+ super(**attrs)
8
+ end
9
+
10
+ def view_template(&block)
11
+ div(**attrs) do
12
+ render_header if @title
13
+ render_items(&block)
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def render_header
20
+ div(group_heading: @title) do
21
+ @title
22
+ end
23
+ end
24
+
25
+ def render_items(&)
26
+ div(group_items: "", role: "group", &)
27
+ end
28
+
29
+ def default_attrs
30
+ {
31
+ class: "overflow-hidden p-1 text-foreground [&_[group-heading]]:px-2 [&_[group-heading]]:py-1.5 [&_[group-heading]]:text-xs [&_[group-heading]]:font-medium [&_[group-heading]]:text-muted-foreground",
32
+ role: "presentation",
33
+ data: {
34
+ value: @title,
35
+ rbui__command_target: "group"
36
+ }
37
+ }
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CommandInput < Base
5
+ def initialize(placeholder: "Type a command or search...", **attrs)
6
+ @placeholder = placeholder
7
+ super(**attrs)
8
+ end
9
+
10
+ def view_template
11
+ input_container do
12
+ search_icon
13
+ input(**attrs)
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def search_icon
20
+ svg(
21
+ xmlns: "http://www.w3.org/2000/svg",
22
+ viewbox: "0 0 20 20",
23
+ fill: "currentColor",
24
+ class: "w-4 h-4 mr-1.5"
25
+ ) do |s|
26
+ s.path(
27
+ fill_rule: "evenodd",
28
+ d:
29
+ "M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z",
30
+ clip_rule: "evenodd"
31
+ )
32
+ end
33
+ end
34
+
35
+ def input_container(&)
36
+ div(class: "flex items-center border-b px-3", &)
37
+ end
38
+
39
+ def default_attrs
40
+ {
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
+ 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",
45
+ autocomplete: "off",
46
+ autocorrect: "off",
47
+ spellcheck: false,
48
+ autofocus: true,
49
+ aria_autocomplete: "list",
50
+ role: "combobox",
51
+ aria_expanded: true,
52
+ value: ""
53
+ }
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CommandItem < Base
5
+ def initialize(value:, text: "", href: "#", **attrs)
6
+ @value = value
7
+ @text = text
8
+ @href = href
9
+ super(**attrs)
10
+ end
11
+
12
+ def view_template(&)
13
+ a(**attrs, &)
14
+ end
15
+
16
+ private
17
+
18
+ def default_attrs
19
+ {
20
+ class: "relative flex cursor-pointer select-none items-center gap-x-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
21
+ href: @href,
22
+ role: "option",
23
+ data: {
24
+ rbui__command_target: "item",
25
+ value: @value,
26
+ text: @text
27
+ }
28
+ # aria_selected: "true", # Toggles aria-selected="true" on keydown
29
+ }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class CommandList < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "divide-y divide-border"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class ContextMenu < Base
5
+ def initialize(options: {}, **attrs)
6
+ @options = options
7
+ @options[:trigger] ||= "manual"
8
+ super(**attrs)
9
+ end
10
+
11
+ def view_template(&)
12
+ div(**attrs, &)
13
+ end
14
+
15
+ private
16
+
17
+ def default_attrs
18
+ {
19
+ data: {
20
+ controller: "rbui--context-menu",
21
+ popover_options_value: @options.to_json
22
+ }
23
+ }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBUI
4
+ class ContextMenuContent < Base
5
+ def view_template(&block)
6
+ template_tag(data: {rbui__context_menu_target: "content"}) do
7
+ div(**attrs, &block)
8
+ end
9
+ end
10
+
11
+ private
12
+
13
+ def default_attrs
14
+ {
15
+ role: "menu",
16
+ aria_orientation: "vertical",
17
+ data_state: "open",
18
+ class:
19
+ "z-50 min-w-[8rem] outline-none pointer-events-auto 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",
20
+ tabindex: "-1",
21
+ data_orientation: "vertical"
22
+ }
23
+ end
24
+ end
25
+ end
@@ -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