blueprintjs keep content mounted in tabs - tabs

I am not sure if this is blueprintjs specific behaviour (new to react as well), but I cannot find a way to keep content loaded in a tab once rendered. I think "keep mounted" is the react terminology.
<Tabs id="mainNavbar" selectedTabId={this.state.mainNavbarTabId} renderActiveTabPanelOnly={true}
onChange={this.handleNavbarTabChange}>
<Tab id="tabOne" title="Tab One" panel={<TabOnePanel/>}/>
<Tab id="tabTwo" title="Tab Two" panel={<TabTwoPanel/>}/>
</Tabs>
Is the technique to use a "alreadyRendered" flag in the render()? Please could you suggest a solution?

According to the doc, you should set renderActiveTabPanelOnly to false (which is the default value). That will keep it mounted. According to the doc:
"Whether inactive tab panels should be removed from the DOM and unmounted in React.
This can be a performance enhancement when rendering many complex panels,
but requires careful support for unmounting and remounting."
[ https://blueprintjs.com/docs/#core/components/tabs ]

Related

Dynamically adding/removing TabViewItem in NativeScript tabs project

I have a NativeScript 8.1 JavaScript project that uses the tabs template, so that the app-root.xml file looks like this:
<TabView tabTextFontSize="16" androidOffscreenTabLimit="0" androidTabsPosition="bottom"
id="tabview" class="ns-light" loaded="onLoaded" >
<TabViewItem title="Riders" iconSource="res://biking_solid" >
<Frame id="main" defaultPage="views/main-page" />
</TabViewItem>
<TabViewItem title="Volunteers" iconSource="res://hands_helping_solid" >
<Frame id="vol" defaultPage="views/volunteers-page" />
</TabViewItem>
<TabViewItem title="Director" iconSource="res://user_ninja_solid" >
<Frame id="director" defaultPage="views/director-page" />
</TabViewItem>
</TabView>
The catch here is that the third tab needs to be conditional and only visible if the user is authorized. I've tried pop'ing the TabView's item's array. I've tried creating a new TabViewItem and pushing it onto the items array. I've tried using the visibility property, and none of these work.
I'll know at startup time whether the third tab should be displayed, so handling this in app-root.js is fine. I'm OK with creating all of the tabs dynamically but I can't get that to work either. I could live with disabling the third tab but the enabled property on TabViewItem is ignored.
In short, I've tried everything I can think of and I'm unable to change the TabViewItem's in any way. I realize the underlying implementations are likely imposing some restrictions, but still, is there any way I can control whether the third tab is visible?
This doesn't really answer the question, but it does solve my problem. I can have two separate app-root files, say app-root2 and app-root3, then in app.js I can apply logic and start the appropriate one:
if (<condition>)
application.run({ moduleName: "app-root2" });
else
application.run({ moduleName: "app-root3" });
Edit 4/10/2022: I ended up switching to the BottomNavigation component and dealt with the same issue. That, and the accompanying solution, is described in this post.

Is This Error Reported by Siteimprove on WAI-ARIA Criterion 1.3.1 A False Positive?

Using the Siteimprove extension v. 126 for Chrome the following HTML snippets are all reporting an issue "Input field has no description 1.3.1"
It seems like no description should be needed as the aria-hidden attribute should completely remove the element as far as the accessibility API is concerned. Likewise the tabindex=-1 attribute value indicates this element is not intended for interaction nor presentation.
Moreover, the extension reports this as an issue even after adding role="none" per the following doc, which is the first cross-referenced solution in the tool:
ARIA4: Using a WAI-ARIA role to expose the role of a user interface component
<input aria-hidden="true" tabindex="-1"
class="MuiSelect-nativeInput"
value="SORTING_OPTIONS_ENDDATE"
style="">
<input aria-hidden="true" tabindex="-1"
class="MuiSelect-nativeInput" role="none"
value="SORTING_OPTIONS_ENDDATE"
style="">
Note: this hidden input element is generated as part of a <Select /> component via Material UI. It's used to hold the selected value
Yes, this is a false positive.
It likely flags this as an issue as it cannot know whether you intend to "unhide" the <select> in the future, at which point it would be inaccessible due to the lack of label.
You can safely ignore this error as the input is never designed to be accessed so the tabindex and aria-hidden states will never change.
One thing I did notice though is they set the opacity to 0 instead of hiding the input, not entirely sure why that is but it may be the other reason it complains as technically anything with 0 opacity could still be accessed by some older screen readers that do not honour aria-hidden. If you could change that to display: none it would be more robust (this needs to be added by JS as otherwise if you set this in the CSS and the JS fails the whole input would be hidden).

How do I hide all v-text-fields in Vuetify?

I am trying to hide the text fields in my dialog box pop up to re utilize the same component for Edit & Delete Feature. Basically I am manipulating the header of dialog but for delete feature I want user to only see heading. But I can't find any option to hide all text fields on Vuetify.
HTML
<v-text-field
v-model="entryData[item]"
:label="getLabel(item)"
:disabled="setDisable(item)">
</v-text-field>
Set Disable function
setDisable (colName) {
return this.entryState === 'read' || colName.toLowerCase().indexOf('id') !== -1;
},
Like disable is there any option for visibility?
you can use v-if
<v-text-field
v-model="entryData[item]"
:label="getLabel(item)"
v-if="setDisable(item)">
</v-text-field>
or v-show
<v-text-field
v-model="entryData[item]"
:label="getLabel(item)"
v-show="setDisable(item)">
</v-text-field>
the difference between the two is that v-if hidden component doesn't get added to your DOM, and the v-show component is added, but set to hidden using styles.
On a side note, as mentioned in an earlier question, try to avoid calling functions in the template. this will trigger a re-render on full tree every time, because function responses are not cached. storing these values in a computed is usually the way to go. You can store multiple attributes in the object, and you already have entryData, so you can adjust is to include other parameters.

Vuetify v-tabs-slider with v-if not working?

I'm using Vuetify 0.16 with VueRouter and Vuex and noticing an issue using v-tabs with the v-tabs-slider with v-if vs v-show.
<v-tabs icons grow light centered v-model="activeTab">
<v-toolbar>
...
<v-tabs-bar v-show="showTabs" class="grey lighten-4" slot="extension">
<v-tabs-slider color="primary"></v-tabs-slider>
<v-tabs-item v-for="tab in tabs" :key="tab.name" :id="tab.name" :to="tab.to" class="primary--text" router>
<v-icon>{{tab.icon}}</v-icon>
{{tab.name}}
</v-tabs-item>
</v-tabs-bar>
</v-toolbar>
</v-tabs>
activeTab, showTabs, and tabs are computed variables that reference getters in my vuex store.
With the code above using v-show, everything works well, including the v-tabs-slider; however, when showTabs is false, the space for the tabs (heigh-wise) is still present. I want the toolbar to show no matter what, but I want to control the display of tabs depending on the route and taking up that space is not desirable (especially for mobile).
If I change it to use v-if, the height issue is resolved and everything works except that the v-tabs-slider only works when the v-tabs-bar is initially loaded (when showTabs becomes true). When showTabs becomes false and then becomes true again, the v-tabs-slider no longer displays. The active tab's icon and text highlight correctly, but the v-tabs-slider does not highlight after it is unloaded and reloaded.
<v-tabs icons grow light centered v-model="activeTab">
<v-toolbar>
...
<v-tabs-bar v-if="showTabs" class="grey lighten-4" slot="extension">
<v-tabs-slider color="primary"></v-tabs-slider>
<v-tabs-item v-for="tab in tabs" :key="tab.name" :id="tab.name" :to="tab.to" class="primary--text" router>
<v-icon>{{tab.icon}}</v-icon>
{{tab.name}}
</v-tabs-item>
</v-tabs-bar>
</v-toolbar>
</v-tabs>
I'm not sure if this is a bug or if I'm just not using this correctly...
Does anyone know?

MVC Sitemap renders empty when the current action is not in the Mvc.sitemap file

Is it possible to force the sitemap control to render the menu when the current action is not listed in the MVC.sitemap file?
I have a simple top nav. When the current action is in the sitemap, the call to .Menu() will render the correct <ul><li>.. data. However, if I got to a page that is not in the sitemap such as /Home/Login, then it will not render any html at all (not even a comment, just empty space). This isn't an [authorize] issue; the menu is fine when i'm in '/Home/Index'.
It seems like it should render what was requested, but just not set the IsCurrentNode and IsNodeInPath properties. Here is the call I am making
<div id="main-nav">
#Html.MvcSiteMap().Menu(0, true, true, 1)
</div>
The Mvc.sitemap file:
<mvcSiteMapNode title="Home" controller="Home" action="Index">
<mvcSiteMapNode title="Form New Human" controller="Person" action="Create"/>
<!-- there is no mvcSiteMapNode for "Home" "Login" -->
</mvcSiteMapNode>
Found the way around it. It apparently isn't a built in extension method, or at least I couldn't find one. You could call Html.MvcSitemap().Menu(Html.MvcSiteMap.Provider.RootNode,...) but I didn't want to instantiate the helper twice.
<div id="main-nav">
#{
var sm = Html.MvcSiteMap();
#sm.Menu(sm.Provider.RootNode, true, true, 2); // 2 levels (home, plus main nav)
}
</div>
Looking around in the disassembly seems to show that it works a little like this:
You really need a starting node
If you don't give it one, it tries to find one based on the current node
plus restrictions (forward searching, depth restrictions, etc)
if you want nodes from level 1, you have to know what level you are on
Since that returns null, starting node is null, which means the helper writes an empty string
There may be a combination of tricks, or an overload or two, which can be finagled into doing this, but I can't find it right now. This works for my needs (simple top menu). There has to be a simpler way to do this, something with wild cards, or route based, with a closest match thing going on. I figured menus were a fairly standard part of a web app, and this would be covered :)