Skip to content

Commit d1d1df6

Browse files
committed
BREAKING: Allow slots to be redefined, removing RedefinedSlotError
1 parent 619f350 commit d1d1df6

File tree

5 files changed

+40
-50
lines changed

5 files changed

+40
-50
lines changed

docs/CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,24 @@ nav_order: 6
1010

1111
## main
1212

13+
* BREAKING: Allow slots to be redefined, removing `RedefinedSlotError`. The following is now possible:
14+
15+
```ruby
16+
class ButtonComponent < ViewComponent::Base
17+
renders_many :leading_items, types: {
18+
icon: IconComponent,
19+
svg: SvgComponent
20+
}
21+
end
22+
23+
class SpecialButtonComponent < ButtonComponent
24+
renders_many :leading_items, types: {
25+
svg: SvgComponent,
26+
checkbox: CheckboxComponent
27+
}
28+
end
29+
```
30+
1331
## 4.0.0.rc1
1432

1533
Almost six years after releasing [v1.0.0](https://github.com/ViewComponent/view_component/releases/tag/v1.0.0), we're proud to ship the first release candidate of ViewComponent 4. This release marks a shift towards a Long Term Support model for the project, having reached significant feature maturity. While contributions are always welcome, we're unlikely to accept further breaking changes or major feature additions.

lib/view_component/errors.rb

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,16 +125,6 @@ def initialize(klass_name, slot_name)
125125
end
126126
end
127127

128-
class RedefinedSlotError < StandardError
129-
MESSAGE =
130-
"COMPONENT declares the SLOT_NAME slot multiple times.\n\n" \
131-
"To fix this issue, choose a different slot name."
132-
133-
def initialize(klass_name, slot_name)
134-
super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("SLOT_NAME", slot_name.to_s))
135-
end
136-
end
137-
138128
class ReservedSingularSlotNameError < InvalidSlotNameError
139129
MESSAGE =
140130
"COMPONENT declares a slot named SLOT_NAME, which is a reserved word in the ViewComponent framework.\n\n" \

lib/view_component/slotable.rb

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,6 @@ def __vc_validate_plural_slot_name(slot_name)
311311
__vc_raise_if_slot_name_uncountable(slot_name)
312312
__vc_raise_if_slot_conflicts_with_call(slot_name)
313313
__vc_raise_if_slot_ends_with_question_mark(slot_name)
314-
__vc_raise_if_slot_registered(slot_name)
315314
end
316315

317316
def __vc_validate_singular_slot_name(slot_name)
@@ -325,13 +324,6 @@ def __vc_validate_singular_slot_name(slot_name)
325324

326325
__vc_raise_if_slot_conflicts_with_call(slot_name)
327326
__vc_raise_if_slot_ends_with_question_mark(slot_name)
328-
__vc_raise_if_slot_registered(slot_name)
329-
end
330-
331-
def __vc_raise_if_slot_registered(slot_name)
332-
if registered_slots.key?(slot_name)
333-
raise RedefinedSlotError.new(name, slot_name)
334-
end
335327
end
336328

337329
def __vc_raise_if_slot_ends_with_question_mark(slot_name)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# frozen_string_literal: true
2+
3+
class SlotsSubclassComponent < SlotsComponent
4+
renders_one :title, ->(&block) do
5+
content_tag :h1 do
6+
block.call
7+
end
8+
end
9+
end

test/sandbox/test/slotable_test.rb

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ def test_renders_slots
3838

3939
assert_selector(".title", text: "This is my title!")
4040

41-
assert_selector(".subtitle", text: "This is my subtitle!")
42-
4341
assert_selector(".tab", text: "Tab A")
4442
assert_selector(".tab", text: "Tab B")
4543

@@ -137,15 +135,6 @@ def test_renders_slots_template_raise_with_unknown_slot
137135
end
138136
end
139137

140-
def test_sub_component_raise_with_duplicate_slot_name
141-
exception =
142-
assert_raises ViewComponent::RedefinedSlotError do
143-
SlotsComponent.renders_one :title
144-
end
145-
146-
assert_includes exception.message, "declares the title slot multiple times"
147-
end
148-
149138
def test_sub_component_with_positional_args
150139
render_inline(SlotsWithPosArgComponent.new) do |component|
151140
component.with_item("my item", classes: "hello") { "My rad item" }
@@ -647,36 +636,28 @@ def test_component_delegation_slots_work_with_helpers
647636
assert_equal 1, PartialHelper::State.calls
648637
end
649638

650-
def test_lambda_slot_content_can_be_provided_via_a_block
651-
render_inline LambdaSlotComponent.new do |component|
652-
component.with_header(classes: "some-class") do
653-
"This is a header!"
639+
def test_subclass_can_redefine_slot
640+
render_inline(SlotsSubclassComponent.new(classes: "mt-4")) do |component|
641+
component.with_title do
642+
"This is my title!"
654643
end
655-
end
656-
657-
assert_selector("h1.some-class", text: "This is a header!")
658-
end
659-
660-
def test_raises_error_on_conflicting_slot_names
661-
error = assert_raises ViewComponent::RedefinedSlotError do
662-
Class.new(ViewComponent::Base) do
663-
renders_one :conflicting_item
664-
renders_many :conflicting_items
644+
component.with_subtitle do
645+
"This is my subtitle!"
665646
end
666647
end
667648

668-
assert_includes error.message, "conflicting_item slot multiple times"
649+
assert_selector("h1", text: "This is my title!")
650+
assert_selector(".subtitle", text: "This is my subtitle!")
669651
end
670652

671-
def test_raises_error_on_conflicting_slot_names_in_reverse_order
672-
error = assert_raises ViewComponent::RedefinedSlotError do
673-
Class.new(ViewComponent::Base) do
674-
renders_many :conflicting_items
675-
renders_one :conflicting_item
653+
def test_lambda_slot_content_can_be_provided_via_a_block
654+
render_inline LambdaSlotComponent.new do |component|
655+
component.with_header(classes: "some-class") do
656+
"This is a header!"
676657
end
677658
end
678659

679-
assert_includes error.message, "conflicting_items slot multiple times"
660+
assert_selector("h1.some-class", text: "This is a header!")
680661
end
681662

682663
def test_slots_dont_interfere_with_content

0 commit comments

Comments
 (0)