@c8y/style
Version:
Styles for Cumulocity IoT applications
332 lines (298 loc) • 7.45 kB
text/less
@import "../mixins/_c8y-scrollbar.less";
/**
* Page Tabs - Horizontal and vertical tab navigation
*
* Note: Uses design tokens for spacing (@size-*), colors, and layout vars.
*
* Intentionally hardcoded values:
* - -6px top: Negative offset for mobile positioning
* - 12px: Off-grid legacy value in calc expression
* - 30px, 31px: Specific dimensions for tab slider controls
* - 3px padding: Fine-tuning for icon alignment
* - Transition durations (0.35s, 0.25s): Animation timing
* - Z-index values: Stacking order
* - 1px borders: Standard border widths
* - 2px box-shadow: Focus indicator width
* - 10000px, 2000px: Large clip values for overflow management
* - Percentages and em units: Relative sizing
*/
.page-tabs {
position: fixed;
right: 0;
left: 0;
z-index: @zindex-navbar-fixed;
margin: 0;
padding: 0;
&:has(.component-tabs) {
position: static;
}
@media (max-width: @screen-xs-max) {
top: -6px;
transition: top 0.35s ease;
.head-open & {
top: calc(@size-base * 10 + calc(@size-base * 1.5));
}
}
}
.page-tabs-horizontal {
// hide when there are no tabs available
&:not(.page-tabs) {
display: none;
}
@media (min-width: @screen-sm-min) {
top: @headerHeight;
right: 0;
left: 0;
z-index: @zindex-navbar-fixed;
clip: rect(0, 10000px, 2000px, 0);
min-height: calc(@size-base * 6);
box-shadow: inset 0 -1px 0 0 @component-border-color, @header-shadow;
&:has(.component-tabs) {
box-shadow: inset 0 -1px 0 0 @component-border-color;
.component-tabs {
min-width: unset ;
padding: 0;
&.nav-tabs > div, &.nav-tabs li {
flex: 0 0 auto;
align-self: stretch;
> a {
height: 100%;
}
}
}
}
&,
&:after {
transition: left @open-menu-time-type;
}
}
@media (min-width: @grid-float-breakpoint) {
&.navigator-open {
left: @navigatorWidth;
}
}
.tabContainer {
overflow-x: auto;
// box-shadow: inset 0 calc(@nav-tabs-border-width-active * -1) 0 0 @nav-tabs-border-color-default;
scroll-behavior: smooth;
overflow: -moz-scrollbars-none; // Firefox
-ms-overflow-style: none; // IE 10+
&::-webkit-scrollbar {
display: none; // Safari and Chrome
}
.nav-tabs {
padding-right: 30px;
padding-left: 30px;
min-width: max-content;
}
@media (min-width: @grid-float-breakpoint) {
.nav-tabs {
min-width: max-content;
}
}
&:has(.tabs-slider) {
.component-tabs {
min-width: max-content;
}
}
}
}
.component-tabs {
position: relative;
background: inherit;
}
c8y-widget-config-section .component-tabs {
min-width: unset
}
c8y-widget-config-section .component-tabs>div,c8y-widget-config-section .component-tabs>li {
flex-shrink: 1
}
c8y-widget-config-section .component-tabs>div .tab-description,c8y-widget-config-section .component-tabs>li .tab-description {
display: none
}
.tabs-slider {
position: absolute;
top: 0;
bottom: 0;
z-index: 1;
padding: 3px 0 0;
width: 31px;
border: 0;
border-radius: 0;
background: none;
background-color: @navbar-background-default;
color: @link-color;
box-shadow: inset 0 -1px 0 0 @nav-tabs-border-color-default;
[class^='dlt-c8y-icon-'],
[class*=' dlt-c8y-icon-'] {
position: relative;
z-index: 3;
font-size: @size-20;
}
&:hover,
&:active,
&:focus {
&:not([disabled]) {
outline: none;
box-shadow: inset 0 0 0 2px @component-color-focus;
color: @link-color-hover;
text-decoration: none;
}
}
&:focus {
border-radius: @component-border-radius-focus;
}
&[disabled] {
cursor: not-allowed;
text-decoration: none;
[class^='dlt-c8y-icon-'],
[class*=' dlt-c8y-icon-'] {
opacity: 0.65;
color: @text-muted;
}
}
}
.tabs-slider-left {
left: 0;
border-right: 1px solid @component-border-color;
}
.tabs-slider-right {
right: 0;
border-left: 1px solid @component-border-color;
}
.page-tabs-vertical {
// hide when there are no tabs available
&:not(.page-tabs) {
display: none;
}
.tabs-slider {
display: none;
}
.nav-tabs {
// Styles from .nav-tabs-vertical class (LESS uses mixin)
display: block;
&:not(.component-tabs) {
padding-top: @size-48;
}
width: @nav-tabs-vertical-width;
border: 0;
box-shadow: none;
&.nav-tabs-vertical--wide {
width: unset;
}
> div,
> li {
position: relative;
> a, > button {
display: flex;
align-items: center;
flex-direction: row;
margin: 0;
padding: @nav-tabs-vertical-padding;
height: auto;
border: 0;
box-shadow: inset 0 -1px 0 @nav-tabs-border-color-default;
text-transform: none;
font-size: inherit;
transition: all 0.25s ease;
[class^='dlt-c8y-icon-'],
[class*=' dlt-c8y-icon-'],
.c8y-icon {
margin: 0 @size-8 0 0;
width: 1.25em;
~ span {
display: inline-block;
overflow: hidden;
max-width: 100%;
vertical-align: middle;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
&.active {
> a, > button {
&, &:hover {
border-left: @size-4 solid @nav-tabs-color-active;
background-color: @nav-tabs-background-active;
box-shadow: inset 0 -1px 0 @nav-tabs-border-color-default ;
border-radius: 0 ;
pointer-events: none;
&::before {
width: 100%;
}
&::after {
left: 100%;
height: 100%;
border-width: calc(@size-16 + @size-4) 0 calc(@size-16 + @size-4) @size-base;
}
}
}
}
a {
> [class^='dlt-c8y-icon-'],
> [class*=' dlt-c8y-icon-'],
> .c8y-icon {
display: inline-block;
}
}
}
}
@media (min-width: @screen-sm-min) {
top: @headerHeight;
right: auto;
bottom: 0;
left: 0;
z-index: 101;
overflow: visible;
padding-right: calc(@grid-gutter-width / 2);
transition: left @open-menu-time-type;
&:before {
position: absolute;
top: 0;
min-height: 100%;
width: @nav-tabs-vertical-width;
box-shadow: 1px 0 0 @nav-tabs-border-color-default;
content: '';
background-color: @component-background-default;
}
.tabContainer {
overflow-y: auto;
.c8y-scrollbar();
max-height: 100%;
}
}
@media (min-width: @grid-float-breakpoint) {
&.navigator-open {
left: @navigatorWidth;
}
}
}
body:not(:has(.app-main-header)) {
@media (min-width: @screen-sm-min) {
.page-tabs-horizontal, .page-tabs-vertical {
top: 0;
.nav-tabs {
padding-top: 0;
}
}
}
&:has(.has-action-bar) {
.page-tabs-vertical {
top: @size-48;
}
}
&:not(:has(.has-action-bar)) {
.page-tabs-vertical {
top: 0;
}
}
}
body:not(:has(.has-action-bar)) {
.page-tabs-vertical {
.nav-tabs {
padding-top: 0;
border-top: 1px solid @component-border-color;
}
}
}