We tried extending TabBarBase to activate tab by its' id as opposed to index. To do this one needs access to _getTabs method, but it's private and call getIndexOfTabById, which is buried in mdcFoundation.adapter_ and is not accessible either
Most of these components are hard to extend. From personal experience, I've gone through so much trouble customizing:
mwc-button
mwc-textfield
mwc-fab
mwc-drawer
mwc-radio
mwc-switch
and probably a couple more I forgot. Most of the times, I simply modify the file locally and go in with my day. When it comes to deployment, I just have to make sure to build the project on the same machine, otherwise the change won't be accounted for.
Here's an example of a simple change I made to the css file for mwc-drawer:
.mdc-drawer-app-content {
/* Default styles */
margin-left: 0;
margin-right: 0;
position: relative;
/* Added style */
width: 100%;
}
On more important client projects, I have unfortunately been forced to either accept the component for what it is, or choose an alternative.
I agree, I don't remember having issues to customize mwc elements on the fly but have been using mwc-tab-bar in few projects now and hell I always spend so much time trying to harmonize its logic with my application. Maybe providing some user-friendly accessibility functions is a good idea ?
For a specific example, it would be nice to be able to use actionItems other than mwc-icon-buttons.
We're currently exploring theming in general in #526.
Are you extending just to modify styling, or do you want to modify behavior as well?
If you just need styling changes, it seems likely we just need to set all private API to protected instead.
Yes, protected API and cleaner way to access adapter methods would be nice
Can you give more details of what you're trying to do? It will help us understand what kind of customization users need. For example, why do you need to call _getTabs?
<my-tab-bar active-tab-id="${this._tab}" @MDCTabBar:activated="${this._tabActivated}">
<mwc-tab id="tab1">Tab 1</mwc-tab>
${this._someCondition ? html`
<mwc-tab id="tab2">Tab 2</mwc-tab>
` : ''}
</my-tab-bar>
class MyTabBar extends TabBarBase {
@property({ type: String, attribute: 'active-tab-id' })
_activeTabId;
firstUpdated() {
if (this._activeTabId)
this.setActiveIndex();
}
setActiveIndex() {
//let tabIndex = this.mdcFoundation['adapter_'].getIndexOfTabById(this._tab);
let tabIndex = this.getIndexOfTabById(this._activeTabId);
if (tabIndex >= 0 && tabIndex != this.activeIndex) {
this.activeIndex = tabIndex;
if (this.mdcFoundation)
this.mdcFoundation.activateTab(this.activeIndex);
}
}
getIndexOfTabById(id: string) {
const tabElements = this['_getTabs']();
for (let i = 0; i < tabElements.length; i++) {
if (tabElements[i].id === id) {
return i;
}
}
return -1;
}
}
customElements.define('my-tab-bar', MyTabBar);
While it would be nice to change the functionality by extending the base class, I think most use cases could be covered by adding properties that customize the behavior of the component. For example, I remember paper-tabs having a property that allowed users to specify what to use as the selected property, instead of the index.
As for styling, most of my use cases have been covered by using the custom properties already available, and when they aren't enough, it has been as easy as adding the relevant custom property into the css file.
Per https://github.com/material-components/material-components-web-components/issues/903#issuecomment-640785717, we should also consider the impact of html in labels.
Most helpful comment
Most of these components are hard to extend. From personal experience, I've gone through so much trouble customizing:
mwc-button
mwc-textfield
mwc-fab
mwc-drawer
mwc-radio
mwc-switch
and probably a couple more I forgot. Most of the times, I simply modify the file locally and go in with my day. When it comes to deployment, I just have to make sure to build the project on the same machine, otherwise the change won't be accounted for.
Here's an example of a simple change I made to the css file for mwc-drawer:
On more important client projects, I have unfortunately been forced to either accept the component for what it is, or choose an alternative.