Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define slot methods in a module so they can be override and references with super #2027

Open
ozydingo opened this issue May 16, 2024 · 3 comments

Comments

@ozydingo
Copy link

Feature request

Allow overriding slot and content methods on a view component with the ability to call super to reference the default implementation. This allows for some nice customization on how to set content or slot content, and follows a pattern seen in ActiveRecord and other gems.

I am happy to work on this feature given some time.

Motivation

In some cases, I want to support developers defining content that will be used in a slot multiple ways. For example, a modal component might have a simple string title, or it might be richer html

= render Modal.new(title: "oh no")
= render Modal.new do |modal|
  modal.with_title do
    ... more html with images, links

Allowing both forms retains flexibility when its needed but simplicity when it's not, reducing the barrier for other devs to use this component.

This would work if I could override title and title? like so:

class Modal < ApplicationViewComponent
  ...

  def initailize(title: nil)
    @title = title
  end

  def title?
    @title.present? || super
  end

  def title
    @title || super
  end
end

This is similar to what you can do with ActiveRecord attribute methods, as the attribute setters and getters are defined on a module that is included my the class. For example,

Note.new.method(:subject).owner
=> Note::GeneratedAttributeMethods

The mongoid gem works similarly:

MongoNote.new.method(:title).owner
=> MongoNote::GeneratedAttributeMethods

However, in Slottable, we define the methods with_foo directly on the component itself, which means if we override title as I attempted above, there is no super. In my specific example:

ComponentLibrary::Modal.new("foo").method(:title).owner
=> ComponentLibrary::Modal

If we defined the slot and content methods on an included module, similar to ActiveRecord and Mongoid, the override would be possible, and at no cost to existing functionality or simplicity to ViewComponent users.

@ozydingo ozydingo changed the title Define slot methods ina module so they can be override and references with super Define slot methods in a module so they can be override and references with super May 16, 2024
@reeganviljoen
Copy link
Collaborator

@ozydingo I think this is reasonable, considering active record patterns, @joelhawksley what do you think?

@joelhawksley
Copy link
Member

@reeganviljoen I think it's reasonable too. @ozydingo would you be up for writing a PR?

@ozydingo
Copy link
Author

@joelhawksley sure thing, I'd be thrilled to contribute!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants