Skip to content

Platform: Tabs Component Technical Design

kavya-b edited this page May 18, 2020 · 19 revisions

Tabs Component

Summary

Tabs organise related content so users can navigate between views within the same page. Tabs consists of list of tab items where user can select the item which they want to view. User will have options to access these items one by one by pressing tab key and he can select particular item by space or enter key.

Tabs enable users to scan a page and easily find what they need. Use tabs to group information into logical sections based on functionality or use case.

Tabs will be used to group related content on the same page. so that user can easily access the information without loading the different web page.

Design

<fdp-tab-nav [list]=“tabNavList” (onChange)="onChangeTab()">
    
</fdp-tab-nav>

<router-outlet></router-outlet>

Property Bindings

tabNavList: TabNavItem[]

The "tabNavList" property accepts an array of TabavItem, and uses these values to create the tab list.


Event Bindings

onChange: EventEmitter<number>

The "onChange" event binding emits an event with a selected index of the tab, whenever the user clicks or press enter key or space on the particular tab item.

Two-Way Bindings

N/A


Content Projection

N/A


Interfaces and Types

TabNav

export interface TabNavItem {
        index:number; // Option for User to specify the tab index
        label:string;  // specifies label for each tab item
        disabled: boolean; // option for disabling the tab
        selected: boolean; // user can able specify the current active tab 
        icon:string;// To specify tab icon
        badge:string:// To Specify badge or counter
        routerLink: string; //  option to provide the routerLink
       

}

i18n

Link to general support for i18n: Supporting internationalization in ngx/platform

This tech spec was last updated in Oct 2019 and may not have the latest spec that is to be followed. i18n section is being written for the Oct 2019 tech spec. fdp-tab-nav cannot be supported for i18n since it does not provide individual items in a declarative approach. Core's fd-tab-list however can support i18n.

Special Usecase: No

  • fd-tab-list from core can be supported as:
<fd-tab-list>
    <fd-tab i18n="@@tabContent" i18n-title="@@linkTab" title="Link">
        Content Link
    </fd-tab>
</fd-tab-list>

Redesign Required: Yes

If following core's design, then not required.


Comments

@Frank

  • What I am missing here how are you going to add a content for the actual tab ? What is you thinking behind it?
  • How do you connect actual content with the click tab?
  • In general there are several approaches to so that you want to support
    • click on the toptakes you to the new routing page ( in this case u would have to use router-outlet
    • Provide view template for each tab
    • Provide one template and let the tablist ot tell you which tab is clicked so you can render specific view

What is you plan?

  • Let's have some uniformity as I commented this on other places for component that accepts list of something let's have binding [list] it will be easier ot work with programaticaly.

  • Once you asnwer my first main question this also asnwer these but .

    • Good you have interface to pass in some structure,
    • what is title, label? -> is this the same thing?
    • you dont have to have content as string right ? Tab is container and you be able to have anything, datatable, tree, forms, etc..
    • I dont think we need to complextTitle it became more complex to put together the structure
    • YOu can have simply icon as part of the Tab interface
    • YOu should have also the counter under the Tab But dont call it counter - this is usually called badge
  • Are we going to support vertical tabs?
    * Do we need to support ID?
    We can have on the root level routerLink instead of creating extra interface * what you want to have also command?: (event?: any) => void;

  • let's just have onChange event

@Kevin

  • I agree with Frank that we need to figure out how manage the tab content. This will probably the most challenging part of the component. I'm kind of partial to the way Angular Material handles tabs, but you need to use some advanced Angular to make this work.
<mat-tab-group>
  <mat-tab>
    <ng-template mat-tab-label>
      The <em>best</em> pasta
    </ng-template>
    <h1>Best pasta restaurants</h1>
    <p>...</p>
  </mat-tab>
  <mat-tab>
    <ng-template mat-tab-label>
      <mat-icon>thumb_down</mat-icon> The worst sushi
    </ng-template>
    <h1>Terrible sushi restaurants</h1>
    <p>...</p>
  </mat-tab>
</mat-tab-group>
  • Here's an example of a possible interface based on Angular Material
<fdp-tab-group>
   <fdp-tab [label]="'First Tab'" [icon]="'bell'" [counter]="5">
     <p>This is the content for the first tab.</p>
   </fdp-tab>
   <fdp-tab [label]="'Second Tab'" [icon]="'star'" [active]="true">
     <p>This is the content for the second tab.</p>
   </fdp-tab>
   <fdp-tab [disabled]="true">
     <ng-template fdp-tab-label><em>Third Tab</em> <fd-icon [glyph]="'car'"></fd-icon></ng-template>
     <p>This is the content for the third tab.</p>
   </fdp-tab>
</fdp-tab-group>
  • The above designed should be discussed, as I'm not sure if it is compatible with our meta-ui goals.
  • Instead of active, I would prefer selected.

@Manu

Q1.

  • What I am missing here how are you going to add a content for the actual tab ? What is you thinking behind it?

Ans. In Tab interface i have an attribute called 'content', when the particular tab clicked I am thinking of loading the content to

 <ng-template></ng-template>. 

I thought of loading the content of tab something like this.

 <ng-template>{{content}}</ng-template>

In Fundamental-ngx for Tab is already a component and their component structure looks like below.

<fd-tab-list>
    <fd-tab [title]="'Link'">
        Content Link
    </fd-tab>
    <fd-tab [title]="'Selected'" [disabled]="false">
        Content Selected
    </fd-tab>
    <fd-tab [title]="'Link'" [disabled]="false">
        Content Link Two
    </fd-tab>
    <fd-tab [title]="'Disabled'" [disabled]="true">
        Disabled
    </fd-tab>
</fd-tab-list>


<fd-tab-list>
    <fd-tab>
        <ng-template fd-tab-title>
            <fd-icon [glyph]="'delete'"></fd-icon>
            <span style="margin-left: 12px;">Delete</span>
        </ng-template>
        Content for tab 1
    </fd-tab>
    <fd-tab>
        <ng-template fd-tab-title>
            <fd-icon [glyph]="'edit'"></fd-icon>
            <span style="margin-left: 12px;">Edit</span>
        </ng-template>
        Content for tab 2
    </fd-tab>
    <fd-tab [title]="'Tab 3'">
        <ng-template fd-tab-title>
            <fd-icon [glyph]="'search'"></fd-icon>
            <span style="margin-left: 12px;">Search</span>
        </ng-template>
        Content for tab 3
    </fd-tab>
</fd-tab-list>

I wanted to wrap this structure and make it to single line component like

<fdp-tab-list [list]=“tabList” [(selectedIndex)]=“selectedtab()”>

Discussion from previous design meeting.

Gaps Identified in Fundamental-ngx Tab components based on the new FRD and design.

  • If more than 5 tab items are present, overflow icon or 'More' option should display. This feature implementation should be discussed with Deno and team. Because we have to do changes in existing Fundamental-ngx Tab component.

  • Implement Tab Navigation feature as a component, at present its in directive structure.

Below is the Design for the new TabNavigation Component.

Design

<fdp-tab-nav [list]=“tabNavList” (onChange)="onChangeTab()">
    
</fdp-tab-nav>

<router-outlet></router-outlet>

Property Bindings

tabNavList: TabNavItem[]

The "tabNavList" property accepts an array of TabItem, and uses these values to create the tab list.


Event Bindings

onChange: EventEmitter<number>

The "onChange" event binding emits an event with a selected index of the tab, whenever the user clicks or press enter key or space on the particular tab item.


Content Projection

N/A


Interfaces and Types

TabNav

export interface TabNavItem {

        index:number; // Option for User to specify the tab index
        label:string;  // specifies label for each tab item
        disabled: boolean; // option for disabling the tab
        selected: boolean; // user can able specify the current active tab 
        icon:string;// To specify tab icon
        badge:string:// To Specify badge or counter
        routerLink: string; //  option to provide the routerLink
       

}

Comments II (10/10/2019)

@Kevin

  • After looking at the @fundamental-ngx core documents, I think the "core" design is fine the way it is. I think we should consider just enhancing the existing TabListComponent; adding the feature to limit the number of tabs displayed.

@Frank Definitely this is good way to go. I would definitelly like to see two approaches

  • TabView

    • Where you woudl work directly with the view just like angular material
    • Somethign like core is handling it we just extend it for more features
    • The if more than 5.. -> thsi should be configurable
  • TabNab

    • Where it woudl be more programatic way, you would pass list just like you have it and render the views
    • I was also thinking to put the router inside completly but its probably not go way. on application level I might put some additional content before or after router-outlet
Clone this wiki locally