UNPKG

tdesign-react

Version:
448 lines (375 loc) 9.61 kB
// 组件允许单个组件打包,因此默认引入公共基础样式 @import "../../base.less"; @import "./_var.less"; @import "./_mixin.less"; @import "../../mixins/_reset.less"; @import "../../mixins/_text.less"; // <name> 替换为组件名 .@{prefix}-tree { .reset; font: @tree-font; color: @tree-node-text-color; position: relative; // 禁用态颜色处理 &.@{prefix}-is-disabled { color: @tree-disabled-color; .t-icon { color: @tree-disabled-color; } .@{prefix}-tree__item { &.@{prefix}-is-active { background-color: @tree-node-bg-hover-color; color: @tree-disabled-color; } .t-icon { color: @tree-icon-disabled-color; } } } &__empty { color: @tree-node-empty-text-color; } &__branch { display: block; } &__item { // 用于树结构缩进计算 --level: 0; // 用于多行 label 计算高度 // 如果使用了多行 label 或者 label 内容高于 34px // 业务方可以增大这个值来让高度动画完全伸展 // 值预期为 Math.max(实际最大高度 / 34, 1) --hscale: 2; will-change: opacity, max-height; position: relative; display: flex; flex-wrap: nowrap; align-items: center; padding: 0 0 0 @tree-node-item-padding-left; cursor: default; transform: translateZ(0); // 开启硬件加速 backface-visibility: hidden; // 防止Chrome、Safari中,使用 transforms/animations,可能造成的页面闪烁 perspective: 1000; // 防止Chrome、Safari中,使用 transforms/animations,可能造成的页面闪烁 .t-icon, .@{prefix}-loading { display: inline-block; position: relative; z-index: 2; font-size: @tree-node-icon-size; } .t-icon { color: @tree-node-icon-color; } .@{prefix}-checkbox { align-items: center; font-size: 0; &__input { flex-shrink: 0; } &__label { overflow: hidden; text-overflow: ellipsis; } } .@{prefix}-tree__icon--default { .t-icon { transform: rotate(0); } } &--open { .t-icon { color: @tree-node-icon-active-color; } .@{prefix}-tree__icon--default { .t-icon { transform: rotate(90deg); } } } // 允许点击 &--clickable { cursor: pointer; } // 过滤时被命中为路径节点 &--locked { color: @tree-disabled-color; } // 过滤时被命中 &--matched { color: inherit; } &--draggable { cursor: pointer; &:hover { background-color: @tree-node-bg-hover-color; background-clip: content-box; } &::after { position: absolute; top: -(@tree-node-drag-tip-height / 2); right: 0; left: 0; display: block; height: @tree-node-drag-tip-height; border-radius: (@tree-node-drag-tip-height / 2); content: ""; padding: inherit; background-clip: content-box; } } &--tip { &-top::after { background-color: @tree-node-drag-tip-bg; } &-bottom::after { top: unset; bottom: -(@tree-node-drag-tip-height / 2); background-color: @tree-node-drag-tip-bg; } &-highlight { background-color: @tree-node-drag-bg-highlight; background-clip: content-box; } } } // 用于撑开节点高度 // 比起使用 padding , 更有利于动画展现 &__item::before { content: ""; display: block; width: 0; flex: 0 0 auto; height: @tree-node-item-height; } &--block-node &__label { flex: 1; } &--hoverable &__label:not(.@{prefix}-is-active):not(.@{prefix}-is-checked):hover { background-color: @tree-node-bg-hover-color; } &__line { --level: 0; --color: @tree-node-icon-line-color; --space: @tree-node-padding-basic; --iconSize: @icon-default; position: absolute; left: @tree-line-position-left; bottom: @tree-line-position-bottom; width: @tree-line-width; height: @tree-node-item-height; pointer-events: none; } &__line::before { content: ""; position: absolute; bottom: 0; left: 0; display: block; height: @tree-node-item-height; width: @tree-line-before-width; border-left: 1px solid var(--color); border-bottom: 1px solid var(--color); } &__line--first::before { height: @tree-line-first-height; } &__line--leaf::before { width: @tree-line-leaf-width; } // 默认图标 &__icon { position: relative; flex: none; display: inline-flex; align-items: center; // 图标居中 text-align: center; width: @tree-node-icon-size; // 当子元素只有一个且为image类型时,会有隐藏占位,因此将font-size设0 font-size: 0; user-select: none; cursor: pointer; } // svg 动画与 icon 背景进行隔离 // :after 仅用于增大点击范围 &__icon::after { content: ""; display: block; position: absolute; left: -2px; top: -2px; width: calc(@tree-node-icon-size + 4px); height: calc(@tree-node-icon-size + 4px); border-radius: @border-radius-default; } // 仅在有图标时呈现背景 // 注意这里背景样式不要加给 ::after // ::after 仅用于增大点击范围 &__icon:not(:empty):hover { background-color: @tree-node-bg-hover-color; } // 没有图标时不呈现指针 &__icon:empty { cursor: initial; } &__label { --ripple-color: @bg-color-container-active; flex-wrap: nowrap; // resoved style issues of tree component does not handle content exceedance flex: 1; padding: @tree-label-padding; margin-left: @tree-label-margin-left; border-radius: @border-radius-default; cursor: pointer; .text-ellipsis(); &.@{prefix}-is-checked { font-weight: 500; color: @tree-node-text-active-color; background-color: @tree-node-bg-active-color; } &::selection { background-color: transparent; } } .@{prefix}-is-active &__label { font-weight: 500; color: @tree-node-text-active-color; background-color: @tree-node-bg-active-color; } &__space { display: block; flex: 1 0 auto; } &__operations { display: flex; flex: 0 0 auto; justify-content: flex-end; align-items: center; margin-left: auto; } &__operations .t-icon { cursor: pointer; } &__item.@{prefix}-is-disabled { color: @tree-disabled-color; cursor: default; .@{prefix}-checkbox { cursor: default; } } } .@{prefix}-tree { &__item--hidden { display: none; } } // 节点动画 .@{prefix}-tree--transition { // 标签动画 .@{prefix}-tree__label { transition: background-color @anim-duration-moderate @anim-time-fn-easing; } // 默认图标 .@{prefix}-tree__icon { transition: color, transform @anim-duration-moderate @anim-time-fn-easing; } .@{prefix}-tree__icon::after { transition: @anim-duration-base linear; } .@{prefix}-tree__icon:not(:empty):hover { transition: @anim-duration-base linear; } // 图标动画 .@{prefix}-tree__icon--default { .t-icon { transition: color, transform @anim-time-fn-easing @anim-duration-base; } } // 节点展示动画 .@{prefix}-tree__item--visible { display: flex; max-height: @tree-node-item-origin-height; opacity: 1; transition: opacity @tree-node-transition-time linear @tree-node-transition-time, max-height @tree-node-transition-time linear 0s; } // 节点隐藏动画 .@{prefix}-tree__item--hidden { display: flex; max-height: 0; opacity: 0; overflow: hidden; pointer-events: none; user-select: none; animation: initial; transition: opacity @tree-node-transition-time linear 0s, max-height @tree-node-transition-time linear @tree-node-transition-time; } // 节点插入动画 .@{prefix}-tree__item--enter-active { animation: t-tree-toggle @tree-node-animation-time linear; } // 节点移除动画 .@{prefix}-tree__item--leave-active { animation: t-tree-toggle @tree-node-animation-time reverse linear forwards; } } // 虚拟滚动样式 .@{prefix}-tree__vscroll { overflow-y: auto; } // 虚拟滚动延迟加载模式 .@{prefix}-tree__lazyload { overflow-y: auto; } // 虚拟滚动游标 .@{prefix}-tree__vscroll-cursor { position: absolute; width: 1px; height: 1px; transition: transform @anim-duration-base; } .@{prefix}-tree--scrolling { .@{prefix}-tree__item { will-change: initial; } .v-enter, .v-leave, .@{prefix}-tree__item--visible, .@{prefix}-tree__item--hidden, .@{prefix}-tree__item--enter, .@{prefix}-tree__item--enter-active, .@{prefix}-tree__item--enter-to, .@{prefix}-tree__item--leave, .@{prefix}-tree__item--leave-active .@{prefix}-tree__item--leave-to { animation: none; transition: none; } .@{prefix}-tree__item--visible { max-height: initial; } .@{prefix}-tree__item--enter-to, .@{prefix}-tree__item--enter-active { max-height: initial; } .@{prefix}-tree__item--leave-to, .@{prefix}-tree__item--leave-active { max-height: 0; } } @keyframes t-tree-toggle { 0% { opacity: 0; max-height: 0; } 50% { opacity: 0; max-height: @tree-node-item-origin-height; } 100% { opacity: 1; max-height: @tree-node-item-origin-height; } }