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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions