Clarity: Integrate tabs with the Angular router

Created on 22 Mar 2017  路  16Comments  路  Source: vmware/clarity

Select one ... (check one with "x")

[ ] bug
[ ] feature request
[ x ] enhancement

Expected behavior


I want to define a tab control where the tab selection can be controlled by my url routing (as well as user selection). When the page loads, if the URL is such that we route to the second tab, only that tab should be shown as active.

Actual behavior


Because Clarity does not like having no tabs selected, it auto-activates the first tab. When the angular routing activates the second tab, both tabs are shown as active.

Reproduction of behavior




Short of writing out a plunker, here's my code:

    <clr-tabs>
      <clr-tab-link routerLink="./stream" routerLinkActive="active">Stream</clr-tab-link>
      <clr-tab-link routerLink="./types" routerLinkActive="active">Types</clr-tab-link>
    </clr-tabs>

My workaround for this issue is a rather ugly adding of a third, active but hidden tab. This prevents the clr-tabs component from auto-activating the first tab.

      <clr-tab-link [clrTabLinkActive]="true" style="display:none"></clr-tab-link>

It works but is obviously not a great solution. Some possible fixes:

  • have a config option to allow zero active tabs
  • listen for programmatic changes in the of 'active' class and remove the 'active' class of all the other tabs. There may be something cleaner.

Environment details

  • Angular version: 2.0.X

  • Clarity version:

  • OS and version:

  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]

@clangular Help Wanted has workaround best with core under consideration website

Most helpful comment

Please check this approach, where static tabs are used instead of Angular component:
https://stackblitz.com/edit/clarit-tabs-with-router-static?file=src/app/clients/clients.component.html

The Angular component has its own underlying state and updating logic, which you also need to update, so what's shown on the screen is not disconnected from the component state (that's where duplicated active tabs come from). Which is possible but rather complicated, and not really necessary, as you want to manage the current tab content via routing anyway.

On the contrary, the Static version seems to integrate with routing pretty naturally.

We need to update our Docs with this recommendation.

All 16 comments

This is actually a bit more involved than listening to the class, I believe what we want is a proper integration of our tabs with the Angular router.

That means have our TabLink component check for an optional RouterLink directive on the host, and interact with it if it finds one.

Routing + tabs has popped up occasionally as a request, but is not a priority at the moment. We'll update this issue when we get to it.

Alternate solution that also handles redirection with the ng router (which the hidden-tab variant does not):

  <clr-tabs>
    <clr-tab-link routerLink="./stream" [clrTabLinkActive]="isActivePath('stream')">Stream</clr-tab-link>
    <clr-tab-link routerLink="./types" [clrTabLinkActive]="isActivePath('list')">Types</clr-tab-link>
  </clr-tabs>

And then in the component file:

  private isActivePath(pathName: string): boolean {
    return this.router.url.startsWith(`/explore/${pathName}`);
  }

Not so pretty, but functional (and not as ugly as a hidden tab).

I have the same task.

I'm looking for this functionality as well

@mathisscott - is there still a workaround for this with the new way tabs are implemented?

@jacobbutton
You can try what @rongery did above to see if that would work for you.

It does, but some changes need to be made to make the workaround compatible with the new tabs markup.

The new markup is...

    <clr-tab>
        <button clrTabLink [routerLink]="./stream">Stream</button>
        <clr-tab-content *clrIfActive="isActivePath('stream')">
            ***
        </clr-tab-content>
    </clr-tab>

@jacobbutton CanDeactivate doesn't work for such an approach. A tab ignores *clrIfActive value

Any updates? Seems like a few people have workarounds, can they post any current workarounds that they think are decent?

is there has any update about this enhancement?

any current workarounds that they think are decent?

This is how we use tabs in combination with the angular router, the tab is given by router param 'tab'
example: http://url/view/item;tab=details

  private activeTab = {
    details: false,
    tickets: false
  };

  ngOnInit() {
    this.initTabs();
    });

  isActiveTab(value) {
    if (value in this.activeTab) {
      return this.activeTab[value];
    }
    return false;
  }

  onTabChange(value) {
    this.activeTab[this._route.snapshot.params.tab] = false;
    this.activeTab[value] = true; 
    this._router.navigate(['./' , { tab: value} ], {relativeTo: this._route.parent});
  }

  initTabs() {
    // Get params from url
    const params = this._route.snapshot.params;

    if (params.tab in this.activeTab) {
      this.activeTab[params.tab] = true;
    } else {
      this.onTabChange('details');
    }
  }
<clr-tabs>
  <clr-tab>
    <button clrTabLink (click)="onTabChange('details')">Details</button>
    <clr-tab-content *clrIfActive="isActiveTab('details')"></clr-tab-content>
  </clr-tab>
      <button clrTabLink (click)="onTabChange('tickets')">Tickets</button>
      <clr-tab-content *clrIfActive="isActiveTab('tickets')"></clr-tab-content>
  </clr-tab>
</clr-tabs>

Please check this approach, where static tabs are used instead of Angular component:
https://stackblitz.com/edit/clarit-tabs-with-router-static?file=src/app/clients/clients.component.html

The Angular component has its own underlying state and updating logic, which you also need to update, so what's shown on the screen is not disconnected from the component state (that's where duplicated active tabs come from). Which is possible but rather complicated, and not really necessary, as you want to manage the current tab content via routing anyway.

On the contrary, the Static version seems to integrate with routing pretty naturally.

We need to update our Docs with this recommendation.

any update on this issue/feature?

It's not on our roadmap. And as our focus with new features is more toward Clarity Core now, it more likely to get discussed in the Core context.

There are a few challenges to implementing this now that we've baked accessibility into the tabs. Given the ability to accomplish this with using the CSS version of the tabs as a workaround, and the future Clarity Core tabs that would likely allow applications to do this, I'm going to close this feature as something we don't plan to build directly into the Angular tabs component.

Added to Support Log/DB, as it is a reoccurring question.

Was this page helpful?
0 / 5 - 0 ratings