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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 518fa1b05606796f9ae57a444aa55f5a5f0fcad5280c1e0ed75fa4778dbe978f
4
+ data.tar.gz: 58c2a5717af15d0326258044a7ffc862d06cb3f3c3cc47f54a269b465bca2bcf
5
+ SHA512:
6
+ metadata.gz: c17770afaf73e476ba5d2a52bd60d4f4ab00c80e84f7390e9870099cd85a827f81992a6a8d1dd2fd246b34785b6fb2640a95d5f7ad5b08b697a710eb29c89db5
7
+ data.tar.gz: d70e491efc576db70d0fa7ea559ce16472a7fdd4f2a7a3a770ec15bc62b25da2ec12d12932baed3a966b9d44f2f0cb8704235f3bb016397b5e483cfe30cb1645
@@ -0,0 +1,130 @@
1
+ require_relative "javascript_utils"
2
+ module RubyUI
3
+ module Generators
4
+ class ComponentGenerator < Rails::Generators::Base
5
+ include RubyUI::Generators::JavascriptUtils
6
+
7
+ namespace "ruby_ui:component"
8
+
9
+ source_root File.expand_path("../../ruby_ui", __dir__)
10
+ argument :component_name, type: :string, required: true
11
+
12
+ def generate_component
13
+ if component_not_found?
14
+ say "Component not found: #{component_name}", :red
15
+ exit
16
+ end
17
+
18
+ say "Generating component files"
19
+ end
20
+
21
+ def copy_main_component_file
22
+ main_component_file_path = File.join(component_folder_path, "#{component_folder_name}.rb")
23
+
24
+ # some components dont't have a main component, eg. Typography
25
+ return unless File.exist? main_component_file_path
26
+
27
+ say "Generating main component"
28
+
29
+ copy_file main_component_file_path, Rails.root.join("app/components/ruby_ui", "#{component_folder_name}.rb")
30
+ end
31
+
32
+ def copy_related_component_files
33
+ return if related_components_file_paths.empty?
34
+
35
+ say "Generating related components"
36
+
37
+ related_components_file_paths.each do |file_path|
38
+ component_file_name = file_path.split("/").last
39
+ copy_file file_path, Rails.root.join("app/components/ruby_ui", component_folder_name, component_file_name)
40
+ end
41
+ end
42
+
43
+ def copy_js_files
44
+ return if js_controller_file_paths.empty?
45
+
46
+ say "Generating Stimulus controllers"
47
+
48
+ js_controller_file_paths.each do |file_path|
49
+ controller_file_name = file_path.split("/").last
50
+ copy_file file_path, Rails.root.join("app/javascript/controllers/ruby_ui", controller_file_name)
51
+ end
52
+
53
+ # Importmap doesn't have controller manifest, instead it uses `eagerLoadControllersFrom("controllers", application)`
54
+ if !using_importmap?
55
+ say "Updating Stimulus controllers manifest"
56
+ run "rake stimulus:manifest:update"
57
+ end
58
+ end
59
+
60
+ def install_dependencies
61
+ return if dependencies.blank?
62
+
63
+ say "Installing dependencies"
64
+
65
+ install_components_dependencies(dependencies["components"])
66
+ install_gems_dependencies(dependencies["gems"])
67
+ install_js_packages(dependencies["js_packages"])
68
+ end
69
+
70
+ private
71
+
72
+ def component_not_found? = !Dir.exist?(component_folder_path)
73
+
74
+ def component_folder_name = component_name.underscore
75
+
76
+ def component_folder_path = File.join(self.class.source_root, component_folder_name)
77
+
78
+ def main_component_file_path = File.join(component_folder_path, "#{component_folder_name}.rb")
79
+
80
+ def related_components_file_paths = Dir.glob(File.join(component_folder_path, "*.rb")) - [main_component_file_path]
81
+
82
+ def js_controller_file_paths = Dir.glob(File.join(component_folder_path, "*.js"))
83
+
84
+ def install_components_dependencies(components)
85
+ components&.each do |component|
86
+ run "bin/rails generate ruby_ui:component #{component}"
87
+ end
88
+ end
89
+
90
+ def install_gems_dependencies(gems)
91
+ gems&.each do |ruby_gem|
92
+ run "bundle show #{ruby_gem} > /dev/null 2>&1 || bundle add #{ruby_gem}"
93
+ end
94
+ end
95
+
96
+ def install_js_packages(js_packages)
97
+ js_packages&.each do |js_package|
98
+ install_js_package(js_package)
99
+ end
100
+ end
101
+
102
+ def pin_motion
103
+ say <<~TEXT
104
+ WARNING: Installing motion from CDN because `bin/importmap pin motion` doesn't download the correct file.
105
+ TEXT
106
+
107
+ inject_into_file Rails.root.join("config/importmap.rb"), <<~RUBY
108
+ pin "motion", to: "https://cdn.jsdelivr.net/npm/motion@11.11.17/+esm"\n
109
+ RUBY
110
+ end
111
+
112
+ def pin_tippy_js
113
+ say <<~TEXT
114
+ WARNING: Installing tippy.js from CDN because `bin/importmap pin tippy.js` doesn't download the correct file.
115
+ TEXT
116
+
117
+ inject_into_file Rails.root.join("config/importmap.rb"), <<~RUBY
118
+ pin "tippy.js", to: "https://cdn.jsdelivr.net/npm/tippy.js@6.3.7/+esm"
119
+ pin "@popperjs/core", to: "https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/+esm"\n
120
+ RUBY
121
+ end
122
+
123
+ def dependencies
124
+ @dependencies ||= YAML.load_file(File.join(__dir__, "dependencies.yml")).freeze
125
+
126
+ @dependencies[component_folder_name]
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,90 @@
1
+ require "rails/generators"
2
+ require_relative "../javascript_utils"
3
+
4
+ module RubyUI
5
+ module Generators
6
+ class InstallGenerator < Rails::Generators::Base
7
+ include RubyUI::Generators::JavascriptUtils
8
+
9
+ namespace "ruby_ui:install"
10
+
11
+ source_root File.expand_path("templates", __dir__)
12
+
13
+ def install_phlex_rails
14
+ say "Checking for phlex-rails"
15
+
16
+ if gem_installed?("phlex-rails")
17
+ if Gem::Specification.find_by_name("phlex-rails").version < "2.0.0.beta2"
18
+ say "You need to upgrade to phlex-rails 2 to use RubyUI", :red
19
+ exit
20
+ else
21
+ say "phlex-rails is already installed", :green
22
+ end
23
+ else
24
+ say "Adding phlex-rails to Gemfile"
25
+ run %(bundle add phlex-rails --github="phlex-ruby/phlex-rails")
26
+
27
+ say "Running phlex-rails structure"
28
+ run "bin/rails generate phlex:install"
29
+ end
30
+ end
31
+
32
+ def install_tailwind_merge
33
+ say "Checking for tailwind_merge"
34
+
35
+ if gem_installed?("tailwind_merge")
36
+ say "tailwind_merge is already installed", :green
37
+ else
38
+ say "Adding phlex-rails to Gemfile"
39
+ run %(bundle add tailwind_merge)
40
+ end
41
+ end
42
+
43
+ def install_ruby_ui_initializer
44
+ say "Creating RubyUI initializer"
45
+ template "ruby_ui.rb.erb", Rails.root.join("config/initializers/ruby_ui.rb")
46
+ end
47
+
48
+ def add_ruby_ui_module_to_components_base
49
+ say "Adding RubyUI Kit to Components::Base"
50
+ insert_into_file Rails.root.join("app/components/base.rb"), after: "include Components" do
51
+ "\n include RubyUI"
52
+ end
53
+ end
54
+
55
+ def add_tailwind_css
56
+ say "Adding RubyUI styles to application css"
57
+ template "application.tailwind.css.erb", Rails.root.join("app/assets/stylesheets/application.tailwind.css")
58
+ end
59
+
60
+ def add_tailwind_config
61
+ say "Adding RubyUI config to tailwind config"
62
+
63
+ if File.exist?(Rails.root.join("tailwind.config.js")) # tailwindcss js package
64
+ template "tailwind.config.js.js-package.erb", Rails.root.join("tailwind.config.js")
65
+ elsif File.exist?(Rails.root.join("config/tailwind.config.js")) # tailwindcss-rails gem
66
+ template "tailwind.config.js.tailwindcss-rails.erb", Rails.root.join("config/tailwind.config.js")
67
+ else
68
+ say "Cannot find tailwind.config.js. You will need to install tailwind config manually", :red
69
+ end
70
+ end
71
+
72
+ def install_tailwind_animate
73
+ say "Installing tailwindcss-animate plugin"
74
+
75
+ install_js_package("tailwindcss-animate")
76
+ end
77
+
78
+ def add_ruby_ui_base
79
+ say "Adding RubyUI::Base component"
80
+ template "../../../../ruby_ui/base.rb", Rails.root.join("app/components/ruby_ui/base.rb")
81
+ end
82
+
83
+ private
84
+
85
+ def gem_installed?(name)
86
+ Gem::Specification.find_all_by_name(name).any?
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,36 @@
1
+ module RubyUI
2
+ module Generators
3
+ module JavascriptUtils
4
+ def install_js_package(package)
5
+ if using_importmap?
6
+ pin_with_importmap(package)
7
+ elsif using_yarn?
8
+ run "yarn add #{package}"
9
+ elsif using_npm?
10
+ run "npm install #{package}"
11
+ else
12
+ say "Could not detect the package manager, you need to install '#{package}' manually", :red
13
+ end
14
+ end
15
+
16
+ def pin_with_importmap(package)
17
+ case package
18
+ when "motion"
19
+ pin_motion
20
+ when "tippy.js"
21
+ pin_tippy_js
22
+ else
23
+ run "bin/importmap pin #{package}"
24
+ end
25
+ end
26
+
27
+ def using_importmap?
28
+ File.exist?(Rails.root.join("config/importmap.rb")) && File.exist?(Rails.root.join("bin/importmap"))
29
+ end
30
+
31
+ def using_npm? = File.exist?(Rails.root.join("package-lock.json"))
32
+
33
+ def using_yarn? = File.exist?(Rails.root.join("yarn.lock"))
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class Accordion < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "w-full"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AccordionContent < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ data: {
14
+ ruby_ui__accordion_target: "content"
15
+ },
16
+ class: "overflow-y-hidden",
17
+ style: "height: 0px;"
18
+ }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AccordionDefaultContent < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "pb-4 pt-0 text-sm"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AccordionDefaultTrigger < Base
5
+ def view_template(&block)
6
+ div(class: "flex items-center justify-between w-full") do
7
+ p(&block)
8
+ RubyUI.AccordionIcon
9
+ end
10
+ end
11
+
12
+ def default_attrs
13
+ {
14
+ data: {action: "click->ruby-ui--accordion#toggle"},
15
+ class: "w-full flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline"
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AccordionIcon < Base
5
+ def view_template(&block)
6
+ span(**attrs) do
7
+ if block
8
+ block.call
9
+ else
10
+ icon
11
+ end
12
+ end
13
+ end
14
+
15
+ def icon
16
+ svg(
17
+ xmlns: "http://www.w3.org/2000/svg",
18
+ viewbox: "0 0 20 20",
19
+ fill: "currentColor",
20
+ class: "w-4 h-4"
21
+ ) do |s|
22
+ s.path(
23
+ fill_rule: "evenodd",
24
+ d:
25
+ "M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z",
26
+ clip_rule: "evenodd"
27
+ )
28
+ end
29
+ end
30
+
31
+ def default_attrs
32
+ {
33
+ class: "opacity-50",
34
+ data: {ruby_ui__accordion_target: "icon"}
35
+ }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AccordionItem < Base
5
+ def initialize(open: false, rotate_icon: 180, **attrs)
6
+ @open = open
7
+ @rotate_icon = rotate_icon
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: "ruby-ui--accordion",
21
+ ruby_ui__accordion_open_value: @open,
22
+ ruby_ui__accordion_rotate_icon_value: @rotate_icon
23
+ },
24
+ class: "border-b"
25
+ }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AccordionTrigger < Base
5
+ def view_template(&)
6
+ button(**attrs, &)
7
+ end
8
+
9
+ def default_attrs
10
+ {
11
+ type: "button",
12
+ data: {action: "click->ruby-ui--accordion#toggle"},
13
+ class: "w-full flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class Alert < Base
5
+ def initialize(variant: nil, **attrs)
6
+ @variant = variant
7
+ super(**attrs) # must be called after variant is set
8
+ end
9
+
10
+ def view_template(&)
11
+ div(**attrs, &)
12
+ end
13
+
14
+ private
15
+
16
+ def colors
17
+ case @variant
18
+ when nil
19
+ "ring-border bg-muted/20 text-foreground [&>svg]:opacity-80"
20
+ when :warning
21
+ "ring-warning/20 bg-warning/5 text-warning [&>svg]:text-warning/80"
22
+ when :success
23
+ "ring-success/20 bg-success/5 text-success [&>svg]:text-success/80"
24
+ when :destructive
25
+ "ring-destructive/20 bg-destructive/5 text-destructive [&>svg]:text-destructive/80"
26
+ end
27
+ end
28
+
29
+ def default_attrs
30
+ base_classes = "backdrop-blur relative w-full ring-1 ring-inset rounded-lg px-4 py-4 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg~*]:pl-8"
31
+ {
32
+ class: [base_classes, colors]
33
+ }
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AlertDescription < Base
5
+ def view_template(&)
6
+ div(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "text-sm [&_p]:leading-relaxed"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AlertTitle < Base
5
+ def view_template(&)
6
+ h5(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ class: "mb-1 font-medium leading-none tracking-tight"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AlertDialog < 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: "ruby-ui--alert-dialog",
20
+ ruby_ui__alert_dialog_open_value: @open.to_s
21
+ },
22
+ class: "inline-block"
23
+ }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AlertDialogAction < Base
5
+ def view_template(&)
6
+ render RubyUI::Button.new(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ variant: :primary
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AlertDialogCancel < Base
5
+ def view_template(&)
6
+ render RubyUI::Button.new(**attrs, &)
7
+ end
8
+
9
+ private
10
+
11
+ def default_attrs
12
+ {
13
+ variant: :outline,
14
+ data: {
15
+ action: "click->ruby-ui--alert-dialog#dismiss"
16
+ },
17
+ class: "mt-2 sm:mt-0"
18
+ }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AlertDialogContent < Base
5
+ def view_template(&block)
6
+ template(**attrs) do
7
+ div(data: {controller: "ruby-ui--alert-dialog"}) do
8
+ background
9
+ container(&block)
10
+ end
11
+ end
12
+ end
13
+
14
+ def background
15
+ div(
16
+ data_state: "open",
17
+ class:
18
+ "fixed inset-0 z-50 bg-black/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",
19
+ style: "pointer-events:auto",
20
+ data_aria_hidden: "true",
21
+ aria_hidden: "true"
22
+ )
23
+ end
24
+
25
+ def container(&)
26
+ div(
27
+ role: "alertdialog",
28
+ data_state: "open",
29
+ class: "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg 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",
30
+ style: "pointer-events:auto",
31
+ &
32
+ )
33
+ end
34
+
35
+ private
36
+
37
+ def default_attrs
38
+ {
39
+ data: {
40
+ ruby_ui__alert_dialog_target: "content"
41
+ }
42
+ }
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AlertDialogDescription < 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 AlertDialogFooter < 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"
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyUI
4
+ class AlertDialogHeader < 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-2 text-center sm:text-left"
14
+ }
15
+ end
16
+ end
17
+ end