-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add manual component installation instructions (#142)
- Loading branch information
Showing
4 changed files
with
270 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
module Components | ||
module ComponentSetup | ||
class ManualSteps < Components::Base | ||
def initialize(component_name:) | ||
@component_name = component_name | ||
@dependencies = RubyUI::FileManager.dependencies(@component_name) | ||
end | ||
|
||
private | ||
|
||
attr_reader :component_name, :dependencies | ||
|
||
def view_template | ||
div(class: "max-w-2xl mx-auto w-full py-10 space-y-6") do | ||
Heading(level: 4, class: "pb-4 border-b") { "Manual installation" } | ||
|
||
render Steps::Builder.new do |steps| | ||
main_component_step(steps) | ||
related_component_steps(steps) | ||
stimulus_controller_steps(steps) | ||
js_dependencies_steps(steps) | ||
ruby_dependencies_steps(steps) | ||
component_dependencies_steps(steps) | ||
end | ||
end | ||
end | ||
|
||
def main_component_step(steps) | ||
main_component_code = RubyUI::FileManager.main_component_code(component_name) | ||
|
||
return if main_component_code.blank? | ||
|
||
steps.add_step do | ||
render Steps::Container do | ||
Text(size: "4", weight: "semibold") do | ||
plain "Add " | ||
InlineCode(class: "whitespace-nowrap") { "RubyUI::#{component_name.camelcase}" } | ||
plain " to " | ||
InlineCode(class: "whitespace-nowrap") { "app/components/ruby_ui/#{component_name.underscore}.rb" } | ||
end | ||
|
||
div(class: "w-full") do | ||
Codeblock(main_component_code, syntax: :ruby) | ||
end | ||
end | ||
end | ||
end | ||
|
||
def related_component_steps(steps) | ||
related_component_file_paths = RubyUI::FileManager.related_component_file_paths(component_name) | ||
|
||
return if related_component_file_paths.empty? | ||
|
||
related_component_file_paths.each do |component_path| | ||
related_component_class = component_path.split("/").last.delete_suffix(".rb").camelcase | ||
related_component_file_name = component_path.split("/").last | ||
related_component_code = RubyUI::FileManager.component_code(component_path) | ||
steps.add_step do | ||
render Steps::Container do | ||
Text(size: "4", weight: "semibold") do | ||
plain "Add " | ||
InlineCode(class: "whitespace-nowrap") { "RubyUI::#{related_component_class}" } | ||
plain " to " | ||
InlineCode(class: "whitespace-nowrap") { "app/components/ruby_ui/#{component_name.underscore}/#{related_component_file_name}" } | ||
end | ||
|
||
div(class: "w-full") do | ||
Codeblock(related_component_code, syntax: :ruby) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
def stimulus_controller_steps(steps) | ||
stimulus_controller_file_paths = RubyUI::FileManager.stimulus_controller_file_paths(component_name) | ||
|
||
return if stimulus_controller_file_paths.empty? | ||
|
||
stimulus_controller_file_paths.each do |controller_path| | ||
controller_file_name = controller_path.split("/").last | ||
controller_code = RubyUI::FileManager.component_code(controller_path) | ||
steps.add_step do | ||
render Steps::Container do | ||
Text(size: "4", weight: "semibold") do | ||
plain "Add " | ||
InlineCode(class: "whitespace-nowrap") { controller_file_name } | ||
plain " to " | ||
InlineCode(class: "whitespace-nowrap") { "app/javascript/controllers/ruby_ui/#{controller_file_name}" } | ||
end | ||
|
||
div(class: "w-full") do | ||
Codeblock(controller_code, syntax: :javascript) | ||
end | ||
end | ||
end | ||
end | ||
|
||
steps.add_step do | ||
render Steps::Container do | ||
Text(size: "4", weight: "semibold") do | ||
plain "Update the Stimulus controllers manifest file" | ||
end | ||
|
||
Alert(variant: :destructive) do | ||
AlertTitle { "Importmap!" } | ||
AlertDescription { "You don't need to run this command if you are using Importmap" } | ||
end | ||
|
||
div(class: "w-full") do | ||
Codeblock("rake stimulus:manifest:update", syntax: :javascript) | ||
end | ||
end | ||
end | ||
end | ||
|
||
def js_dependencies_steps(steps) | ||
return unless dependencies["js_packages"].present? | ||
|
||
dependencies["js_packages"].each do |js_package| | ||
steps.add_step do | ||
code = <<~CODE | ||
// with yarn | ||
yarn add #{js_package} | ||
// with npm | ||
npm install #{js_package} | ||
// with importmaps | ||
#{pin_importmap_instructions(js_package)} | ||
CODE | ||
|
||
render Steps::Container do | ||
Text(size: "4", weight: "semibold") do | ||
plain "Install " | ||
InlineCode(class: "whitespace-nowrap") { js_package } | ||
plain " Javascript dependency" | ||
end | ||
|
||
div(class: "w-full") do | ||
Codeblock(code, syntax: :javascript) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
def ruby_dependencies_steps(steps) | ||
return unless dependencies["gems"].present? | ||
|
||
dependencies["gems"].each do |gem| | ||
steps.add_step do | ||
code = <<~CODE | ||
bundle add #{gem} | ||
CODE | ||
|
||
render Steps::Container do | ||
Text(size: "4", weight: "semibold") do | ||
plain "Install " | ||
InlineCode(class: "whitespace-nowrap") { gem } | ||
plain " Ruby gem" | ||
end | ||
|
||
div(class: "w-full") do | ||
Codeblock(code, syntax: :javascript) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
def component_dependencies_steps(steps) | ||
return unless dependencies["components"].present? | ||
|
||
steps.add_step do | ||
render Steps::Container do | ||
Text(size: "4", weight: "semibold") do | ||
plain "Install required components" | ||
end | ||
|
||
Text do | ||
plain "Component " | ||
InlineCode(class: "whitespace-nowrap") { component_name.camelcase } | ||
plain " relies on the following RubyUI components. Refer to their individual installation guides for setup instructions:" | ||
end | ||
|
||
TypographyList do | ||
dependencies["components"].each do |component| | ||
TypographyListItem do | ||
Link(size: :lg, target: "_blank", href: public_send(:"docs_#{component.underscore}_path")) do | ||
span(class: "font-bold") { component.camelcase } | ||
span { " - Installation guide" } | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
# Temporary solution while we don't remove | ||
# motion adn tippy.js dependencies | ||
def pin_importmap_instructions(js_package) | ||
case js_package | ||
when "motion" | ||
<<~CODE | ||
// Add to your config/importmap.rb | ||
pin "motion", to: "https://cdn.jsdelivr.net/npm/[email protected]/+esm" | ||
CODE | ||
when "tippy.js" | ||
<<~CODE | ||
// Add to your config/importmap.rb | ||
pin "tippy.js", to: "https://cdn.jsdelivr.net/npm/[email protected]/+esm" | ||
pin "@popperjs/core", to: "https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/+esm"\n | ||
CODE | ||
else | ||
"bin/importmap pin #{js_package}" | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
module RubyUI | ||
module FileManager | ||
extend self | ||
|
||
def main_component_code(component_name) | ||
component_code main_component_file_path(component_name) | ||
end | ||
|
||
def component_code(file_path) | ||
File.read(file_path) if File.exist?(file_path) | ||
end | ||
|
||
def main_component_file_path(component_name) | ||
component_name = component_name.underscore | ||
File.join(component_folder(component_name), "#{component_name}.rb") | ||
end | ||
|
||
def related_component_file_paths(component_name) | ||
Dir[File.join(component_folder(component_name), "*.rb")] - [main_component_file_path(component_name)] | ||
end | ||
|
||
def stimulus_controller_file_paths(component_name) | ||
Dir[File.join(component_folder(component_name), "*.js")] | ||
end | ||
|
||
def component_folder(component_name) | ||
component_name = component_name.underscore | ||
File.join(gem_path, "lib", "ruby_ui", component_name) | ||
end | ||
|
||
def dependencies(component_name) | ||
DEPENDENCIES[component_name.underscore].to_h | ||
end | ||
|
||
def gem_path | ||
@gem_path ||= Gem::Specification.find_by_name("ruby_ui").gem_dir | ||
end | ||
|
||
DEPENDENCIES = YAML.load_file(File.join(gem_path, "lib/generators/ruby_ui/dependencies.yml")).freeze | ||
end | ||
end |