mefechoel / svelte-navigator

Simple, accessible routing for Svelte
Other
502 stars 39 forks source link

Meta prop not working #24

Closed marroquinsamy closed 3 years ago

marroquinsamy commented 3 years ago

Hi again, thank you for your support. Hope you're doing well! Today I was trying to implement a kind of accessibility features to my website. I'm trying to do a a11y.createAnnouncement function based on the example you give in the README.md When I add a meta object to a Route, this is not added to the component and when I print the information it is undefined. Here you can see:

To Reproduce Steps to reproduce the behavior:

  1. Make a createAnnouncement function like this:
    const createAnnouncement = (route, location) => {
    const viewName = route.meta.name
    const { pathname } = location
    console.log(`Navegado a la vista de ${viewName} en ${pathname}`)
    return `Navegado a la vista de ${viewName} en ${pathname}`
    }
  2. Before returning the value, I print the information.
  3. Go to the console of the browser and load a page.
  4. See error

Expected behavior route.meta.name is filled with the meta I pass to the Route component.

Screenshots My code: Screenshot from 2020-12-15 20-33-15

The console in my browser: Screenshot from 2020-12-15 20-21-41

Desktop (please complete the following information):

Additional context And a more question 😅: What are the types of route and location in the parameters of the function? I'd love to know them to type them in my code since I'm working with TypeScript.

mefechoel commented 3 years ago

Thanks for the detailed example! I'll setup a similar app so I can test the bug later :)

mefechoel commented 3 years ago

Oh and regarding your second question, the type of the createAnnouncement function is Router.A11yConfig.CreateAnnouncementFn and the types of the parameters are RouteInstance<Params, Meta> and NavigatorLocation. You can import all of them from the main package.

See types/Router.d.ts for more details.

mefechoel commented 3 years ago

Hmm, I couldn't reproduce the issue. I tried it out using this setup, which is basically the same as yours:

<script>
    import { Router, Route, Link } from "svelte-navigator";

    const createAnnouncement = (route, location) => {
        const viewName = route.meta.name;
        const { pathname } = location;
        console.log(`Navigated to the ${viewName} view at ${pathname}`);
        return `Navigated to the ${viewName} view at ${pathname}`;
    };
</script>

<Router a11y={{ createAnnouncement }}>
    <header>
        <h1>Svelte Navigator</h1>
        <nav>
            <Link to="/">Home</Link>
            <Link to="about">About</Link>
            <Link to="somewhere-else">Somewhere else</Link>
        </nav>
    </header>

    <main>
        <Route path="/" meta={{ name: 'Home' }}>
            <h3>Home</h3>
            <p>Home sweet home...</p>
        </Route>

        <Route path="about" meta={{ name: 'About' }}>
            <h3>About</h3>
            <p>That's what it's all about!</p>
        </Route>

        <Route meta={{ name: 'Not Found' }}>
            <h3>Default</h3>
            <p>No Route could be matched.</p>
        </Route>
    </main>
</Router>

Could you provide an example for me to reproduce the issue? In the Svelte REPL for example or in a little github repo I can clone?

mefechoel commented 3 years ago

Oh, wait a second... I think I know where the issue is coming from. You're navigating to /products/something, but in the code snippet, you just have a products/* route. Is there a nested Route somewhere in your Products component? If so, that Route is missing a meta prop. Svelte Navigator always tries to pick the most specific Route that is rendered after a navigation. This usually means the Route, that is nested most deeply. That way the announcements are most specific and focus management works best. The downside is, that you need to add a meaningful meta prop to every Route.

If that's to much of a hassle you could leave the meta.name property out of the announcement and use something like const createAnnouncement = route => 'Navigated to ' + route.uri in the appropriate language (I'm sorry, I don't know what language your example is in... I'm guessing spanish or portugese?).

marroquinsamy commented 3 years ago

Thank you very very much!!! You're right: I have to write the meta object in the most deeply Route component in my routes. I tried to do so and it worked nice. Sorry for taking your time 😅. I will keep using the original createAnnouncement function because my app doesn't have so much routes and I control them in an easy way. And yes, it's Spanish 😅. I'm a Spanish native speaker, from Guatemala.

Thank you very much for helping me and teaching me this new thing. Your library is excellent, I love the focus management it has!!!

Hope you're good.

mefechoel commented 3 years ago

No worries! I'm glad I could help! Thanks so much!