How can I set an elements class attribute based on the return value of a function in svelte?
I am trying to make a speed typing game with svelte. I need to display the currently typed letters in different colors based on their state (inactive/active/right/wrong).
I have a function that gets the state of a typed letter from the array sentenceState
where x
is the words index and y
is a letters index.
function getLetterStyle(x, y) {
const state = sentenceState[x][y];
switch (state) {
case null:
return '';
case 0:
return 'text-black border-l border-black';
case 1:
case 2:
return 'text-green-500';
case -1:
return 'text-red-500';
}
}
The sentenceState is a reactive array of arrays where each value is either null, 0, 1, 2
or -1
.
Based on these values I want to dynamically change the class attribute of an element.
I tried to use this function like this:
{#each activeSentence as word, wordIndex}
{#each word as letter, letterIndex}
<span class={getLetterStyle(wordIndex, letterIndex)>{letter}</span>
{/each}
{/each}
This does not seem to work the way I would have imagined. It works on the initial page load. But when sentenceState
updates, the class does not change accordingly.
getLetterStyle()
will only be called once. Is there a way to use a function with parameters for the class attribute? What am I doing wrong here?
Thanks in advance!
Edit: here is a REPL https://svelte.dev/repl/4b02dd3eacee43748e05de3071e59f0b?version=3.42.2
There's nothing making your #each
loop reactive.
The #each
loop is generating elements based on sentence
, but this variable never gets updated, so it never re-renders.
One solution here is to instead calculate your styles per-letter reactively and then letting the #each
generate elements based on that.
Working REPL: https://svelte.dev/repl/77977b39b8964c8ba32acb063ceeb407?version=3.42.2