mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-02-17 13:20:52 +08:00
refactor(tree): show-line
This commit is contained in:
parent
99b7d83586
commit
1d5907052b
@ -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']
|
||||
: []
|
||||
}
|
||||
}
|
||||
|
@ -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']
|
||||
: []
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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'//"
|
||||
})
|
||||
})()
|
||||
|
@ -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>
|
||||
)
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -314,12 +314,7 @@ export default defineComponent({
|
||||
visibility: 'collapse'
|
||||
}}
|
||||
>
|
||||
{repeat(
|
||||
compitableColumn * 2,
|
||||
<td
|
||||
class={`${mergedClsPrefix}-descriptions-table-content`}
|
||||
/>
|
||||
)}
|
||||
{repeat(compitableColumn * 2, <td />)}
|
||||
</tr>
|
||||
)}
|
||||
{rows}
|
||||
|
@ -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()
|
||||
})
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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'
|
||||
|
@ -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'
|
||||
|
||||
|
@ -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. | |
|
||||
|
@ -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` | 节点完成拖拽动作后的回调函数 | |
|
||||
|
@ -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}
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user