Repository: svelte
Issue: `$ref()` rune for using directives on components
Labels: feature request,runes

### Describe the problem

A commonly requested feature (#12229, #2870, #5236) is to have parity between native elements and svelte components for directives such as `class:`, `style:`, `use:` or `transition:`. This currently errors:

```svelte
<Component style:color="red" />
<!-- This type of directive is not valid on components -->
```

Why is this bad? It breaks intuition for new developers who expect components to behave the same as elements. It makes wrapper components inherently more limited than native elements.

Several points of implementation difficulty have been brought up in the past:
1. How do you deal with scoped CSS classes?
2. Which element inside the component do you apply the directives to?
3. What if multiple elements in a component need to receive the directive?

### Describe the proposed solution

The `$ref` rune would provide a way for components to determine which element receives the directives.

```svelte
<script>
  const props = $props();
  let ref = $ref();
</script>

<button bind:this={ref} {...props}></button>
```

Any component that does not explicitly use `$ref()` still throws an error when a directive is used on it.

I believe this answers the main issues on this topic.
1. How do you deal with scoped CSS classes?

Right now, if you pass a `class` prop to a component, it uses the scoped css hash from that component ([playground](https://svelte.dev/playground/hello-world?version=5.16.0#H4sIAAAAAAAAA41QwWrDMAz9FSEGbSEktMfUDYxedux93iFNFBJwLGOr7UrIv4943Uq3duwmPb0n6b0BbdkT5vhCxjCc2Jsa5lR3QvUCE2w6QwHz1wHl7CbeBGDypXp2Lg1HMjJh-zLQPbxiK2QlYI4qVL5zUmirpesde4Et944tWYHGcw-zNPtGLitma21VdlVa1S6hMmUIG40Ns8ZiV3qyorJ2WWirritvWJB9qoOcDcUX0oYZhqnSUrFhn4Onej0BY7wZmZig0LtgLv5AY_Igip9f3wZyZ_ogloptEHCeXYANPMVivvgdwepiboiMNDZjsW07U6usXf3D6t4c6NixIfnb8dv4ARVBRTgmAgAA)). `class:` would behave the same way, i.e. `<Comp class:foo />` would use the `.foo` defined in `Comp.svelte`.

2. Which element inside the component do you apply the directives to?

This proposal leaves the choice to the component creator. They could specify which of the root elements receives the directives, or a non-root element, or a child component like this:

```svelte
<!-- Parent.svelte -->
<Child use:action />

<!-- Child.svelte -->
<script>
  const ref = $ref();
</script>
<Grandchild bind:this={ref} />

<!-- Grandchild.svelte -->
<script>
  const ref = $ref();
</script>
<div bind:this={ref} />
<!-- this element receives the action -->
```

3. What if multiple elements in a component need to receive the directive?

In this proposal, it would be impossible. However, here are some alternatives:

### Alternatives

1. Use the rune only inside the property:

```svelte
<div bind:this={$ref()}></div>
```
This doesn't allow using the bind:this for a local use, though.

2. Don't use bind:this

```svelte
<script>
  let canvas;
  const ref = $ref();
</script>
<canvas bind:this={canvas} {ref}></canvas>
```
Could also be `svelte:ref={ref}` or something.

3. Allow multiple `$ref()`s per component

```svelte
<script>
  let ref1 = $ref();
  let ref2 = $ref();
</script>
<div bind:this={ref1}></div>
<div bind:this={ref2}></div>
```
In this case, the directives would be duplicated and both elements would receive them.


I'm interested in knowing if there's some other barrier that makes this impossible, but I haven't found one while researching this issue!

### Importance

would make my life easier