ruby_ui 1.0.0.beta1

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 (155) hide show
  1. checksums.yaml +7 -0
  2. data/lib/generators/ruby_ui/component_generator.rb +130 -0
  3. data/lib/generators/ruby_ui/install/install_generator.rb +90 -0
  4. data/lib/generators/ruby_ui/javascript_utils.rb +36 -0
  5. data/lib/ruby_ui/accordion/accordion.rb +17 -0
  6. data/lib/ruby_ui/accordion/accordion_content.rb +21 -0
  7. data/lib/ruby_ui/accordion/accordion_default_content.rb +17 -0
  8. data/lib/ruby_ui/accordion/accordion_default_trigger.rb +19 -0
  9. data/lib/ruby_ui/accordion/accordion_icon.rb +38 -0
  10. data/lib/ruby_ui/accordion/accordion_item.rb +28 -0
  11. data/lib/ruby_ui/accordion/accordion_trigger.rb +17 -0
  12. data/lib/ruby_ui/alert/alert.rb +36 -0
  13. data/lib/ruby_ui/alert/alert_description.rb +17 -0
  14. data/lib/ruby_ui/alert/alert_title.rb +17 -0
  15. data/lib/ruby_ui/alert_dialog/alert_dialog.rb +26 -0
  16. data/lib/ruby_ui/alert_dialog/alert_dialog_action.rb +17 -0
  17. data/lib/ruby_ui/alert_dialog/alert_dialog_cancel.rb +21 -0
  18. data/lib/ruby_ui/alert_dialog/alert_dialog_content.rb +45 -0
  19. data/lib/ruby_ui/alert_dialog/alert_dialog_description.rb +17 -0
  20. data/lib/ruby_ui/alert_dialog/alert_dialog_footer.rb +17 -0
  21. data/lib/ruby_ui/alert_dialog/alert_dialog_header.rb +17 -0
  22. data/lib/ruby_ui/alert_dialog/alert_dialog_title.rb +17 -0
  23. data/lib/ruby_ui/alert_dialog/alert_dialog_trigger.rb +18 -0
  24. data/lib/ruby_ui/aspect_ratio/aspect_ratio.rb +33 -0
  25. data/lib/ruby_ui/avatar/avatar.rb +31 -0
  26. data/lib/ruby_ui/avatar/avatar_fallback.rb +17 -0
  27. data/lib/ruby_ui/avatar/avatar_image.rb +26 -0
  28. data/lib/ruby_ui/badge/badge.rb +60 -0
  29. data/lib/ruby_ui/base.rb +22 -0
  30. data/lib/ruby_ui/button/button.rb +97 -0
  31. data/lib/ruby_ui/calendar/calendar.rb +39 -0
  32. data/lib/ruby_ui/calendar/calendar_body.rb +19 -0
  33. data/lib/ruby_ui/calendar/calendar_days.rb +104 -0
  34. data/lib/ruby_ui/calendar/calendar_header.rb +17 -0
  35. data/lib/ruby_ui/calendar/calendar_next.rb +43 -0
  36. data/lib/ruby_ui/calendar/calendar_prev.rb +43 -0
  37. data/lib/ruby_ui/calendar/calendar_title.rb +27 -0
  38. data/lib/ruby_ui/calendar/calendar_weekdays.rb +33 -0
  39. data/lib/ruby_ui/card/card.rb +17 -0
  40. data/lib/ruby_ui/card/card_content.rb +17 -0
  41. data/lib/ruby_ui/card/card_description.rb +17 -0
  42. data/lib/ruby_ui/card/card_footer.rb +17 -0
  43. data/lib/ruby_ui/card/card_header.rb +17 -0
  44. data/lib/ruby_ui/card/card_title.rb +17 -0
  45. data/lib/ruby_ui/chart/chart.rb +23 -0
  46. data/lib/ruby_ui/checkbox/checkbox.rb +23 -0
  47. data/lib/ruby_ui/checkbox/checkbox_group.rb +20 -0
  48. data/lib/ruby_ui/clipboard/clipboard.rb +42 -0
  49. data/lib/ruby_ui/clipboard/clipboard_popover.rb +40 -0
  50. data/lib/ruby_ui/clipboard/clipboard_source.rb +19 -0
  51. data/lib/ruby_ui/clipboard/clipboard_trigger.rb +20 -0
  52. data/lib/ruby_ui/codeblock/codeblock.rb +102 -0
  53. data/lib/ruby_ui/collapsible/collapsible.rb +25 -0
  54. data/lib/ruby_ui/collapsible/collapsible_content.rb +18 -0
  55. data/lib/ruby_ui/collapsible/collapsible_trigger.rb +19 -0
  56. data/lib/ruby_ui/combobox/combobox.rb +24 -0
  57. data/lib/ruby_ui/combobox/combobox_content.rb +31 -0
  58. data/lib/ruby_ui/combobox/combobox_empty.rb +21 -0
  59. data/lib/ruby_ui/combobox/combobox_group.rb +38 -0
  60. data/lib/ruby_ui/combobox/combobox_input.rb +22 -0
  61. data/lib/ruby_ui/combobox/combobox_item.rb +53 -0
  62. data/lib/ruby_ui/combobox/combobox_list.rb +27 -0
  63. data/lib/ruby_ui/combobox/combobox_search_input.rb +56 -0
  64. data/lib/ruby_ui/combobox/combobox_separator.rb +15 -0
  65. data/lib/ruby_ui/combobox/combobox_trigger.rb +52 -0
  66. data/lib/ruby_ui/combobox/combobox_value.rb +27 -0
  67. data/lib/ruby_ui/command/command.rb +9 -0
  68. data/lib/ruby_ui/command/command_dialog.rb +17 -0
  69. data/lib/ruby_ui/command/command_dialog_content.rb +48 -0
  70. data/lib/ruby_ui/command/command_dialog_trigger.rb +29 -0
  71. data/lib/ruby_ui/command/command_empty.rb +19 -0
  72. data/lib/ruby_ui/command/command_group.rb +40 -0
  73. data/lib/ruby_ui/command/command_input.rb +56 -0
  74. data/lib/ruby_ui/command/command_item.rb +32 -0
  75. data/lib/ruby_ui/command/command_list.rb +17 -0
  76. data/lib/ruby_ui/context_menu/context_menu.rb +26 -0
  77. data/lib/ruby_ui/context_menu/context_menu_content.rb +25 -0
  78. data/lib/ruby_ui/context_menu/context_menu_item.rb +66 -0
  79. data/lib/ruby_ui/context_menu/context_menu_label.rb +24 -0
  80. data/lib/ruby_ui/context_menu/context_menu_separator.rb +19 -0
  81. data/lib/ruby_ui/context_menu/context_menu_trigger.rb +20 -0
  82. data/lib/ruby_ui/dialog/dialog.rb +25 -0
  83. data/lib/ruby_ui/dialog/dialog_content.rb +78 -0
  84. data/lib/ruby_ui/dialog/dialog_description.rb +17 -0
  85. data/lib/ruby_ui/dialog/dialog_footer.rb +17 -0
  86. data/lib/ruby_ui/dialog/dialog_header.rb +17 -0
  87. data/lib/ruby_ui/dialog/dialog_middle.rb +17 -0
  88. data/lib/ruby_ui/dialog/dialog_title.rb +17 -0
  89. data/lib/ruby_ui/dialog/dialog_trigger.rb +20 -0
  90. data/lib/ruby_ui/dropdown_menu/dropdown_menu.rb +26 -0
  91. data/lib/ruby_ui/dropdown_menu/dropdown_menu_content.rb +22 -0
  92. data/lib/ruby_ui/dropdown_menu/dropdown_menu_item.rb +28 -0
  93. data/lib/ruby_ui/dropdown_menu/dropdown_menu_label.rb +17 -0
  94. data/lib/ruby_ui/dropdown_menu/dropdown_menu_separator.rb +19 -0
  95. data/lib/ruby_ui/dropdown_menu/dropdown_menu_trigger.rb +18 -0
  96. data/lib/ruby_ui/form/form.rb +15 -0
  97. data/lib/ruby_ui/form/form_field.rb +20 -0
  98. data/lib/ruby_ui/form/form_field_error.rb +20 -0
  99. data/lib/ruby_ui/form/form_field_hint.rb +15 -0
  100. data/lib/ruby_ui/form/form_field_label.rb +15 -0
  101. data/lib/ruby_ui/hover_card/hover_card.rb +27 -0
  102. data/lib/ruby_ui/hover_card/hover_card_content.rb +22 -0
  103. data/lib/ruby_ui/hover_card/hover_card_trigger.rb +20 -0
  104. data/lib/ruby_ui/input/input.rb +26 -0
  105. data/lib/ruby_ui/link/link.rb +97 -0
  106. data/lib/ruby_ui/masked_input/masked_input.rb +15 -0
  107. data/lib/ruby_ui/pagination/pagination.rb +19 -0
  108. data/lib/ruby_ui/pagination/pagination_content.rb +17 -0
  109. data/lib/ruby_ui/pagination/pagination_ellipsis.rb +42 -0
  110. data/lib/ruby_ui/pagination/pagination_item.rb +28 -0
  111. data/lib/ruby_ui/popover/popover.rb +26 -0
  112. data/lib/ruby_ui/popover/popover_content.rb +27 -0
  113. data/lib/ruby_ui/popover/popover_trigger.rb +20 -0
  114. data/lib/ruby_ui/radio_button/radio_button.rb +22 -0
  115. data/lib/ruby_ui/select/select.rb +23 -0
  116. data/lib/ruby_ui/select/select_content.rb +32 -0
  117. data/lib/ruby_ui/select/select_group.rb +15 -0
  118. data/lib/ruby_ui/select/select_input.rb +22 -0
  119. data/lib/ruby_ui/select/select_item.rb +52 -0
  120. data/lib/ruby_ui/select/select_label.rb +17 -0
  121. data/lib/ruby_ui/select/select_trigger.rb +54 -0
  122. data/lib/ruby_ui/select/select_value.rb +27 -0
  123. data/lib/ruby_ui/sheet/sheet.rb +17 -0
  124. data/lib/ruby_ui/sheet/sheet_content.rb +77 -0
  125. data/lib/ruby_ui/sheet/sheet_description.rb +17 -0
  126. data/lib/ruby_ui/sheet/sheet_footer.rb +17 -0
  127. data/lib/ruby_ui/sheet/sheet_header.rb +17 -0
  128. data/lib/ruby_ui/sheet/sheet_middle.rb +17 -0
  129. data/lib/ruby_ui/sheet/sheet_title.rb +17 -0
  130. data/lib/ruby_ui/sheet/sheet_trigger.rb +17 -0
  131. data/lib/ruby_ui/shortcut_key/shortcut_key.rb +17 -0
  132. data/lib/ruby_ui/table/table.rb +19 -0
  133. data/lib/ruby_ui/table/table_body.rb +17 -0
  134. data/lib/ruby_ui/table/table_caption.rb +17 -0
  135. data/lib/ruby_ui/table/table_cell.rb +17 -0
  136. data/lib/ruby_ui/table/table_footer.rb +17 -0
  137. data/lib/ruby_ui/table/table_head.rb +17 -0
  138. data/lib/ruby_ui/table/table_header.rb +17 -0
  139. data/lib/ruby_ui/table/table_row.rb +17 -0
  140. data/lib/ruby_ui/tabs/tabs.rb +25 -0
  141. data/lib/ruby_ui/tabs/tabs_content.rb +26 -0
  142. data/lib/ruby_ui/tabs/tabs_list.rb +17 -0
  143. data/lib/ruby_ui/tabs/tabs_trigger.rb +28 -0
  144. data/lib/ruby_ui/textarea/textarea.rb +26 -0
  145. data/lib/ruby_ui/theme_toggle/theme_toggle.rb +41 -0
  146. data/lib/ruby_ui/tooltip/tooltip.rb +26 -0
  147. data/lib/ruby_ui/tooltip/tooltip_content.rb +26 -0
  148. data/lib/ruby_ui/tooltip/tooltip_trigger.rb +19 -0
  149. data/lib/ruby_ui/typography/heading.rb +60 -0
  150. data/lib/ruby_ui/typography/inline_code.rb +17 -0
  151. data/lib/ruby_ui/typography/inline_link.rb +22 -0
  152. data/lib/ruby_ui/typography/text.rb +53 -0
  153. data/lib/ruby_ui/typography/typography_blockquote.rb +17 -0
  154. data/lib/ruby_ui.rb +5 -0
  155. metadata +280 -0
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class PaginationEllipsis < Base
5
+ def view_template(&block)
6
+ li do
7
+ span(**attrs) do
8
+ icon
9
+ span(class: "sr-only") { "More pages" }
10
+ end
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def icon
17
+ svg(
18
+ xmlns: "http://www.w3.org/2000/svg",
19
+ width: "24",
20
+ height: "24",
21
+ viewbox: "0 0 24 24",
22
+ fill: "none",
23
+ stroke: "currentColor",
24
+ stroke_width: "2",
25
+ stroke_linecap: "round",
26
+ stroke_linejoin: "round",
27
+ class: "h-4 w-4"
28
+ ) do |s|
29
+ s.circle(cx: "12", cy: "12", r: "1")
30
+ s.circle(cx: "19", cy: "12", r: "1")
31
+ s.circle(cx: "5", cy: "12", r: "1")
32
+ end
33
+ end
34
+
35
+ def default_attrs
36
+ {
37
+ aria: {hidden: true},
38
+ class: "flex h-9 w-9 items-center justify-center"
39
+ }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class PaginationItem < Base
5
+ def initialize(href: "#", active: false, **attrs)
6
+ @href = href
7
+ @active = active
8
+ super(**attrs)
9
+ end
10
+
11
+ def view_template(&block)
12
+ li do
13
+ a(href: @href, **attrs, &block)
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def default_attrs
20
+ {
21
+ aria: {current: @active ? "page" : nil},
22
+ class: [
23
+ RubyUI::Button.new(variant: @active ? :outline : :ghost).attrs[:class]
24
+ ]
25
+ }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class Popover < 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: "ruby-ui--popover",
20
+ ruby_ui__popover_options_value: @options.to_json,
21
+ ruby_ui__popover_trigger_value: @options[:trigger] || "hover"
22
+ }
23
+ }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class PopoverContent < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {
14
+ ruby_ui__popover_target: "content"
15
+ },
16
+ class: [
17
+ "hidden z-50 rounded-md border bg-background p-1 text-foreground shadow-md outline-none",
18
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
19
+ "data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
20
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
21
+ "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
22
+ "absolute"
23
+ ]
24
+ }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class PopoverTrigger < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {
14
+ ruby_ui__popover_target: "trigger"
15
+ },
16
+ class: "inline-block"
17
+ }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class RadioButton < Base
5
+ def view_template
6
+ input(**attrs)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ type: "radio",
14
+ data: {
15
+ ruby_ui__form_field_target: "input",
16
+ action: "change->ruby-ui--form-field#onInput invalid->ruby-ui--form-field#onInvalid"
17
+ },
18
+ class: "h-4 w-4 p-0 border-primary rounded-full flex-none"
19
+ }
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class Select < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {
14
+ controller: "ruby-ui--select",
15
+ ruby_ui__select_open_value: "false",
16
+ action: "click@window->ruby-ui--select#clickOutside",
17
+ ruby_ui__select_ruby_ui__select_item_outlet: ".item"
18
+ },
19
+ class: "group/select w-full relative"
20
+ }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class SelectContent < Base
5
+ def initialize(**attrs)
6
+ @id = "content#{SecureRandom.hex(4)}"
7
+ super
8
+ end
9
+
10
+ def view_template(&block)
11
+ div(**attrs) do
12
+ div(
13
+ class: "max-h-96 min-w-max overflow-auto rounded-md border bg-background p-1 text-foreground shadow-md animate-out group-data-[ruby-ui--select-open-value=true]/select:animate-in fade-out-0 group-data-[ruby-ui--select-open-value=true]/select:fade-in-0 zoom-out-95 group-data-[ruby-ui--select-open-value=true]/select:zoom-in-95 slide-in-from-top-2", &block
14
+ )
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def default_attrs
21
+ {
22
+ id: @id,
23
+ role: "listbox",
24
+ tabindex: "-1",
25
+ data: {
26
+ ruby_ui__select_target: "content"
27
+ },
28
+ class: "hidden w-full absolute top-0 left-0 z-50"
29
+ }
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class SelectGroup < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {}
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class SelectInput < Base
5
+ def view_template
6
+ input(**attrs)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "hidden",
14
+ data: {
15
+ ruby_ui__select_target: "input",
16
+ ruby_ui__form_field_target: "input",
17
+ action: "change->ruby-ui--form-field#onChange invalid->ruby-ui--form-field#onInvalid"
18
+ }
19
+ }
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class SelectItem < Base
5
+ def initialize(value: nil, **attrs)
6
+ @value = value
7
+ super(**attrs)
8
+ end
9
+
10
+ def view_template(&block)
11
+ div(**attrs) do
12
+ selected_icon
13
+ block&.call
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def selected_icon
20
+ svg(
21
+ xmlns: "http://www.w3.org/2000/svg",
22
+ viewbox: "0 0 24 24",
23
+ fill: "none",
24
+ stroke: "currentColor",
25
+ class: "invisible group-aria-selected:visible mr-2 h-4 w-4 flex-none",
26
+ stroke_width: "2",
27
+ stroke_linecap: "round",
28
+ stroke_linejoin: "round"
29
+ ) do |s|
30
+ s.path(
31
+ d: "M20 6 9 17l-5-5"
32
+ )
33
+ end
34
+ end
35
+
36
+ def default_attrs
37
+ {
38
+ role: "option",
39
+ tabindex: "0",
40
+ class: "item group 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",
41
+ data: {
42
+ controller: "ruby-ui--select-item",
43
+ action: "click->ruby-ui--select#selectItem keydown.enter->ruby-ui--select#selectItem keydown.down->ruby-ui--select#handleKeyDown keydown.up->ruby-ui--select#handleKeyUp keydown.esc->ruby-ui--select#handleEsc",
44
+ ruby_ui__select_target: "item"
45
+ },
46
+ data_value: @value,
47
+ data_orientation: "vertical",
48
+ aria_selected: "false"
49
+ }
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class SelectLabel < 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,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class SelectTrigger < Base
5
+ def view_template(&block)
6
+ button(**attrs) do
7
+ block&.call
8
+ icon
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def icon
15
+ svg(
16
+ xmlns: "http://www.w3.org/2000/svg",
17
+ viewbox: "0 0 24 24",
18
+ fill: "none",
19
+ stroke: "currentColor",
20
+ class: "ml-2 h-4 w-4 shrink-0 opacity-50",
21
+ stroke_width: "2",
22
+ stroke_linecap: "round",
23
+ stroke_linejoin: "round"
24
+ ) do |s|
25
+ s.path(
26
+ d: "m7 15 5 5 5-5"
27
+ )
28
+ s.path(
29
+ d: "m7 9 5-5 5 5"
30
+ )
31
+ end
32
+ end
33
+
34
+ def default_attrs
35
+ {
36
+ data: {
37
+ action: "ruby-ui--select#onClick",
38
+ ruby_ui__select_target: "trigger"
39
+ },
40
+ type: "button",
41
+ role: "combobox",
42
+ aria: {
43
+ controls: "radix-:r0:",
44
+ expanded: "false",
45
+ autocomplete: "none",
46
+ haspopup: "listbox",
47
+ activedescendant: true
48
+ },
49
+ class:
50
+ "truncate w-full flex h-9 items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
51
+ }
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class SelectValue < Base
5
+ def initialize(placeholder: nil, **attrs)
6
+ @placeholder = placeholder
7
+ super(**attrs)
8
+ end
9
+
10
+ def view_template(&block)
11
+ span(**attrs) do
12
+ block ? block.call : @placeholder
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def default_attrs
19
+ {
20
+ data: {
21
+ ruby_ui__select_target: "value"
22
+ },
23
+ class: "pointer-events-none"
24
+ }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class Sheet < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {controller: "ruby-ui--sheet"}
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class SheetContent < Base
5
+ SIDE_CLASS = {
6
+ top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
7
+ right: "inset-y-0 right-0 h-full border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right",
8
+ bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
9
+ left: "inset-y-0 left-0 h-full border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left"
10
+ }
11
+
12
+ def initialize(side: :right, **attrs)
13
+ @side = side
14
+ @side_classes = SIDE_CLASS[side]
15
+ super(**attrs)
16
+ end
17
+
18
+ def view_template(&block)
19
+ template(data: {ruby_ui__sheet_target: "content"}) do
20
+ div(data: {controller: "ruby-ui--sheet-content"}) do
21
+ backdrop
22
+ div(**attrs) do
23
+ block&.call
24
+ close_button
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def default_attrs
33
+ {
34
+ data_state: "open", # For animate in
35
+ class: [
36
+ "fixed pointer-events-auto z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500",
37
+ @side_classes
38
+ ]
39
+ }
40
+ end
41
+
42
+ def close_button
43
+ button(
44
+ type: "button",
45
+ 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",
46
+ data_action: "click->ruby-ui--sheet-content#close"
47
+ ) do
48
+ svg(
49
+ width: "15",
50
+ height: "15",
51
+ viewbox: "0 0 15 15",
52
+ fill: "none",
53
+ xmlns: "http://www.w3.org/2000/svg",
54
+ class: "h-4 w-4"
55
+ ) do |s|
56
+ s.path(
57
+ d:
58
+ "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",
59
+ fill: "currentColor",
60
+ fill_rule: "evenodd",
61
+ clip_rule: "evenodd"
62
+ )
63
+ end
64
+ span(class: "sr-only") { "Close" }
65
+ end
66
+ end
67
+
68
+ def backdrop
69
+ div(
70
+ data_state: "open",
71
+ data_action: "click->ruby-ui--sheet-content#close",
72
+ class:
73
+ "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"
74
+ )
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class SheetDescription < 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 RubyUI
4
+ class SheetFooter < 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 RubyUI
4
+ class SheetHeader < 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 RubyUI
4
+ class SheetMiddle < 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 RubyUI
4
+ class SheetTitle < 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,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class SheetTrigger < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {action: "click->ruby-ui--sheet#open"}
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class ShortcutKey < Base
5
+ def view_template(&)
6
+ kbd(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class Table < Base
5
+ def view_template(&block)
6
+ div(class: "relative w-full overflow-auto") do
7
+ table(**attrs, &block)
8
+ end
9
+ end
10
+
11
+ private
12
+
13
+ def default_attrs
14
+ {
15
+ class: "w-full caption-bottom text-sm"
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class TableBody < Base
5
+ def view_template(&)
6
+ tbody(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "[&_tr:last-child]:border-0"
14
+ }
15
+ end
16
+ end
17
+ end