Skip to content

[Tracking] Bottom navigation & tabs components #6967

Closed

Description

@MartoYankov

Overview

The TabView component is a navigation component that is usually at the base of a mobile app. As such it's very important to get it right. Following lots of reported issues and discussions, we decided to do a re-design of how the developer uses and customizes the component. This should be done by introducing several new components including BottomNavigation and Tabs and there should be no breaking changes for existing apps. See the design doc below for the detailed information.

Design

Implementation details and motivation of the feature can be found in its design document.

Tasks

NativeScript 6.0 (components released as BETA / EXPERIMENTAL)

BottomNavigation

  • native implementation [Android]
  • nesting navigations
  • load one view at a time
  • TabStrip declaration
  • Angular support

Tabs

  • native implementation [iOS]
  • nesting navigations
  • pre-load one view to the sides by default
  • TabStrip declaration
  • offscreenTabLimit
  • tabsPosition
  • swipeEnabled
  • Angular support

TabStrip

  • CSS background-color

TabStripItem

  • CSS pseudo class :active
  • CSS background-color
  • CSS color
  • CSS font
  • CSS font-size
  • CSS highlight-color
  • CSS text-transform
  • iconSource font-icon support
  • Image instead of iconSource declaration
  • Label instead of title declaration

Issues:

NativeScript 6.1 (components released as OFFICIAL)

BottomNavigation

  • Vue.js support
  • No TabStrip support (tabBarVisibility/no declaration)
  • limit bar to 5 tabs

Tabs

  • Vue.js support
  • safe area improvements
  • No TabStrip support (tabBarVisibility/no declaration)

TabStrip

TabStripItem

Issues:

Angular

NativeScript 6.2

Issues:

NativeScript vNext

BottomNavigation

Tabs

TabBars

  • BottomNavigationBar
  • TabsBar

Issues:

Contributing

If you want to work on a task from the list, tell us and we will do our best to help you!
If you have another great idea on how to make the tab view even cooler, share it in the comments!

Discussion

Please, don't report problems here. Instead, open a new issue and link it to this one.
Let's use this discussion for suggestions and improvement ideas. We would love to hear from you!


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Activity

  1. changed the title [-][Tracking] TabView re-design[/-] [+][Tracking] Bottom navigation & tabs components[/+] on Jul 4, 2019
  2. webleaf commented on Jul 26, 2019

    @webleaf

    I expect ability to use FormattedString for TabStripItem. I think TabStripItem should extend TextBase. This would give full control over how it should look (because it behaves essentially like a Button).
    I do not feel any special advantages over what was before.
    For example, I need combine icon font, with formatted text in tab title.

  3. MartoYankov commented on Jul 26, 2019

    @MartoYankov
    ContributorAuthor

    @webleaf Unfortunately, customization options are greatly limited by the underlying native implementations. For example, on iOS the BottomNavigation TabStripItem is not even a UIView, so we can't really make it a TextBase. What we can do though, is provide the option to remove the bar and let you create your own bar with layouts and text views and animations and everything. Check out the PR - #7580. There is an example there. Will this work for you?

  4. henrychavez commented on Jul 31, 2019

    @henrychavez
    Contributor

    Hi guys,

    I have a plugin nativescript-bottom-navigation based on material components that would be part of nativescript-material-components and I'm wondering if my plugin will give you issues because I'm registering the component as BottomNavigation for angular and in some projects the error below is appearing and another issue that already was addressed here

    ERROR in ../node_modules/nativescript-angular/element-registry.js
    Module not found: Error: Can't resolve 'tns-core-modules/ui/bottom-navigation' in 'BugRepo\node_modules\nativescript-angular'
     @ ../node_modules/nativescript-angular/element-registry.js 142:57-105
     @ ../node_modules/nativescript-angular/renderer.js
     @ ../node_modules/nativescript-angular/nativescript.module.js
     @ ./app/app.module.ts
     @ ./main.ts
    
  5. MartoYankov commented on Jul 31, 2019

    @MartoYankov
    ContributorAuthor

    Hi @henrychavez

    This is a known error that occurs when you use a certain newer version of nativescript-angular and version pre 6.0 of the tns-core-modules. Either update nativescript-angular to the latest patch or update tns-core-modules to 6.0. The problem should go away.

    There shouldn't be a problem with clashing names. You should be able to override the core modules elements. Both nativescript-angular and nativescript-vue should support overriding of registered elements, so the last one wins.

    That being said, I think there actually might be a problem with your plugin's name and its functionality. From your code I see that you are exposing BottomNavigationBar components as in, only the bar, not the whole navigation component. It's a bit confusing, but the material guidelines declare BottomNavigation and Tabs more as patterns whereas the components are the MDCBottomNavigationBar and MDCTabBar. I'm saying this because for 6.1 we will expose the ability to use BottomNavigation, but remove the default bar and use your own - see #7580. If you keep the element name BottomNavigation for your plugin, it will override the core modules one and this won't be possible. If you rename it to BottomNavigationBar you will be able to combine the two and achieve more :) Let me know your thoughts.

  6. henrychavez commented on Jul 31, 2019

    @henrychavez
    Contributor

    Hi @MartoYankov,

    I agree with you the docs are a little confusing related to BottomNavigation and Tabs that the material design team describe in their documentation.

    I just review the code for bottom-navigation that you guys are doing and you are right, is better if I rename the plugin to BottomNavigationBar because I'm just exposing the component and leaving the implementation of navigation to the developer and you guys are preparing a more complete solution.

    I like the possibility to combine both, so in that way, the developer can use the bottom-navigation-bar that fits their needs (you have a custom bar to support fonts and custom items, something that can't be done using the BottomNavigationView or MDCBottomNavigationBar provided by material components) that being said, the developer can use my plugin if they want to use what the material components provide us or your implementation of the bottom-navigation-bar if they want something more custom, am I right? :D

  7. vahidvdn commented on Aug 8, 2019

    @vahidvdn

    Hey @MartoYankov
    When will this be a part of the tab template when we are creating a new app with tns create command? (It generates the template with the old TabView atm)

  8. manoldonev commented on Aug 26, 2019

    @manoldonev
    Contributor

    @vahidvdn Tab template should start generating app with BottomNavigation component for NativeScript 6.1 in September -- the changes are currently on PR NativeScript/nativescript-app-templates#79

  9. michalMajkel commented on Aug 29, 2019

    @michalMajkel

    Is it expected that on iOS placing tabs inside some other element breaks the view ?
    I am using old TabView for general navigation, and now in one of my pages i want to have another tabview ( inside a CardView ), I have used new Tabs item. It looks good(ish) on android but totally doesn't work on iOS - is the scenario i'm trying to achieve possible or it is expected to be impossible ? Same code produces following results on both platforms ( left iOS, right Android )
    tabs-os-difference

  10. MartoYankov commented on Aug 29, 2019

    @MartoYankov
    ContributorAuthor

    @michalMajkel This is an interesting scenario. Can you try nesting the Tabs component in a layout. See this article about nesting - https://docs.nativescript.org/core-concepts/nested-navigation#simple-rule

  11. jawa-the-hutt commented on Sep 2, 2019

    @jawa-the-hutt

    Question: Is there a way to not preload tabs at all? Essentially setting the offscreenTabLimit to zero?. This would cause issues with swipe, but that could be disabled as well.

    Possible use case would be providing three different views and subsequent actions based off the same data where by the data might be a different state that would cause it to show up in only one tab at a time.

    For example. I have a list of Appointments and I'd like to have them show up in 3 tabs: Requested, Responded and Scheduled.

    As it stands right now with a custom Tab UI implementation, when I load a tab, I go to the database and load the data. The query to the database prefiltrs the data so that it only brings the data it needs into the specific tab. I realize there are a lot of different ways I can do this, but this is the pattern being used and I wondered if it was possible to continue with the pattern.

    The alternative is to load all the data in the parent tabs view, hold it somewhere and then have the specific tabs filter the data as we transition between them. This will work fine for us in our situation, but there might be a use case for someone else where this pattern doesn't work and they'd like to keep the database queries on a per tab basis.

  12. MartoYankov commented on Sep 3, 2019

    @MartoYankov
    ContributorAuthor

    @jawa-the-hutt In short, you should use the BottomNavigation component. It doesn't pre-load tabs. Do you have an issue with it?

    Otherwise, we tried disabling pre-load with the old TabView component. On Android it's not possible to tell the ViewPager to not pre-load tabs. We did a hacky workaround that proved to bring lots of bugs and problems.

    This is part of the reason why we decided to split the tab navigation. The BottomNavigation component doesn't pre-load and doesn't have a swipe gesture. The Tabs pre-loads at least one tab to the sides and has the swipe gesture. Both have their use cases. We ultimately decided they can't be combined in one component safely.

  13. jawa-the-hutt commented on Sep 5, 2019

    @jawa-the-hutt

    @MartoYankov. Thanks for the info. My use case calls for the Tabs to be just below the header in the app and not at the bottom. So...in a perfect world, I'd have the functionality of the bottom navigation, but be able to position it vertically wherever I wanted in the UI.

    However, I do understand having to deal with the limitations of what the native platforms give us.

  14. MartoYankov commented on Sep 5, 2019

    @MartoYankov
    ContributorAuthor

    @jawa-the-hutt The way I understand it the reason why the BottomNavigation bar is on the bottom is that when you don't have the swipe gesture it's hard to reach to the top with your thumb to navigate.

    That being said, the scenario you want should be possible with the BottomNavigation without (with a hidden) a TabStrip and use a custom tab bar on top. There are also a couple of plugins that provide tab bars that you can position anywhere.

  15. 6 remaining items

  16. MartoYankov commented on Sep 25, 2019

    @MartoYankov
    ContributorAuthor

    @PeterStaev It seems iOS 13 brought lots of breaking/behavior changes to lots of UIKit components. There are also problems with XCode11/iOS13 with our testing infrastructure too, which is the reason we couldn't extensively test everything. We are receiving increasing issue reports about this and we're aware of it. It's not connected to the BottomNav/Tabs components only.

  17. PeterStaev commented on Sep 25, 2019

    @PeterStaev
    Contributor

    Thanks @MartoYankov. Leave it to Apple/Google to mess up the things... 😄 I guess I will see to downgrade to XCode 10.3 and hope that Apple review wont deny the app release for not targeting iOS13 😜

  18. AtoianAvetik commented on Oct 4, 2019

    @AtoianAvetik

    I want to change tab indicator (bottom line) height (for android), how I can do that? Can someone please help me.

  19. felixkrautschuk commented on Oct 7, 2019

    @felixkrautschuk
    Contributor

    @AtoianAvetik

    TabStrip{
        highlight-color: red;
    }
    

    They have updated the docs here

  20. AtoianAvetik commented on Oct 7, 2019

    @AtoianAvetik

    Thanks @felix-idf! But I mean the height(weight) of line, not a color :)

  21. MartoYankov commented on Oct 8, 2019

    @MartoYankov
    ContributorAuthor

    @AtoianAvetik This isn't supported at the moment. You can open a feature request for it.

  22. mkrierQape commented on Oct 17, 2019

    @mkrierQape

    @AtoianAvetik

    TabStrip{
        highlight-color: red;
    }
    

    They have updated the docs here

    it dont work

  23. MartoYankov commented on Oct 21, 2019

    @MartoYankov
    ContributorAuthor

    @mkrierQape Here is a playground link from the blog post - https://play.nativescript.org/?template=play-tsc&id=hhPr9s . The highlight color is changed to white.

  24. semocodev commented on Nov 8, 2019

    @semocodev

    Issue related nested routing on BottomNavigation using nativescript-angular

    Navigation structure according this structure:

    • App-routing:
    const routes: Routes = [
        { path: "welcome", component: WelcomeComponent },
        { path: "pages", loadChildren: () => import("./pages/pages.module").then(m => m.PagesModule) },
        { path: "", redirectTo: "welcome", pathMatch: "full" },
    ];
    
    • Pages-routing module
    const routes: Routes = [
      {
        path: '',
        component: PagesComponent,
        children: [
          {
            path: 'home',
            outlet: 'homeoutlet',
            component: HomeComponent
          },
          {
            path: 'advices',
            outlet: 'advicesoutlet',
            component: AdvicesComponent
          },
          {
            path: 'alerts',
            outlet: 'alertsoutlet',
            component: AlertsComponent
          },
          { path: '', redirectTo: '/(homeoutlet:home//advicesoutlet:advices//alertsoutlet:alerts)', pathMatch: 'prefix' }
        ]
      }
    ];
    

    When i am trying to navigate from /welcome route to pages/[path] route,
    this.routerExtensions.navigate([{ outlets: { homeoutlet: ['pages', 'home'] } }]);

    i get this error:
    Error: ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'pages/home'

    Playground example: https://play.nativescript.org/?template=play-ng&id=sVR895&v=3

  25. Angusoft-India commented on Feb 11, 2020

    @Angusoft-India

    @smorcuend

    The path:'' shouldn't be empty when you use named outlet in your pages-routing.module.ts.
    Just try path:'default' to have the outlet find the activeRoute.

    Thanks

  26. jessorlisa commented on Nov 4, 2020

    @jessorlisa

    Just curios, is someone still working on the open issues? Or is the list outdated?

  27. triniwiz commented on May 12, 2021

    @triniwiz
    Member

    @farfromrefug a little something for your plugin 😄

  28. rigor789 commented on Sep 7, 2023

    @rigor789
    Member

    Closing because BottomNavigation and Tabs are no longer part of core since NativeScript 8.0:

    https://blog.nativescript.org/nativescript-8-announcement/#important-note-about-bottomnavigation-and-tabs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions