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

[RRFC] SlotController #7

Open
1 task done
justinfagnani opened this issue Aug 13, 2022 · 4 comments
Open
1 task done

[RRFC] SlotController #7

justinfagnani opened this issue Aug 13, 2022 · 4 comments

Comments

@justinfagnani
Copy link
Contributor

  • I searched for an existing RRFC which might be relevant to my RRFC

Motivation

Moved from lit/lit#2693

There are a few common patterns for using slots that could be nicely wrapped up in a reactive controller:

  • Determining when a slot has assigned content so you can style the component differently (ex: add padding when there's content).
  • Tracking slotted children to call APIs (set properties, add/remove event listeners, call methods) when child enter and exit the slot.

Example

We could make a SlotController(s) to help.

class MyElement extends LitElement {
  private _slotController = new SlotController(this);
    
  render() {
    const slotStyles = {
      padding: this._slotController.hasAssignedElements() ? '4px' : 0,
    };
    return html`<slot style=${styleMap(slotStyles)}></slot>`;
  }  
}

How

See https://gist.github.com/justinfagnani/a90eefb8da6bbfa4250a46732a8e5fbc

Current Behavior

Libraries write their own slot controller, like https://github.com/shoelace-style/shoelace/blob/next/src/internal/slot.ts or users use slotchange.

Desired Behavior

It's easier.

References

  • n/a
@justinfagnani
Copy link
Contributor Author

As mentioned in shoelace-style/shoelace#778, SlotController might be useful as a way of detecting whether slots have assigned elements in shadow DOM. It would require SSR-specific code in SlotController, which we don't quite have a way to do yet, and probably specific support to parse children or notifiy on children with parts in lit-ssr. cc @aomarks

@sorvell
Copy link
Member

sorvell commented Sep 18, 2023

Here is a prototype of a slightly different take on this same idea, called SlottableController.

The difference is that the elements tracked are host slottable candidates and not actually assigned nodes. This makes it easier to conditionally render slots and perform manual slot assignment based on the existence of child elements. It also integrates well with the slottable-request protocol.

The API prototyped for the controller includes:

  • has(name): returns true if a host child exists with a slot of name.
  • get(name): returns a list of host children with a slot of name.
  • getSlot(name): returns a slot of the given name in the host's shadowRoot
  • slottablesChanged: callback provided in the controller constructor and called whenever slottable children change after the host updates. This is especially useful for performing manual slot assignment, say, after deciding to render some slots based on slottable presence.

@justinfagnani
Copy link
Contributor Author

@sorvell would you say that's a polyfill or companion to imperative slotting?

One thing I've wanted with imperative slotting is a helper that takes a callback on new child elements being added and returns a slot to assign too, as well as maybe handling serializing things to named slots for SSR.

@sorvell
Copy link
Member

sorvell commented Sep 18, 2023

It's not a polyfill, it's a helper. Imperative slotting is well supported now =).

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

2 participants