Q:

Toggle between button states and perform function call in Svelte

I must admit I haven't quite grassped the concepts of Svelte yet. I made a component which purpose is to excecute a API-request of some sort. Each button component can have two or more buttons:
Screenshot of "Button component"
When clicking a button in the buttongroup-component I want to do following:

Set clicked button to a state "active" so I can apply som kind of
class to it.
Unset other button/-s with state "active".
Perform a custom function call

Button component
<div class="buttons-wrapper">
    <label>
        {labelTitle}
        {#if helpText}
            <Icon iconType="help" iconSize="small" iconTitle={helpText} />
        {/if}
    </label>
    <div class="buttons">
        {#each options as option, index}
            <button class={index === 0 ? 'selected' : ''} 
                value={option.id}
                name={option.name}
                on:click={setSelected}>
                    {option.name}
            </button>
        {/each}
    </div>
</div>

Parent component
<ButtonGroup options={[{ id: 0, name: 'Option 1' }, { id: 1, name: 'Option 2' }]} labelTitle="Button label" />
I my example i call setSelected on click, should I do it from the component itself or from the parent component?
I'm really lost here...

A:

You can make your ButtonGroup a Controlled Component (it gets its current value through props and notifies changes) or make a Uncontrolled Component (stores its own state internally). Alternatively your component can support both, for example:
<script>
    import { createEventDispatcher } from 'svelte';

    const dispatch = createEventDispatcher();

    export let labelTitle = 'button label';
    export let options = []
    export let selected = 0

    function setSelected(e){
        const newValue = Number(e.target.value)

        selected = newValue

        dispatch('change', {value: newValue})
    }
</script>

<style>
    button.selected {
        background-color: red;
    }
</style>

<div class="buttons-wrapper">
    <label>
        {labelTitle}
    </label>
    <div class="buttons">
        {#each options as option, index}
            <button class={selected === index ? 'selected' : ''} 
                value={option.id}
                name={option.name}
                on:click={setSelected}>
                    {option.name}
            </button>
        {/each}
    </div>
</div>

https://svelte.dev/repl/12f5112852bd4dceb382578a4cfeed06?version=3.12.1

