refactor(tree): show-line

This commit is contained in:
07akioni 2023-06-13 23:47:53 +08:00
parent 99b7d83586
commit 1d5907052b
23 changed files with 211 additions and 154 deletions

View File

@ -35,7 +35,7 @@ export default defineNuxtConfig({
optimizeDeps: {
include:
process.env.NODE_ENV === 'development'
? ['naive-ui', 'vueuc', 'date-fns-tz/esm/formatInTimeZone']
? ['naive-ui', 'vueuc', 'date-fns-tz/formatInTimeZone']
: []
}
}

View File

@ -35,7 +35,7 @@ export default defineNuxtConfig({
optimizeDeps: {
include:
process.env.NODE_ENV === 'development'
? ['naive-ui', 'vueuc', 'date-fns-tz/esm/formatInTimeZone']
? ['naive-ui', 'vueuc', 'date-fns-tz/formatInTimeZone']
: []
}
}

View File

@ -68,8 +68,7 @@ module.exports = {
// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
moduleNameMapper: {
'^lodash-es$': 'lodash',
'^date-fns/esm(.*)$': 'date-fns$1',
'^date-fns-tz/esm(.*)$': 'date-fns-tz$1'
'^date-fns/esm(.*)$': 'date-fns$1'
},
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader

View File

@ -15,9 +15,7 @@ const { genWebTypes } = require('./gen-web-types')
// the sequence is crucial
"'lodash'": "'lodash-es'",
"'date-fns/(.*)'//": "'date-fns/esm/$1'",
"'date-fns-tz/(.*)'//": "'date-fns-tz/esm/$1'",
"'date-fns'//": "'date-fns/esm'",
"'date-fns-tz'//": "'date-fns-tz/esm'"
"'date-fns'//": "'date-fns/esm'"
})
// generate web-types.json for webstorm & vetur

View File

@ -4,7 +4,6 @@ const { replaceDefine, srcDir } = require('../utils')
;(async () => {
await replaceDefine([srcDir], {
"'lodash-es'": "'lodash'",
"'date-fns/esm(.*)'": "'date-fns$1'//",
"'date-fns-tz/esm(.*)'": "'date-fns-tz$1'//"
"'date-fns/esm(.*)'": "'date-fns$1'//"
})
})()

View File

@ -20,7 +20,8 @@ import {
createKey,
type MaybeArray,
type ExtractPublicPropTypes,
warnOnce
warnOnce,
resolveWrappedSlot
} from '../../_utils'
import { checkboxLight } from '../styles'
import type { CheckboxTheme } from '../styles'
@ -325,6 +326,16 @@ export default defineComponent({
handleClick
} = this
this.onRender?.()
const labelNode = resolveWrappedSlot($slots.default, (children) => {
if (label || children) {
return (
<span class={`${mergedClsPrefix}-checkbox__label`} id={labelId}>
{label || children}
</span>
)
}
return null
})
return (
<div
ref="selfRef"
@ -335,7 +346,8 @@ export default defineComponent({
renderedChecked && `${mergedClsPrefix}-checkbox--checked`,
mergedDisabled && `${mergedClsPrefix}-checkbox--disabled`,
indeterminate && `${mergedClsPrefix}-checkbox--indeterminate`,
privateInsideTable && `${mergedClsPrefix}-checkbox--inside-table`
privateInsideTable && `${mergedClsPrefix}-checkbox--inside-table`,
labelNode && `${mergedClsPrefix}-checkbox--show-label`
]}
tabindex={mergedDisabled || !focusable ? undefined : 0}
role="checkbox"
@ -381,11 +393,7 @@ export default defineComponent({
<div class={`${mergedClsPrefix}-checkbox-box__border`} />
</div>
</div>
{label !== null || $slots.default ? (
<span class={`${mergedClsPrefix}-checkbox__label`} id={labelId}>
{$slots.default ? $slots.default() : label}
</span>
) : null}
{labelNode}
</div>
)
}

View File

@ -27,7 +27,6 @@ import { iconSwitchTransition } from '../../../_styles/transitions/icon-switch.c
// --n-label-padding
export default c([
cB('checkbox', `
line-height: var(--n-label-line-height);
font-size: var(--n-font-size);
outline: none;
cursor: pointer;
@ -35,13 +34,13 @@ export default c([
flex-wrap: nowrap;
align-items: flex-start;
word-break: break-word;
line-height: var(--n-size);
--n-merged-color-table: var(--n-color-table);
`, [
cM('show-label', 'line-height: var(--n-label-line-height);'),
c('&:hover', [
cB('checkbox-box', [
cE('border', {
border: 'var(--n-border-checked)'
})
cE('border', 'border: var(--n-border-checked);')
])
]),
c('&:focus:not(:active)', [
@ -123,18 +122,18 @@ export default c([
cB('checkbox-box', `
background-color: var(--n-color-disabled);
`, [
cE('border', {
border: 'var(--n-border-disabled)'
}),
cE('border', `
border: var(--n-border-disabled);
`),
cB('checkbox-icon', [
c('.check-icon, .line-icon', {
fill: 'var(--n-check-mark-color-disabled)'
})
c('.check-icon, .line-icon', `
fill: var(--n-check-mark-color-disabled);
`)
])
]),
cE('label', {
color: 'var(--n-text-color-disabled)'
})
cE('label', `
color: var(--n-text-color-disabled);
`)
]),
cB('checkbox-box-wrapper', `
position: relative;

View File

@ -314,12 +314,7 @@ export default defineComponent({
visibility: 'collapse'
}}
>
{repeat(
compitableColumn * 2,
<td
class={`${mergedClsPrefix}-descriptions-table-content`}
/>
)}
{repeat(compitableColumn * 2, <td />)}
</tr>
)}
{rows}

View File

@ -61,12 +61,12 @@ describe('n-descriptions', () => {
})
expect(
wrapper.find('.n-descriptions-table-row').element.childNodes.length
).toBe(3)
).toBe(6) // 3 * 2
await wrapper.setProps({ column: 4 })
expect(
wrapper.find('.n-descriptions-table-row').element.childNodes.length
).toBe(4)
).toBe(8) // 4 * 2
wrapper.unmount()
})

View File

@ -2357,7 +2357,7 @@ exports[`locale works 17`] = `
<div class="n-input n-input--resizable n-input--stateful" style="--n-bezier: cubic-bezier(.4, 0, .2, 1); --n-count-text-color: rgb(118, 124, 130); --n-count-text-color-disabled: rgba(194, 194, 194, 1); --n-color: rgba(255, 255, 255, 1); --n-font-size: 14px; --n-border-radius: 3px; --n-height: 34px; --n-padding-left: 12px; --n-padding-right: 12px; --n-text-color: rgb(51, 54, 57); --n-caret-color: #18a058; --n-text-decoration-color: rgb(51, 54, 57); --n-border: 1px solid rgb(224, 224, 230); --n-border-disabled: 1px solid rgb(224, 224, 230); --n-border-hover: 1px solid #36ad6a; --n-border-focus: 1px solid #36ad6a; --n-placeholder-color: rgba(194, 194, 194, 1); --n-placeholder-color-disabled: rgba(209, 209, 209, 1); --n-icon-size: 16px; --n-line-height-textarea: 1.6; --n-color-disabled: rgb(250, 250, 252); --n-color-focus: rgba(255, 255, 255, 1); --n-text-color-disabled: rgba(194, 194, 194, 1); --n-box-shadow-focus: 0 0 0 2px rgba(24, 160, 88, 0.2); --n-loading-color: #18a058; --n-caret-color-warning: #f0a020; --n-color-focus-warning: rgba(255, 255, 255, 1); --n-box-shadow-focus-warning: 0 0 0 2px rgba(240, 160, 32, 0.2); --n-border-warning: 1px solid #f0a020; --n-border-focus-warning: 1px solid #fcb040; --n-border-hover-warning: 1px solid #fcb040; --n-loading-color-warning: #f0a020; --n-caret-color-error: #d03050; --n-color-focus-error: rgba(255, 255, 255, 1); --n-box-shadow-focus-error: 0 0 0 2px rgba(208, 48, 80, 0.2); --n-border-error: 1px solid #d03050; --n-border-focus-error: 1px solid #de576d; --n-border-hover-error: 1px solid #de576d; --n-loading-color-error: #d03050; --n-clear-color: rgba(194, 194, 194, 1); --n-clear-size: 16px; --n-clear-color-hover: rgba(146, 146, 146, 1); --n-clear-color-pressed: rgba(175, 175, 175, 1); --n-icon-color: rgba(194, 194, 194, 1); --n-icon-color-hover: rgba(146, 146, 146, 1); --n-icon-color-pressed: rgba(175, 175, 175, 1); --n-icon-color-disabled: rgba(209, 209, 209, 1); --n-suffix-text-color: rgb(51, 54, 57);" tabindex="0">
<div class="n-input-wrapper">
<!---->
<div class="n-input__input"><input type="text" class="n-input__input-el" tabindex="-1" placeholder="Selecione Data e Hora" size="20">
<div class="n-input__input"><input type="text" class="n-input__input-el" tabindex="-1" placeholder="Selecione a data e hora" size="20">
<!---->
<!---->
</div>

View File

@ -86,6 +86,8 @@ export type SelectGroupOption =
export interface SelectInst {
focus: () => void
blur: () => void
focusInput: () => void
blurInput: () => void
}
export type SelectFallbackOption = (value: string & number) => SelectOption

View File

@ -32,7 +32,7 @@ import {
getHours,
getSeconds
} from 'date-fns/esm'
import formatInTimeZone from 'date-fns-tz/esm/formatInTimeZone'
import formatInTimeZone from 'date-fns-tz/formatInTimeZone'
import type { Locale } from 'date-fns'
import type { FormValidationStatus } from '../../form/src/interface'
import { strictParse } from '../../date-picker/src/utils'

View File

@ -7,7 +7,7 @@ import {
} from 'vue'
import { format, formatDistanceStrict, fromUnixTime } from 'date-fns/esm'
import type { Locale } from 'date-fns'
import formatInTimeZone from 'date-fns-tz/esm/formatInTimeZone'
import formatInTimeZone from 'date-fns-tz/formatInTimeZone'
import { useLocale } from '../../_mixins'
import { type ExtractPublicPropTypes } from '../../_utils'

View File

@ -73,7 +73,7 @@ checkbox-placement.vue
| selectable | `boolean` | `true` | Whether the node can be selected. | |
| selected-keys | `Array<string \| number>` | `undefined` | If set, selected status will work in controlled manner. | |
| show-irrelevant-nodes | `boolean` | `true` | Whether to filter unmached nodes when tree is in filter mode. | 2.28.1 |
| show-line | `boolean` | `true` | Whether to display the connection line. | NEXT_VERSION |
| show-line | `boolean` | `false` | Whether to display the connection line. | NEXT_VERSION |
| virtual-scroll | `boolean` | `false` | Whether to enable virtual scroll. You need to set proper style height of the tree in advance. | |
| watch-props | `Array<'defaultCheckedKeys' \| 'defaultSelectedKeys' \|'defaultExpandedKeys'>` | `undefined` | Default prop names that needed to be watched. Components will be updated after the prop is changed. Note: the `watch-props` itself is not reactive. | |
| on-dragend | `(data: { node: TreeOption, event: DragEvent }) => void` | `undefined` | The callback function after the node completes the dragging action. | |

View File

@ -79,7 +79,7 @@ expand-debug.vue
| selectable | `boolean` | `true` | 节点是否可以被选中 | |
| selected-keys | `Array<string \| number>` | `undefined` | 如果设定则 `selected` 状态受控 | |
| show-irrelevant-nodes | `boolean` | `true` | 是否在搜索状态显示和搜索无关的节点 | 2.28.1 |
| show-line | `boolean` | `true` | 是否显示连接线 | NEXT_VERSION |
| show-line | `boolean` | `false` | 是否显示连接线 | NEXT_VERSION |
| virtual-scroll | `boolean` | `false` | 是否启用虚拟滚动,启用前你需要设定好树的高度样式 | |
| watch-props | `Array<'defaultCheckedKeys' \| 'defaultSelectedKeys' \|'defaultExpandedKeys'>` | `undefined` | 需要检测变更的默认属性,检测后组件状态会更新。注意:`watch-props` 本身不是响应式的 | |
| on-dragend | `(data: { node: TreeOption, event: DragEvent }) => void` | `undefined` | 节点完成拖拽动作后的回调函数 | |

View File

@ -24,7 +24,7 @@ import {
} from 'treemate'
import { useMergedState } from 'vooks'
import { type VirtualListInst, VVirtualList } from 'vueuc'
import { getPadding } from 'seemly'
import { depx, getPadding, pxfy } from 'seemly'
import { treeSelectInjectionKey } from '../../tree-select/src/interface'
import { useConfig, useTheme, useThemeClass, useRtl } from '../../_mixins'
import type { ThemeProps } from '../../_mixins'
@ -71,13 +71,7 @@ import { treeInjectionKey } from './interface'
import MotionWrapper from './MotionWrapper'
import { defaultAllowDrop } from './dnd'
import style from './styles/index.cssr'
import { ScrollbarProps } from '../../scrollbar/src/Scrollbar'
// TODO:
// During expanding, some node are mis-applied with :active style
// Async dnd has bug
const ITEM_SIZE = 30 // 24 + 3 + 3
import { type ScrollbarProps } from '../../scrollbar/src/Scrollbar'
export function createTreeMateOptions<T> (
keyField: string,
@ -685,6 +679,7 @@ export default defineComponent({
void nextTick(syncScrollbar)
return
}
const nodeHeight = depx(themeRef.value.self.nodeHeight)
const prevVSet = new Set(prevValue)
let addedKey: Key | null = null
let removedKey: Key | null = null
@ -710,7 +705,7 @@ export default defineComponent({
const viewportHeight = (
virtualScroll ? virtualListInstRef.value!.listElRef : selfElRef.value!
).offsetHeight
const viewportItemCount = Math.ceil(viewportHeight / ITEM_SIZE) + 1
const viewportItemCount = Math.ceil(viewportHeight / nodeHeight) + 1
// play add animation
let baseExpandedKeys: Key[] | undefined
if (addedKey !== null) {
@ -742,7 +737,7 @@ export default defineComponent({
__motion: true,
mode: 'expand',
height: virtualScroll
? expandedChildren.length * ITEM_SIZE
? expandedChildren.length * nodeHeight
: undefined,
nodes: virtualScroll
? expandedChildren.slice(0, viewportItemCount)
@ -769,7 +764,7 @@ export default defineComponent({
__motion: true,
mode: 'collapse',
height: virtualScroll
? collapsedChildren.length * ITEM_SIZE
? collapsedChildren.length * nodeHeight
: undefined,
nodes: virtualScroll
? collapsedChildren.slice(0, viewportItemCount)
@ -1519,6 +1514,7 @@ export default defineComponent({
droppingOffsetLevelRef,
fNodesRef,
pendingNodeKeyRef,
showLineRef: toRef(props, 'showLine'),
disabledFieldRef: toRef(props, 'disabledField'),
internalScrollableRef: toRef(props, 'internalScrollable'),
internalCheckboxFocusableRef: toRef(props, 'internalCheckboxFocusable'),
@ -1575,9 +1571,17 @@ export default defineComponent({
loadingColor,
nodeTextColor,
nodeTextColorDisabled,
dropMarkColor
dropMarkColor,
nodeWrapperPadding,
nodeHeight,
lineHeight
}
} = themeRef.value
const lineOffsetTop = getPadding(nodeWrapperPadding, 'top')
const lineOffsetBottom = getPadding(nodeWrapperPadding, 'bottom')
const nodeContentHeight = pxfy(
depx(nodeHeight) - depx(lineOffsetTop) - depx(lineOffsetBottom)
)
return {
'--n-arrow-color': arrowColor,
'--n-loading-color': loadingColor,
@ -1589,7 +1593,12 @@ export default defineComponent({
'--n-node-color-pressed': nodeColorPressed,
'--n-node-text-color': nodeTextColor,
'--n-node-text-color-disabled': nodeTextColorDisabled,
'--n-drop-mark-color': dropMarkColor
'--n-drop-mark-color': dropMarkColor,
'--n-node-wrapper-padding': nodeWrapperPadding,
'--n-line-offset-top': `-${lineOffsetTop}`,
'--n-line-offset-bottom': `-${lineOffsetBottom}`,
'--n-node-content-height': nodeContentHeight,
'--n-line-height': lineHeight
}
})
const themeClassHandle = inlineThemeDisabled
@ -1626,7 +1635,6 @@ export default defineComponent({
mergedClsPrefix,
blockNode,
blockLine,
showLine,
draggable,
disabled,
internalFocusable,
@ -1643,8 +1651,7 @@ export default defineComponent({
rtlEnabled && `${mergedClsPrefix}-tree--rtl`,
checkable && `${mergedClsPrefix}-tree--checkable`,
(blockLine || blockNode) && `${mergedClsPrefix}-tree--block-node`,
blockLine && `${mergedClsPrefix}-tree--block-line`,
showLine && `${mergedClsPrefix}-tree--show-line`
blockLine && `${mergedClsPrefix}-tree--block-line`
]
const createNode = (tmNode: TmNode | MotionData): VNode => {
return '__motion' in tmNode ? (
@ -1687,7 +1694,7 @@ export default defineComponent({
<VVirtualList
ref="virtualListInstRef"
items={this.fNodes}
itemSize={ITEM_SIZE}
itemSize={depx(mergedTheme.self.nodeHeight)}
ignoreItemResize={this.aip}
paddingTop={padding.top}
paddingBottom={padding.bottom}

View File

@ -6,7 +6,8 @@ import {
type PropType,
ref,
type ComponentPublicInstance,
onMounted
onMounted,
type VNode
} from 'vue'
import { useMemo } from 'vooks'
import { happensIn, repeat } from 'seemly'
@ -44,7 +45,8 @@ const TreeNode = defineComponent({
blockLineRef,
checkboxPlacementRef,
checkOnClickRef,
disabledFieldRef
disabledFieldRef,
showLineRef
} = NTree
const checkboxDisabledRef = useMemo(
@ -217,6 +219,43 @@ const TreeNode = defineComponent({
})
}
}
const indentNodes = computed(() => {
const { clsPrefix } = props
const { value: indent } = indentRef
if (showLineRef.value) {
const indentNodes: VNode[] = []
let cursor = props.tmNode.parent
while (cursor) {
if (cursor.isLastChild) {
indentNodes.push(
<div class={`${clsPrefix}-tree-node-indent`}>
<div style={{ width: `${indent}px` }} />
</div>
)
} else {
indentNodes.push(
<div
class={[
`${clsPrefix}-tree-node-indent`,
`${clsPrefix}-tree-node-indent--show-line`
]}
>
<div style={{ width: `${indent}px` }} />
</div>
)
}
cursor = cursor.parent
}
return indentNodes.reverse()
} else {
return repeat(
props.tmNode.level,
<div class={`${props.clsPrefix}-tree-node-indent`}>
<div style={{ width: `${indent}px` }} />
</div>
)
}
})
return {
showDropMark: useMemo(() => {
const { value: draggingNode } = draggingNodeRef
@ -273,8 +312,10 @@ const TreeNode = defineComponent({
droppingOffsetLevel: droppingOffsetLevelRef,
indent: indentRef,
checkboxPlacement: checkboxPlacementRef,
showLine: showLineRef,
contentInstRef,
contentElRef,
indentNodes,
handleCheck,
handleDrop,
handleDragStart,
@ -300,6 +341,7 @@ const TreeNode = defineComponent({
draggable,
blockLine,
indent,
indentNodes,
disabled,
pending,
internalScrollable,
@ -324,6 +366,7 @@ const TreeNode = defineComponent({
const checkboxOnRight = checkboxPlacement === 'right'
const checkboxNode = checkable ? (
<NTreeNodeCheckbox
indent={indent}
right={checkboxOnRight}
focusable={this.checkboxFocusable}
disabled={disabled || this.checkboxDisabled}
@ -360,20 +403,30 @@ const TreeNode = defineComponent({
: undefined
}
>
{repeat(
tmNode.level,
<div class={`${clsPrefix}-tree-node-indent`}>
{indentNodes}
{tmNode.isLeaf && this.showLine ? (
<div
class={[
`${clsPrefix}-tree-node-indent`,
`${clsPrefix}-tree-node-indent--show-line`,
tmNode.isLeaf && `${clsPrefix}-tree-node-indent--is-leaf`,
tmNode.isLastChild &&
`${clsPrefix}-tree-node-indent--last-child`
]}
>
<div style={{ width: `${indent}px` }} />
</div>
) : (
<NTreeNodeSwitcher
clsPrefix={clsPrefix}
expanded={this.expanded}
selected={selected}
loading={this.loading}
hide={tmNode.isLeaf}
indent={indent}
onClick={this.handleSwitcherClick}
/>
)}
<NTreeNodeSwitcher
clsPrefix={clsPrefix}
expanded={this.expanded}
selected={selected}
loading={this.loading}
hide={tmNode.isLeaf}
onClick={this.handleSwitcherClick}
/>
{!checkboxOnRight ? checkboxNode : null}
<NTreeNodeContent
ref="contentInstRef"

View File

@ -9,6 +9,10 @@ export default defineComponent({
type: String,
required: true
},
indent: {
type: Number,
required: true
},
right: Boolean,
focusable: Boolean,
disabled: Boolean,
@ -41,6 +45,7 @@ export default defineComponent({
indeterminate,
disabled,
focusable,
indent,
handleUpdateValue
} = this
return (
@ -49,6 +54,9 @@ export default defineComponent({
`${clsPrefix}-tree-node-checkbox`,
this.right && `${clsPrefix}-tree-node-checkbox--right`
]}
style={{
width: `${indent}px`
}}
data-checkbox
>
<NCheckbox

View File

@ -10,6 +10,7 @@ export default defineComponent({
type: String,
required: true
},
indent: { type: Number, required: true },
expanded: Boolean,
selected: Boolean,
hide: Boolean,
@ -20,16 +21,17 @@ export default defineComponent({
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const { renderSwitcherIconRef } = inject(treeInjectionKey, null)!
return () => {
const { clsPrefix } = props
const { clsPrefix, expanded, hide, indent, onClick } = props
return (
<span
data-switcher
class={[
`${clsPrefix}-tree-node-switcher`,
props.expanded && `${clsPrefix}-tree-node-switcher--expanded`,
props.hide && `${clsPrefix}-tree-node-switcher--hide`
expanded && `${clsPrefix}-tree-node-switcher--expanded`,
hide && `${clsPrefix}-tree-node-switcher--hide`
]}
onClick={props.onClick}
style={{ width: `${indent}px` }}
onClick={onClick}
>
<div class={`${clsPrefix}-tree-node-switcher__icon`}>
<NIconSwitchTransition>

View File

@ -121,6 +121,7 @@ export interface TreeInjection {
internalTreeSelect: boolean
checkOnClickRef: Ref<boolean | CheckOnClick>
disabledFieldRef: Ref<string>
showLineRef: Ref<boolean>
handleSwitcherClick: (node: TreeNode<TreeOption>) => void
handleSelect: (node: TreeNode<TreeOption>) => void
handleCheck: (node: TreeNode<TreeOption>, checked: boolean) => void

View File

@ -2,6 +2,8 @@ import { c, cB, cE, cM, cNotM } from '../../../_utils/cssr'
import { iconSwitchTransition } from '../../../_styles/transitions/icon-switch.cssr'
import { fadeInHeightExpandTransition } from '../../../_styles/transitions/fade-in-height-expand.cssr'
const iconSwitchTransitionNode = iconSwitchTransition()
// vars:
// --n-arrow-color
// --n-bezier
@ -12,6 +14,11 @@ import { fadeInHeightExpandTransition } from '../../../_styles/transitions/fade-
// --n-node-color-pressed
// --n-node-text-color
// --n-node-text-color-disabled
// --n-node-wrapper-padding
// --n-line-offset-top
// --n-line-offset-bottom
// --n-node-content-height
// --n-line-height
export default cB('tree', `
font-size: var(--n-font-size);
outline: none;
@ -23,9 +30,7 @@ export default cB('tree', `
`),
c('>', [
cB('tree-node', [
c('&:first-child', {
marginTop: 0
})
c('&:first-child', 'margin-top: 0;')
])
]),
cB('tree-motion-wrapper', [
@ -43,7 +48,7 @@ export default cB('tree', `
]),
cB('tree-node-wrapper', `
box-sizing: border-box;
padding: 3px 0;
padding: var(--n-node-wrapper-padding);
`),
cB('tree-node', `
transform: translate3d(0,0,0);
@ -54,9 +59,7 @@ export default cB('tree', `
`, [
cM('highlight', [
cB('tree-node-content', [
cE('text', {
borderBottomColor: 'var(--n-node-text-color-disabled)'
})
cE('text', 'border-bottom-color: var(--n-node-text-color-disabled);')
])
]),
cM('disabled', [
@ -83,26 +86,20 @@ export default cB('tree', `
cB('tree-node', [
cNotM('disabled', [
cB('tree-node-content', [
c('&:hover', {
backgroundColor: 'var(--n-node-color-hover)'
})
c('&:hover', 'background: var(--n-node-color-hover);')
]),
cM('selectable', [
cB('tree-node-content', [
c('&:active', {
backgroundColor: 'var(--n-node-color-pressed)'
})
c('&:active', 'background: var(--n-node-color-pressed);')
])
]),
cM('pending', [
cB('tree-node-content', `
background-color: var(--n-node-color-hover);
background: var(--n-node-color-hover);
`)
]),
cM('selected', [
cB('tree-node-content', {
backgroundColor: 'var(--n-node-color-active)'
})
cB('tree-node-content', 'background: var(--n-node-color-active);')
])
])
])
@ -110,60 +107,61 @@ export default cB('tree', `
cM('block-line', [
cB('tree-node', [
cNotM('disabled', [
c('&:hover', {
backgroundColor: 'var(--n-node-color-hover)'
}),
c('&:hover', 'background: var(--n-node-color-hover);'),
cM('pending', `
background-color: var(--n-node-color-hover);
background: var(--n-node-color-hover);
`),
cM('selectable', [
cNotM('selected', [
c('&:active', {
backgroundColor: 'var(--n-node-color-pressed)'
})
c('&:active', 'background: var(--n-node-color-pressed);')
])
]),
cM('selected', {
backgroundColor: 'var(--n-node-color-active)'
})
cM('selected', 'background: var(--n-node-color-active);')
]),
cM('disabled', `
cursor: not-allowed;
`)
])
]),
cM('show-line', [
cB('tree-node-indent', `
flex-grow: 0;
flex-shrink: 0;
position: relative
`, [
cB('tree-node-indent', `
flex-grow: 0;
flex-shrink: 0;
`, [
cM('show-line', 'position: relative', [
c('&::before', `
position: absolute;
left: 50%;
box-sizing: border-box;
border: 1px solid var(--n-border-color);
border-left: 1px solid var(--n-border-color);
transition: border-color .3s var(--n-bezier);
transform: translate(-50%);
content: "";
top: -5px;
bottom: -5px;
}
`)
])
]),
cNotM('show-line', [
cB('tree-node-indent', `
flex-grow: 0;
flex-shrink: 0;
height: 0;
`)
top: var(--n-line-offset-top);
bottom: var(--n-line-offset-bottom);
`),
cM('last-child', [
c('&::before', `
bottom: 50%;
`)
]),
cM('is-leaf', [
c('&::after', `
position: absolute;
content: "";
left: calc(50% + 0.5px);
right: 0;
bottom: 50%;
transition: border-color .3s var(--n-bezier);
border-bottom: 1px solid var(--n-border-color);
`)
])
]),
cNotM('show-line', 'height: 0;')
]),
cB('tree-node-switcher', `
cursor: pointer;
display: inline-flex;
flex-shrink: 0;
height: 24px;
width: 24px;
height: var(--n-node-content-height);
align-items: center;
justify-content: center;
transition: transform .15s var(--n-bezier);
@ -178,7 +176,9 @@ export default cB('tree', `
transition: color .3s var(--n-bezier);
font-size: 14px;
`, [
cB('icon', [iconSwitchTransition()]),
cB('icon', [
iconSwitchTransitionNode
]),
cB('base-loading', `
color: var(--n-loading-color);
position: absolute;
@ -187,58 +187,41 @@ export default cB('tree', `
right: 0;
bottom: 0;
`, [
iconSwitchTransition()
iconSwitchTransitionNode
]),
cB('base-icon', [
iconSwitchTransition()
iconSwitchTransitionNode
])
]),
cM('hide', {
visibility: 'hidden'
}),
cM('expanded', {
transform: 'rotate(90deg)'
})
cM('hide', 'visibility: hidden;'),
cM('expanded', 'transform: rotate(90deg);')
]),
cB('tree-node-checkbox', `
display: inline-flex;
height: 24px;
width: 16px;
height: var(--n-node-content-height);
vertical-align: bottom;
align-items: center;
justify-content: center;
margin-right: 4px;
`, [
cM('right', 'margin-left: 4px;')
]),
cM('checkable', [
cB('tree-node-content', `
padding: 0 6px;
`)
]),
`),
cB('tree-node-content', `
user-select: none;
position: relative;
display: inline-flex;
align-items: center;
min-height: 24px;
min-height: var(--n-node-content-height);
box-sizing: border-box;
line-height: 1.5;
line-height: var(--n-line-height);
vertical-align: bottom;
padding: 0 6px 0 4px;
cursor: default;
border-radius: var(--n-node-border-radius);
text-decoration-color: #0000;
text-decoration-line: underline;
color: var(--n-node-text-color);
transition:
color .3s var(--n-bezier),
text-decoration-color .3s var(--n-bezier),
background-color .3s var(--n-bezier),
border-color .3s var(--n-bezier);
`, [
c('&:last-child', {
marginBottom: 0
}),
c('&:last-child', 'margin-bottom: 0;'),
cE('prefix', `
display: inline-flex;
margin-right: 8px;

View File

@ -19,6 +19,9 @@ export const self = (vars: ThemeCommonVars) => {
} = vars
return {
fontSize,
lineHeight: '1.5',
nodeHeight: '30px',
nodeWrapperPadding: '3px 0',
nodeBorderRadius: borderRadiusSmall,
nodeColorHover: hoverColor,
nodeColorPressed: pressedColor,

View File

@ -34,7 +34,7 @@ module.exports = {
'async-validator',
'css-render',
'date-fns/esm',
'date-fns-tz/esm/getTimezoneOffset',
'date-fns-tz/getTimezoneOffset',
'evtd',
'highlight.js',
'lodash-es',