Svelte Uber Eats Navigation

- 2/2024

This type of navigation is very popular with delivery apps, and is quite short to do with Svelte Actions.

But is not very intuitive, so I wanted to share how it’s done.

Here are the links:


a screenshot of the navigation

a screenshot of the navigation


Knowing what is on the screen

First, we need to know which food category is on the screen, for this we use the IntersectionObserver:

function enterViewPort(e) {
    const observer = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting) {
            titleInFocus = e.id;
        }
    });

    observer.observe(e);
}

This function will assing the element id (e.id) to titleInFocus each time an element enters the screen.

Then we add Svelte Action to each title (if you are not familiar with actions, Joy of Code has an amazing video about it). In our case with simply have to add use:enterViewPort to the element.

Focusing the button on the nav bar

Now we have to listen for every change in titleInFocus to scroll the button to the left.

We have to do some manual work know the position at which the scroll should be. scrollIntoView has APIs to do this, but they didn’t work for me.


$: {
        let targetElement = document.getElementById(`nav-${titleInFocus}`);
        let rect = targetElement?.getBoundingClientRect();
        if (rect) {
            navReference?.scrollTo({ left: navReference?.scrollLeft + rect?.left - 10, behavior: 'smooth' });
        }
}

Note1: we are using id for the title and nav-id for the button (e.g. dishes and nav-dishes).

Note2: this hack only works if the nav starts at position 0,0 in the viewport. Open for sugestions.

Note3: I could not make both scrolling smooth when clicking in a button (e.g. the nav bar is smooth but not the page scrolling) bc they would overlap and stop. Open for sugestions.

Conclusion

I’m amazed by how little Svelte is needed to do this, is almost pure DOM.

If you want a more impressive example of Svelte Actions you should check Geoff Rich: Detecting sticky positioning with Svelte actions.




Comments

If you want to leave a comment do it on this reddit post