Angular Material mdTabs : is it possible to have vertical tabs? - angularjs

I am looking for Tabs displayed top to bottom with tab navigation on the left. Is there anyway this can be achieved in Angular Material library?

This codepen by Rahul Sagore uses vanilla Material, not specifically for Angular, but it's exactly what you want. I was looking for the same thing as you; it's a shame Material doesn't offer this, but I can see how it would go against their principles and make Material too extensive.
It comprises of custom css (perhaps overriding, I'm not sure) and use of particular Material classnames. Below I've pasted the contents into a snippet.
I had an issue with the mdl-cell--n-col classes so I changed the content one from 10-col to 6-col so it wouldn't wrap the content beneath the tabs in the restrictive space of this post. You'll probably have to tinker with that yourself, or scrap that and use Material styles the way you know how. Similarly, I cannot see what the .hollow-circle spans are doing, so perhaps they aren't needed.
/*Vertical Tabs*/
.vertical-mdl-tabs {
margin-top: 30px;
}
.vertical-mdl-tabs .mdl-tabs__tab-bar {
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
padding-bottom: 35px;
height: inherit;
border-bottom: none;
border-right: 1px solid rgba(10, 11, 49, 0.20);
}
.vertical-mdl-tabs .mdl-tabs__tab {
width: 100%;
height: 35px;
line-height: 35px;
box-sizing: border-box;
letter-spacing: 2px;
}
.vertical-mdl-tabs.mdl-tabs.is-upgraded a.mdl-tabs__tab.is-active {
border-right: 2px solid #ED462F;
}
.vertical-mdl-tabs.mdl-tabs.is-upgraded .mdl-tabs__tab.is-active:after {
content: inherit;
height: 0;
}
.vertical-mdl-tabs.mdl-tabs.is-upgraded .mdl-tabs__panel.is-active, .mdl-tabs__panel {
padding: 0 30px;
}
.vertical-mdl-tabs.mdl-tabs .mdl-tabs__tab {
text-align: left;
}
<script src="https://storage.googleapis.com/code.getmdl.io/1.1.0/material.min.js"></script>
<link href="https://storage.googleapis.com/code.getmdl.io/1.1.0/material.indigo-pink.min.css" rel="stylesheet"/>
<div class="mdl-tabs vertical-mdl-tabs mdl-js-tabs mdl-js-ripple-effect">
<div class="mdl-grid mdl-grid--no-spacing">
<div class="mdl-cell mdl-cell--2-col">
<div class="mdl-tabs__tab-bar">
<a href="#tab1-panel" class="mdl-tabs__tab is-active">
<span class="hollow-circle"></span>
Tab 1
</a>
<a href="#tab2-panel" class="mdl-tabs__tab">
<span class="hollow-circle"></span>
Tab 2
</a>
<a href="#tab3-panel" class="mdl-tabs__tab">
<span class="hollow-circle"></span>
Tab 3
</a>
</div>
</div>
<div class="mdl-cell mdl-cell--6-col">
<div class="mdl-tabs__panel is-active" id="tab1-panel">
Content 1
</div>
<div class="mdl-tabs__panel" id="tab2-panel">
Content 2
</div>
<div class="mdl-tabs__panel" id="tab3-panel">
Content 3
</div>
</div>
</div>
</div>

you can have verticval tabs by adding vertical attribute to the mat-tab-group and adding following css to your page.
mat-tab-group[vertical] .mat-tab-labels {
display: flex;
flex-direction: column!important;
}
mat-tab-group[vertical] {
display: flex;
flex-direction: row!important;
}
here's the mat-tab-group element with vertical attribute
<mat-tab-group flex="1" vertical>
<mat-tab label="Tab 1"> Loading ... </mat-tab>
<mat-tab label="Tab 2" > Loading ... </mat-tab>
</mat-tab-group>

Related

How to adjust the overlay card same size and position as its bottom card in React?

I want to make a hover animation effect in scss. The idea is when cursor hover on the card, another hidden card appear on top of the hovered card.
But now I got stuck on making the hidden card scss: I am not sure how to make the card the same size and the same position as the bottom card(dark blue card). It is for the className "card-hover"
Below is the code for js:
<div className="gallery">
{data.map((item)=>
<div className="card-holder" key={item.id}>
<div className="card-head">
<img className="card-img" src={item.image} alt="project item" />
</div>
<div className="card-body">
<h2 className="item-name">{item.title}</h2>
<div className="item-date">{item.year}</div>
</div>
<div className="card-hover">
<div className="item-role">{item.role}</div>
<div className="item-type">{item.type}</div>
<div className="item-decs">{item.desc}</div>
</div>
</div>
)}
</div>
Code for scss:
.gallery{
margin-left: 10rem;
margin-right: 10rem;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 8px;
justify-content: center;
}
.card-holder{
border-radius: 4px;
margin-top: 1rem;
background-color: $darkBlue;
box-shadow: 0px 8px 56px rgb(15 80 100 / 16%);
}
.card-hover {
position: absolute;
background-color: #D62839;
display: inline;
width: 100%;
height: 100%;
}
The current result:
enter image description here
I have looked through tutorial videos of how to make this kind of hover effect, but all solutions so far were to set
width:100%;
height:100%
or
top:0;
bottom:0;
left:0;
right:0;
However, when I tried them the result is like the screenshot above. Can someone help me with this? Thank you

React-Icons: Icon not aligning with Text

I am using react-icons in one of my projects and I am not able to align the icons (vertically) with the text. Following is what I am getting currently.
As you can see -- The icons are a little higher than the text.
Following is my HTML code:
<div className="route-info-container">
<div>
<p>Difficulty (1-10)</p>
<h2><AiFillFire />{route.difficulty}</h2>
</div>
<div>
<p>Length</p>
<h2><GiTrail />{route.length}</h2>
</div>
<div>
<p>Est Driving Time</p>
<h2><RiTimerFlashFill />{route.estimatedDrivingTime}</h2>
</div>
<div>
<p>Permits</p>
<h2><IoNewspaperSharp />{route.permits? 'Required': 'Not Required'}</h2>
</div>
</div>
Following is my css:
.route-info-container {
display: grid;
grid-template-columns: auto auto;
}
.route-info-container h2 {
font-size: 25px;
margin-top: 10px;
}
It' s because the svg' s alignment. You can't do too much things to svg but try to do this to h2:
h2 {
display: flex;
align-items: center;
}

ons-back-button goes back to home instead of previous page in stack

I recently updated a Cordova mobile app to use OnsenUI v1.3.8 (in order to fix a problem with broken back buttons when viewing the app on iOS 8.4). The problem I'm now seeing is that the back buttons throughout the app, send you all the way back home. Even levels down in the app, pressing the back button takes you to the previous page, then seems to fire another event to go back again.
I have the following syntax in my index.html (home) page:
<body onload="onLoad()">
<ons-navigator title="Navigator" var="myNavigator" page="main.html">
</ons-navigator>
</body>
In the rest of my app, I'm using the following syntax:
<ons-toolbar>
<div class="left animated fadeIn">
<ons-back-button><div class="animated fadeIn">Back</div></ons-back-button>
</div>
<div class="center animated fadeIn">{{ title }}</div>
</ons-toolbar>
Main.html is simply...
<div ui-view></div>
Any idea on how to resolve this?
[EDIT]
Below is the HTML behind the button/s:
<ons-back-button class="ng-scope">
<span class="toolbar-button--quiet " ng-click="" style="height: 44px; line-height: 0; padding: 0; position: relative;">
<i class="ion-ios-arrow-back ons-back-button__icon" style="vertical-align: top; background-color: transparent; height: 44px; line-height: 44px; font-size: 36px; margin-left: 8px; margin-right: 2px; width: 16px; display: inline-block; padding-top: 1px;"></i><span style="vertical-align: top; display: inline-block; line-height: 44px; height: 44px;" class="back-button__label"><div class="animated fadeIn ng-scope">Back</div></span>
</span>
</ons-back-button>

AngularJS an Bootstrap tooltip with span

I have an Angular1.0.7 web application. I´m adding a Twitter Bootstrap 2 tooltip to an span tag, but the tooltip is displayed very narrow. This is not happening with many other tooltips I have in the application.
<span style="line-height: 45px" ng-show="controlSkipperType || createBoatPoliciesForm.skipperType.$error.validateSkipperType" class="text-error" ng-switch="skipperTypeError">
<span ng-switch-when="OPTIONAL_ERROR" style="position: relative; top: -15px; margin-left: 10px" class="pull-left">{{'SKIPPER_TYPE_OPTIONAL_ERROR' | translate}}.</span>
<span ng-switch="skipperTypeError" style="position: relative; top: -15px; margin-left: 10px">
<i ng-switch-when="OPTIONAL_ERROR" class="fa-icon-question-sign" tooltip="Text to show in the tooltip"></i>
See the picture:
Something like this:
div > div .popover-content {
min-width: 620px !important;
}

Display several sequences of events with possible line break in middle [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am a HTML / CSS newbie.
I need to do something like this:
My web page is receiving sequences of events dynamically and I would like to visualize them on in the page.
I would like one sequence of events to be in a box, with lots of slots, and each slot has the event id.
So if I have several sequences, then I will have several such boxes.
However, the length of a sequence is dynamic. And the web page's window might be adjusted by the users, so even for a sequence, if it is too long or the window is too narrow, I have to break the box into several lines.
the above is my drawing of the design.
The A, B, etc, are the sequence title, then the numbers are the ids.
ideally, the space of all events / sequences should be as compact as possible.
And if a box has to change line, then it should be half-borded to indicate the continuous.
How can I do that? using CSS 3?
And also the framework I am using is AngularJS to control the data / UI binding, even if I manage to handle this case, how to dynamically bind the data to adjust this requirement?
Thanks
Doing this in CSS is tricky, because you want a border between elements only if those elements are on the same line. CSS doesn't know anything about wrapping.
I've solved the problem by:
Adding a left border on all boxes
Adding a right border on the last box only.
Adding a -1px left margin on all boxes except the first.
Placing the boxes in a container with overflow: hidden.
Having the right border on the last box only solves the right-hand issue.
The -1px left margin solves the left-hand issue.
Snippet:
.sequences {
overflow: hidden;
}
.sequence > div {
border: 1px solid black;
border-right: none;
height: 50px;
float: left;
margin-bottom: 10px;
}
.sequence > div:last-of-type {
border-right: 1px solid black;
margin-right: 20px;
}
.sequence > div:not(:first-of-type) {
margin-left: -1px;
}
.yellow div {background: yellow; width: 100px;}
.green div {background: lightgreen; width: 80px;}
.blue div {background: lightblue; width: 120px;}
<div class="sequences">
<div class="sequence yellow">
<div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div>
</div>
<div class="sequence green">
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
<div class="sequence blue">
<div></div><div></div><div></div>
<div></div><div></div><div></div>
</div>
</div>
You can solve this using CSS by doing something like this.
I've given each sequence element a top, left and bottom border. T
This will give the illusion of a right border when the elements are floated next to eachother but when they're the last on that line it will brake of as per your request.
I also added a right border to the last div element and the last div in each section.
Fiddle
div{
width: 100px;
height: 50px;
line-height: 50px;
text-align: center;
float:left;
background: #eee;
border: 1px solid #000;
border-width: 1px 0 1px 1px;
margin-bottom: 10px;
}
div.last{margin-right: 5px;}
div.last,
div:last-child{border-right-width: 1px;}
<div class="seq-1">1</div>
<div class="seq-1">2</div>
<div class="seq-1">3</div>
<div class="seq-1">4</div>
<div class="seq-1 last">5</div>
<div class="seq-2">1</div>
<div class="seq-2">2</div>
<div class="seq-2 last">3</div>
Edit:
I just noticed you wan't the border to be 0px/blank on the last element and the first element each row. Now that is a bit trickier.
I'm not positive there's a good solution to solving that using css since your sequences seem to be dynamic.
Please correct me if I'm wrong, but I think you need to use javascript to manage this.
Edit 2: CSS and JQuery solution
I made a quick jquery solution that utilies my previously provided CSS code.
The jQuery script removes the left border if the elements left offset(within it's parent) is 0 and if the element is not the first element in each sequenc(first class added).
Fiddle
var containerOffset = $('.container').offset().left;
setBorderWidth();
$(window).resize(function(){
setBorderWidth();
});
function setBorderWidth(){
$('.block').each(function() {
var childOffset = $(this).offset().left;
if(childOffset - containerOffset == 0 && !$(this).hasClass('first'))
$(this).css("border-left-width", "0px");
else
$(this).css("border-left-width", "1px");
});
}
.container{width: 100%;}
.block{
width: 100px;
height: 50px;
line-height: 50px;
text-align: center;
float:left;
background: #eee;
border: 1px solid #000;
border-width: 1px 0 1px 1px;
margin-bottom: 10px;
}
.block.last{margin-right: 5px;}
.block.last,
.block:last-child{border-right-width: 1px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div class="container">
<div class="seq-1 block first">1</div>
<div class="seq-1 block">2</div>
<div class="seq-1 block">3</div>
<div class="seq-1 block">4</div>
<div class="seq-1 block last">5</div>
<div class="seq-2 block first">1</div>
<div class="seq-2 block">2</div>
<div class="seq-2 block last">3</div>
</div>
What I would recommend is to have 3 CSS classes
1) beginning of sequence
2) middle of sequence
3) end of sequence
then display different borders using:
.beginning-of-seq {
border-top-style: solid;
border-right-style: none;
border-bottom-style: solid;
border-left-style: solid;
}
for instance.
about the angular part just use ng-repeat="seq in sequences" for instance and then render the sequence with the classes you created so it will look good (of course you need the scope to have the sequences)
<span ng-repeat="seq in sequences">
<span class="beginning-of-seq"> {{seq.title}} </span>
<span class="middle-of-seq ng-repeat="elem in seq.otherElements">{{elem}}</span>
<span class="end-of-seq"> {{seq.lastElem}} </span>
</span>
</span>
this is a bit crude and i don't know how you implemented it but it should give you an idea where to start
This HTML/CSS should do the trick. As you mentioned about the user having different resolutions, I've used percentages for the widths (depending on your scenario, media queries may be needed).
.container {
width: 30%; /*Change this to fit your design*/
}
.seq {
display: inline;
border: 0.1em solid #000;
margin-right: 1em;
}
.seq .item {
display: inline-block;
width: 5%; /*Change this to fit your design*/
margin-bottom: 1em;
}
.seq .item:not(:last-child) {
border-right: 0.1em solid #000;
}
<div class="container">
<div class="seq">
<div class="item item-title">A</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div class="seq">
<div class="item item-title">B</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
<div class="seq">
<div class="item item-title">C</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
<div class="seq">
<div class="item item-title">D</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
</div>
About the AngularJS binding:
In your controller define your array of sequences and some functions to manipulate the sequences:
$scope.sequences = [];
$scope.addSequence = function(sequenceName){
var newSequence = { name : sequenceName, events: [] };
$scope.sequences.push(newSequence);
};
$scope.addEventToSequence = function(sequenceName, event){
var sequence = getSequence(sequenceName); // write this function to get the right sequence from the array
sequence.events.push(event);
}
Now in your html loop over the sequences and events using ng-repeat
<ul>
<li ng-repeat="sequence in sequences">
<ul>
<li>{{sequence.name}}</li>
<li ng-repeat="event in sequence.event">{{event.name}}</li>
</ul>
</li>
</ul>

Resources