Skip to content

Feature request: Allow custom Stimulus outlet name  #717

@janko

Description

@janko

Problem

I have a use case where users can manage "permission groups", which can have multiple "attachments". I modeled this by having a permission-group-form controller that handles general logic and permission-group-form--attachment controller that handles logic within a single attachment row.

<div data-controller="permission-group-form">
  <div data-controller="permission-group-form--attachment">...</div>
  <div data-controller="permission-group-form--attachment">...</div>
  <div data-controller="permission-group-form--attachment">...</div>
  ...
</div>

I want to create an attachments outlet on the permission-group-form controller. However, since Stimulus requires outlet names to match the controller name, I have to call the outlet permission-group-form--attachment. This means I have to declare it like this:

<div data-controller="permission-group-form" data-permission-group-form-permission-group-form--attachment-outlet=".attachment">
  <div class="attachment" data-controller="permission-group-form--attachment">...</div>
  <div class="attachment" data-controller="permission-group-form--attachment">...</div>
  <div class="attachment" data-controller="permission-group-form--attachment">...</div>
  ...
</div>

And in the controller I have a lot of repetition as well:

// app/javascript/controllers/permission_group_form_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static outlets = [
    "permission-group-form--attachment" // I want just "attachment"
  ]

  connect() {
    this.permissionGroupFormAttachmentOutlets // I want just "attachmentOutlets"
  }
}

Proposed solution

I wanted to propose the ability to choose a custom name for outlets, and map them to the Stimulus controller. The API could look something like this:

// app/javascript/controllers/permission_group_form_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static outlets = {
    attachment: "permission-group-form--attachment"
  }

  connect() {
    this.attachmentOutlets //=> [...]
  }
}

And then the DOM declaration would be a lot simpler as well:

<div data-controller="permission-group-form" data-permission-group-form-attachment-outlet=".attachment">
  ...
</div>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions