I've written a component that renders strings from an array as spans in a div if there is space sufficient width available in the div.
Calling the renderDinos() method onMount() works as expected. From there I wanted to update the component to dynamically re-render the strings in the div (adding or subtracting strings from the array) when the width of the div changes.
To achieve this I'm calling renderDinos() again in the afterUpdate() if the width of the component has changed. When onMount() runs the scrollWidth is the width of dinosaurs[i] so the scrollWidthSum is calculated accurately.
When the same method is called by afterUpdate() the initial value of scrollWidth is 0, not the width of dinosaurs[i]. This messes up the calculation for scrollWidthSum. I'd also like to subtract the scrollWidth from currentWidth in the if block in order to align the children better but, again; the value is initially 0 when I call the method from onUpdate.
Is there a way to resolve this? Is there a simpler way to re-render the content of the div when it resizes?
<script>
import { onMount, tick, afterUpdate } from 'svelte'
let dinosaurs = [
'dinosaur1',
'dinosaur2',
'dinosaur3',
'dinosaur4',
'dinosaur5',
]
let currentWidth = 0,
previousWidth = 0,
scrollWidth,
scrollWidthSum
$: dinosToShow = []
onMount(async () => {
previousWidth = currentWidth
renderDinos()
})
afterUpdate(() => {
if (previousWidth != currentWidth) {
renderDinos()
previousWidth = currentWidth
}
})
async function renderDinos() {
dinosToShow = []
scrollWidthSum = 0
scrollWidth = 0
for (let i = 0; i < dinosaurs.length; i++) {
dinosToShow = [...dinosToShow, `${dinosaurs[i]},\xa0`]
await tick()
console.log(scrollWidth)
scrollWidthSum += scrollWidth
if (scrollWidthSum > currentWidth - 60) {
dinosToShow.pop()
await tick()
break
}
}
}
</script>
<style>
.display {
overflow: hidden;
}
.dinosaur {
display: inline-block;
}
</style>
<div class="display" bind:clientWidth={currentWidth}>
{#each dinosToShow as r}
<span bind:clientWidth={scrollWidth} class="dinosaur">{r}</span>
{/each}
</div>