vuematerial / vue-material

Vue.js Framework - ready-to-use Vue components with Material Design, free forever.
https://www.creative-tim.com/vuematerial
MIT License
9.9k stars 1.15k forks source link

Are tabs head swipable? #267

Closed zapping closed 7 years ago

zapping commented 7 years ago

Hi, Can you please take a look at this codepen https://codepen.io/zapping/pen/bBPyOz .

I tried added the tabs component. But when the no. of tabs increases it does not seem to have a scroll option on desktop browser nor can the tabs be swipped on mobile.

Have I missed/overlooked something? Can you please clarify on how the tab heads can be navigated in such a case i,e when you have lots of tabs. It will be preferable to have the swipe option.

Thanks and you have a great set of components.

marcosmoura commented 7 years ago

This is not possible yet! I will develop this in the next versions. For now, a possible workaround on mobile devices, is to add a custom css:

.md-tabs-navigation {
  overflow: hidden;
}

Sorry about that. Thank you.

zapping commented 7 years ago

np. Thank you for the work around.

igor-ribeiro commented 7 years ago

I got it to work, only problem is the indicator.

tabs-header-scroll

igor-ribeiro commented 7 years ago

Got it!

tabs-header-scroll

zapping commented 7 years ago

Oh, thats nice!! Does it mean that this will be available on the release sooner, thx.

marcosmoura commented 7 years ago

@zapping Yep!

zapping commented 7 years ago

Hi Marcos, Can you please take a look at this pen, http://codepen.io/zapping/pen/bBPyOz , and let me know what I missed? The add button on top needs to be clicked twice for the first tab to appear and also the tab needs to be clicked for the content to appear. Same is the case with the delete button too.

Is there a way to customize the tab headers so that a small delete button can be added to each tab header to close it?

When I try to change the Add button to <md-button @click="addTab()">Add the method of @click is not being called for some reason.

Thanks.

zapping commented 7 years ago

Hi Marcos, Please ignore the last one, realized that @click.native="addTab()" is the way to go.

Thanks.

zapping commented 7 years ago

Hi @marcosmoura , Can you please check the first 2 queries on the previous comment https://github.com/marcosmoura/vue-material/issues/267#issuecomment-280055906

Thanks.

igor-ribeiro commented 7 years ago

@zapping I found the problem: https://github.com/marcosmoura/vue-material/blob/master/src/components/mdTabs/mdTabs.vue#L100 Adding/removing keys to an object like that it's not guaranteed the Vue will keep track of changes (https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats). I changed to this.$set and this.$delete and it worked. @marcosmoura Where do you want me to push the fix?

For now you can hack it adding ref="tabs" to md-tabs and this.$nextTick(() => this.$refs.tabs.$forceUpdate()); at the end of addTab and removeTab.

ezgif-1-f1bb7d7475

zapping commented 7 years ago

@igor-ribeiro thank you for the work around. On the other query can the tab header be customized so that I can add a close icon to it.

Also can you let me know how to specify the font colors for the tab headers.

Thanks.

igor-ribeiro commented 7 years ago

@zapping For now, I guess neither one is possible.

zapping commented 7 years ago

@igor-ribeiro and @marcosmoura np guess will try your work arounds for now and wait for the updates.

It will be good if you can plan something for these customization because it will be helpful for dynamic tabs. Like along with the label in the header it would be nice to add some status indicators like * in case contents of a tab has been modified. If a closed/inactive record has been opened in a then an indicator/label that its read-only. Many a time having ellipises and title with the header is handy just in case the label spans out. So if its possible to give custom contents for the headers too then it will be cool.

You guys have a wonderful set of components with the materials guidelines. Thank you.

marcosmoura commented 7 years ago

@igor-ribeiro Can you create another PR for this issue?

zapping commented 7 years ago

Hi @igor-ribeiro / @marcosmoura Can you please take a look at this one http://jsfiddle.net/zapping/d2141cwq/6/ A customization has been done to the tab to include a close icon with the tab header. The issue is the tab content does not seem to get removed when the close icon is clicked on the header. Also when the last tab is closed the tab content still remains even though the header has been removed. The unregisterTab() method is being called on the close icon click.

But when you click on the Delete button on top of the page the header and contents both gets deleted. Do you have any suggestion or is there a fix for it.

Thanks.

igor-ribeiro commented 7 years ago

@zapping You are unregistering the tab internally only and not modifying the lstObj and that's why the content is still present. You can emit an event when clicking on the button passing the index/id of the tab.

<md-tabs @close="closeTab">
closeTab: function (id) {
  this.lstObj = this.lstObj.filter((tab) => tab.id !== id);
}
zapping commented 7 years ago

@igor-ribeiro Thank you the tips, it worked out!

zapping commented 7 years ago

@igor-ribeiro / @marcosmoura There is one more thing that you might want to look into or let me know if I used and messed a property. The tab has a property 'id' which says it needs to be unique for each tab. If its set like :id="item.Id" when creating tab in the template with a unique Id from the users data object then when the html is rendered the divs get the item.Id as in the image below tabcontentid

But when you delete tab(s) from the beginning or randomly from the middle the div ids of the deleted tabs seems to be getting reused or reassigned to the existing tab content div. Thereafter if the deleted objects are dynamically added back to the tab then the divs get duplicate or multiple ids causing issues. This pen https://codepen.io/zapping/pen/bBPyOz has been adjusted to delete tabs from the beginning and add new tabs to the end.

Though this does not happen if you delete tabs from the end and add new tabs to the end. Also this does not happen if the Id property is not used or not set at all when creating the tabs in the then template.

igor-ribeiro commented 7 years ago

@zapping That's because you are setting the new id based on the lstObjt.length. If you have 3 items and delete the second the new id will be 3 (length + 1), but you already have the id 3, so you need to get the last id to set the next.

var ind = (this.lstObj.length)
  ? this.lstObj[this.lstObj.length - 1].id + 1
  : 0; // if the lstObj is empty the id will be 0

https://codepen.io/igor-ribeiro/pen/WpaqBY?editors=0010

The best option is to use an unique id generator.

zapping commented 7 years ago

@igor-ribeiro Oh you are right, the code in my pen was buggy too with the id part. I guess that was not a good sample code for the issue. But the issue I mentioned still exist because in my actual application these objects come from the database and the id in the object is unique from the database. To replicate the issue maybe you could try this out on your pen https://codepen.io/igor-ribeiro/pen/WpaqBY?editors=0010.

  1. First add add 8 tabs and if you check the divs in the browser inspector they have ids from Name0 .. Name7.
  2. Now delete the first 4 tabs and the tab header will now show tabs Name4 .. Name7. But if you check the divs in the browser inspector the ids are that of old/deleted ones Name0 .. Name3 for these remaining tabs. They somehow got changed or reassigned. Am attaching a screen grab. tabcontentid1
  3. Now at this point if you try to bring back the deleted 4 objects into the tab they all show duplicate div ids.

The pen I gave before, https://codepen.io/zapping/pen/bBPyOz , has been modified with an incremental id to keep it unique. Also a new button has been added to replicate adding back deleted objects. So you can try out step 3 with this new button and check the div ids. A screen grab has been attached after adding back 2 deleted objects. tabcontentid2

In my pen if you try removing the :id="'Name'+obj.id" from the <md-tab> in the html the same script will work fine.

Sorry its become a lengthy comment and thank you for your patience.

igor-ribeiro commented 7 years ago

@zapping Adding a :key="obj.id" solved the issue. https://vuejs.org/v2/guide/list.html#key

https://codepen.io/igor-ribeiro/pen/WpaqBY?editors=1000

zapping commented 7 years ago

@igor-ribeiro That solved it. Thank you for the doc link too. It has some suggestions on using the key in terms of performance.

nishantbrevitaz commented 5 years ago

Got it!

tabs-header-scroll

@igor-ribeiro how can i achive the scroll effect in small device urgent for me ?

igor-ribeiro commented 5 years ago

@nishantbrevitaz they did a refactor on the project, I'm not sure this works anymore.

sinisarudan commented 3 years ago

Hi, is this still not solved? Namely, even after adding the prop:

, md-tabs looks like this. tabs being cut-out, squeezed and not swipeable. ![image](https://user-images.githubusercontent.com/1769627/126728902-fc0a602a-075b-48d1-881c-7129444d56ed.png)