@eclipse-scout/core
Version:
Eclipse Scout runtime
297 lines (248 loc) • 7.75 kB
text/less
/*
* Copyright (c) 2010, 2023 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
*/
.tree {
position: relative;
// The value of the css variable is read by Tree.js and added to the level padding if the parent node has an icon
--node-padding-level-diff-parent-has-icon: @tree-node-padding-level-diff-parent-has-icon;
&:focus,
&.focused {
outline: none;
& > .tree-data {
& > .animation-wrapper > .tree-node.selected,
& > .tree-node.selected {
background-color: @item-selection-background-color;
&::after {
border-color: @item-selection-border-color;
}
}
}
}
& > .filter-field {
--filter-field-max-bottom: calc(~'50% - ' (var(--filter-field-height) + var(--menubar-height)) / 2);
bottom: calc(min(var(--filter-field-bottom), var(--filter-field-max-bottom)) + var(--menubar-height));
&:not(.focused).empty {
--filter-field-max-bottom: calc(~'50% - ' (@filter-field-icon-size + var(--menubar-height)) / 2);
}
}
}
.tree-data {
/* necessary for scrollbars */
position: relative;
overflow: hidden;
width: 100%; /* expand to outer container, needed for breadcrumb */
/* required because text shouldn't go into ellipsis mode when scrollbars are enabled */
&.scrollable-tree {
overflow-anchor: none;
& > .tree-node,
& > .animation-wrapper > .tree-node {
overflow: visible;
}
& > .tree-node > .text,
& > .animation-wrapper > .tree-node > .text {
text-overflow: clip;
}
}
&.checkable {
& > .tree-node,
& > .animation-wrapper > .tree-node {
cursor: pointer;
}
&.disabled > .tree-node,
&.disabled > .animation-wrapper > .tree-node,
& > .tree-node.disabled,
& > .animation-wrapper > .tree-node.disabled {
cursor: default;
}
}
}
.navigation-breadcrumb .tree-data {
float: left;
}
.tree-node {
display: flex;
align-items: start;
position: relative;
padding: @tree-node-padding-y @tree-node-padding-right @tree-node-padding-y @tree-node-padding-left;
#scout.overflow-ellipsis-nowrap();
&:active {
background-color: @tree-node-active-background-color;
}
&.selected {
background-color: @item-selection-nonfocus-background-color;
&::after {
#scout.item-selection-border();
}
}
&.disabled {
/* Tree node is disabled -> use lighter disabled color */
color: @disabled-color;
}
.disabled > .animation-wrapper > &,
.disabled > & {
/* Whole tree is disabled -> use darker disabled color */
color: @text-disabled-color;
}
.disabled.read-only > .animation-wrapper > &,
.disabled.read-only > & {
color: @read-only-color;
}
& > .text {
vertical-align: top;
display: inline-block;
flex-grow: 1;
#scout.overflow-ellipsis-nowrap();
&.measure {
flex-grow: 0;
}
}
& > .icon {
vertical-align: top;
padding-right: @tree-node-icon-padding-right;
display: inline-block;
text-align: center;
min-width: @tree-node-icon-width;
/* Use content-box for images because it leads to wrong behavior when someone sets a min-width/height
* on an IMG element that has padding and the available space for the image is 'min-width' - 'padding'
* See ticket 208111 */
box-sizing: content-box;
&.image-icon {
margin-top: @tree-node-bitmap-icon-margin-top;
/* required to reserve space for bitmap icons in the tree when image resource is not yet loaded */
min-width: @tree-node-bitmap-icon-size;
min-height: @tree-node-bitmap-icon-size;
}
&.font-icon {
/* Necessary to align with the text, depends on the used font size */
line-height: @tree-node-font-icon-line-height;
font-size: @tree-node-font-icon-size;
}
}
}
.tree-node-checkbox {
display: block;
position: absolute;
top: auto;
left: auto;
margin-top: @tree-node-checkbox-margin-top;
margin-left: -@tree-node-checkbox-size - 8px;
width: @tree-node-checkbox-size;
height: @tree-node-checkbox-size;
& > .check-box {
&:not(.checked).children-checked {
#scout.checkbox-undefined();
// Check box gets disabled class if a single node is disabled
&.disabled {
#scout.checkbox-disabled();
#scout.checkbox-undefined-disabled();
}
}
// If the tree or a parent widget is disabled, the check box doesn't get the disabled class
.tree.disabled > .tree-data > .tree-node > &,
.tree.disabled > .tree-data > .animation-wrapper > .tree-node > & {
#scout.checkbox-disabled();
&.checked {
#scout.checkbox-checked-disabled();
}
&:not(.checked).children-checked {
#scout.checkbox-undefined-disabled();
}
}
}
}
// The class can be added if the parent node should not visualize that a child node is checked.
// Currently, there is no official property on the tree for this case because it is rarely used.
// .tree is necessary to be more specific than rule above
.tree.no-children-checked-style {
& > .tree-data > .tree-node,
& > .tree-data > .animation-wrapper > .tree-node {
& > .tree-node-checkbox > :not(.checked).children-checked {
background-color: inherit;
border-color: @check-box-border-color;
.disabled&,
&.disabled {
background-color: inherit;
border-color: @check-box-disabled-border-color;
}
&::before {
display: none;
}
}
}
}
.tree-node-control {
display: block;
position: absolute;
top: 0;
left: 0;
cursor: pointer;
padding: @tree-node-padding-y 8px @tree-node-padding-y @tree-node-control-padding-left;
height: 100%;
line-height: @tree-node-control-line-height; /* Necessary to align with the text, depends on the used font size */
color: @tree-node-control-color;
&::before {
display: block;
transition: transform 0.3s;
#scout.font-icon();
font-size: @tree-node-control-size;
content: @icon-angle-right;
.tree-node.lazy > & {
font-family: @font-default-family;
content: '+';
/* Move to left because '+' sign is not as wide as 'arrow-down' */
margin-left: -2px;
}
.tree-node.expanded > & {
/* This "imprecise" angle is a workaround for firefox to prevent shifting the div a little when the animation finishes. */
/* See https://bugzilla.mozilla.org/show_bug.cgi?id=739176 */
#scout.transform(rotate(89.99deg));
}
}
&:hover {
color: @highlight-color;
}
}
/* bread crumb style */
.tree.breadcrumb {
& > .tree-data {
& > .tree-node,
& > .animation-wrapper > .tree-node {
white-space: normal;
display: none;
border-top: 0;
border-bottom: 1px solid @border-color;
padding: 8px 10px;
&.ancestor-of-selected,
&.child-of-selected,
/* Selecting a node will remove all child-of-selected classes of the parent's children, hence the selected node will be temporarily invisible.
If that happens the active state won't be removed correctly (browser bug?). To prevent this we make sure the node will not get invisible when touched. */
&:active {
display: flex;
}
&.selected {
display: flex;
cursor: default;
}
& > .text {
white-space: normal;
}
& > .tree-node-control {
display: none;
}
}
}
}
/* key handling */
.tree-node .key-box {
top: calc(~'50% - 11px');
}
.tree > .tree-data > .key-box {
top: 6px;
left: 4px;
}