Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,22 @@ While we don't have specific test coverage requirements, all contributions shoul

If your changes include new components, modify how components should be used, or add new behaviors, it is highly recommended to also open a PR on the [ruby-ui/web](https://github.com/ruby-ui/web) repository. This ensures the documentation website stays up-to-date with the latest component changes.

### Installing Documentation Files

RubyUI includes documentation files for each component that can be installed into your Rails application. These files are located at `lib/ruby_ui/{component}/{component}_docs.rb` and provide usage examples for each component.

To install the documentation files:

```bash
bin/rails g ruby_ui:install:docs
```

To overwrite existing documentation files:

```bash
bin/rails g ruby_ui:install:docs --force
```

This will copy the documentation files to `app/views/docs/` in your Rails application.

Thank you for contributing to make RubyUI better!
33 changes: 33 additions & 0 deletions lib/generators/ruby_ui/install/docs_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

require "rails/generators"

module RubyUI
module Generators
module Install
class DocsGenerator < Rails::Generators::Base
namespace "ruby_ui:install:docs"
source_root File.expand_path("../../../ruby_ui", __dir__)
class_option :force, type: :boolean, default: false

def copy_docs_files
say "Installing RubyUI documentation files..."

docs_file_paths.each do |source_path|
dest_filename = File.basename(source_path).sub("_docs", "")
copy_file source_path, Rails.root.join("app/views/docs", dest_filename), force: options["force"]
end

say ""
say "Documentation installed to app/views/docs/", :green
end

private

def docs_file_paths
Dir.glob(File.join(self.class.source_root, "*", "*_docs.rb"))
end
end
end
end
end
143 changes: 143 additions & 0 deletions lib/ruby_ui/button/button_docs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# frozen_string_literal: true

class Views::Docs::Button < Views::Base
def view_template
component = "Button"

div(class: "max-w-2xl mx-auto w-full py-10 space-y-10") do
render Docs::Header.new(title: "Button", description: "Displays a button or a component that looks like a button.")

Heading(level: 2) { "Usage" }

render Docs::VisualCodeExample.new(title: "Example", context: self) do
<<~RUBY
Button { "Button" }
RUBY
end

render Docs::VisualCodeExample.new(title: "Primary", context: self) do
<<~RUBY
Button(variant: :primary) { "Primary" }
RUBY
end

render Docs::VisualCodeExample.new(title: "Secondary", context: self) do
<<~RUBY
Button(variant: :secondary) { "Secondary" }
RUBY
end

render Docs::VisualCodeExample.new(title: "Destructive", context: self) do
<<~RUBY
Button(variant: :destructive) { "Destructive" }
RUBY
end

render Docs::VisualCodeExample.new(title: "Outline", context: self) do
<<~RUBY
Button(variant: :outline) { "Outline" }
RUBY
end

render Docs::VisualCodeExample.new(title: "Ghost", context: self) do
<<~RUBY
Button(variant: :ghost) { "Ghost" }
RUBY
end

render Docs::VisualCodeExample.new(title: "Link", context: self) do
<<~RUBY
Button(variant: :link) { "Link" }
RUBY
end

render Docs::VisualCodeExample.new(title: "Disabled", context: self) do
<<~RUBY
Button(disabled: true) { "Disabled" }
RUBY
end

render Docs::VisualCodeExample.new(title: "Aria Disabled", context: self) do
<<~RUBY
Button(aria: {disabled: "true"}) { "Aria Disabled" }
RUBY
end

render Docs::VisualCodeExample.new(title: "Icon", context: self) do
<<~RUBY
Button(variant: :outline, icon: true) do
svg(
xmlns: "http://www.w3.org/2000/svg",
viewbox: "0 0 20 20",
fill: "currentColor",
class: "w-5 h-5"
) do |s|
s.path(
fill_rule: "evenodd",
d:
"M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z",
clip_rule: "evenodd"
)
end
end
RUBY
end

render Docs::VisualCodeExample.new(title: "With Icon", context: self) do
<<~RUBY
Button(variant: :primary) do
svg(
xmlns: "http://www.w3.org/2000/svg",
fill: "none",
viewbox: "0 0 24 24",
stroke_width: "1.5",
stroke: "currentColor",
class: "w-4 h-4 mr-2"
) do |s|
s.path(
stroke_linecap: "round",
stroke_linejoin: "round",
d:
"M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75"
)
end
span { "Login with Email" }
end
RUBY
end

render Docs::VisualCodeExample.new(title: "With Icon", context: self) do
<<~RUBY
Button(variant: :primary, disabled: true) do
svg(
xmlns: "http://www.w3.org/2000/svg",
viewbox: "0 0 20 20",
fill: "currentColor",
class: "w-4 h-4 mr-2 animate-spin"
) do |s|
s.path(
fill_rule: "evenodd",
d:
"M15.312 11.424a5.5 5.5 0 01-9.201 2.466l-.312-.311h2.433a.75.75 0 000-1.5H3.989a.75.75 0 00-.75.75v4.242a.75.75 0 001.5 0v-2.43l.31.31a7 7 0 0011.712-3.138.75.75 0 00-1.449-.39zm1.23-3.723a.75.75 0 00.219-.53V2.929a.75.75 0 00-1.5 0V5.36l-.31-.31A7 7 0 003.239 8.188a.75.75 0 101.448.389A5.5 5.5 0 0113.89 6.11l.311.31h-2.432a.75.75 0 000 1.5h4.243a.75.75 0 00.53-.219z",
clip_rule: "evenodd"
)
end
span { "Please wait" }
end
RUBY
end

render Docs::VisualCodeExample.new(title: "Submit", context: self) do
<<~RUBY
Button(variant: :primary, type: :submit) do
span { "Submit application" }
end
RUBY
end

render Components::ComponentSetup::Tabs.new(component_name: component)

render Docs::ComponentsTable.new(component_files(component))
end
end
end
14 changes: 14 additions & 0 deletions lib/ruby_ui/docs/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Views
class Base < Phlex::HTML
def Heading(level:, &)
tag = :"h#{level}"
send(tag, &)
end

def component_files(component_name)
[]
end
end
end
15 changes: 15 additions & 0 deletions lib/ruby_ui/docs/component_setup_tabs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module Components
module ComponentSetup
class Tabs < Phlex::HTML
def initialize(component_name:)
@component_name = component_name
end

def view_template
# Minimal stub - empty by default
end
end
end
end
13 changes: 13 additions & 0 deletions lib/ruby_ui/docs/components_table.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

module Docs
class ComponentsTable < Phlex::HTML
def initialize(files)
@files = files
end

def view_template
# Minimal stub - empty by default
end
end
end
17 changes: 17 additions & 0 deletions lib/ruby_ui/docs/header.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

module Docs
class Header < Phlex::HTML
def initialize(title:, description: nil)
@title = title
@description = description
end

def view_template
div do
h1 { @title }
p { @description } if @description
end
end
end
end
19 changes: 19 additions & 0 deletions lib/ruby_ui/docs/visual_code_example.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module Docs
class VisualCodeExample < Phlex::HTML
def initialize(title:, context:)
@title = title
@context = context
end

def view_template(&block)
code = block.call
div do
h3 { @title }
pre { code }
@context.instance_eval(code)
end
end
end
end
2 changes: 1 addition & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
module RubyUI
extend Phlex::Kit

Dir.glob("lib/ruby_ui/**/*.rb").map do |path|
Dir.glob("lib/ruby_ui/**/*.rb").reject { |f| f.include?("/docs/") || f.end_with?("_docs.rb") }.map do |path|
class_name = path.split("/").last.delete_suffix(".rb").split("_").map(&:capitalize).join.to_sym

autoload class_name, path
Expand Down