Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create previews for components #55

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@

# rspec failure tracking
.rspec_status

# combustion
spec/internal/db/*.sqlite
spec/internal/log
spec/internal/tmp
21 changes: 16 additions & 5 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@

source "https://rubygems.org"

# Specify your gem's dependencies in view_component-form.gemspec
gemspec

gem "appraisal", require: false
gem "capybara", require: false
gem "combustion", "~> 1.3.7"
gem "combustion"
gem "generator_spec"
gem "rails"
gem "rake", "~> 13.0"
Expand All @@ -18,4 +15,18 @@ gem "rubocop", require: false
gem "rubocop-performance", require: false
gem "rubocop-rspec", require: false
gem "simplecov", require: false, group: :test
gem "sqlite3", require: false, group: :test
gem "sqlite3"

group :development do
gem "view_component"

gem "lookbook", ">= 2.0.0.beta.3"
gem "puma"

# Optional dependencies of Lookbook 2.0
gem "actioncable"
gem "listen"
end

# Specify your gem's dependencies in view_component-form.gemspec
gemspec
54 changes: 44 additions & 10 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -98,22 +98,41 @@ GEM
thor (>= 0.14.6)
concurrent-ruby (1.2.0)
crass (1.0.6)
css_parser (1.14.0)
addressable
date (3.3.3)
diff-lcs (1.5.0)
docile (1.4.0)
erubi (1.12.0)
ffi (1.15.5)
generator_spec (0.9.4)
activesupport (>= 3.0.0)
railties (>= 3.0.0)
globalid (1.1.0)
activesupport (>= 5.0)
htmlbeautifier (1.4.2)
htmlentities (4.3.4)
i18n (1.12.0)
concurrent-ruby (~> 1.0)
json (2.6.3)
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
loofah (2.19.1)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.8.0.1)
lookbook (2.0.0.beta.3)
activemodel
css_parser
htmlbeautifier (~> 1.3)
htmlentities (~> 4.3.4)
railties (>= 5.0)
redcarpet (~> 3.5)
rouge (>= 3.26, < 5.0)
view_component (>= 2.0)
yard (~> 0.9.25)
zeitwerk (~> 2.5)
mail (2.8.1)
mini_mime (>= 0.1.1)
net-imap
net-pop
Expand All @@ -134,17 +153,19 @@ GEM
net-smtp (0.3.3)
net-protocol
nio4r (2.5.8)
nokogiri (1.14.1)
nokogiri (1.14.2)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
nokogiri (1.14.1-x86_64-darwin)
nokogiri (1.14.2-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.14.1-x86_64-linux)
nokogiri (1.14.2-x86_64-linux)
racc (~> 1.4)
parallel (1.22.1)
parser (3.2.0.0)
ast (~> 2.4.1)
public_suffix (5.0.1)
puma (6.0.2)
nio4r (~> 2.0)
racc (1.6.2)
rack (2.2.6.2)
rack-test (2.0.2)
Expand Down Expand Up @@ -177,13 +198,18 @@ GEM
zeitwerk (~> 2.5)
rainbow (3.1.1)
rake (13.0.6)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
redcarpet (3.6.0)
regexp_parser (2.6.2)
rexml (3.2.5)
rouge (4.1.0)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.0)
rspec-core (3.12.1)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.2)
diff-lcs (>= 1.2.0, < 2.0)
Expand Down Expand Up @@ -217,7 +243,7 @@ GEM
parser (>= 3.1.1.0)
rubocop-capybara (2.17.0)
rubocop (~> 1.41)
rubocop-performance (1.15.2)
rubocop-performance (1.16.0)
rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0)
rubocop-rspec (2.18.1)
Expand All @@ -239,27 +265,34 @@ GEM
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.4.2)
view_component (3.0.0.rc1)
view_component (2.82.0)
activesupport (>= 5.2.0, < 8.0)
concurrent-ruby (~> 1.0)
method_source (~> 1.0)
webrick (1.7.0)
websocket-driver (0.7.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.6.6)
yard (0.9.28)
webrick (~> 1.7.0)
zeitwerk (2.6.7)

PLATFORMS
ruby
x86_64-darwin-19
x86_64-linux

DEPENDENCIES
actioncable
appraisal
capybara
combustion (~> 1.3.7)
combustion
generator_spec
listen
lookbook (>= 2.0.0.beta.3)
puma
rails
rake (~> 13.0)
rspec (~> 3.0)
Expand All @@ -270,7 +303,8 @@ DEPENDENCIES
rubocop-rspec
simplecov
sqlite3
view_component
view_component-form!

BUNDLED WITH
2.2.33
2.4.6
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,10 +389,10 @@ end
# spec/components/form/text_field_component_spec.rb
RSpec.describe Form::TextFieldComponent, type: :component do
let(:object) { User.new } # replace with a model of your choice
let(:form) { form_with(object) }
let(:form) { form_with(model: object) }
let(:options) { {} }

let(:component) { render_inline(described_class.new(form, object_name, :first_name, options)) }
let(:component) { render_inline(described_class.new(form, :user, :first_name, options)) }

context "with simple args" do
it do
Expand Down
20 changes: 18 additions & 2 deletions config.ru
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
# frozen_string_literal: true

ENV["RAILS_ENV"] ||= "development"

require "rubygems"
require "bundler"

Bundler.require :default, :development
Bundler.require(:default, :development)

Combustion.initialize! :all do
config.logger = ActiveSupport::TaggedLogging.new(Logger.new(nil))
config.log_level = :fatal

config.cache_classes = false

config.file_watcher = ActiveSupport::EventedFileUpdateChecker

config.view_component.preview_paths << Rails.root.join("test/components/previews")
config.view_component.default_preview_layout = "component_preview"

config.lookbook.project_name = "ViewComponent::Form"
config.lookbook.listen_paths << Rails.root.join("../../app/components")
end

Combustion.initialize! :all
run Combustion::Application
31 changes: 26 additions & 5 deletions lib/view_component/form/test_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,40 @@
module ViewComponent
module Form
module TestHelpers
def form_with(object, builder: ViewComponent::Form::Builder, **options)
builder.new(object_name, object, template, options)
include ActionView::ModelNaming

# See: https://github.com/rails/rails/blob/83217025a171593547d1268651b446d3533e2019/actionview/lib/action_view/helpers/form_helper.rb#L737
def form_with(model: nil, scope: nil, **options)
if model
model = model.last if model.is_a?(Array)
scope ||= model_name_from_record_or_class(model)&.param_key
end

instanciate_form_builder(scope, model, **options)
end

def object_name
:user
# See: https://github.com/rails/rails/blob/83217025a171593547d1268651b446d3533e2019/actionview/lib/action_view/helpers/form_helper.rb#L1561
def instanciate_form_builder(record_name, record_object = nil, **options)
case record_name
when String, Symbol
object = record_object
object_name = record_name
else
object = record_name
object_name = model_name_from_record_or_class(object).param_key if object
end

builder = options[:builder] || ViewComponent::Form::Builder
builder.new(object_name, object, template, options)
end

private

if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new("6.1")
def template
lookup_context = ActionView::LookupContext.new(ActionController::Base.view_paths)

ActionView::Base.new(lookup_context, {}, ApplicationController.new)
ActionView::Base.new(lookup_context, {}, ActionController::Base.view_paths)
end
else
def template
Expand Down
Empty file.
Empty file.
4 changes: 4 additions & 0 deletions spec/internal/app/models/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

class User < ActiveRecord::Base
end
18 changes: 18 additions & 0 deletions spec/internal/app/views/layouts/component_preview.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>

<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<%= csrf_meta_tags %>
<%= csp_meta_tag %>

<%#= stylesheet_pack_tag "application", media: "all", "data-turbo-track": "reload" %>
<%#= javascript_pack_tag "application", "data-turbo-track": "reload" %>
</head>

<body>
<%= yield %>
</body>
</html>
4 changes: 4 additions & 0 deletions spec/internal/config/database.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
development:
adapter: sqlite3
database: db/combustion_development.sqlite

test:
adapter: sqlite3
database: db/combustion_test.sqlite
2 changes: 2 additions & 0 deletions spec/internal/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

Rails.application.routes.draw do
# Add your own routes here, or remove this file if you don't have need for it.

mount Lookbook::Engine, at: "/" if Rails.env.development?
end
5 changes: 5 additions & 0 deletions spec/internal/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@

create_table(:cities, force: true) do |t|
t.belongs_to :country
end

create_table(:users, force: true) do |t|
t.string :first_name
t.string :last_name
t.timestamps
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

require "view_component/form/test_helpers"

module ViewComponent
module Form
class LabelComponentPreview < ViewComponent::Preview
include ViewComponent::Form::TestHelpers

def default
# TODO: maybe stop passing object_name to components since
# it is accessing from form_builder (delegated in BaseComponent)
render ViewComponent::Form::LabelComponent.new(form_builder, form_builder.object_name, :first_name)
end

private

def form_builder
instanciate_form_builder(User.new)
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

require "view_component/form/test_helpers"

module ViewComponent
module Form
class SubmitComponentPreview < ViewComponent::Preview
include ViewComponent::Form::TestHelpers

def default
# TODO: maybe stop passing object_name to components since
# it is accessing from form_builder (delegated in BaseComponent)
render ViewComponent::Form::SubmitComponent.new(form_builder, form_builder.object_name)
end

private

def form_builder
instanciate_form_builder(User.new)
end
end
end
end
Loading