GithubHelp home page GithubHelp logo

andreasbm / router-slot Goto Github PK

View Code? Open in Web Editor NEW
114.0 114.0 20.0 1.44 MB

A powerful web component router.

Home Page: https://codepen.io/andreasbm/pen/XWWZpvM

License: MIT License

JavaScript 1.25% TypeScript 97.95% HTML 0.79%
customelements pwa router webapp webcomponents

router-slot's Introduction

router-slot's People

Contributors

andreasbm avatar scttdavs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

router-slot's Issues

Named router slot

I'm searching for feature similar to Angular router, where you can define multiple router-outlets and render multiple components there.
Example:

http://localhost/home(modal:popup), renders home component into main router-slot and popup component renders to router-slot named modal.

Nested routes example?

What is the correct way for creating nested routes?
Currently I'm creating a new RoutetSlot instance in the parent component and inserting router-slot tag in the required position.

Overall it's working fine, but I noticed that I can't invoke a promise based function before initializing the router. In that case the view of the nested components is just not rendering.

Is there a better way to achieve nested routes?

What's this?

Failed to load module script: The server responded with a non-JavaScript MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.

/test is matched when specifying path: '/'

Goal:
match '/' for home
and default anything else to a 404Component

However, when speciying my "IComponentRoute":

{
path: '/',
component: whatever,
fuzzy: false
}

the deduced regex by util::router::matchRoute is
^[/]?(\/|$)/
which then matches the path /test

I would expect /test not to be matched.

For now, I am specifying for path '/[^\w]' which seems to be sufficient but that relies too much on implementation
new RegExp(`^[\/]?${routePath}(\/|$)`);
which takes the string as is.
May better directly offer possibility to input regex in this case if we don't handle the '/' as strict match

Maybe I overlooked something though?

history.pushState to a unexsting path doesn't redirect correctly

window.history.pushState(null, '', redirectTo || 'menu');

I'm using the code above to decide where my Login page will redirect to when it is accessed while the user is already logged in.

The problem is that, even though my routes are as follows:

customElements.whenDefined('router-slot').then(async () => {
  const routerSlot = document.querySelector('router-slot');
  await routerSlot.add([
    {
      path: 'menu',
      component: () => import('./pages/menu-page'),
      guards: [sessionGuard],
    },
    {
      path: 'send-song',
      component: () => import('./pages/send-song-page'),
      guards: [sessionGuard],
    },
    {
      path: 'vote',
      component: () => import('./pages/vote-page'),
      guards: [sessionGuard],
    },
    {
      path: 'logout',
      component: () => import('./pages/logout-page'),
      guards: [sessionGuard],
    },
    {
      path: '',
      component: () => import('./pages/login-page'),
    },
    {
      path: '**',
      redirectTo: 'menu',
    },
  ]);
});

Meaning that I have a path: '**' with a redirectTo: 'menu', it doesn't work properly if the pushState's redirectTo is nonsense. In this case it just tries to access the nonsensical route instead of redirecting to 'menu'.

Is this a bug or am I doing something wrong?

Thanks

Anchor link with something other than plain text causes full reload

Great router btw,

The world will embrace web components and then we need routers like this!

The small bug I found when I had for example

<a href="about">
     <h1>About</h1>
</a>

and click on it, it causes a full reload. While without the h1 tag it works fine.

I know I can use the router-link element and this seem to work. But yeah it would be very smooth to use anchor tags everywhere

Thanks for the good work

TypeScript type errors in `router-slot.d.ts`

I'm having trouble using your library with TypeScript (3.5.2).

I get the type errors shown below during compilation. They are coming from within router-slot.d.ts. These errors might have something to do with breaking-changes in TypeScript 3.5.

node_modules/@appnest/web-router/router-slot.d.ts:30:3 - error TS2416: Property 'parent' in type 'RouterSlot<D, P>' is not assignable to the same property in base type 'IRouterSlot<unknown, unknown>'.
  Type 'IRouterSlot<P, unknown> | null | undefined' is not assignable to type 'IRouterSlot<unknown, unknown> | null | undefined'.
    Type 'IRouterSlot<P, unknown>' is not assignable to type 'IRouterSlot<unknown, unknown>'.
      Types of property 'add' are incompatible.
        Type '(routes: IRoute<P>[], navigate?: boolean | undefined) => void' is not assignable to type '(routes: IRoute<unknown>[], navigate?: boolean | undefined) => void'.
          Types of parameters 'routes' and 'routes' are incompatible.
            Type 'IRoute<unknown>[]' is not assignable to type 'IRoute<P>[]'.
              Type 'IRoute<unknown>' is not assignable to type 'IRoute<P>'.
                Type 'IRedirectRoute<unknown>' is not assignable to type 'IRoute<P>'.
                  Type 'IRedirectRoute<unknown>' is not assignable to type 'IRedirectRoute<P>'.
                    Type 'unknown' is not assignable to type 'P'.

30   parent: IRouterSlot<P> | null | undefined;
     ~~~~~~

node_modules/@appnest/web-router/router-slot.d.ts:63:3 - error TS2416: Property 'queryParentRouterSlot' in type 'RouterSlot<D, P>' is not assignable to the same property in base type 'IRouterSlot<unknown, unknown>'.
  Type '() => IRouterSlot<P, unknown> | null' is not assignable to type '() => IRouterSlot<unknown, unknown> | null'.
    Type 'IRouterSlot<P, unknown> | null' is not assignable to type 'IRouterSlot<unknown, unknown> | null'.
      Type 'IRouterSlot<P, unknown>' is not assignable to type 'IRouterSlot<unknown, unknown>'.

63   queryParentRouterSlot(): IRouterSlot<P> | null;
     ~~~~~~~~~~~~~~~~~~~~~

node_modules/@appnest/web-router/router-slot.d.ts:74:3 - error TS2416: Property 'add' in type 'RouterSlot<D, P>' is not assignable to the same property in base type 'IRouterSlot<unknown, unknown>'.
  Type '(routes: IRoute<D>[], navigate?: boolean | undefined) => void' is not assignable to type '(routes: IRoute<unknown>[], navigate?: boolean | undefined) => void'.
    Types of parameters 'routes' and 'routes' are incompatible.
      Type 'IRoute<unknown>[]' is not assignable to type 'IRoute<D>[]'.
        Type 'IRoute<unknown>' is not assignable to type 'IRoute<D>'.
          Type 'IRedirectRoute<unknown>' is not assignable to type 'IRoute<D>'.
            Type 'IRedirectRoute<unknown>' is not assignable to type 'IRedirectRoute<D>'.
              Type 'unknown' is not assignable to type 'D'.

74   add(routes: IRoute<D>[], navigate?: boolean): void;
     ~~~

Can't install on Windows 11 with npm

Hey,
I just tried to install dev dependencies on a Windows 11 machine, but failed:

...
npm WARN deprecated @wessberg/[email protected]: this package has been renamed to rollup-plugin-ts. Please install rollup-plugin-ts instead
npm ERR! code 1
npm ERR! path Z:\source\repos\_inspiration\router-slot\node_modules\node-sass
npm ERR! command failed
npm ERR! command C:\WINDOWS\system32\cmd.exe /d /s /c node scripts/build.js
npm ERR! Building: C:\Program Files\nodejs\node.exe Z:\source\repos\_inspiration\router-slot\node_modules\node-gyp\bin\node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp verb cli [
...
  • node version: 16.19.0
  • npm version: 8.19.2
  • VS Code current

Looks like @appnest/web-config": "^0.5.4 is the issue.

Are there other requirements?

Btw. the lit example does not work:

firstUpdated (props: PropertyValues) {
    super.firstUpdated(props);
    this.$routerSlot.add(ROUTES); // throws error: add is not a function
}

Best regards,
Dirk

Navigate to a relative URL

I'm not sure what the proper way is to navigate to a relative URL. I dispatch an event from a component and the page that acts on the event needs to change the URL. I can't use absolute paths because the page is used from more than one location.

Say I have https://myapp.com/page1/sec1 and an event is dispatched that is handled by page1 and needs to change to sec2.
I tried window.pushState({}, null, '../sec2'); but the router takes me back to my apps default route. I also tried ./sec2 and just sec2.

The only way I got it to work was to get a handle to the router-slot, call constructAbsolutePath('sec2') and then using the result in the pushState call. If that is what is needed, that is fine. Just wanted to know if there should be an easier way to navigate.

Why using a slot?

Hi there,

I've been looking at your library and I'm wondering what is the purpose of using a single slot within the shadow dom? Since basically everything that is injected in the slot is rendered with the light dom anyway, wouldn't it be simpler to not use the shadow dom at all?
I'm really curious to understand this so if you could explain me the reasoning, that would help me to understand this design decision.

Thanks for your time :)

Using address bar

All works for me so far including routing to a LitElement in a separate file. But, typing a valid route at the address bar results in page reload and a "Not Found" page. Not sure if this behavior is avoidable. Is this expected behavior, and if so is there a plan or approach for using the address bar with router-slot?

Feat: more generic rule to skip history API

First of all, thanks a lot for this ! it is really well thought through, esp. the way to nest <router-slot>, and allow relative router (smth all other web-component friendly routing lib I had a look at fail to do properly).

The old Polymer <app-location> had a parameter to skip url from being handled by the router based on a regex.

You could for instance do <app-location route="{{route}}" url-space-regex="^(?!/api/).+"></app-location> to skip all url starting with /api.

In app-router, you'd need to add data-router-slot=disabled to all such links. It would be more convenient in some cases to rely on a more generic rule.

I can have a go at trying to add this feature if this is something you might consider adding.

The main difficulty is to find a proper way to inject this additional logic to the ensureAnchorHistory function and call it later on in the instantiation process. Maybe when the root app-router is attached ?

Nested Router Slots

I'm trying to replace the Polymer app-route component. That component has a "tail" property which allows you to pass along the subroute after handling the matched route.

What I need is <my-app> to match some basic urls like /login, /ext, and /int. This lazy loads three different components <login>, <ext>, and <int> (as an example). In <ext> is another set of routes that match everything after /ext to a new set of paths such as /user/123 so the full url is /ext/user/123 and it loads a component within a slot in . /int/user/123 is also valid and it loads the component within a slot in <int>.

How can I use multiple <router-slot> components nested to specify /int paths in the <int> component and /ext paths in the <ext> component.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.