Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save AnalyzePlatypus/77e7e164dd5eb80a70b5c0ee62f80fed to your computer and use it in GitHub Desktop.

Select an option

Save AnalyzePlatypus/77e7e164dd5eb80a70b5c0ee62f80fed to your computer and use it in GitHub Desktop.

Revisions

  1. AnalyzePlatypus revised this gist Mar 9, 2025. 1 changed file with 6 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions rails_view_component_tailwind__component_css_files.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,7 @@
    # ViewComponents: Individual component CSS files

    [ViewComponent](https://viewcomponent.org/) is a Rails library for building reusable front-end components.

    I prefer to colocate my component-specific CSS within the component's directory.

    For example, `table` is stored like this:
    @@ -16,6 +18,10 @@ app/

    I think this layout is clean and easy to understand.

    I heavily use [Tailwind CSS](http://tailwindcss.com), and I want any additional CSS files to be run through Tailwind's pipeline so I can use the `@apply` directive.

    > For my Stimulus.js setup, see [this gist](https://gist.github.com/AnalyzePlatypus/3305d91593a0146a8ea23953c76a8949).
    ## Setting up CSS imports for controllers

    ### TL;DR:
  2. AnalyzePlatypus created this gist Mar 9, 2025.
    111 changes: 111 additions & 0 deletions rails_view_component_tailwind__component_css_files.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,111 @@
    # ViewComponents: Individual component CSS files

    I prefer to colocate my component-specific CSS within the component's directory.

    For example, `table` is stored like this:

    ```
    app/
    β”œβ”€ components/
    β”œβ”€ table/
    β”œβ”€ table_component.rb
    β”œβ”€ table_component.html.erb
    β”œβ”€ table_component.css
    β”œβ”€ table_component_controller.js
    ```

    I think this layout is clean and easy to understand.

    ## Setting up CSS imports for controllers

    ### TL;DR:
    * A Rake task finds all component CSS, and generates a CSS file that contains all the imports.
    * Import the generated file into the main CSS file.
    * An optional process watches the `app/components` directory and regenerates the import file when changes are made.

    ### 1. Creating the task

    Create `lib/tasks/component_css.rake`:

    ```ruby
    namespace :build do
    desc "Generate _components.css with imports for all component CSS files"
    task :component_css do
    components_dir = Rails.root.join("app/components")
    css_files = Dir.glob("#{components_dir}/**/*.css")

    imports = css_files.map { |file| "@import \"../../components/#{file.gsub("#{components_dir}/", "")}\";" }

    output_file = Rails.root.join("app/assets/stylesheets/_components.css")
    file_leading_comment = "/* This file is auto-generated by the task `rake build:component_css`.\n Instead of modifying it directly, re-run the task. */\n\n"

    File.write(output_file, file_leading_comment + imports.join("\n"))

    puts "βœ… Updated _components.css with #{css_files.count} components."
    end
    end
    ```

    Running `rake build:component_css` will generate the file `app/assets/stylesheets/_components.css`.
    > Make sure to check it in to your source control. Do not add this to `.gitignore`, even though it's a generated file.
    ### 2. Importing the generated file

    Modify `app/assets/tailwind/application.css`:

    ```css
    @import "../stylesheets/_components.css" layer(utilities);
    ```

    Re-run `rake build:component_css` after you add any new component CSS files.

    (If you don't want to remember this, add a custom file watcher to your dev environment in the next step.)

    ### 3. [Optional] Add a watch process to regenerate the file when new CSS files are created

    We'll use the `listen` gem to build a file watcher.
    1. `bundle add listen --group=development`
    2. Create the watch script and make it executable:

    ```bash
    touch bin/component-css
    chmod +x bin/component-css
    ```

    3. Write the watch script:

    ```ruby
    #!/usr/bin/env ruby

    require 'listen'

    # Path to watch
    watch_dirs = ['app/components']

    # Callback function
    listener = Listen.to(*watch_dirs, only: /\.css$/) do |_modified, _added, _removed|
    puts "[WATCHER] Detected changes in component CSS files. Running rake task..."
    system("bin/rails build:component_css")
    end

    puts "[WATCHER] Watching component CSS..."
    listener.start
    sleep
    ```

    4. Add to `Procfile` (or `Procfile.dev`):

    ```
    component_css: bin/component-css
    ```

    Finally, restart the dev server: `bin/dev`

    ## **πŸŽ‰ Done!**

    * βœ… All component CSS is automatically inlined into your main CSS file
    * βœ… Tailwind can be used in all component CSS files
    * βœ… Any new component CSS files will be automatically detected and added to the build.

    > πŸ’‘ **Note:** The app build process doesn't need to be changed, because the generated `_component.css` CSS file is checked in to source control