@eclipse-scout/core
Version:
Eclipse Scout runtime
649 lines (541 loc) • 17.5 kB
text/less
/*
* Copyright (c) 2010, 2024 BSI Business Systems Integration AG
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
#scout {
.vendor(@property, @value) {
-webkit-@{property}: @value;
-moz-@{property}: @value;
-ms-@{property}: @value;
-o-@{property}: @value;
@{property}: @value;
}
.glow(@color, @radius: 5px) {
box-shadow: 0 0 @radius @color;
}
.inner-glow(@color, @radius: 4px) {
box-shadow: inset 0 0 @radius @color;
}
.drop-shadow(@x: 0px, @y: @drop-shadow-y, @blur: @drop-shadow-blur, @spread: 0px, @alpha: @drop-shadow-alpha) {
box-shadow: @x @y @blur @spread rgba(0, 0, 0, @alpha);
}
.double-drop-shadow(@x1: 0, @y1: 0, @blur1: 0, @spread1: 0, @color1: @palette-black, @x2: 0px, @y2: 6px, @blur2: 13px, @spread2: 0px, @alpha2: @drop-shadow-alpha) {
--box-shadow-1-x: @x1;
--box-shadow-1-y: @y1;
--box-shadow-1-blur: @blur1;
--box-shadow-1-spread: @spread1;
--box-shadow-1-color: @color1;
--box-shadow-2-x: @x2;
--box-shadow-2-y: @y2;
--box-shadow-2-blur: @blur2;
--box-shadow-2-spread: @spread2;
--box-shadow-2-alpha: @alpha2;
box-shadow: var(--box-shadow-1-x) var(--box-shadow-1-y) var(--box-shadow-1-blur) var(--box-shadow-1-spread) var(--box-shadow-1-color), var(--box-shadow-2-x) var(--box-shadow-2-y) var(--box-shadow-2-blur) var(--box-shadow-2-spread) rgba(0, 0, 0, var(--box-shadow-2-alpha));
}
.drop-shadow-large(@x: 0px, @y: @drop-shadow-large-y, @blur: @drop-shadow-large-blur, @spread: 0px, @alpha: @drop-shadow-large-alpha) {
#scout.drop-shadow(@x, @y, @blur, @spread, @alpha);
}
.focus-border(@box-shadow-size: @focus-box-shadow-size, @box-shadow-color: @focus-box-shadow-color, @border-color: @focus-box-shadow-border-color) {
#scout.focus-box-shadow(@box-shadow-size, @box-shadow-color);
border-color: @border-color;
}
.no-focus-border() {
outline: none;
border: 0;
box-shadow: 0 0 0 0;
}
.focus-box-shadow(@box-shadow-size: @focus-box-shadow-size, @box-shadow-color: @focus-box-shadow-color) {
outline: none;
box-shadow: 0 0 0 @box-shadow-size @box-shadow-color;
}
.focus-inset-box-shadow() {
outline: none;
box-shadow: inset 0 0 0 @focus-box-shadow-size @focus-box-shadow-color;
}
.focus-box-shadow-transition() {
transition: box-shadow 0.3s ease;
}
.alternative-focus-border() {
border-bottom-color: @focus-border-color;
border-bottom-width: 2px;
box-shadow: none;
padding-bottom: 0;
}
.inverted-bottom-round-edge(@border-radius: 12px, @color: #ffffff) {
@border-width: 5px;
--color: @color; // Allows to change color only
position: absolute;
pointer-events: none;
background-color: transparent;
bottom: -@border-width;
height: @border-radius;
width: @border-radius;
box-sizing: content-box;
border: @border-width solid var(--color);
border-top: none;
&.left {
left: -@border-radius;
border-bottom-right-radius: @border-radius+@border-width;
border-left: none;
}
&.right {
right: -@border-radius;
border-bottom-left-radius: @border-radius+@border-width;
border-right: none;
}
}
// noinspection CssUnknownProperty
.transform(@args) {
-webkit-transform: @args;
-ms-transform: @args;
transform: @args;
}
// noinspection CssUnknownProperty
.transform-origin(@args) {
-webkit-transform-origin: @args;
-moz-transform-origin: @args;
-ms-transform-origin: @args;
transform-origin: @args;
}
.text-selection() {
background: @text-selection-background-color;
color: @text-selection-color;
}
.text-selection-disabled() {
background: @text-selection-disabled-background-color;
color: @text-selection-disabled-color;
}
.placeholder() {
color: @text-field-placeholder-color;
opacity: 1; /* necessary for firefox */
}
.placeholder-disabled() {
/* Fade a little to make it distinguishable from real text. Don't use opacity here because it affects background as well (IE). */
color: fade(@disabled-color, 50%);
}
.fake-placeholder() {
/* placeholder only works for input elements -> this fake placeholder is intended for a before element*/
#scout.placeholder();
content: attr(placeholder);
}
.overlay(@left: 0, @top: 0, @diffW: 0, @diffH: 0) {
position: absolute;
content: '';
left: @left;
top: @top;
width: calc(~'100% + ' @diffW);
height: calc(~'100% + ' @diffH);
}
/* Use dashed line instead of solid to avoid visual conflict with editable fields */
.read-only() {
background-color: transparent;
border-color: transparent;
border-bottom: dashed 1px @border-color;
color: @read-only-color;
}
.value-field-with-icon(@className: ~'.icon') {
&.focused > @{className}::before,
&.focused > .field > @{className}::before {
color: @text-field-icon-focus-color;
}
&.has-error > @{className}::before,
&.has-error > .field > @{className}::before,
&.has-error > .field > @{className}::before {
color: @text-field-icon-error-color;
}
&.disabled > @{className},
&.disabled > .field > @{className},
&.compact > @{className},
&.compact > .field > @{className} {
display: none;
}
&.alternative.has-error:focus > .field > @{className}::before,
&.alternative.has-error.focused > .field > @{className}::before {
color: @text-field-icon-error-color;
}
}
.status {
display: flex;
align-items: center;
&::before {
#scout.font-icon();
font-size: @status-font-icon-size;
border-radius: @control-border-radius;
width: @field-status-size;
height: @field-status-size;
display: flex;
align-items: center;
justify-content: center;
}
}
.menu-status {
visibility: visible;
cursor: pointer;
&::before {
content: @icon-ellipsis-v;
color: @status-menu-color;
font-size: @status-font-icon-size;
}
&:hover::before {
background-color: @hover-background-color;
color: @status-menu-hover-color;
}
&:active::before,
&.selected::before {
background-color: @active-background-color;
color: @status-menu-hover-color;
}
}
.tooltip-status {
visibility: visible;
cursor: pointer;
&::before {
content: @icon-info;
color: @status-info-color;
font-size: @status-font-icon-size;
}
&:hover::before {
background-color: @hover-background-color;
color: @status-info-hover-color;
}
&:active::before,
&.selected::before {
background-color: @active-background-color;
color: @status-info-hover-color;
}
}
.info-status {
#scout.tooltip-status();
}
.ok-status {
visibility: visible;
cursor: pointer;
&::before {
content: @icon-info;
color: @status-ok-color;
font-size: @status-font-icon-size;
}
&:hover::before {
background-color: @hover-background-color;
color: @status-ok-hover-color;
}
&:active::before,
&.selected::before {
background-color: @active-background-color;
color: @status-ok-hover-color;
}
}
.warning-status {
visibility: visible;
cursor: pointer;
&::before {
content: @icon-exclamation-mark-circle;
color: @status-warning-color;
font-size: @status-font-icon-size;
}
&:hover::before {
background-color: @hover-background-color;
color: @status-warning-hover-color;
}
&:active::before,
&.selected::before {
background-color: @active-background-color;
color: @status-warning-hover-color;
}
}
.error-status {
visibility: visible;
cursor: pointer;
&::before {
content: @icon-exclamation-mark-circle;
color: @status-error-color;
font-size: @status-font-icon-size;
}
&:hover::before {
background-color: @hover-background-color;
color: @status-error-hover-color;
}
&:active::before,
&.selected::before {
background-color: @active-background-color;
color: @status-error-hover-color;
}
}
.loading-indicator(@loading-animation-size: 30px, @border-width: 1px) {
display: inline-block;
position: absolute;
top: 50%;
left: 50%;
margin-top: -(@loading-animation-size / 2);
margin-left: -(@loading-animation-size / 2);
#scout.animation(fade-in 0.15s);
#scout.loading-indicator-before(@loading-animation-size, @border-width);
&.animate-remove {
#scout.animation(fade-out-from-current 0.15s);
}
}
.loading-indicator-before(@loading-animation-size: 30px, @border-width: 1px) {
&::before {
#scout.animation(pulsate 2s cubic-bezier(0.5, 0.1, 0.1, 0.5) infinite);
content: '';
display: inline-block;
vertical-align: middle;
border-radius: 50%;
border: @border-width fade(@busyindicator-color, 80%) solid;
width: @loading-animation-size;
height: @loading-animation-size;
}
}
.loading-indicator-knight-rider() {
display: block;
position: absolute;
top: 0;
left: 0;
height: 2px;
width: 100%;
opacity: 0;
animation: fade-in 1s forwards, slideout-right 1.5s ease-in-out infinite alternate;
animation-delay: 0.5s;
&::before {
animation: slideout-left 1.5s ease-in-out infinite alternate;
animation-delay: 0.5s;
content: '';
position: absolute;
background: linear-gradient(to right, transparent 0%, @loading-indicator-knight-rider-color 20%, @loading-indicator-knight-rider-color 80%, transparent 100%);
left: 0;
width: 50px;
height: 100%;
}
}
.user-select(@mode) {
-webkit-user-select: @mode;
-moz-user-select: @mode;
-ms-user-select: @mode;
user-select: @mode;
}
.overflow-ellipsis() {
overflow: hidden;
text-overflow: ellipsis;
}
.overflow-ellipsis-nowrap() {
#scout.overflow-ellipsis();
white-space: nowrap;
}
.overflow-nowrap() {
overflow: hidden;
white-space: nowrap;
}
.overflow-clip() {
// clip is not supported for Safari < 16 -> it will be ignored and fall back to hidden
overflow: hidden;
overflow: clip;
}
.white-space-nowrap() {
white-space: nowrap;
}
// Can be used in a before or after element to enlarge a text to a size it would have if it was bold
.bold-text-enlarger() {
content: attr(data-text);
display: block;
font-weight: @title-font-weight;
visibility: hidden;
height: 0;
}
.triangle-top-left(@size, @color) {
width: 0;
height: 0;
border-style: solid;
border-width: @size @size 0 0;
#scout.triangle-top-left-color(@color);
}
.triangle-top-left-color(@color) {
border-color: @color transparent transparent transparent;
}
.item-selection-border(@border-color: @item-selection-nonfocus-border-color) {
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
border: @item-selection-border-width solid @border-color;
border-radius: @control-border-radius;
pointer-events: none;
}
/* Font Mixins */
.font-text-small(@font-weight: @font-weight-normal) {
font-family: @font-default-family;
font-weight: @font-weight;
font-size: @font-size-small;
}
.font-text-normal(@font-weight: @font-weight-normal) {
font-family: @font-default-family;
font-weight: @font-weight;
font-size: @font-size-normal;
}
.font-text-plus(@font-weight: @font-weight-normal) {
font-family: @font-default-family;
font-weight: @font-weight;
font-size: @font-size-plus;
}
.font-text-large(@font-weight: @font-weight-normal) {
font-family: @font-default-family;
font-weight: @font-weight;
font-size: @font-size-large;
}
.font-icon() {
font-family: scoutIcons, @font-default-family;
font-weight: @font-weight-normal;
speak: none;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.submenu-icon() {
#scout.font-icon();
font-size: 16px;
}
.submenu-icon-open() {
#scout.transform(rotateX(180deg) translateY(-1px));
}
/* Invisible pseudo element that enables vertical-align if container has height set */
.vertical-align-helper(@minHeight: 0) {
content: '';
display: inline-block;
vertical-align: middle;
height: 100%;
min-height: @minHeight;
}
.vertical-align-helper-before(@minHeight: 0) {
&::before {
#scout.vertical-align-helper(@minHeight);
}
}
.vertical-align-helper-after(@minHeight: 0) {
&::after {
#scout.vertical-align-helper(@minHeight);
}
}
//noinspection CssInvalidPropertyValue
.cursor-grab {
/* "grab" cursor with fallback for browsers that don't understand CSS3 cursors */
cursor: move;
cursor: -webkit-grab;
cursor: -moz-grab;
cursor: grab;
}
//noinspection CssInvalidPropertyValue
.cursor-grabbing {
/* "grabbing" cursor with fallback for browsers that don't understand CSS3 cursors */
cursor: move;
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
cursor: grabbing;
}
/* Mixin for chooser popups as used in smart-field */
.chooser-popup {
position: absolute;
overflow: hidden;
#scout.control-popup();
&.touch {
background-color: @table-header-background-color;
}
}
.backdrop-filter(@background-color, @backdrop-filter, @fallback-background-color) {
background-color: @fallback-background-color; // For browsers that don't support backdrop-filter
@supports ((-webkit-backdrop-filter: none) or (backdrop-filter: none)) {
background-color: @background-color;
-webkit-backdrop-filter: @backdrop-filter;
backdrop-filter: @backdrop-filter;
}
}
.popup {
background-color: @popup-background-color;
border: @popup-border-width solid @popup-border-color;
border-radius: @popup-border-radius;
#scout.drop-shadow-large();
}
.popup-backdrop-filter() {
#scout.backdrop-filter(@background-color: @popup-backdrop-background-color, @backdrop-filter: @popup-backdrop-filter, @fallback-background-color: @popup-background-color);
}
// Second layer popups that are normally a little smaller than the other popups
.popup-2(@border-radius: @border-radius-medium) {
background-color: @popup-2-background-color;
border: @popup-border-width solid @popup-border-color;
border-radius: @border-radius;
#scout.drop-shadow-large();
}
.popup-2-backdrop-filter() {
#scout.backdrop-filter(@background-color: @popup-2-backdrop-background-color, @backdrop-filter: @popup-2-backdrop-filter, @fallback-background-color: @popup-2-background-color);
}
.control-popup() {
#scout.popup-2(@control-border-radius);
margin: @control-popup-margin;
}
/* Mixin for scrollbar positioning */
.scrollbar-y-padding(@padding: @scrollbar-side-padding, @padding-hover: @scrollbar-side-padding-hover) {
& > .scrollbar-thumb.y-axis {
padding-left: @padding;
}
&:hover.y-axis > .scrollbar-thumb.y-axis,
&.y-axis > .scrollbar-thumb.y-axis.scrollbar-thumb-move {
padding-left: @padding-hover;
}
}
.scrollbar-x-padding(@padding: @scrollbar-side-padding, @padding-hover: @scrollbar-side-padding-hover) {
& > .scrollbar-thumb.x-axis {
padding-top: @padding;
}
&:hover.x-axis > .scrollbar-thumb.x-axis,
&.x-axis > .scrollbar-thumb.x-axis.scrollbar-thumb-move {
padding-top: @padding-hover;
}
}
/*
* Hides the scrollbars but lets the user still scroll (e.g. using mousewheel or touch).
* This works a bit different for every browser.
*/
.hide-scrollbars {
&::-webkit-scrollbar {
display: none;
}
-ms-overflow-style: none;
/* Firefox: https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-width */
scrollbar-width: none;
}
/**
* Uses the inverted colors of the scrollbars. Use this mixin in a widget that requires inverted scrollbars (e.g. a widget with white background in dark mode).
*/
.inverted-scrollbars {
& > .scrollbar > .scrollbar-thumb {
& > .scrollbar-thumb-handle {
background-color: @scrollbar-thumb-inverted-color;
}
&.scrollbar-thumb-move > .scrollbar-thumb-handle,
&:hover > .scrollbar-thumb-handle {
background-color: @scrollbar-thumb-inverted-hover-color;
}
&.container-too-small-for-thumb > .scrollbar-thumb-handle {
background-color: @scrollbar-thumb-inverted-small-color;
}
&.container-too-small-for-thumb.scrollbar-thumb-move > .scrollbar-thumb-handle,
&.container-too-small-for-thumb.scrollbar-thumb:hover > .scrollbar-thumb-handle {
background-color: @scrollbar-thumb-inverted-small-hover-color;
}
}
}
/**
* Adds a rule for a css class with the name @{edge}-resize that defines the cursor with the same name, e.g. resize-w.
*/
.resize-cursor(@edge) {
.@{edge}-resize,
.@{edge}-resize * { /* NOSONAR (universal selector is okay here) */
cursor: ~'@{edge}-resize !important'; /* NOSONAR !important is necessary to override any defined cursor on underlying components */
}
}
}