view_component 2.44.0 → 2.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of view_component might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +2 -1
- data/app/controllers/view_components_controller.rb +1 -2
- data/app/helpers/preview_helper.rb +52 -4
- data/app/views/view_components/_preview_source.html.erb +3 -3
- data/app/views/view_components/preview.html.erb +7 -3
- data/docs/CHANGELOG.md +219 -16
- data/lib/rails/generators/abstract_generator.rb +5 -1
- data/lib/rails/generators/component/component_generator.rb +3 -0
- data/lib/rails/generators/component/templates/component.rb.tt +1 -1
- data/lib/rails/generators/locale/component_generator.rb +46 -0
- data/lib/rails/generators/stimulus/component_generator.rb +1 -1
- data/lib/rails/generators/tailwindcss/component_generator.rb +11 -0
- data/lib/rails/generators/tailwindcss/templates/component.html.erb.tt +1 -0
- data/lib/view_component/base.rb +44 -12
- data/lib/view_component/collection.rb +20 -6
- data/lib/view_component/compile_cache.rb +5 -1
- data/lib/view_component/compiler.rb +85 -42
- data/lib/view_component/engine.rb +19 -1
- data/lib/view_component/preview.rb +1 -1
- data/lib/view_component/slot_v2.rb +4 -2
- data/lib/view_component/slotable.rb +4 -4
- data/lib/view_component/slotable_v2.rb +3 -3
- data/lib/view_component/test_helpers.rb +8 -2
- data/lib/view_component/version.rb +1 -1
- data/lib/view_component.rb +10 -1
- metadata +24 -7
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 3abce9e08dcb71614178ed68b9c8443211ff78790911057752d8fda6fbb194b7
         | 
| 4 | 
            +
              data.tar.gz: 3ac0a8ff1d7cafd2eb12e04a24f1d8f3362675833e4fda780bc238b8fc5ed41f
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: dba31d0d37e73b7a1e26863d167f5d1eaefb8c5f53d9f542e47667090802b5f53b5c6b9c4b0a9188bf76f42d375c5d7a2cd3024065620aa9ff40b15911706cb8
         | 
| 7 | 
            +
              data.tar.gz: f329872b25f36fe8fa0d018c2a5847ed0b6e47b095d16a27e89d2b0c7180f938d09730d0868405483a8e7c4fe4075afed56927a018b7a273ac4c94950d174fac
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,4 +1,5 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            
         | 
| 2 | 
            +
            
         | 
| 2 3 |  | 
| 3 4 | 
             
            A framework for building reusable, testable & encapsulated view components in Ruby on Rails.
         | 
| 4 5 |  | 
| @@ -29,12 +29,11 @@ class ViewComponentsController < Rails::ApplicationController # :nodoc: | |
| 29 29 | 
             
                  @example_name = File.basename(params[:path])
         | 
| 30 30 | 
             
                  @render_args = @preview.render_args(@example_name, params: params.permit!)
         | 
| 31 31 | 
             
                  layout = determine_layout(@render_args[:layout], prepend_views: false)[:layout]
         | 
| 32 | 
            -
                  template = @render_args[:template]
         | 
| 33 32 | 
             
                  locals = @render_args[:locals]
         | 
| 34 33 | 
             
                  opts = {}
         | 
| 35 34 | 
             
                  opts[:layout] = layout if layout.present? || layout == false
         | 
| 36 35 | 
             
                  opts[:locals] = locals if locals.present?
         | 
| 37 | 
            -
                  render  | 
| 36 | 
            +
                  render "view_components/preview", opts # rubocop:disable GitHub/RailsControllerRenderLiteral
         | 
| 38 37 | 
             
                end
         | 
| 39 38 | 
             
              end
         | 
| 40 39 |  | 
| @@ -4,16 +4,64 @@ module PreviewHelper | |
| 4 4 | 
             
              AVAILABLE_PRISM_LANGUAGES = ["ruby", "erb", "haml"]
         | 
| 5 5 | 
             
              FALLBACK_LANGUAGE = "ruby"
         | 
| 6 6 |  | 
| 7 | 
            -
              def  | 
| 7 | 
            +
              def preview_source
         | 
| 8 | 
            +
                return if @render_args.nil?
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                render "preview_source" # rubocop:disable GitHub/RailsViewRenderPathsExist
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              def find_template_data(lookup_context:, template_identifier:)
         | 
| 14 | 
            +
                template = lookup_context.find_template(template_identifier)
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                if Rails.version.to_f >= 6.1 || template.source.present?
         | 
| 17 | 
            +
                  return {
         | 
| 18 | 
            +
                    source: template.source,
         | 
| 19 | 
            +
                    prism_language_name: prism_language_name_by_template(template: template)
         | 
| 20 | 
            +
                  }
         | 
| 21 | 
            +
                else
         | 
| 22 | 
            +
                  # Fetch template source via finding it through preview paths
         | 
| 23 | 
            +
                  # to accomodate source view when exclusively using templates
         | 
| 24 | 
            +
                  # for previews for Rails < 6.1.
         | 
| 25 | 
            +
                  all_template_paths = ViewComponent::Base.preview_paths.map do |preview_path|
         | 
| 26 | 
            +
                    Dir.glob("#{preview_path}/**/*")
         | 
| 27 | 
            +
                  end.flatten
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  # Search for templates the contain `html`.
         | 
| 30 | 
            +
                  matching_templates = all_template_paths.find_all do |template|
         | 
| 31 | 
            +
                    template =~ /#{template_identifier}*.(html)/
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  # In-case of a conflict due to multiple template files with
         | 
| 35 | 
            +
                  # the same name
         | 
| 36 | 
            +
                  raise "found 0 matches for templates for #{template_identifier}." if matching_templates.empty?
         | 
| 37 | 
            +
                  raise "found multiple templates for #{template_identifier}." if matching_templates.size > 1
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  template_file_path = matching_templates.first
         | 
| 40 | 
            +
                  template_source = File.read(template_file_path)
         | 
| 41 | 
            +
                  prism_language_name = prism_language_name_by_template_path(template_file_path: template_file_path)
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  return {
         | 
| 44 | 
            +
                    source: template_source,
         | 
| 45 | 
            +
                    prism_language_name: prism_language_name
         | 
| 46 | 
            +
                  }
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              private
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              def prism_language_name_by_template(template:)
         | 
| 8 53 | 
             
                language = template.identifier.split(".").last
         | 
| 54 | 
            +
             | 
| 9 55 | 
             
                return FALLBACK_LANGUAGE unless AVAILABLE_PRISM_LANGUAGES.include? language
         | 
| 10 56 |  | 
| 11 57 | 
             
                language
         | 
| 12 58 | 
             
              end
         | 
| 13 59 |  | 
| 14 | 
            -
              def  | 
| 15 | 
            -
                 | 
| 60 | 
            +
              def prism_language_name_by_template_path(template_file_path:)
         | 
| 61 | 
            +
                language = template_file_path.gsub(".html", "").split(".").last
         | 
| 16 62 |  | 
| 17 | 
            -
                 | 
| 63 | 
            +
                return FALLBACK_LANGUAGE unless AVAILABLE_PRISM_LANGUAGES.include? language
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                language
         | 
| 18 66 | 
             
              end
         | 
| 19 67 | 
             
            end
         | 
| @@ -7,9 +7,9 @@ | |
| 7 7 | 
             
                    <%= h @preview.preview_source(@example_name) %>
         | 
| 8 8 | 
             
                  </code>
         | 
| 9 9 | 
             
                <% else %>
         | 
| 10 | 
            -
                  <%  | 
| 11 | 
            -
                  <code class="language-<%= prism_language_name | 
| 12 | 
            -
                    <%= h  | 
| 10 | 
            +
                  <% template_data = find_template_data(lookup_context: @view_renderer.lookup_context, template_identifier: @render_args[:template]) %>
         | 
| 11 | 
            +
                  <code class="language-<%= template_data[:prism_language_name] %>">
         | 
| 12 | 
            +
                    <%= h template_data[:source] %>
         | 
| 13 13 | 
             
                  </code>
         | 
| 14 14 | 
             
                <% end %>
         | 
| 15 15 | 
             
              </pre>
         | 
| @@ -1,7 +1,11 @@ | |
| 1 | 
            -
            <% if  | 
| 2 | 
            -
               | 
| 1 | 
            +
            <% if @render_args[:component] %>
         | 
| 2 | 
            +
              <% if ViewComponent::Base.render_monkey_patch_enabled || Rails.version.to_f >= 6.1 %>
         | 
| 3 | 
            +
                <%= render(@render_args[:component], @render_args[:args], &@render_args[:block]) %>
         | 
| 4 | 
            +
              <% else %>
         | 
| 5 | 
            +
                <%= render_component(@render_args[:component], &@render_args[:block]) %>
         | 
| 6 | 
            +
              <% end %>
         | 
| 3 7 | 
             
            <% else %>
         | 
| 4 | 
            -
              <%=  | 
| 8 | 
            +
              <%= render template: @render_args[:template], locals: @render_args[:locals] || {} %>
         | 
| 5 9 | 
             
            <% end %>
         | 
| 6 10 |  | 
| 7 11 | 
             
            <% if ViewComponent::Base.show_previews_source %>
         | 
    
        data/docs/CHANGELOG.md
    CHANGED
    
    | @@ -7,6 +7,203 @@ title: Changelog | |
| 7 7 |  | 
| 8 8 | 
             
            ## main
         | 
| 9 9 |  | 
| 10 | 
            +
            ## 2.48.0
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            * Correct path in example test command in Contributing docs.
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                *Mark Wilkinson*
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            * Update link to GOV.UK Components library in the resources list.
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                *Peter Yates*
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            * Add Lookbook to Resources docs page.
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                *Mark Perkins*
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            * Add blocking compiler mode for use in Rails development and testing modes, improving thread safety.
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                *Horia Radu*
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            * Add generators to support `tailwindcss-rails`.
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                *Dino Maric*, *Hans Lemuet*
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            * Add a namespaced component example to docs.
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                *Hans Lemuet*
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            * Setup `Appraisal` to add flexibility when testing ViewComponent against multiple Rails versions.
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                *Hans Lemuet*
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            * Return correct values for `request.path` and `request.query_string` methods when using the `with_request_url` test helper.
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                *Vasiliy Matyushin*
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            * Improve style in generators docs.
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                *Hans Lemuet*
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            * Correctly type Ruby version strings and update Rails versions used in CI configuration.
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                *Hans Lemuet*
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            * Make `ViewComponent::Collection` act like a collection of view components.
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                *Sammy Henningsson*
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            * Update `@param` of `#render_inline` to include `ViewComponent::Collection`.
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                *Yutaka Kamei*
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            * Add Wecasa to users list.
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                *Mohamed Ziata*
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            ## 2.47.0
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            * Display preview source on previews that exclusively use templates.
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                *Edwin Mak*
         | 
| 69 | 
            +
             | 
| 70 | 
            +
            * Add a test to ensure trailing newlines are stripped when rendering with `#render_in`.
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                *Simon Fish*
         | 
| 73 | 
            +
             | 
| 74 | 
            +
            * Add WEBrick as a depenency to the application.
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                *Connor McQuillan*
         | 
| 77 | 
            +
             | 
| 78 | 
            +
            * Update Ruby version in `.tool-versions`.
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                *Connor McQuillan*
         | 
| 81 | 
            +
             | 
| 82 | 
            +
            * Add a test to ensure blocks can be passed into lambda slots without the need for any other arguments.
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                *Simon Fish*
         | 
| 85 | 
            +
             | 
| 86 | 
            +
            * Add linters for file consistency.
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                *Simon Fish*
         | 
| 89 | 
            +
             | 
| 90 | 
            +
            * Add @boardfish to docs/index.md and sort contributors.
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                *Simon Fish*
         | 
| 93 | 
            +
             | 
| 94 | 
            +
            * Set up Codespaces for bug replication.
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                *Simon Fish*
         | 
| 97 | 
            +
             | 
| 98 | 
            +
            * Add instructions for replicating bugs and failures.
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                *Simon Fish*
         | 
| 101 | 
            +
             | 
| 102 | 
            +
            * Make @boardfish a committer.
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                *Joel Hawksley*
         | 
| 105 | 
            +
             | 
| 106 | 
            +
            * Validate collection parameter with Active Model attribute names.
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                *Simon Fish*
         | 
| 109 | 
            +
             | 
| 110 | 
            +
            * Fix `helpers` not working with component slots when rendered more than 2 component levels deep.
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                *Blake Williams*
         | 
| 113 | 
            +
             | 
| 114 | 
            +
            * Update ruby to the latest versions
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                *Pedro Paiva*
         | 
| 117 | 
            +
             | 
| 118 | 
            +
            * Fix `vale` linter config options.
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                *Hans Lemuet*
         | 
| 121 | 
            +
             | 
| 122 | 
            +
            * Improve Contributing docs to include how to run tests for a specific version on Rails.
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                *Hans Lemuet*
         | 
| 125 | 
            +
             | 
| 126 | 
            +
            * Add failing test for default form builder and documentation around known issue.
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                *Simon Fish*
         | 
| 129 | 
            +
             | 
| 130 | 
            +
            * Add `--locale` flag to the component generator. Generates as many locale files as defined in `I18n.available_locales`, alongside the component.
         | 
| 131 | 
            +
            * Add config option `config.view_component.generate_locale` to enable project-wide locale generation.
         | 
| 132 | 
            +
            * Add config option `config.view_component.generate_distinct_locale_files` to enable project-wide per-locale translations file generation.
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                *Bob Maerten*
         | 
| 135 | 
            +
             | 
| 136 | 
            +
            * Add config option `config.view_component.generate_sidecar` to always generate in the sidecar directory.
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                *Gleydson Tavares*
         | 
| 139 | 
            +
             | 
| 140 | 
            +
            ## 2.46.0
         | 
| 141 | 
            +
             | 
| 142 | 
            +
            * Add thread safety to the compiler.
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                *Horia Radu*
         | 
| 145 | 
            +
             | 
| 146 | 
            +
            * Add theme-specific logo images to readme.
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                *Dylan Smith*
         | 
| 149 | 
            +
             | 
| 150 | 
            +
            * Add Orbit to users list.
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                *Nicolas Goutay*
         | 
| 153 | 
            +
             | 
| 154 | 
            +
            * Increase clarity around purpose and use of slots.
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                *Simon Fish*
         | 
| 157 | 
            +
             | 
| 158 | 
            +
            * Deprecate loading `view_component/engine` directly.
         | 
| 159 | 
            +
             | 
| 160 | 
            +
              **Upgrade notice**: You should update your `Gemfile` like this:
         | 
| 161 | 
            +
             | 
| 162 | 
            +
              ```diff
         | 
| 163 | 
            +
              - gem "view_component", require: "view_component/engine"`
         | 
| 164 | 
            +
              + gem "view_component"
         | 
| 165 | 
            +
              ```
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                *Yoshiyuki Hirano*
         | 
| 168 | 
            +
             | 
| 169 | 
            +
            ## 2.45.0
         | 
| 170 | 
            +
             | 
| 171 | 
            +
            * Remove internal APIs from API documentation, fix link to license.
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                *Joel Hawksley*
         | 
| 174 | 
            +
             | 
| 175 | 
            +
            * Add @yhirano55 to triage team.
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                *Joel Hawksley*
         | 
| 178 | 
            +
             | 
| 179 | 
            +
            * Correct a typo in the sample slots code.
         | 
| 180 | 
            +
             | 
| 181 | 
            +
                *Simon Fish*
         | 
| 182 | 
            +
             | 
| 183 | 
            +
            * Add note about `allowed_queries`.
         | 
| 184 | 
            +
             | 
| 185 | 
            +
                *Joel Hawksley*
         | 
| 186 | 
            +
             | 
| 187 | 
            +
            * Add `vale` content linter.
         | 
| 188 | 
            +
             | 
| 189 | 
            +
                *Joel Hawksley*
         | 
| 190 | 
            +
             | 
| 191 | 
            +
            * Remove `require "rails/generators/test_case"` in generator tests.
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                *Yoshiyuki Hirano*
         | 
| 194 | 
            +
             | 
| 195 | 
            +
            * Suppress zeitwerk warning about circular require.
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                *Yoshiyuki Hirano*
         | 
| 198 | 
            +
             | 
| 199 | 
            +
            * Move `test_unit_generator_test.rb` from `test/view_component/` to `test/generators/`.
         | 
| 200 | 
            +
             | 
| 201 | 
            +
                *Yoshiyuki Hirano*
         | 
| 202 | 
            +
             | 
| 203 | 
            +
            * Unify test code of `TestUnitGeneratorTest` with the other generators tests.
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                *Yoshiyuki Hirano*
         | 
| 206 | 
            +
             | 
| 10 207 | 
             
            ## 2.44.0
         | 
| 11 208 |  | 
| 12 209 | 
             
            * Rename internal accessor to use private naming.
         | 
| @@ -142,7 +339,7 @@ title: Changelog | |
| 142 339 |  | 
| 143 340 | 
             
                *Matthew Rider*
         | 
| 144 341 |  | 
| 145 | 
            -
            * Fix bug where `with_collection_parameter`  | 
| 342 | 
            +
            * Fix bug where `with_collection_parameter` didn't inherit from parent component.
         | 
| 146 343 |  | 
| 147 344 | 
             
                *Will Drexler*, *Christian Campoli*
         | 
| 148 345 |  | 
| @@ -346,7 +543,7 @@ title: Changelog | |
| 346 543 |  | 
| 347 544 | 
             
                *Hans Lemuet*
         | 
| 348 545 |  | 
| 349 | 
            -
            * Fix bug where ViewComponents  | 
| 546 | 
            +
            * Fix bug where ViewComponents didn't work in ActionMailers.
         | 
| 350 547 |  | 
| 351 548 | 
             
                *dark-panda*
         | 
| 352 549 |  | 
| @@ -394,7 +591,7 @@ title: Changelog | |
| 394 591 |  | 
| 395 592 | 
             
            ## 2.31.0
         | 
| 396 593 |  | 
| 397 | 
            -
            _Note: This release includes an underlying change to Slots that may affect incorrect usage of the API, where Slots were set on a line prefixed by `<%=`. The result of setting a Slot  | 
| 594 | 
            +
            _Note: This release includes an underlying change to Slots that may affect incorrect usage of the API, where Slots were set on a line prefixed by `<%=`. The result of setting a Slot shouldn't be returned. (`<%`)_
         | 
| 398 595 |  | 
| 399 596 | 
             
            * Add `#with_content` to allow setting content without a block.
         | 
| 400 597 |  | 
| @@ -405,7 +602,7 @@ _Note: This release includes an underlying change to Slots that may affect incor | |
| 405 602 | 
             
                *Mario Schüttel*
         | 
| 406 603 |  | 
| 407 604 | 
             
            * Improve feature parity with Rails translations
         | 
| 408 | 
            -
              * Don't create a translation  | 
| 605 | 
            +
              * Don't create a translation back end if the component has no translation file
         | 
| 409 606 | 
             
              * Mark translation keys ending with `html` as HTML-safe
         | 
| 410 607 | 
             
              * Always convert keys to String
         | 
| 411 608 | 
             
              * Support multiple keys
         | 
| @@ -447,7 +644,7 @@ _Note: This release includes an underlying change to Slots that may affect incor | |
| 447 644 |  | 
| 448 645 | 
             
                *Alex Robbin, Blake Williams*
         | 
| 449 646 |  | 
| 450 | 
            -
            * Experimental: call `._sidecar_files` to fetch the sidecar files for a given list of extensions,  | 
| 647 | 
            +
            * Experimental: call `._sidecar_files` to fetch the sidecar files for a given list of extensions, for example passing `["yml", "yaml"]`.
         | 
| 451 648 |  | 
| 452 649 | 
             
                *Elia Schito*
         | 
| 453 650 |  | 
| @@ -487,11 +684,11 @@ _Note: This release includes an underlying change to Slots that may affect incor | |
| 487 684 |  | 
| 488 685 | 
             
            ## 2.26.0
         | 
| 489 686 |  | 
| 490 | 
            -
            *  | 
| 687 | 
            +
            * Delay evaluating component `content` in `render?`, preventing the `content` block from being evaluated when `render?` returns false.
         | 
| 491 688 |  | 
| 492 689 | 
             
                *Blake Williams*
         | 
| 493 690 |  | 
| 494 | 
            -
            *  | 
| 691 | 
            +
            * Don't generate template when using `--inline` flag.
         | 
| 495 692 |  | 
| 496 693 | 
             
                *Hans Lemuet*
         | 
| 497 694 |  | 
| @@ -552,7 +749,7 @@ _Note: This release includes an underlying change to Slots that may affect incor | |
| 552 749 | 
             
              * `with_slot collection: true` becomes `renders_many`.
         | 
| 553 750 | 
             
              * Slot definitions now accept either a component class, component class name, or a lambda instead of a `class_name:` keyword argument.
         | 
| 554 751 | 
             
              * Slots now support positional arguments.
         | 
| 555 | 
            -
              * Slots no longer use the `content` attribute to render content, instead relying on `to_s`.  | 
| 752 | 
            +
              * Slots no longer use the `content` attribute to render content, instead relying on `to_s`. for example `<%= my_slot %>`.
         | 
| 556 753 | 
             
              * Slot values are no longer set via the `slot` method, and instead use the name of the slot.
         | 
| 557 754 |  | 
| 558 755 | 
             
                *Blake Williams*
         | 
| @@ -615,7 +812,7 @@ _Note: This release includes an underlying change to Slots that may affect incor | |
| 615 812 |  | 
| 616 813 | 
             
            ## 2.18.2
         | 
| 617 814 |  | 
| 618 | 
            -
            * Raise an error if controller or view context is accessed during initialize as they  | 
| 815 | 
            +
            * Raise an error if controller or view context is accessed during initialize as they're only available in render.
         | 
| 619 816 |  | 
| 620 817 | 
             
                *Julian Nadeau*
         | 
| 621 818 |  | 
| @@ -631,7 +828,7 @@ _Note: This release includes an underlying change to Slots that may affect incor | |
| 631 828 |  | 
| 632 829 | 
             
            ## 2.18.0
         | 
| 633 830 |  | 
| 634 | 
            -
            * Fix auto | 
| 831 | 
            +
            * Fix auto loading of previews (changes no longer require a server restart)
         | 
| 635 832 |  | 
| 636 833 | 
             
                *Matt Brictson*
         | 
| 637 834 |  | 
| @@ -724,7 +921,7 @@ _Note: This release includes an underlying change to Slots that may affect incor | |
| 724 921 |  | 
| 725 922 | 
             
            ## 2.10.0
         | 
| 726 923 |  | 
| 727 | 
            -
            * Raise an `ArgumentError` with a helpful message when Ruby  | 
| 924 | 
            +
            * Raise an `ArgumentError` with a helpful message when Ruby can't parse a component class.
         | 
| 728 925 |  | 
| 729 926 | 
             
                *Max Beizer*
         | 
| 730 927 |  | 
| @@ -816,7 +1013,7 @@ _Note: This release includes an underlying change to Slots that may affect incor | |
| 816 1013 |  | 
| 817 1014 | 
             
            ## v2.2.1
         | 
| 818 1015 |  | 
| 819 | 
            -
            * Fix bug where template  | 
| 1016 | 
            +
            * Fix bug where template couldn't be found if `inherited` was redefined.
         | 
| 820 1017 |  | 
| 821 1018 | 
             
                *Joel Hawksley*
         | 
| 822 1019 |  | 
| @@ -832,7 +1029,7 @@ _Note: This release includes an underlying change to Slots that may affect incor | |
| 832 1029 |  | 
| 833 1030 | 
             
            ## v2.1.0
         | 
| 834 1031 |  | 
| 835 | 
            -
            * Support rendering collections ( | 
| 1032 | 
            +
            * Support rendering collections (for example, `render(MyComponent.with_collection(@items))`).
         | 
| 836 1033 |  | 
| 837 1034 | 
             
                *Tim Clem*
         | 
| 838 1035 |  | 
| @@ -854,7 +1051,7 @@ _Note: This release includes an underlying change to Slots that may affect incor | |
| 854 1051 |  | 
| 855 1052 | 
             
                *Andrew Mason*
         | 
| 856 1053 |  | 
| 857 | 
            -
            * ViewComponent generators  | 
| 1054 | 
            +
            * ViewComponent generators don't not prompt for content requirement.
         | 
| 858 1055 |  | 
| 859 1056 | 
             
                *Joel Hawksley*
         | 
| 860 1057 |  | 
| @@ -976,7 +1173,7 @@ _Note: This release includes an underlying change to Slots that may affect incor | |
| 976 1173 |  | 
| 977 1174 | 
             
                *Jon Palmer*
         | 
| 978 1175 |  | 
| 979 | 
            -
            * Add `#render?` hook to  | 
| 1176 | 
            +
            * Add `#render?` hook to allow components to be no-ops.
         | 
| 980 1177 |  | 
| 981 1178 | 
             
                *Kyle Fox*
         | 
| 982 1179 |  | 
| @@ -1044,7 +1241,9 @@ _Note: This release includes an underlying change to Slots that may affect incor | |
| 1044 1241 |  | 
| 1045 1242 | 
             
            * Fix edge case issue with extracting variants from less conventional source_locations.
         | 
| 1046 1243 |  | 
| 1244 | 
            +
            <!-- vale proselint.GenderBias = NO -->
         | 
| 1047 1245 | 
             
                *Ryan Workman*
         | 
| 1246 | 
            +
            <!-- vale proselint.GenderBias = YES -->
         | 
| 1048 1247 |  | 
| 1049 1248 | 
             
            ## v1.6.0
         | 
| 1050 1249 |  | 
| @@ -1080,7 +1279,9 @@ _Note: This release includes an underlying change to Slots that may affect incor | |
| 1080 1279 |  | 
| 1081 1280 | 
             
            * Add support for RSpec to generators.
         | 
| 1082 1281 |  | 
| 1282 | 
            +
            <!-- vale proselint.GenderBias = NO -->
         | 
| 1083 1283 | 
             
                *Dylan Clark, Ryan Workman*
         | 
| 1284 | 
            +
            <!-- vale proselint.GenderBias = YES -->
         | 
| 1084 1285 |  | 
| 1085 1286 | 
             
            * Require controllers as part of setting autoload paths.
         | 
| 1086 1287 |  | 
| @@ -1104,7 +1305,9 @@ Note: `actionview-component` is now loaded by requiring `actionview/component`, | |
| 1104 1305 |  | 
| 1105 1306 | 
             
            * Fix issue with generating component method signatures.
         | 
| 1106 1307 |  | 
| 1308 | 
            +
            <!-- vale proselint.GenderBias = NO -->
         | 
| 1107 1309 | 
             
                *Ryan Workman, Dylan Clark*
         | 
| 1310 | 
            +
            <!-- vale proselint.GenderBias = YES -->
         | 
| 1108 1311 |  | 
| 1109 1312 | 
             
            * Create component generator.
         | 
| 1110 1313 |  | 
| @@ -1176,7 +1379,7 @@ Note: `actionview-component` is now loaded by requiring `actionview/component`, | |
| 1176 1379 |  | 
| 1177 1380 | 
             
            ## v1.3.3
         | 
| 1178 1381 |  | 
| 1179 | 
            -
            *  | 
| 1382 | 
            +
            * Don't raise error when sidecar files that aren't templates exist.
         | 
| 1180 1383 |  | 
| 1181 1384 | 
             
                *Joel Hawksley*
         | 
| 1182 1385 |  | 
| @@ -15,7 +15,7 @@ module ViewComponent | |
| 15 15 | 
             
                end
         | 
| 16 16 |  | 
| 17 17 | 
             
                def destination_directory
         | 
| 18 | 
            -
                  if  | 
| 18 | 
            +
                  if sidecar?
         | 
| 19 19 | 
             
                    File.join(component_path, class_path, destination_file_name)
         | 
| 20 20 | 
             
                  else
         | 
| 21 21 | 
             
                    File.join(component_path, class_path)
         | 
| @@ -42,5 +42,9 @@ module ViewComponent | |
| 42 42 | 
             
                      gsub("/", "--")
         | 
| 43 43 | 
             
                  end
         | 
| 44 44 | 
             
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def sidecar?
         | 
| 47 | 
            +
                  options["sidecar"] || ViewComponent::Base.generate_sidecar
         | 
| 48 | 
            +
                end
         | 
| 45 49 | 
             
              end
         | 
| 46 50 | 
             
            end
         | 
| @@ -15,6 +15,7 @@ module Rails | |
| 15 15 | 
             
                  class_option :parent, type: :string, desc: "The parent class for the generated component"
         | 
| 16 16 | 
             
                  class_option :stimulus, type: :boolean, default: ViewComponent::Base.generate_stimulus_controller
         | 
| 17 17 | 
             
                  class_option :sidecar, type: :boolean, default: false
         | 
| 18 | 
            +
                  class_option :locale, type: :boolean, default: ViewComponent::Base.generate_locale
         | 
| 18 19 |  | 
| 19 20 | 
             
                  def create_component_file
         | 
| 20 21 | 
             
                    template "component.rb", File.join(component_path, class_path, "#{file_name}_component.rb")
         | 
| @@ -26,6 +27,8 @@ module Rails | |
| 26 27 |  | 
| 27 28 | 
             
                  hook_for :stimulus, type: :boolean
         | 
| 28 29 |  | 
| 30 | 
            +
                  hook_for :locale, type: :boolean
         | 
| 31 | 
            +
             | 
| 29 32 | 
             
                  hook_for :template_engine do |instance, template_engine|
         | 
| 30 33 | 
             
                    instance.invoke template_engine, [instance.name]
         | 
| 31 34 | 
             
                  end
         | 
| @@ -6,7 +6,7 @@ class <%= class_name %>Component < <%= parent_class %> | |
| 6 6 | 
             
                <%= initialize_body %>
         | 
| 7 7 | 
             
              end
         | 
| 8 8 | 
             
            <%- end -%>
         | 
| 9 | 
            -
            <%- if initialize_call_method_for_inline? -%> | 
| 9 | 
            +
            <%- if initialize_call_method_for_inline? -%>
         | 
| 10 10 | 
             
              def call
         | 
| 11 11 | 
             
                content_tag :h1, "Hello world!"<%= ", data: { controller: \"#{stimulus_controller}\" }" if options["stimulus"] %>
         | 
| 12 12 | 
             
              end
         | 
| @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "rails/generators/abstract_generator"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Locale
         | 
| 6 | 
            +
              module Generators
         | 
| 7 | 
            +
                class ComponentGenerator < ::Rails::Generators::NamedBase
         | 
| 8 | 
            +
                  include ViewComponent::AbstractGenerator
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  source_root File.expand_path("templates", __dir__)
         | 
| 11 | 
            +
                  argument :attributes, type: :array, default: [], banner: "attribute"
         | 
| 12 | 
            +
                  class_option :sidecar, type: :boolean, default: false
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  def create_locale_file
         | 
| 15 | 
            +
                    if ViewComponent::Base.generate_distinct_locale_files
         | 
| 16 | 
            +
                      I18n.available_locales.each do |locale|
         | 
| 17 | 
            +
                        create_file destination(locale), translations_hash([locale]).to_yaml
         | 
| 18 | 
            +
                      end
         | 
| 19 | 
            +
                    else
         | 
| 20 | 
            +
                      create_file destination, translations_hash(I18n.available_locales).to_yaml
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  private
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  def translations_hash(locales = [:en])
         | 
| 27 | 
            +
                    locales.map { |locale| [locale.to_s, translation_keys] }.to_h
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  def translation_keys
         | 
| 31 | 
            +
                    keys = attributes.map(&:name)
         | 
| 32 | 
            +
                    keys = %w[hello] if keys.empty?
         | 
| 33 | 
            +
                    keys.map { |name| [name, name.capitalize] }.to_h
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  def destination(locale = nil)
         | 
| 37 | 
            +
                    extention = ".#{locale}" if locale
         | 
| 38 | 
            +
                    if sidecar?
         | 
| 39 | 
            +
                      File.join(component_path, class_path, "#{file_name}_component", "#{file_name}_component#{extention}.yml")
         | 
| 40 | 
            +
                    else
         | 
| 41 | 
            +
                      File.join(component_path, class_path, "#{file_name}_component#{extention}.yml")
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
            end
         | 
| @@ -23,7 +23,7 @@ module Stimulus | |
| 23 23 | 
             
                  private
         | 
| 24 24 |  | 
| 25 25 | 
             
                  def destination
         | 
| 26 | 
            -
                    if  | 
| 26 | 
            +
                    if sidecar?
         | 
| 27 27 | 
             
                      File.join(component_path, class_path, "#{file_name}_component", "#{file_name}_component_controller.js")
         | 
| 28 28 | 
             
                    else
         | 
| 29 29 | 
             
                      File.join(component_path, class_path, "#{file_name}_component_controller.js")
         | 
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "rails/generators/erb/component_generator"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Tailwindcss
         | 
| 6 | 
            +
              module Generators
         | 
| 7 | 
            +
                class ComponentGenerator < Erb::Generators::ComponentGenerator
         | 
| 8 | 
            +
                  source_root File.expand_path("templates", __dir__)
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
            end
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            <div<%= data_attributes %>>Add <%= class_name %> template here</div>
         | 
    
        data/lib/view_component/base.rb
    CHANGED
    
    | @@ -152,7 +152,7 @@ module ViewComponent | |
| 152 152 | 
             
                  if view_context.nil?
         | 
| 153 153 | 
             
                    raise(
         | 
| 154 154 | 
             
                      ViewContextCalledBeforeRenderError,
         | 
| 155 | 
            -
                      "`#controller`  | 
| 155 | 
            +
                      "`#controller` can't be used during initialization, as it depends " \
         | 
| 156 156 | 
             
                      "on the view context that only exists once a ViewComponent is passed to " \
         | 
| 157 157 | 
             
                      "the Rails render pipeline.\n\n" \
         | 
| 158 158 | 
             
                      "It's sometimes possible to fix this issue by moving code dependent on " \
         | 
| @@ -171,7 +171,7 @@ module ViewComponent | |
| 171 171 | 
             
                  if view_context.nil?
         | 
| 172 172 | 
             
                    raise(
         | 
| 173 173 | 
             
                      ViewContextCalledBeforeRenderError,
         | 
| 174 | 
            -
                      "`#helpers`  | 
| 174 | 
            +
                      "`#helpers` can't be used during initialization, as it depends " \
         | 
| 175 175 | 
             
                      "on the view context that only exists once a ViewComponent is passed to " \
         | 
| 176 176 | 
             
                      "the Rails render pipeline.\n\n" \
         | 
| 177 177 | 
             
                      "It's sometimes possible to fix this issue by moving code dependent on " \
         | 
| @@ -206,7 +206,7 @@ module ViewComponent | |
| 206 206 | 
             
                #
         | 
| 207 207 | 
             
                # @private
         | 
| 208 208 | 
             
                def format
         | 
| 209 | 
            -
                  # Ruby 2.6 throws a warning without checking `defined?`, 2.7  | 
| 209 | 
            +
                  # Ruby 2.6 throws a warning without checking `defined?`, 2.7 doesn't
         | 
| 210 210 | 
             
                  if defined?(@__vc_variant)
         | 
| 211 211 | 
             
                    @__vc_variant
         | 
| 212 212 | 
             
                  end
         | 
| @@ -279,11 +279,31 @@ module ViewComponent | |
| 279 279 | 
             
                #
         | 
| 280 280 | 
             
                mattr_accessor :generate_stimulus_controller, instance_writer: false, default: false
         | 
| 281 281 |  | 
| 282 | 
            +
                # Always generate translations file alongside the component:
         | 
| 283 | 
            +
                #
         | 
| 284 | 
            +
                #     config.view_component.generate_locale = true
         | 
| 285 | 
            +
                #
         | 
| 286 | 
            +
                # Defaults to `false`.
         | 
| 287 | 
            +
                #
         | 
| 288 | 
            +
                mattr_accessor :generate_locale, instance_writer: false, default: false
         | 
| 289 | 
            +
             | 
| 290 | 
            +
                # Always generate as many translations files as available locales:
         | 
| 291 | 
            +
                #
         | 
| 292 | 
            +
                #     config.view_component.generate_distinct_locale_files = true
         | 
| 293 | 
            +
                #
         | 
| 294 | 
            +
                # Defaults to `false`.
         | 
| 295 | 
            +
                #
         | 
| 296 | 
            +
                # One file will be generated for each configured `I18n.available_locales`.
         | 
| 297 | 
            +
                # Fallback on `[:en]` when no available_locales is defined.
         | 
| 298 | 
            +
                #
         | 
| 299 | 
            +
                mattr_accessor :generate_distinct_locale_files, instance_writer: false, default: false
         | 
| 300 | 
            +
             | 
| 282 301 | 
             
                # Path for component files
         | 
| 283 302 | 
             
                #
         | 
| 284 303 | 
             
                #     config.view_component.view_component_path = "app/my_components"
         | 
| 285 304 | 
             
                #
         | 
| 286 | 
            -
                # Defaults to  | 
| 305 | 
            +
                # Defaults to `app/components`.
         | 
| 306 | 
            +
                #
         | 
| 287 307 | 
             
                mattr_accessor :view_component_path, instance_writer: false, default: "app/components"
         | 
| 288 308 |  | 
| 289 309 | 
             
                # Parent class for generated components
         | 
| @@ -291,8 +311,16 @@ module ViewComponent | |
| 291 311 | 
             
                #     config.view_component.component_parent_class = "MyBaseComponent"
         | 
| 292 312 | 
             
                #
         | 
| 293 313 | 
             
                # Defaults to "ApplicationComponent" if defined, "ViewComponent::Base" otherwise.
         | 
| 294 | 
            -
                 | 
| 295 | 
            -
             | 
| 314 | 
            +
                #
         | 
| 315 | 
            +
                mattr_accessor :component_parent_class, instance_writer: false
         | 
| 316 | 
            +
             | 
| 317 | 
            +
                # Always generate a component with a sidecar directory:
         | 
| 318 | 
            +
                #
         | 
| 319 | 
            +
                #     config.view_component.generate_sidecar = true
         | 
| 320 | 
            +
                #
         | 
| 321 | 
            +
                # Defaults to `false`.
         | 
| 322 | 
            +
                #
         | 
| 323 | 
            +
                mattr_accessor :generate_sidecar, instance_writer: false, default: false
         | 
| 296 324 |  | 
| 297 325 | 
             
                class << self
         | 
| 298 326 | 
             
                  # @private
         | 
| @@ -318,7 +346,7 @@ module ViewComponent | |
| 318 346 |  | 
| 319 347 | 
             
                    # Add support for nested components defined in the same file.
         | 
| 320 348 | 
             
                    #
         | 
| 321 | 
            -
                    #  | 
| 349 | 
            +
                    # for example
         | 
| 322 350 | 
             
                    #
         | 
| 323 351 | 
             
                    # class MyComponent < ViewComponent::Base
         | 
| 324 352 | 
             
                    #   class MyOtherComponent < ViewComponent::Base
         | 
| @@ -431,7 +459,7 @@ module ViewComponent | |
| 431 459 | 
             
                  end
         | 
| 432 460 |  | 
| 433 461 | 
             
                  # Ensure the component initializer accepts the
         | 
| 434 | 
            -
                  # collection parameter. By default, we  | 
| 462 | 
            +
                  # collection parameter. By default, we don't
         | 
| 435 463 | 
             
                  # validate that the default parameter name
         | 
| 436 464 | 
             
                  # is accepted, as support for collection
         | 
| 437 465 | 
             
                  # rendering is optional.
         | 
| @@ -442,7 +470,7 @@ module ViewComponent | |
| 442 470 | 
             
                    return unless parameter
         | 
| 443 471 | 
             
                    return if initialize_parameter_names.include?(parameter)
         | 
| 444 472 |  | 
| 445 | 
            -
                    # If Ruby  | 
| 473 | 
            +
                    # If Ruby can't parse the component class, then the initalize
         | 
| 446 474 | 
             
                    # parameters will be empty and ViewComponent will not be able to render
         | 
| 447 475 | 
             
                    # the component.
         | 
| 448 476 | 
             
                    if initialize_parameters.empty?
         | 
| @@ -455,14 +483,14 @@ module ViewComponent | |
| 455 483 | 
             
                    end
         | 
| 456 484 |  | 
| 457 485 | 
             
                    raise ArgumentError.new(
         | 
| 458 | 
            -
                      "The initializer for #{self}  | 
| 486 | 
            +
                      "The initializer for #{self} doesn't accept the parameter `#{parameter}`, " \
         | 
| 459 487 | 
             
                      "which is required in order to render it as a collection.\n\n" \
         | 
| 460 488 | 
             
                      "To fix this issue, update the initializer to accept `#{parameter}`.\n\n" \
         | 
| 461 489 | 
             
                      "See https://viewcomponent.org/guide/collections.html for more information on rendering collections."
         | 
| 462 490 | 
             
                    )
         | 
| 463 491 | 
             
                  end
         | 
| 464 492 |  | 
| 465 | 
            -
                  # Ensure the component initializer  | 
| 493 | 
            +
                  # Ensure the component initializer doesn't define
         | 
| 466 494 | 
             
                  # invalid parameters that could override the framework's
         | 
| 467 495 | 
             
                  # methods.
         | 
| 468 496 | 
             
                  # @private TODO: add documentation
         | 
| @@ -470,7 +498,7 @@ module ViewComponent | |
| 470 498 | 
             
                    return unless initialize_parameter_names.include?(RESERVED_PARAMETER)
         | 
| 471 499 |  | 
| 472 500 | 
             
                    raise ViewComponent::ComponentError.new(
         | 
| 473 | 
            -
                      "#{self} initializer  | 
| 501 | 
            +
                      "#{self} initializer can't accept the parameter `#{RESERVED_PARAMETER}`, as it will override a " \
         | 
| 474 502 | 
             
                      "public ViewComponent method. To fix this issue, rename the parameter."
         | 
| 475 503 | 
             
                    )
         | 
| 476 504 | 
             
                  end
         | 
| @@ -507,6 +535,10 @@ module ViewComponent | |
| 507 535 | 
             
                  private
         | 
| 508 536 |  | 
| 509 537 | 
             
                  def initialize_parameter_names
         | 
| 538 | 
            +
                    return attribute_names.map(&:to_sym) if respond_to?(:attribute_names)
         | 
| 539 | 
            +
             | 
| 540 | 
            +
                    return attribute_types.keys.map(&:to_sym) if Rails::VERSION::MAJOR <= 5 && respond_to?(:attribute_types)
         | 
| 541 | 
            +
             | 
| 510 542 | 
             
                    initialize_parameters.map(&:last)
         | 
| 511 543 | 
             
                  end
         | 
| 512 544 |  | 
| @@ -4,20 +4,34 @@ require "action_view/renderer/collection_renderer" if Rails.version.to_f >= 6.1 | |
| 4 4 |  | 
| 5 5 | 
             
            module ViewComponent
         | 
| 6 6 | 
             
              class Collection
         | 
| 7 | 
            +
                include Enumerable
         | 
| 7 8 | 
             
                attr_reader :component
         | 
| 8 9 |  | 
| 9 10 | 
             
                delegate :format, to: :component
         | 
| 11 | 
            +
                delegate :size, to: :@collection
         | 
| 10 12 |  | 
| 11 13 | 
             
                def render_in(view_context, &block)
         | 
| 14 | 
            +
                  components.map do |component|
         | 
| 15 | 
            +
                    component.render_in(view_context, &block)
         | 
| 16 | 
            +
                  end.join.html_safe # rubocop:disable Rails/OutputSafety
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def components
         | 
| 20 | 
            +
                  return @components if defined? @components
         | 
| 21 | 
            +
             | 
| 12 22 | 
             
                  iterator = ActionView::PartialIteration.new(@collection.size)
         | 
| 13 23 |  | 
| 14 24 | 
             
                  component.validate_collection_parameter!(validate_default: true)
         | 
| 15 25 |  | 
| 16 | 
            -
                  @collection.map do |item|
         | 
| 17 | 
            -
                     | 
| 18 | 
            -
             | 
| 19 | 
            -
                     | 
| 20 | 
            -
                  end | 
| 26 | 
            +
                  @components = @collection.map do |item|
         | 
| 27 | 
            +
                    component.new(**component_options(item, iterator)).tap do |component|
         | 
| 28 | 
            +
                      iterator.iterate!
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def each(&block)
         | 
| 34 | 
            +
                  components.each(&block)
         | 
| 21 35 | 
             
                end
         | 
| 22 36 |  | 
| 23 37 | 
             
                private
         | 
| @@ -42,7 +56,7 @@ module ViewComponent | |
| 42 56 | 
             
                def component_options(item, iterator)
         | 
| 43 57 | 
             
                  item_options = { component.collection_parameter => item }
         | 
| 44 58 | 
             
                  item_options[component.collection_counter_parameter] = iterator.index + 1 if component.counter_argument_present?
         | 
| 45 | 
            -
                  item_options[component.collection_iteration_parameter] = iterator if component.iteration_argument_present?
         | 
| 59 | 
            +
                  item_options[component.collection_iteration_parameter] = iterator.dup if component.iteration_argument_present?
         | 
| 46 60 |  | 
| 47 61 | 
             
                  @options.merge(item_options)
         | 
| 48 62 | 
             
                end
         | 
| @@ -2,7 +2,7 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            module ViewComponent
         | 
| 4 4 | 
             
              # Keeps track of which templates have already been compiled
         | 
| 5 | 
            -
              # This  | 
| 5 | 
            +
              # This isn't part of the public API
         | 
| 6 6 | 
             
              module CompileCache
         | 
| 7 7 | 
             
                mattr_accessor :cache, instance_reader: false, instance_accessor: false do
         | 
| 8 8 | 
             
                  Set.new
         | 
| @@ -18,6 +18,10 @@ module ViewComponent | |
| 18 18 | 
             
                  cache.include? klass
         | 
| 19 19 | 
             
                end
         | 
| 20 20 |  | 
| 21 | 
            +
                def invalidate_class!(klass)
         | 
| 22 | 
            +
                  cache.delete(klass)
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 21 25 | 
             
                def invalidate!
         | 
| 22 26 | 
             
                  cache.clear
         | 
| 23 27 | 
             
                end
         | 
| @@ -2,66 +2,95 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            module ViewComponent
         | 
| 4 4 | 
             
              class Compiler
         | 
| 5 | 
            +
                # Lock required to be obtained before compiling the component
         | 
| 6 | 
            +
                attr_reader :__vc_compiler_lock
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                # Compiler mode. Can be either:
         | 
| 9 | 
            +
                # * development (a blocking mode which ensures thread safety when redefining the `call` method for components,
         | 
| 10 | 
            +
                #                default in Rails development and test mode)
         | 
| 11 | 
            +
                # * production (a non-blocking mode, default in Rails production mode)
         | 
| 12 | 
            +
                DEVELOPMENT_MODE = :development
         | 
| 13 | 
            +
                PRODUCTION_MODE = :production
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                class_attribute :mode, default: PRODUCTION_MODE
         | 
| 16 | 
            +
             | 
| 5 17 | 
             
                def initialize(component_class)
         | 
| 6 18 | 
             
                  @component_class = component_class
         | 
| 19 | 
            +
                  @__vc_compiler_lock = Monitor.new
         | 
| 7 20 | 
             
                end
         | 
| 8 21 |  | 
| 9 22 | 
             
                def compiled?
         | 
| 10 23 | 
             
                  CompileCache.compiled?(component_class)
         | 
| 11 24 | 
             
                end
         | 
| 12 25 |  | 
| 26 | 
            +
                def development?
         | 
| 27 | 
            +
                  self.class.mode == DEVELOPMENT_MODE
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 13 30 | 
             
                def compile(raise_errors: false)
         | 
| 14 31 | 
             
                  return if compiled?
         | 
| 15 32 |  | 
| 16 | 
            -
                   | 
| 33 | 
            +
                  with_lock do
         | 
| 34 | 
            +
                    CompileCache.invalidate_class!(component_class)
         | 
| 17 35 |  | 
| 18 | 
            -
             | 
| 19 | 
            -
                    raise ViewComponent::ComponentError.new(
         | 
| 20 | 
            -
                      "#{component_class} implements a reserved method, `#with_content`.\n\n" \
         | 
| 21 | 
            -
                      "To fix this issue, change the name of the method."
         | 
| 22 | 
            -
                    )
         | 
| 23 | 
            -
                  end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                  if template_errors.present?
         | 
| 26 | 
            -
                    raise ViewComponent::TemplateError.new(template_errors) if raise_errors
         | 
| 36 | 
            +
                    subclass_instance_methods = component_class.instance_methods(false)
         | 
| 27 37 |  | 
| 28 | 
            -
                     | 
| 29 | 
            -
             | 
| 38 | 
            +
                    if subclass_instance_methods.include?(:with_content) && raise_errors
         | 
| 39 | 
            +
                      raise ViewComponent::ComponentError.new(
         | 
| 40 | 
            +
                        "#{component_class} implements a reserved method, `#with_content`.\n\n" \
         | 
| 41 | 
            +
                        "To fix this issue, change the name of the method."
         | 
| 42 | 
            +
                      )
         | 
| 43 | 
            +
                    end
         | 
| 30 44 |  | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
                      "`#before_render_check` will be removed in v3.0.0.\n\n" \
         | 
| 34 | 
            -
                      "To fix this issue, use `#before_render` instead."
         | 
| 35 | 
            -
                    )
         | 
| 36 | 
            -
                  end
         | 
| 45 | 
            +
                    if template_errors.present?
         | 
| 46 | 
            +
                      raise ViewComponent::TemplateError.new(template_errors) if raise_errors
         | 
| 37 47 |  | 
| 38 | 
            -
             | 
| 39 | 
            -
                     | 
| 40 | 
            -
                    component_class.validate_collection_parameter!
         | 
| 41 | 
            -
                  end
         | 
| 48 | 
            +
                      return false
         | 
| 49 | 
            +
                    end
         | 
| 42 50 |  | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 51 | 
            +
                    if subclass_instance_methods.include?(:before_render_check)
         | 
| 52 | 
            +
                      ActiveSupport::Deprecation.warn(
         | 
| 53 | 
            +
                        "`#before_render_check` will be removed in v3.0.0.\n\n" \
         | 
| 54 | 
            +
                        "To fix this issue, use `#before_render` instead."
         | 
| 55 | 
            +
                      )
         | 
| 56 | 
            +
                    end
         | 
| 47 57 |  | 
| 48 | 
            -
                    if  | 
| 49 | 
            -
                      component_class. | 
| 58 | 
            +
                    if raise_errors
         | 
| 59 | 
            +
                      component_class.validate_initialization_parameters!
         | 
| 60 | 
            +
                      component_class.validate_collection_parameter!
         | 
| 50 61 | 
             
                    end
         | 
| 51 62 |  | 
| 52 | 
            -
                     | 
| 63 | 
            +
                    templates.each do |template|
         | 
| 64 | 
            +
                      # Remove existing compiled template methods,
         | 
| 65 | 
            +
                      # as Ruby warns when redefining a method.
         | 
| 66 | 
            +
                      method_name = call_method_name(template[:variant])
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                      if component_class.instance_methods.include?(method_name.to_sym)
         | 
| 69 | 
            +
                        component_class.send(:undef_method, method_name.to_sym)
         | 
| 70 | 
            +
                      end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                      component_class.class_eval <<-RUBY, template[:path], -1
         | 
| 53 73 | 
             
                      def #{method_name}
         | 
| 54 74 | 
             
                        @output_buffer = ActionView::OutputBuffer.new
         | 
| 55 75 | 
             
                        #{compiled_template(template[:path])}
         | 
| 56 76 | 
             
                      end
         | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 77 | 
            +
                      RUBY
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                    define_render_template_for
         | 
| 59 81 |  | 
| 60 | 
            -
             | 
| 82 | 
            +
                    component_class._after_compile
         | 
| 61 83 |  | 
| 62 | 
            -
             | 
| 84 | 
            +
                    CompileCache.register(component_class)
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
                end
         | 
| 63 87 |  | 
| 64 | 
            -
             | 
| 88 | 
            +
                def with_lock(&block)
         | 
| 89 | 
            +
                  if development?
         | 
| 90 | 
            +
                    __vc_compiler_lock.synchronize(&block)
         | 
| 91 | 
            +
                  else
         | 
| 92 | 
            +
                    block.call
         | 
| 93 | 
            +
                  end
         | 
| 65 94 | 
             
                end
         | 
| 66 95 |  | 
| 67 96 | 
             
                private
         | 
| @@ -77,16 +106,30 @@ module ViewComponent | |
| 77 106 | 
             
                    "elsif variant.to_sym == :#{variant}\n    #{call_method_name(variant)}"
         | 
| 78 107 | 
             
                  end.join("\n")
         | 
| 79 108 |  | 
| 80 | 
            -
                   | 
| 109 | 
            +
                  body = <<-RUBY
         | 
| 110 | 
            +
                    if variant.nil?
         | 
| 111 | 
            +
                      call
         | 
| 112 | 
            +
                    #{variant_elsifs}
         | 
| 113 | 
            +
                    else
         | 
| 114 | 
            +
                      call
         | 
| 115 | 
            +
                    end
         | 
| 116 | 
            +
                  RUBY
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                  if development?
         | 
| 119 | 
            +
                    component_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         | 
| 81 120 | 
             
                    def render_template_for(variant = nil)
         | 
| 82 | 
            -
                       | 
| 83 | 
            -
                         | 
| 84 | 
            -
                      #{variant_elsifs}
         | 
| 85 | 
            -
                      else
         | 
| 86 | 
            -
                        call
         | 
| 121 | 
            +
                      self.class.compiler.with_lock do
         | 
| 122 | 
            +
                        #{body}
         | 
| 87 123 | 
             
                      end
         | 
| 88 124 | 
             
                    end
         | 
| 89 | 
            -
             | 
| 125 | 
            +
                    RUBY
         | 
| 126 | 
            +
                  else
         | 
| 127 | 
            +
                    component_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         | 
| 128 | 
            +
                    def render_template_for(variant = nil)
         | 
| 129 | 
            +
                      #{body}
         | 
| 130 | 
            +
                    end
         | 
| 131 | 
            +
                    RUBY
         | 
| 132 | 
            +
                  end
         | 
| 90 133 | 
             
                end
         | 
| 91 134 |  | 
| 92 135 | 
             
                def template_errors
         | 
| @@ -95,7 +138,7 @@ module ViewComponent | |
| 95 138 | 
             
                      errors = []
         | 
| 96 139 |  | 
| 97 140 | 
             
                      if (templates + inline_calls).empty?
         | 
| 98 | 
            -
                        errors << " | 
| 141 | 
            +
                        errors << "Couldn't find a template file or inline render method for #{component_class}."
         | 
| 99 142 | 
             
                      end
         | 
| 100 143 |  | 
| 101 144 | 
             
                      if templates.count { |template| template[:variant].nil? } > 1
         | 
| @@ -1,7 +1,6 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 3 | 
             
            require "rails"
         | 
| 4 | 
            -
            require "view_component"
         | 
| 5 4 |  | 
| 6 5 | 
             
            module ViewComponent
         | 
| 7 6 | 
             
              class Engine < Rails::Engine # :nodoc:
         | 
| @@ -116,6 +115,14 @@ module ViewComponent | |
| 116 115 | 
             
                  end
         | 
| 117 116 | 
             
                end
         | 
| 118 117 |  | 
| 118 | 
            +
                initializer "compiler mode" do |app|
         | 
| 119 | 
            +
                  ViewComponent::Compiler.mode = if Rails.env.development? || Rails.env.test?
         | 
| 120 | 
            +
                                                   ViewComponent::Compiler::DEVELOPMENT_MODE
         | 
| 121 | 
            +
                                                 else
         | 
| 122 | 
            +
                                                   ViewComponent::Compiler::PRODUCTION_MODE
         | 
| 123 | 
            +
                                                 end
         | 
| 124 | 
            +
                end
         | 
| 125 | 
            +
             | 
| 119 126 | 
             
                config.after_initialize do |app|
         | 
| 120 127 | 
             
                  options = app.config.view_component
         | 
| 121 128 |  | 
| @@ -145,3 +152,14 @@ module ViewComponent | |
| 145 152 | 
             
                end
         | 
| 146 153 | 
             
              end
         | 
| 147 154 | 
             
            end
         | 
| 155 | 
            +
             | 
| 156 | 
            +
            # :nocov:
         | 
| 157 | 
            +
            unless defined?(ViewComponent::Base)
         | 
| 158 | 
            +
              ActiveSupport::Deprecation.warn(
         | 
| 159 | 
            +
                "This manually engine loading is deprecated and will be removed in v3.0.0. " \
         | 
| 160 | 
            +
                "Remove `require \"view_component/engine\"`."
         | 
| 161 | 
            +
              )
         | 
| 162 | 
            +
             | 
| 163 | 
            +
              require "view_component"
         | 
| 164 | 
            +
            end
         | 
| 165 | 
            +
            # :nocov:
         | 
| @@ -80,7 +80,7 @@ module ViewComponent # :nodoc: | |
| 80 80 | 
             
                    if preview_path.nil?
         | 
| 81 81 | 
             
                      raise(
         | 
| 82 82 | 
             
                        PreviewTemplateError,
         | 
| 83 | 
            -
                        "A preview template for example #{example}  | 
| 83 | 
            +
                        "A preview template for example #{example} doesn't exist.\n\n" \
         | 
| 84 84 | 
             
                        "To fix this issue, create a template for the example."
         | 
| 85 85 | 
             
                      )
         | 
| 86 86 | 
             
                    end
         | 
| @@ -20,7 +20,7 @@ module ViewComponent | |
| 20 20 | 
             
                # component, or a function that returns a component, we render that
         | 
| 21 21 | 
             
                # component instance, returning the string.
         | 
| 22 22 | 
             
                #
         | 
| 23 | 
            -
                # If the slot renderable is a function and returns a string, it | 
| 23 | 
            +
                # If the slot renderable is a function and returns a string, it's
         | 
| 24 24 | 
             
                # set as `@__vc_content` and is returned directly.
         | 
| 25 25 | 
             
                #
         | 
| 26 26 | 
             
                # If there is no slot renderable, we evaluate the block passed to
         | 
| @@ -40,6 +40,8 @@ module ViewComponent | |
| 40 40 |  | 
| 41 41 | 
             
                  @content =
         | 
| 42 42 | 
             
                    if defined?(@__vc_component_instance)
         | 
| 43 | 
            +
                      @__vc_component_instance.__vc_original_view_context = @parent.__vc_original_view_context
         | 
| 44 | 
            +
             | 
| 43 45 | 
             
                      if defined?(@__vc_content_set_by_with_content)
         | 
| 44 46 | 
             
                        @__vc_component_instance.with_content(@__vc_content_set_by_with_content)
         | 
| 45 47 |  | 
| @@ -69,7 +71,7 @@ module ViewComponent | |
| 69 71 |  | 
| 70 72 | 
             
                # Allow access to public component methods via the wrapper
         | 
| 71 73 | 
             
                #
         | 
| 72 | 
            -
                #  | 
| 74 | 
            +
                # for example
         | 
| 73 75 | 
             
                #
         | 
| 74 76 | 
             
                # calling `header.name` (where `header` is a slot) will call `name`
         | 
| 75 77 | 
             
                # on the `HeaderComponent` instance.
         | 
| @@ -29,12 +29,12 @@ module ViewComponent | |
| 29 29 | 
             
                    )
         | 
| 30 30 |  | 
| 31 31 | 
             
                    slot_names.each do |slot_name|
         | 
| 32 | 
            -
                      # Ensure slot_name  | 
| 32 | 
            +
                      # Ensure slot_name isn't already declared
         | 
| 33 33 | 
             
                      if self.slots.key?(slot_name)
         | 
| 34 34 | 
             
                        raise ArgumentError.new("#{slot_name} slot declared multiple times")
         | 
| 35 35 | 
             
                      end
         | 
| 36 36 |  | 
| 37 | 
            -
                      # Ensure slot name  | 
| 37 | 
            +
                      # Ensure slot name isn't :content
         | 
| 38 38 | 
             
                      if slot_name == :content
         | 
| 39 39 | 
             
                        raise ArgumentError.new ":content is a reserved slot name. Please use another name, such as ':body'"
         | 
| 40 40 | 
             
                      end
         | 
| @@ -105,7 +105,7 @@ module ViewComponent | |
| 105 105 | 
             
                # <% end %>
         | 
| 106 106 | 
             
                #
         | 
| 107 107 | 
             
                def slot(slot_name, **args, &block)
         | 
| 108 | 
            -
                  # Raise ArgumentError if `slot`  | 
| 108 | 
            +
                  # Raise ArgumentError if `slot` doesn't exist
         | 
| 109 109 | 
             
                  unless slots.keys.include?(slot_name)
         | 
| 110 110 | 
             
                    raise ArgumentError.new "Unknown slot '#{slot_name}' - expected one of '#{slots.keys}'"
         | 
| 111 111 | 
             
                  end
         | 
| @@ -140,7 +140,7 @@ module ViewComponent | |
| 140 140 | 
             
                    instance_variable_set(slot[:instance_variable_name], slot_instance)
         | 
| 141 141 | 
             
                  end
         | 
| 142 142 |  | 
| 143 | 
            -
                  # Return nil, as this method  | 
| 143 | 
            +
                  # Return nil, as this method shouldn't output anything to the view itself.
         | 
| 144 144 | 
             
                  nil
         | 
| 145 145 | 
             
                end
         | 
| 146 146 | 
             
              end
         | 
| @@ -121,7 +121,7 @@ module ViewComponent | |
| 121 121 | 
             
                    singular_name = ActiveSupport::Inflector.singularize(slot_name)
         | 
| 122 122 |  | 
| 123 123 | 
             
                    # Define setter for singular names
         | 
| 124 | 
            -
                    #  | 
| 124 | 
            +
                    # for example `renders_many :items` allows fetching all tabs with
         | 
| 125 125 | 
             
                    # `component.tabs` and setting a tab with `component.tab`
         | 
| 126 126 | 
             
                    define_method singular_name do |*args, &block|
         | 
| 127 127 | 
             
                      set_slot(slot_name, nil, *args, &block)
         | 
| @@ -181,7 +181,7 @@ module ViewComponent | |
| 181 181 | 
             
                      # If callable is a string, we assume it's referencing an internal class
         | 
| 182 182 | 
             
                      slot[:renderable_class_name] = callable
         | 
| 183 183 | 
             
                    elsif callable.respond_to?(:call)
         | 
| 184 | 
            -
                      # If slot  | 
| 184 | 
            +
                      # If slot doesn't respond to `render_in`, we assume it's a proc,
         | 
| 185 185 | 
             
                      # define a method, and save a reference to it to call when setting
         | 
| 186 186 | 
             
                      method_name = :"_call_#{slot_name}"
         | 
| 187 187 | 
             
                      define_method method_name, &callable
         | 
| @@ -256,7 +256,7 @@ module ViewComponent | |
| 256 256 | 
             
                  # 1. If this is a `content_area` style sub-component, we will render the
         | 
| 257 257 | 
             
                  # block via the `slot`
         | 
| 258 258 | 
             
                  #
         | 
| 259 | 
            -
                  # 2. Since we  | 
| 259 | 
            +
                  # 2. Since we've to pass block content to components when calling
         | 
| 260 260 | 
             
                  # `render`, evaluating the block here would require us to call
         | 
| 261 261 | 
             
                  # `view_context.capture` twice, which is slower
         | 
| 262 262 | 
             
                  slot.__vc_content_block = block if block_given?
         | 
| @@ -38,7 +38,7 @@ module ViewComponent | |
| 38 38 | 
             
                # assert_text("Hello, World!")
         | 
| 39 39 | 
             
                # ```
         | 
| 40 40 | 
             
                #
         | 
| 41 | 
            -
                # @param component [ViewComponent::Base] The instance of the component to be rendered.
         | 
| 41 | 
            +
                # @param component [ViewComponent::Base, ViewComponent::Collection] The instance of the component to be rendered.
         | 
| 42 42 | 
             
                # @return [Nokogiri::HTML]
         | 
| 43 43 | 
             
                def render_inline(component, **args, &block)
         | 
| 44 44 | 
             
                  @rendered_component =
         | 
| @@ -103,7 +103,7 @@ module ViewComponent | |
| 103 103 | 
             
                  @controller = old_controller
         | 
| 104 104 | 
             
                end
         | 
| 105 105 |  | 
| 106 | 
            -
                # Set the URL  | 
| 106 | 
            +
                # Set the URL of the current request (such as when using request-dependent path helpers):
         | 
| 107 107 | 
             
                #
         | 
| 108 108 | 
             
                # ```ruby
         | 
| 109 109 | 
             
                # with_request_url("/users/42") do
         | 
| @@ -113,16 +113,22 @@ module ViewComponent | |
| 113 113 | 
             
                #
         | 
| 114 114 | 
             
                # @param path [String] The path to set for the current request.
         | 
| 115 115 | 
             
                def with_request_url(path)
         | 
| 116 | 
            +
                  old_request_path_info = request.path_info
         | 
| 116 117 | 
             
                  old_request_path_parameters = request.path_parameters
         | 
| 117 118 | 
             
                  old_request_query_parameters = request.query_parameters
         | 
| 119 | 
            +
                  old_request_query_string = request.query_string
         | 
| 118 120 | 
             
                  old_controller = defined?(@controller) && @controller
         | 
| 119 121 |  | 
| 122 | 
            +
                  request.path_info = path
         | 
| 120 123 | 
             
                  request.path_parameters = Rails.application.routes.recognize_path(path)
         | 
| 121 124 | 
             
                  request.set_header("action_dispatch.request.query_parameters", Rack::Utils.parse_query(path.split("?")[1]))
         | 
| 125 | 
            +
                  request.set_header(Rack::QUERY_STRING, path.split("?")[1])
         | 
| 122 126 | 
             
                  yield
         | 
| 123 127 | 
             
                ensure
         | 
| 128 | 
            +
                  request.path_info = old_request_path_info
         | 
| 124 129 | 
             
                  request.path_parameters = old_request_path_parameters
         | 
| 125 130 | 
             
                  request.set_header("action_dispatch.request.query_parameters", old_request_query_parameters)
         | 
| 131 | 
            +
                  request.set_header(Rack::QUERY_STRING, old_request_query_string)
         | 
| 126 132 | 
             
                  @controller = old_controller
         | 
| 127 133 | 
             
                end
         | 
| 128 134 |  | 
    
        data/lib/view_component.rb
    CHANGED
    
    | @@ -19,4 +19,13 @@ module ViewComponent | |
| 19 19 | 
             
              autoload :Translatable
         | 
| 20 20 | 
             
            end
         | 
| 21 21 |  | 
| 22 | 
            -
             | 
| 22 | 
            +
            # :nocov:
         | 
| 23 | 
            +
            if defined?(ViewComponent::Engine)
         | 
| 24 | 
            +
              ActiveSupport::Deprecation.warn(
         | 
| 25 | 
            +
                "This manually engine loading is deprecated and will be removed in v3.0.0. " \
         | 
| 26 | 
            +
                "Remove `require \"view_component/engine\"`."
         | 
| 27 | 
            +
              )
         | 
| 28 | 
            +
            elsif defined?(Rails::Engine)
         | 
| 29 | 
            +
              require "view_component/engine"
         | 
| 30 | 
            +
            end
         | 
| 31 | 
            +
            # :nocov:
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: view_component
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2. | 
| 4 | 
            +
              version: 2.48.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - GitHub Open Source
         | 
| 8 | 
            -
            autorequire: | 
| 8 | 
            +
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2022-01-14 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activesupport
         | 
| @@ -44,6 +44,20 @@ dependencies: | |
| 44 44 | 
             
                - - "~>"
         | 
| 45 45 | 
             
                  - !ruby/object:Gem::Version
         | 
| 46 46 | 
             
                    version: '1.0'
         | 
| 47 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 48 | 
            +
              name: appraisal
         | 
| 49 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 50 | 
            +
                requirements:
         | 
| 51 | 
            +
                - - "~>"
         | 
| 52 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 53 | 
            +
                    version: '2.4'
         | 
| 54 | 
            +
              type: :development
         | 
| 55 | 
            +
              prerelease: false
         | 
| 56 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 57 | 
            +
                requirements:
         | 
| 58 | 
            +
                - - "~>"
         | 
| 59 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 60 | 
            +
                    version: '2.4'
         | 
| 47 61 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 48 62 | 
             
              name: benchmark-ips
         | 
| 49 63 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -268,7 +282,7 @@ dependencies: | |
| 268 282 | 
             
                - - ">="
         | 
| 269 283 | 
             
                  - !ruby/object:Gem::Version
         | 
| 270 284 | 
             
                    version: '0'
         | 
| 271 | 
            -
            description: | 
| 285 | 
            +
            description:
         | 
| 272 286 | 
             
            email:
         | 
| 273 287 | 
             
            - opensource+view_component@github.com
         | 
| 274 288 | 
             
            executables: []
         | 
| @@ -295,6 +309,7 @@ files: | |
| 295 309 | 
             
            - lib/rails/generators/erb/templates/component.html.erb.tt
         | 
| 296 310 | 
             
            - lib/rails/generators/haml/component_generator.rb
         | 
| 297 311 | 
             
            - lib/rails/generators/haml/templates/component.html.haml.tt
         | 
| 312 | 
            +
            - lib/rails/generators/locale/component_generator.rb
         | 
| 298 313 | 
             
            - lib/rails/generators/preview/component_generator.rb
         | 
| 299 314 | 
             
            - lib/rails/generators/preview/templates/component_preview.rb.tt
         | 
| 300 315 | 
             
            - lib/rails/generators/rspec/component_generator.rb
         | 
| @@ -303,6 +318,8 @@ files: | |
| 303 318 | 
             
            - lib/rails/generators/slim/templates/component.html.slim.tt
         | 
| 304 319 | 
             
            - lib/rails/generators/stimulus/component_generator.rb
         | 
| 305 320 | 
             
            - lib/rails/generators/stimulus/templates/component_controller.js.tt
         | 
| 321 | 
            +
            - lib/rails/generators/tailwindcss/component_generator.rb
         | 
| 322 | 
            +
            - lib/rails/generators/tailwindcss/templates/component.html.erb.tt
         | 
| 306 323 | 
             
            - lib/rails/generators/test_unit/component_generator.rb
         | 
| 307 324 | 
             
            - lib/rails/generators/test_unit/templates/component_test.rb.tt
         | 
| 308 325 | 
             
            - lib/view_component.rb
         | 
| @@ -341,7 +358,7 @@ licenses: | |
| 341 358 | 
             
            - MIT
         | 
| 342 359 | 
             
            metadata:
         | 
| 343 360 | 
             
              allowed_push_host: https://rubygems.org
         | 
| 344 | 
            -
            post_install_message: | 
| 361 | 
            +
            post_install_message:
         | 
| 345 362 | 
             
            rdoc_options: []
         | 
| 346 363 | 
             
            require_paths:
         | 
| 347 364 | 
             
            - lib
         | 
| @@ -356,8 +373,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 356 373 | 
             
                - !ruby/object:Gem::Version
         | 
| 357 374 | 
             
                  version: '0'
         | 
| 358 375 | 
             
            requirements: []
         | 
| 359 | 
            -
            rubygems_version: 3.1. | 
| 360 | 
            -
            signing_key: | 
| 376 | 
            +
            rubygems_version: 3.1.4
         | 
| 377 | 
            +
            signing_key:
         | 
| 361 378 | 
             
            specification_version: 4
         | 
| 362 379 | 
             
            summary: View components for Rails
         | 
| 363 380 | 
             
            test_files: []
         |