Just as you can bind to DOM elements, you can bind to component instances themselves with bind:this
.
This is useful in the rare cases that you need to interact with a component programmatically (rather than by providing it with updated props). Revisiting our canvas app from a few exercises ago, it would be nice to add a button to clear the screen.
First, let’s export a function from Canvas.svelte
:
Canvas
let canvas = $state();
let context = $state();
let coords = $state();
export function clear() {
context.clearRect(0, 0, canvas.width, canvas.height);
}
Then, create a reference to the component instance:
App
let selected = $state(colors[0]);
let size = $state(10);
let showMenu = $state(true);
let canvas;
App
<Canvas bind:this={canvas} color={selected} size={size} />
Finally, add a button that calls the clear
function:
App
<div class="controls">
<button class="show-menu" onclick={() => showMenu = !showMenu}>
{showMenu ? 'close' : 'menu'}
</button>
<button onclick={() => canvas.clear()}>
clear
</button>
</div>
previous next
<script>
import Canvas from './Canvas.svelte';
import { trapFocus } from './actions.svelte.js';
const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet', 'white', 'black'];
let selected = $state(colors[0]);
let size = $state(10);
let showMenu = $state(true);
</script>
<div class="container">
<Canvas color={selected} size={size} />
{#if showMenu}
<div
role="presentation"
class="modal-background"
onclick={(event) => {
if (event.target === event.currentTarget) {
showMenu = false;
}
}}
onkeydown={(e) => {
if (e.key === 'Escape') {
showMenu = false;
}
}}
>
<div class="menu" use:trapFocus>
<div class="colors">
{#each colors as color}
<button
class="color"
aria-label={color}
aria-current={selected === color}