From 4bf833cbcc603c5d91f5b603ade765df0dfd4776 Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Sun, 26 May 2024 21:33:25 +0200 Subject: [PATCH 01/18] add: helpers macro --- lib/view_component/use_helpers.rb | 23 +++++++++++++------ .../use_helpers_macro_component.html.erb | 7 ++++++ .../components/use_helpers_macro_component.rb | 5 ++++ test/sandbox/app/helpers/macro_helper.rb | 11 +++++++++ test/sandbox/test/rendering_test.rb | 12 ++++++++++ 5 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 test/sandbox/app/components/use_helpers_macro_component.html.erb create mode 100644 test/sandbox/app/components/use_helpers_macro_component.rb create mode 100644 test/sandbox/app/helpers/macro_helper.rb diff --git a/lib/view_component/use_helpers.rb b/lib/view_component/use_helpers.rb index 32d13cd43..a31929755 100644 --- a/lib/view_component/use_helpers.rb +++ b/lib/view_component/use_helpers.rb @@ -4,14 +4,23 @@ module ViewComponent::UseHelpers extend ActiveSupport::Concern class_methods do - def use_helpers(*args) + def use_helpers(*args, from: nil) + helper_source = from args.each do |helper_method| - class_eval(<<-RUBY, __FILE__, __LINE__ + 1) - def #{helper_method}(*args, &block) - raise HelpersCalledBeforeRenderError if view_context.nil? - __vc_original_view_context.#{helper_method}(*args, &block) - end - RUBY + if helper_source.nil? + class_eval(<<-RUBY, __FILE__, __LINE__ + 1) + def #{helper_method}(*args, &block) + raise HelpersCalledBeforeRenderError if view_context.nil? + __vc_original_view_context.#{helper_method}(*args, &block) + end + RUBY + else + class_eval(<<-RUBY, __FILE__, __LINE__ + 1) + def #{helper_method}(*args, &block) + #{helper_source}.instance_method(:#{helper_method}).bind(self).call(*args, &block) + end + RUBY + end ruby2_keywords(helper_method) if respond_to?(:ruby2_keywords, true) end diff --git a/test/sandbox/app/components/use_helpers_macro_component.html.erb b/test/sandbox/app/components/use_helpers_macro_component.html.erb new file mode 100644 index 000000000..23bbda032 --- /dev/null +++ b/test/sandbox/app/components/use_helpers_macro_component.html.erb @@ -0,0 +1,7 @@ +
+ <%= message %> +
+ +
+ <%= message_with_args('macro helper method') %> +
diff --git a/test/sandbox/app/components/use_helpers_macro_component.rb b/test/sandbox/app/components/use_helpers_macro_component.rb new file mode 100644 index 000000000..83a928fe4 --- /dev/null +++ b/test/sandbox/app/components/use_helpers_macro_component.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class UseHelpersMacroComponent < ViewComponent::Base + use_helpers :message, :message_with_args, from: MacroHelper +end diff --git a/test/sandbox/app/helpers/macro_helper.rb b/test/sandbox/app/helpers/macro_helper.rb new file mode 100644 index 000000000..5714e9596 --- /dev/null +++ b/test/sandbox/app/helpers/macro_helper.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module MacroHelper + def message + "Hello helper method" + end + + def message_with_args(name) + "Hello #{name}" + end +end diff --git a/test/sandbox/test/rendering_test.rb b/test/sandbox/test/rendering_test.rb index c50712b21..0fecd6bd1 100644 --- a/test/sandbox/test/rendering_test.rb +++ b/test/sandbox/test/rendering_test.rb @@ -1122,4 +1122,16 @@ def test_inline_component_renders_without_trailing_whitespace refute @rendered_content =~ /\s+\z/, "Rendered component contains trailing whitespace" end + + def test_use_helper_macros + render_inline(UseHelpersMacroComponent.new) + + assert_selector ".helper__message", text: "Hello helper method" + end + + def test_use_helper_macros_with_args + render_inline(UseHelpersMacroComponent.new) + + assert_selector ".helper__args-message", text: "Hello macro helper method" + end end From 04a1ab064115493efcb278db43e56a66afa22aed Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Sun, 26 May 2024 21:52:14 +0200 Subject: [PATCH 02/18] refactor helpers macro --- lib/view_component/use_helpers.rb | 40 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/lib/view_component/use_helpers.rb b/lib/view_component/use_helpers.rb index a31929755..74d96729a 100644 --- a/lib/view_component/use_helpers.rb +++ b/lib/view_component/use_helpers.rb @@ -6,22 +6,34 @@ module ViewComponent::UseHelpers class_methods do def use_helpers(*args, from: nil) helper_source = from + if helper_source.nil? + define_helpers_without_source(*args) + else + define_helpers_with_source(*args, source: helper_source) + end + end + + private + + def define_helpers_without_source(*args) args.each do |helper_method| - if helper_source.nil? - class_eval(<<-RUBY, __FILE__, __LINE__ + 1) - def #{helper_method}(*args, &block) - raise HelpersCalledBeforeRenderError if view_context.nil? - __vc_original_view_context.#{helper_method}(*args, &block) - end - RUBY - else - class_eval(<<-RUBY, __FILE__, __LINE__ + 1) - def #{helper_method}(*args, &block) - #{helper_source}.instance_method(:#{helper_method}).bind(self).call(*args, &block) - end - RUBY - end + class_eval(<<-RUBY, __FILE__, __LINE__ + 1) + def #{helper_method}(*args, &block) + raise HelpersCalledBeforeRenderError if view_context.nil? + __vc_original_view_context.#{helper_method}(*args, &block) + end + RUBY + ruby2_keywords(helper_method) if respond_to?(:ruby2_keywords, true) + end + end + def define_helpers_with_source(*args, source:) + args.each do |helper_method| + class_eval(<<-RUBY, __FILE__, __LINE__ + 1) + def #{helper_method}(*args, &block) + #{source}.instance_method(:#{helper_method}).bind(self).call(*args, &block) + end + RUBY ruby2_keywords(helper_method) if respond_to?(:ruby2_keywords, true) end end From d0d6979f54c5450aa834ca9634915719466bd199 Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Sun, 26 May 2024 21:54:35 +0200 Subject: [PATCH 03/18] refactor helpers macro --- lib/view_component/use_helpers.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/view_component/use_helpers.rb b/lib/view_component/use_helpers.rb index 74d96729a..962bed341 100644 --- a/lib/view_component/use_helpers.rb +++ b/lib/view_component/use_helpers.rb @@ -5,11 +5,10 @@ module ViewComponent::UseHelpers class_methods do def use_helpers(*args, from: nil) - helper_source = from - if helper_source.nil? + if from.nil? define_helpers_without_source(*args) else - define_helpers_with_source(*args, source: helper_source) + define_helpers_with_source(*args, source: from) end end From f37e33c7e0f9b20fbce860b4f8a7c66e76701b7c Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Sun, 26 May 2024 21:59:36 +0200 Subject: [PATCH 04/18] add: kwargs tests --- .../app/components/use_helpers_macro_component.html.erb | 4 ++++ test/sandbox/app/components/use_helpers_macro_component.rb | 2 +- test/sandbox/app/helpers/macro_helper.rb | 4 ++++ test/sandbox/test/rendering_test.rb | 6 ++++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/test/sandbox/app/components/use_helpers_macro_component.html.erb b/test/sandbox/app/components/use_helpers_macro_component.html.erb index 23bbda032..253b88bce 100644 --- a/test/sandbox/app/components/use_helpers_macro_component.html.erb +++ b/test/sandbox/app/components/use_helpers_macro_component.html.erb @@ -5,3 +5,7 @@
<%= message_with_args('macro helper method') %>
+ +
+ <%= message_with_kwargs(name: 'macro kwargs helper method') %> +
diff --git a/test/sandbox/app/components/use_helpers_macro_component.rb b/test/sandbox/app/components/use_helpers_macro_component.rb index 83a928fe4..7b0433215 100644 --- a/test/sandbox/app/components/use_helpers_macro_component.rb +++ b/test/sandbox/app/components/use_helpers_macro_component.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class UseHelpersMacroComponent < ViewComponent::Base - use_helpers :message, :message_with_args, from: MacroHelper + use_helpers :message, :message_with_args, :message_with_kwargs, from: MacroHelper end diff --git a/test/sandbox/app/helpers/macro_helper.rb b/test/sandbox/app/helpers/macro_helper.rb index 5714e9596..bec282508 100644 --- a/test/sandbox/app/helpers/macro_helper.rb +++ b/test/sandbox/app/helpers/macro_helper.rb @@ -8,4 +8,8 @@ def message def message_with_args(name) "Hello #{name}" end + + def message_with_kwargs(name:) + "Hello #{name}" + end end diff --git a/test/sandbox/test/rendering_test.rb b/test/sandbox/test/rendering_test.rb index 0fecd6bd1..2408aa666 100644 --- a/test/sandbox/test/rendering_test.rb +++ b/test/sandbox/test/rendering_test.rb @@ -1134,4 +1134,10 @@ def test_use_helper_macros_with_args assert_selector ".helper__args-message", text: "Hello macro helper method" end + + def test_use_helper_macros_with_kwargs + render_inline(UseHelpersMacroComponent.new) + + assert_selector ".helper__kwargs-message", text: "Hello macro kwargs helper method" + end end From d63f5b4dc3ac735ae7026c06e2e1555271a8547d Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Mon, 27 May 2024 21:45:35 +0200 Subject: [PATCH 05/18] add: documentation --- docs/guide/helpers.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/guide/helpers.md b/docs/guide/helpers.md index 495277f2b..b26381e3a 100644 --- a/docs/guide/helpers.md +++ b/docs/guide/helpers.md @@ -69,6 +69,18 @@ class UseHelpersComponent < ViewComponent::Base end ``` +Methods defined in helper modules that are not available in the component can be included individually using the `from:` keyword: + +```ruby +class UserComponent < ViewComponent::Base + use_helpers :icon, from: IconHelper + + def profile_icon + icon :user + end +end +``` + ## Nested URL helpers Rails nested URL helpers implicitly depend on the current `request` in certain cases. Since ViewComponent is built to enable reusing components in different contexts, nested URL helpers should be passed their options explicitly: From a3ea509fbec46a85efb7dacce8f3515de7e7d4af Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Mon, 27 May 2024 21:53:28 +0200 Subject: [PATCH 06/18] add: changelog entry --- docs/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 4db5eb010..4df34b618 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -18,6 +18,10 @@ nav_order: 5 *Reegan Viljoen* +* Add `from:` option to `use_helpers` to allow for more flexible helper inclusion from modules. + + *Reegan Viljoen* + ## 3.12.1 * Ensure content is rendered correctly for forwarded slots. From cd52c86af6f14d8a69b523bb7f1741de61336660 Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Fri, 31 May 2024 16:58:10 +0200 Subject: [PATCH 07/18] add: block test and use_helper singular method --- lib/view_component/use_helpers.rb | 45 ++++++++++--------- .../use_helper_macro_component.html copy.erb | 15 +++++++ .../components/use_helper_macro_component.rb | 12 +++++ .../app/components/use_helpers_component.rb | 2 +- .../use_helpers_macro_component.html.erb | 4 ++ .../components/use_helpers_macro_component.rb | 6 ++- test/sandbox/app/helpers/macro_helper.rb | 4 ++ test/sandbox/test/rendering_test.rb | 36 +++++++++++++-- 8 files changed, 98 insertions(+), 26 deletions(-) create mode 100644 test/sandbox/app/components/use_helper_macro_component.html copy.erb create mode 100644 test/sandbox/app/components/use_helper_macro_component.rb diff --git a/lib/view_component/use_helpers.rb b/lib/view_component/use_helpers.rb index 962bed341..a645e3764 100644 --- a/lib/view_component/use_helpers.rb +++ b/lib/view_component/use_helpers.rb @@ -5,36 +5,39 @@ module ViewComponent::UseHelpers class_methods do def use_helpers(*args, from: nil) + args.each do |helper_method| + use_helper(helper_method, from: from) + end + end + + def use_helper(helper_method, from: nil) if from.nil? - define_helpers_without_source(*args) + define_helpers_without_source(helper_method: helper_method) else - define_helpers_with_source(*args, source: from) + define_helpers_with_source(helper_method: helper_method, source: from) end end private - def define_helpers_without_source(*args) - args.each do |helper_method| - class_eval(<<-RUBY, __FILE__, __LINE__ + 1) - def #{helper_method}(*args, &block) - raise HelpersCalledBeforeRenderError if view_context.nil? - __vc_original_view_context.#{helper_method}(*args, &block) - end - RUBY - ruby2_keywords(helper_method) if respond_to?(:ruby2_keywords, true) - end + def define_helpers_without_source(helper_method:) + class_eval(<<-RUBY, __FILE__, __LINE__ + 1) + def #{helper_method}(*args, **kwargs, &block) + raise HelpersCalledBeforeRenderError if view_context.nil? + __vc_original_view_context.#{helper_method}(*args, **kwargs, &block) + end + RUBY + ruby2_keywords(helper_method) if respond_to?(:ruby2_keywords, true) end - def define_helpers_with_source(*args, source:) - args.each do |helper_method| - class_eval(<<-RUBY, __FILE__, __LINE__ + 1) - def #{helper_method}(*args, &block) - #{source}.instance_method(:#{helper_method}).bind(self).call(*args, &block) - end - RUBY - ruby2_keywords(helper_method) if respond_to?(:ruby2_keywords, true) - end + def define_helpers_with_source(helper_method:, source:) + class_eval(<<-RUBY, __FILE__, __LINE__ + 1) + def #{helper_method}(*args, **kwargs, &block) + raise HelpersCalledBeforeRenderError if view_context.nil? + #{source}.instance_method(:#{helper_method}).bind(self).call(*args, **kwargs, &block) + end + RUBY + ruby2_keywords(helper_method) if respond_to?(:ruby2_keywords, true) end end end diff --git a/test/sandbox/app/components/use_helper_macro_component.html copy.erb b/test/sandbox/app/components/use_helper_macro_component.html copy.erb new file mode 100644 index 000000000..0744510f4 --- /dev/null +++ b/test/sandbox/app/components/use_helper_macro_component.html copy.erb @@ -0,0 +1,15 @@ +
+ <%= message %> +
+ +
+ <%= message_with_args('macro helper method') %> +
+ +
+ <%= message_with_kwargs(name: 'macro kwargs helper method') %> +
+ +
+ <%= block_content %> +
diff --git a/test/sandbox/app/components/use_helper_macro_component.rb b/test/sandbox/app/components/use_helper_macro_component.rb new file mode 100644 index 000000000..ff1822019 --- /dev/null +++ b/test/sandbox/app/components/use_helper_macro_component.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class UseHelperMacroComponent < ViewComponent::Base + use_helper :message, from: MacroHelper + use_helper :message_with_args, from: MacroHelper + use_helper :message_with_kwargs, from: MacroHelper + use_helper :message_with_block, from: MacroHelper + + def block_content + message_with_block { "Hello block helper method" } + end +end diff --git a/test/sandbox/app/components/use_helpers_component.rb b/test/sandbox/app/components/use_helpers_component.rb index a83bd2e16..752e83f0c 100644 --- a/test/sandbox/app/components/use_helpers_component.rb +++ b/test/sandbox/app/components/use_helpers_component.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class UseHelpersComponent < ViewComponent::Base - use_helpers :message + use_helper :message end diff --git a/test/sandbox/app/components/use_helpers_macro_component.html.erb b/test/sandbox/app/components/use_helpers_macro_component.html.erb index 253b88bce..0744510f4 100644 --- a/test/sandbox/app/components/use_helpers_macro_component.html.erb +++ b/test/sandbox/app/components/use_helpers_macro_component.html.erb @@ -9,3 +9,7 @@
<%= message_with_kwargs(name: 'macro kwargs helper method') %>
+ +
+ <%= block_content %> +
diff --git a/test/sandbox/app/components/use_helpers_macro_component.rb b/test/sandbox/app/components/use_helpers_macro_component.rb index 7b0433215..861cd36fd 100644 --- a/test/sandbox/app/components/use_helpers_macro_component.rb +++ b/test/sandbox/app/components/use_helpers_macro_component.rb @@ -1,5 +1,9 @@ # frozen_string_literal: true class UseHelpersMacroComponent < ViewComponent::Base - use_helpers :message, :message_with_args, :message_with_kwargs, from: MacroHelper + use_helpers :message, :message_with_args, :message_with_kwargs, :message_with_block, from: MacroHelper + + def block_content + message_with_block { "Hello block helper method" } + end end diff --git a/test/sandbox/app/helpers/macro_helper.rb b/test/sandbox/app/helpers/macro_helper.rb index bec282508..89b63b32d 100644 --- a/test/sandbox/app/helpers/macro_helper.rb +++ b/test/sandbox/app/helpers/macro_helper.rb @@ -12,4 +12,8 @@ def message_with_args(name) def message_with_kwargs(name:) "Hello #{name}" end + + def message_with_block + yield + end end diff --git a/test/sandbox/test/rendering_test.rb b/test/sandbox/test/rendering_test.rb index 4aef86963..435902771 100644 --- a/test/sandbox/test/rendering_test.rb +++ b/test/sandbox/test/rendering_test.rb @@ -1122,21 +1122,51 @@ def test_inline_component_renders_without_trailing_whitespace refute @rendered_content =~ /\s+\z/, "Rendered component contains trailing whitespace" end - def test_use_helper_macros + def test_use_helpers_macros render_inline(UseHelpersMacroComponent.new) assert_selector ".helper__message", text: "Hello helper method" end - def test_use_helper_macros_with_args + def test_use_helpers_macros_with_args render_inline(UseHelpersMacroComponent.new) assert_selector ".helper__args-message", text: "Hello macro helper method" end - def test_use_helper_macros_with_kwargs + def test_use_helpers_macros_with_kwargs render_inline(UseHelpersMacroComponent.new) assert_selector ".helper__kwargs-message", text: "Hello macro kwargs helper method" end + + def test_use_helpers_with_block + render_inline(UseHelpersMacroComponent.new) + + assert_selector ".helper__block-message", text: "Hello block helper method" + end + + def test_use_helper_macros + render_inline(UseHelperMacroComponent.new) + + assert_selector ".helper__message", text: "Hello helper method" + end + + def test_use_helper_macros_with_args + render_inline(UseHelperMacroComponent.new) + + assert_selector ".helper__args-message", text: "Hello macro helper method" + end + + def test_use_helper_macros_with_kwargs + render_inline(UseHelperMacroComponent.new) + + assert_selector ".helper__kwargs-message", text: "Hello macro kwargs helper method" + end + + def test_use_helper_macros_with_block + render_inline(UseHelperMacroComponent.new) + + assert_selector ".helper__block-message", text: "Hello block helper method" + end end From 3da4bccad3b3edeb62c69a504309f7600bc201c8 Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Fri, 31 May 2024 17:04:01 +0200 Subject: [PATCH 08/18] fix: ruby2_keywords warnings --- lib/view_component/use_helpers.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/view_component/use_helpers.rb b/lib/view_component/use_helpers.rb index a645e3764..69cc2147d 100644 --- a/lib/view_component/use_helpers.rb +++ b/lib/view_component/use_helpers.rb @@ -22,9 +22,9 @@ def use_helper(helper_method, from: nil) def define_helpers_without_source(helper_method:) class_eval(<<-RUBY, __FILE__, __LINE__ + 1) - def #{helper_method}(*args, **kwargs, &block) + def #{helper_method}(*args, &block) raise HelpersCalledBeforeRenderError if view_context.nil? - __vc_original_view_context.#{helper_method}(*args, **kwargs, &block) + __vc_original_view_context.#{helper_method}(*args, &block) end RUBY ruby2_keywords(helper_method) if respond_to?(:ruby2_keywords, true) @@ -32,9 +32,9 @@ def #{helper_method}(*args, **kwargs, &block) def define_helpers_with_source(helper_method:, source:) class_eval(<<-RUBY, __FILE__, __LINE__ + 1) - def #{helper_method}(*args, **kwargs, &block) + def #{helper_method}(*args, &block) raise HelpersCalledBeforeRenderError if view_context.nil? - #{source}.instance_method(:#{helper_method}).bind(self).call(*args, **kwargs, &block) + #{source}.instance_method(:#{helper_method}).bind(self).call(*args, &block) end RUBY ruby2_keywords(helper_method) if respond_to?(:ruby2_keywords, true) From 49cc43ab17c81fffcceaa203db874546f3b536c9 Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Fri, 31 May 2024 17:12:56 +0200 Subject: [PATCH 09/18] add: singular documentation --- docs/guide/helpers.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/guide/helpers.md b/docs/guide/helpers.md index b26381e3a..382d9e6e8 100644 --- a/docs/guide/helpers.md +++ b/docs/guide/helpers.md @@ -59,11 +59,11 @@ By default, ViewComponents don't have access to helper methods defined externall ```ruby class UseHelpersComponent < ViewComponent::Base - use_helpers :icon + use_helpers :icon, :icon? erb_template <<-ERB
- <%= icon :user %> + <%= icon? ? icon :user : icon :guest %>
ERB end @@ -73,7 +73,19 @@ Methods defined in helper modules that are not available in the component can be ```ruby class UserComponent < ViewComponent::Base - use_helpers :icon, from: IconHelper + use_helpers :icon, :icon?, from: IconHelper + + def profile_icon + icon? ? icon :user : icon :guest + end +end +``` + +The singular version `use_helper` is also available for a single helper: + +```ruby +class UserComponent < ViewComponent::Base + use_helper :icon, from: IconHelper def profile_icon icon :user From fbec8424740a0949c12d14123eb1c0d75af26903 Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Fri, 31 May 2024 17:24:22 +0200 Subject: [PATCH 10/18] fix: linting --- docs/guide/helpers.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/helpers.md b/docs/guide/helpers.md index 382d9e6e8..984ebd4db 100644 --- a/docs/guide/helpers.md +++ b/docs/guide/helpers.md @@ -63,7 +63,7 @@ class UseHelpersComponent < ViewComponent::Base erb_template <<-ERB
- <%= icon? ? icon :user : icon :guest %> + <%= icon? ? icon(:user) : icon(:guest) %>
ERB end @@ -76,7 +76,7 @@ class UserComponent < ViewComponent::Base use_helpers :icon, :icon?, from: IconHelper def profile_icon - icon? ? icon :user : icon :guest + icon? ? icon(:user) : icon(:guest) end end ``` From 36825babd352453f08a9a49bc36bb518bbe27bc3 Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Tue, 4 Jun 2024 17:17:03 +0200 Subject: [PATCH 11/18] fix: linting --- docs/guide/helpers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/helpers.md b/docs/guide/helpers.md index 984ebd4db..1a70aeba6 100644 --- a/docs/guide/helpers.md +++ b/docs/guide/helpers.md @@ -69,7 +69,7 @@ class UseHelpersComponent < ViewComponent::Base end ``` -Methods defined in helper modules that are not available in the component can be included individually using the `from:` keyword: +Methods defined in helper modules that aren't available in the component can be included individually using the `from:` keyword: ```ruby class UserComponent < ViewComponent::Base From ec4a40a99b2b28c71eb3b6a077668fb6c555c0fd Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Tue, 4 Jun 2024 17:20:52 +0200 Subject: [PATCH 12/18] fix: lint --- docs/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index fb0b34b8e..7138d806d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -23,9 +23,9 @@ nav_order: 5 *Reegan Viljoen* * Add `from:` option to `use_helpers` to allow for more flexible helper inclusion from modules. - + *Reegan Viljoen* - + * Fixed ruby head matcher issue. *Reegan Viljoen* From 0c37f4fc558744404785aebab8751350824587bc Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Mon, 10 Jun 2024 16:34:29 +0200 Subject: [PATCH 13/18] refactor: code --- lib/view_component/use_helpers.rb | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/lib/view_component/use_helpers.rb b/lib/view_component/use_helpers.rb index 69cc2147d..61e6bd515 100644 --- a/lib/view_component/use_helpers.rb +++ b/lib/view_component/use_helpers.rb @@ -5,39 +5,26 @@ module ViewComponent::UseHelpers class_methods do def use_helpers(*args, from: nil) - args.each do |helper_method| - use_helper(helper_method, from: from) - end + args.each { |helper_method| use_helper(helper_method, from: from) } end def use_helper(helper_method, from: nil) - if from.nil? - define_helpers_without_source(helper_method: helper_method) - else - define_helpers_with_source(helper_method: helper_method, source: from) - end - end - - private - - def define_helpers_without_source(helper_method:) class_eval(<<-RUBY, __FILE__, __LINE__ + 1) def #{helper_method}(*args, &block) raise HelpersCalledBeforeRenderError if view_context.nil? - __vc_original_view_context.#{helper_method}(*args, &block) + + #{define_helper(helper_method: helper_method, source: from)} end RUBY ruby2_keywords(helper_method) if respond_to?(:ruby2_keywords, true) end - def define_helpers_with_source(helper_method:, source:) - class_eval(<<-RUBY, __FILE__, __LINE__ + 1) - def #{helper_method}(*args, &block) - raise HelpersCalledBeforeRenderError if view_context.nil? - #{source}.instance_method(:#{helper_method}).bind(self).call(*args, &block) - end - RUBY - ruby2_keywords(helper_method) if respond_to?(:ruby2_keywords, true) + private + + def define_helper(helper_method:, source:) + return "__vc_original_view_context.#{helper_method}(*args, &block)" unless source.present? + + "#{source}.instance_method(:#{helper_method}).bind(self).call(*args, &block)" end end end From 3849f2986ff1c7bc5b1de2ebd2cdfaac11ca0c28 Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Thu, 20 Jun 2024 07:55:38 +0200 Subject: [PATCH 14/18] fix rails main tests --- test/sandbox/test/rendering_test.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/sandbox/test/rendering_test.rb b/test/sandbox/test/rendering_test.rb index 435902771..87593addc 100644 --- a/test/sandbox/test/rendering_test.rb +++ b/test/sandbox/test/rendering_test.rb @@ -563,7 +563,8 @@ def test_backtrace_returns_correct_file_and_line_number render_inline(ExceptionInTemplateComponent.new) end - assert_match %r{app/components/exception_in_template_component\.html\.erb:2}, error.backtrace.first + component_error_index = (Rails::VERSION::STRING < "8.0") ? 0 : 1 + assert_match %r{app/components/exception_in_template_component\.html\.erb:2}, error.backtrace[component_error_index] end def test_render_collection From d5b8f1e3891b48d07646c37cea70afe7c9629d09 Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Thu, 20 Jun 2024 07:59:06 +0200 Subject: [PATCH 15/18] fix: linting --- test/sandbox/test/rendering_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/sandbox/test/rendering_test.rb b/test/sandbox/test/rendering_test.rb index 87593addc..619c7f164 100644 --- a/test/sandbox/test/rendering_test.rb +++ b/test/sandbox/test/rendering_test.rb @@ -563,8 +563,8 @@ def test_backtrace_returns_correct_file_and_line_number render_inline(ExceptionInTemplateComponent.new) end - component_error_index = (Rails::VERSION::STRING < "8.0") ? 0 : 1 - assert_match %r{app/components/exception_in_template_component\.html\.erb:2}, error.backtrace[component_error_index] + component_error_index = (Rails::VERSION::STRING < "8.0") ? 0 : 1 + assert_match %r{app/components/exception_in_template_component\.html\.erb:2}, error.backtrace[component_error_index] end def test_render_collection From 569c608d1fbc49766fa7eb7bce133649e3f09c2f Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Thu, 20 Jun 2024 08:02:04 +0200 Subject: [PATCH 16/18] fix linting --- docs/adrs/0003-polymorphic-slot-definitions.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/adrs/0003-polymorphic-slot-definitions.md b/docs/adrs/0003-polymorphic-slot-definitions.md index 470c7de8d..2079290c9 100644 --- a/docs/adrs/0003-polymorphic-slot-definitions.md +++ b/docs/adrs/0003-polymorphic-slot-definitions.md @@ -52,7 +52,6 @@ Here's how the `Item` sub-component of the list example above would be implement ```ruby class Item < ViewComponent::Base - renders_one :leading_visual, types: { icon: IconComponent, avatar: AvatarComponent } From 946552e81559f22658757f333924d3c22c4ed256 Mon Sep 17 00:00:00 2001 From: Reegan Viljoen Date: Thu, 20 Jun 2024 08:08:04 +0200 Subject: [PATCH 17/18] fix: linting --- lib/view_component/instrumentation.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/view_component/instrumentation.rb b/lib/view_component/instrumentation.rb index 380dea016..d63efd283 100644 --- a/lib/view_component/instrumentation.rb +++ b/lib/view_component/instrumentation.rb @@ -16,7 +16,7 @@ def render_in(view_context, &block) identifier: self.class.identifier } ) do - super(view_context, &block) + super end end From 1c25a4f704be6c6cdf785fb2c333c940447af6fe Mon Sep 17 00:00:00 2001 From: Joel Hawksley Date: Thu, 20 Jun 2024 15:13:37 -0600 Subject: [PATCH 18/18] Apply suggestions from code review --- docs/guide/helpers.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/helpers.md b/docs/guide/helpers.md index 1a70aeba6..99a6f2520 100644 --- a/docs/guide/helpers.md +++ b/docs/guide/helpers.md @@ -69,7 +69,7 @@ class UseHelpersComponent < ViewComponent::Base end ``` -Methods defined in helper modules that aren't available in the component can be included individually using the `from:` keyword: +Use the `from:` keyword to include individual methods defined in helper modules not available in the component: ```ruby class UserComponent < ViewComponent::Base @@ -81,7 +81,7 @@ class UserComponent < ViewComponent::Base end ``` -The singular version `use_helper` is also available for a single helper: +The singular version `use_helper` is also available: ```ruby class UserComponent < ViewComponent::Base