HHH v4

Rails8 ViewComponent load css and stimulus JS files from components folder

Edit
equivalent Web Development
Public
Rails
ViewComponent

In Rails 8 with Propshaft & Importmaps 
 I use ViewComponent (3.21.0) and I would like to store  Stimulus JS controllers and vanilla CSS files from within component folder

Someting like this :
app/
  components/
    tag_component.rb
    tag_component.html.erb
    tag_component_controller.js
    tag_component.css

Example content:

/* app/components/tag_component.css */
.tag {
  display: inline-block;
  padding: 0.5em 1em;
  background: #f44336;
  color: #fff;
}

// app/components/tag_component_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  connect() {
    alert("Hello World!")
  }
}

# app/components/tag_component.rb
class TagComponent < ApplicationComponent
  def initialize(title:)
    @title = title
  end
end

# app/components/tag_component.html.erb
<div class="tag" data-controller="tag-component">
  <%= @title %>
</div>

# app/views/pages/index.html.erb

<%= render(TagComponent.new(title: "Foo") %>


To achieve this I need to tell Propshaft and Importmaps to include `app/components` folder

# config/initializers/assets.rb
# ...
+Rails.application.config.assets.paths << "app/components"
+Rails.application.config.importmap.cache_sweepers << Rails.root.join("app/components")

# config/importmap.rb
# ...
pin_all_from "app/components", under: "controllers", to: ""

Importmaps will recognize the JS file and Alert will pop (sofar code is production ready)

One more improvement we can do is to define 

# app/components/application_component.rb
class ApplicationComponent < ViewComponent::Base
  def stimulus_controller
    "#{self.class.name.underscore.dasherize.gsub('/', '--')}"
  end
end

# app/components/tag_component.html.erb
<div class="tag" data-controller="<%= stimulus_controller %>">
  <%= @title %>
</div>

Everything sofar is heavily inspired by article https://blog.theamazingrando.com/posts/rails-propshaft-stimulus-viewcomponent.html

When it comes to our CSS Propshaft needs explicitly load the component css from <style> tag. Sofar I got this ( following is not production ready)

# app/views/layouts/application.html.erb
#...
<head>
  <%# Includes all stylesheet files in app/assets/stylesheets %>
  <%= stylesheet_link_tag :app, "data-turbo-track": "reload" %>

  <% Dir.glob("app/components/**/*.css").map{ File.basename(it, ".css") }.each do %>
    <%= stylesheet_link_tag it, "data-turbo-track": "reload" %>
  <% end %>

  <%= javascript_importmap_tags %>
</head>
#...