ViewComponent / view_component

A framework for building reusable, testable & encapsulated view components in Ruby on Rails.
https://viewcomponent.org
MIT License
3.3k stars 431 forks source link

Component and View Colocation #618

Open BlakeWilliams opened 3 years ago

BlakeWilliams commented 3 years ago

Currently, components live in a dedicated app/components directory. This has worked well so far, but we'd like to explore a more unified approach.

This isn't set in stone, but the goals would be to:

A more complete example may look like:

# app/controllers/users_controller.rb
class UsersController < ApplicationController
  def show
    user = User.find(params[:id])
    render :show, user: user
  end
end
# app/views/users/show.rb
class Users::Show < ViewComponent::Base
  def initialize(user:)
    @user = user
  end
end
<%# app/views/users/show.html.erb %>
<div>
  <h1><%= @user.name %>'s page!</h1>
   <%= render "users/profile_content", user: user # will render the app/views/users/profile_content.rb component %>
</div>

part of https://github.com/github/view_component/issues/617

MatheusRich commented 3 years ago

Related: https://github.com/github/view_component/discussions/588

BlakeWilliams commented 3 years ago

I've spiked this out a bit here: https://github.com/BlakeWilliams/view_component-rails-test/pull/1/files (PR's showing off other ideas or approaches are welcome)

Some take-aways:

I think the flexibility of view components (e.g. user defined initializers) may make it more challenging to make them work with Rails as seamlessly as we'd like, but I'll keep experimenting with it.

choilive commented 3 years ago

@BlakeWilliams I actually prefer the explicit object instantiation over using strings. Makes it easier to refactor and also makes it clearer that it is a "component" and not a partial. Would be OK with being able to use both ways though as a matter of user preference.

At the moment I feel like trying to unify view components with the existing rails approach to views seems like it would be a bit inconsistent . View_component encourages a more django-like "views and templates" approach that doesn't seem like it would mesh well. Perhaps I just need to play around more with it and see how it would work in practice.

boardfish commented 3 years ago

Just found out about this issue while I've been looking around.

Some observations here:

# app/controllers/some_controller.rb
def index
  assigns.posts = Post.all
  # Behind the scenes, the controller will do this:
  # render Index.new, **assigns
end

Effectively, we'd be emulating the idea that you build up instance variables in the controller and pass them to the view, but we'd instead be doing this through assigns so that anything passed to the view (component) is still contained to that component.

boardfish commented 1 year ago

1412 brought this to my attention again. A couple of quick draft thoughts:

Spone commented 1 year ago

Relevant wizardry using Phlex: https://fly.io/ruby-dispatch/component-driven-development-on-rails-with-phlex/ I'm posting it here, since it might give some ideas on the above points.

bradgessler commented 3 months ago

So awesome to see this come to life!

boardfish commented 3 months ago

Ditto that! It would be amazing to use ViewComponent as a view and view model layer in Rails 🎉

joelhawksley commented 3 months ago

@bradgessler @joeldrapper giving dhh's closing of the Rails PR, what do you think about writing a shared gem for implicit renderable rendering that both ViewComponent and Phlex could share?

joeldrapper commented 3 months ago

Yeah, that makes sense to me. Phlex-Rails could depend on that gem.

joelhawksley commented 3 months ago

@joeldrapper great. Want to pick a name? rails-implicit-renderable-rendering?

reeganviljoen commented 2 months ago

@joeldrapper @joelhawksley I really liked this idea, and just put together some code here, mind taking a look https://github.com/reeganviljoen/render_kit