Skip to content

Commit

Permalink
feat(tree-select): component (#211)
Browse files Browse the repository at this point in the history
* site: tree-select route

* refactor(internal-selection): remove useless remote prop & on-delete-last-option

* refactor(dropdown, popselect): set slots stable mark from true to 1

* fix(scrollbar): attributes applied multiple times

* wip(tree-select): add exports

* fix(tree): misses `on-update-expanded-keys`, `on-update-selected-keys`, `on-update-checked-keys` prop

* feat(tree): support keyboard operations

* feat(tree): scroll with keyboard target node

* fix(tree): `selected-keys` prop influences original array

* feat(tree): pending on selected node at first

* feat(tree): follow tree-select's pending status

* feat(tree): `internalCheckboxFocusable` prop

* refactor(tree): split treeMate to displayTreeMate & dataTreeMate to work with tree-select

* fix(tree): scrollbar won't sync in virtual scroll mode

* feat(tree-select)

* docs: changelog

* docs(tree-select)

* feat(tree-select): stricter type

* fix: typo

* fix(select): input blinks in filterable mode when click at menu and input has value

* fix(tree): multiple line style

* docs(tree-select)

* refactor(tree-select): disable tree expand animation on tree select

* feat(tree-select): change expanded keys on filter

* chore(tree): add comment about animation

* chore

* feat(tree-select): close on single select

* fix(base-selection): input has useless empty row in multiple filterable mode

* docs(tree-select): add clearable in filterable demo
  • Loading branch information
07akioni authored Jun 21, 2021
1 parent 00ff423 commit 6ee3896
Show file tree
Hide file tree
Showing 58 changed files with 2,905 additions and 248 deletions.
10 changes: 6 additions & 4 deletions CHANGELOG.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
### Feats

- `n-dropdown` add `on-clickoutside` prop, closes [#123](https://github.com/TuSimple/naive-ui/issues/123).

## Pending

- `n-menu` add `renderLabel` prop, closes [#84](https://github.com/TuSimple/naive-ui/issues/84)
- `n-menu` add `render-label` prop, closes [#84](https://github.com/TuSimple/naive-ui/issues/84)
- `n-tree` supports keyboard operations.
- Add `n-tree-select` component.

### Fixes

- Fix `n-tree` drag over leaf node causes error, closes [#200](https://github.com/TuSimple/naive-ui/issues/200).
- Fix `n-tree` misses `on-update-expanded-keys`, `on-update-selected-keys`, `on-update-checked-keys` prop.
- Fix `n-tree`'s `selected-keys` prop influences original array.
- Fix `n-select`'s input has useless empty row in multiple filterable mode.

## 2.12.2 (2021-06-19)

Expand Down
10 changes: 6 additions & 4 deletions CHANGELOG.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
### Feats

- `n-dropdown` 新增 `on-clickoutside` 属性,关闭 [#123](https://github.com/TuSimple/naive-ui/issues/123)

## Pending

- `n-menu` 新增 `renderLabel` 属性,关闭 [#84](https://github.com/TuSimple/naive-ui/issues/84)
- `n-menu` 新增 `render-label` 属性,关闭 [#84](https://github.com/TuSimple/naive-ui/issues/84)
- `n-tree` 支持键盘操作
- 新增 `n-tree-select` 组件

### Fixes

- 修复 `n-tree` 缺少 `on-update-expanded-keys``on-update-selected-keys``on-update-checked-keys` 属性
- 修复 `n-tree` 拖拽悬浮叶节点报错,关闭 [#200](https://github.com/TuSimple/naive-ui/issues/200)
- 修复 `n-tree``selected-keys` 属性影响原数组
- 修复 `n-select` 砸爱 multiple filterable 模式下输入框有无用的空行

## 2.12.2 (2021-06-19)

Expand Down
10 changes: 10 additions & 0 deletions demo/routes/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,11 @@ export const enComponentRoutes = [
path: 'color-picker',
component: () =>
import('../../src/color-picker/demos/enUS/index.demo-entry.md')
},
{
path: 'tree-select',
component: () =>
import('../../src/tree-select/demos/enUS/index.demo-entry.md')
}
]

Expand Down Expand Up @@ -775,6 +780,11 @@ export const zhComponentRoutes = [
path: 'color-picker',
component: () =>
import('../../src/color-picker/demos/zhCN/index.demo-entry.md')
},
{
path: 'tree-select',
component: () =>
import('../../src/tree-select/demos/zhCN/index.demo-entry.md')
}
]

Expand Down
6 changes: 6 additions & 0 deletions demo/store/menu-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,12 @@ export function createComponentMenuOptions ({ lang, theme, mode }) {
enSuffix: true,
path: '/transfer'
},
{
en: 'Tree Select',
zh: '树型选择',
enSuffix: true,
path: '/tree-select'
},
{
en: 'Upload',
zh: '上传',
Expand Down
17 changes: 17 additions & 0 deletions design-notes/todo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# TODO

## Tree

- (moderate) Use set to check if node is checked or selected internally

## DataTable

- (moderate) Add fast path for virtual mode if no cell crosses rows

## Tabs

- (moderate) Add iOS styled tabs

## TreeSelect

- (moderate) Async
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
"superagent": "^6.1.0",
"typescript": "^4.3.2",
"vite": "^2.1.3",
"vue": "^3.0.10",
"vue": "^3.1.1",
"vue-router": "^4.0.5"
},
"peerDependencies": {
Expand Down
26 changes: 19 additions & 7 deletions src/_internal/selection/src/Selection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ export default defineComponent({
},
multiple: Boolean,
filterable: Boolean,
remote: Boolean,
clearable: Boolean,
disabled: Boolean,
size: {
Expand All @@ -80,7 +79,6 @@ export default defineComponent({
onBlur: Function as PropType<(e: FocusEvent) => void>,
onFocus: Function as PropType<(e: FocusEvent) => void>,
onDeleteOption: Function,
onDeleteLastOption: Function,
maxTagCount: [String, Number] as PropType<number | 'responsive'>,
onClear: Function as PropType<(e: MouseEvent) => void>,
onPatternInput: Function as PropType<(e: InputEvent) => void>
Expand All @@ -95,6 +93,7 @@ export default defineComponent({
const counterRef = ref<TagRef | null>(null)
const counterWrapperRef = ref<HTMLElement | null>(null)
const overflowRef = ref<VOverflowInst | null>(null)
const inputTagElRef = ref<HTMLElement | null>(null)

const showTagsPopoverRef = ref<boolean>(false)
const patternInputFocusedRef = ref(false)
Expand Down Expand Up @@ -143,6 +142,17 @@ export default defineComponent({
}
}
}
function hideInputTag (): void {
const { value: inputTagEl } = inputTagElRef
if (inputTagEl) inputTagEl.style.display = 'none'
}
function showInputTag (): void {
const { value: inputTagEl } = inputTagElRef
if (inputTagEl) inputTagEl.style.display = 'inline-block'
}
watch(toRef(props, 'active'), (value) => {
if (!value) hideInputTag()
})
watch(toRef(props, 'pattern'), () => {
if (props.multiple) {
void nextTick(syncMirrorWidth)
Expand All @@ -160,10 +170,6 @@ export default defineComponent({
const { onDeleteOption } = props
if (onDeleteOption) onDeleteOption(value)
}
function doDeleteLastOption (): void {
const { onDeleteLastOption } = props
if (onDeleteLastOption) onDeleteLastOption()
}
function doClear (e: MouseEvent): void {
const { onClear } = props
if (onClear) onClear(e)
Expand Down Expand Up @@ -204,7 +210,10 @@ export default defineComponent({
function handlePatternKeyDown (e: KeyboardEvent): void {
if (e.code === 'Backspace') {
if (!props.pattern.length) {
doDeleteLastOption()
const { selectedOptions } = props
if (selectedOptions?.length) {
handleDeleteOption(selectedOptions[selectedOptions.length - 1])
}
}
}
}
Expand Down Expand Up @@ -250,6 +259,7 @@ export default defineComponent({
function focusInput (): void {
const { value: patternInputEl } = patternInputRef
if (patternInputEl) {
showInputTag()
patternInputEl.focus()
}
}
Expand Down Expand Up @@ -319,6 +329,7 @@ export default defineComponent({
singleElRef,
patternInputWrapperRef,
overflowRef,
inputTagElRef,
handleMouseDown,
handleFocusin,
handleClear,
Expand Down Expand Up @@ -493,6 +504,7 @@ export default defineComponent({
const input = filterable ? (
<div
class={`${clsPrefix}-base-selection-input-tag`}
ref="inputTagElRef"
key="__input-tag__"
>
<input
Expand Down
2 changes: 1 addition & 1 deletion src/_internal/selection/src/styles/index.cssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ export default c([
height: calc(var(--height) - 6px);
line-height: calc(var(--height) - 6px);
outline: none;
display: inline-block;
display: none;
position: relative;
margin-bottom: 3px;
max-width: 100%;
Expand Down
3 changes: 2 additions & 1 deletion src/_utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ export {
getVNodeChildren,
keysOf,
render,
getFirstSlotVNode
getFirstSlotVNode,
createDataKey
} from './vue'
export type { MaybeArray } from './vue'
export { warn, warnOnce, throwError, smallerSize, largerSize } from './naive'
Expand Down
3 changes: 3 additions & 0 deletions src/_utils/vue/create-data-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function createDataKey (key: string | number): string {
return typeof key === 'string' ? `s-${key}` : `n-${key}`
}
1 change: 1 addition & 0 deletions src/_utils/vue/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export { call } from './call'
export { keysOf } from './keysOf'
export { render } from './render'
export { getFirstSlotVNode } from './get-first-slot-vnode'
export { createDataKey } from './create-data-key'
export type { MaybeArray } from './call'
12 changes: 0 additions & 12 deletions src/cascader/src/Cascader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -609,16 +609,6 @@ export default defineComponent({
}
}
}
function handleDeleteLastOption (): void {
if (props.multiple) {
const { value: mergedValue } = mergedValueRef
if (Array.isArray(mergedValue)) {
const newValue = Array.from(mergedValue)
newValue.pop()
doUpdateValue(newValue)
}
}
}
function handlePatternInput (e: InputEvent): void {
patternRef.value = (e.target as HTMLInputElement).value
}
Expand Down Expand Up @@ -716,7 +706,6 @@ export default defineComponent({
handleTriggerBlur,
handleTriggerClick,
handleClear,
handleDeleteLastOption,
handleDeleteOption,
handlePatternInput,
handleKeyDown,
Expand Down Expand Up @@ -799,7 +788,6 @@ export default defineComponent({
onBlur={this.handleTriggerBlur}
onClick={this.handleTriggerClick}
onClear={this.handleClear}
onDeleteLastOption={this.handleDeleteLastOption}
onDeleteOption={this.handleDeleteOption}
onPatternInput={this.handlePatternInput}
onKeydown={this.handleKeyDown}
Expand Down
1 change: 1 addition & 0 deletions src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export * from './timeline'
export * from './tooltip'
export * from './transfer'
export * from './tree'
export * from './tree-select'
export * from './typography'
export * from './upload'

Expand Down
6 changes: 4 additions & 2 deletions src/config-provider/src/internal-interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ import type { TimePickerTheme } from '../../time-picker/styles'
import type { TimelineTheme } from '../../timeline/styles'
import type { TooltipTheme } from '../../tooltip/styles'
import type { TransferTheme } from '../../transfer/styles'
import type { TypographyTheme } from '../../typography/styles'
import type { TreeTheme } from '../../tree/styles'
import type { TreeSelectTheme } from '../../tree-select/styles'
import type { TypographyTheme } from '../../typography/styles'
import type { UploadTheme } from '../../upload/styles'
import type { InternalSelectMenuTheme } from '../../_internal/select-menu/styles'
import type { InternalSelectionTheme } from '../../_internal/selection/styles'
Expand Down Expand Up @@ -152,8 +153,9 @@ export interface GlobalThemeWithoutCommon {
Timeline?: TimelineTheme
Tooltip?: TooltipTheme
Transfer?: TransferTheme
Typography?: TypographyTheme
Tree?: TreeTheme
TreeSelect?: TreeSelectTheme
Typography?: TypographyTheme
Upload?: UploadTheme
// internal
InternalSelectMenu?: InternalSelectMenuTheme
Expand Down
2 changes: 1 addition & 1 deletion src/data-table/src/TableParts/Body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ export default defineComponent({
verticalRailStyle={{ zIndex: 3 }}
xScrollable
onScroll={virtualScroll ? undefined : this.handleTableBodyScroll}
privateOnSetSL={setHeaderScrollLeft}
internalOnUpdateScrollLeft={setHeaderScrollLeft}
onResize={onResize}
>
{{
Expand Down
2 changes: 1 addition & 1 deletion src/dropdown/src/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ export default defineComponent({
<NPopover {...keep(this.$props, popoverPropKeys)} {...popoverProps}>
{{
trigger: this.$slots.default,
_: true
_: 1
}}
</NPopover>
)
Expand Down
2 changes: 1 addition & 1 deletion src/menu/demos/enUS/render-label.demo.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Render Label

The `renderLabel` can be used to batch render menu options.
The `render-label` can be used to batch render menu options.

```html
<n-menu :options="menuOptions" :render-label="renderMenuLabel" />
Expand Down
2 changes: 1 addition & 1 deletion src/menu/demos/zhCN/render-label.demo.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 批量处理菜单渲染

使用 `renderLabel` 可以批量控制菜单的选项渲染。
使用 `render-label` 可以批量控制菜单的选项渲染。

```html
<n-menu :options="menuOptions" :render-label="renderMenuLabel" />
Expand Down
2 changes: 1 addition & 1 deletion src/popselect/src/Popselect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export default defineComponent({
<NPopover {...omit(this.$props, panelPropKeys)} {...popoverProps}>
{{
trigger: this.$slots.default,
_: true
_: 1
}}
</NPopover>
)
Expand Down
5 changes: 4 additions & 1 deletion src/scrollbar/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export { default as NScrollbar } from './src/ScrollBar'
export {
default as NScrollbar,
XScrollbar as NxScrollbar
} from './src/ScrollBar'
export type { ScrollbarInst, ScrollbarProps } from './src/ScrollBar'
Loading

0 comments on commit 6ee3896

Please sign in to comment.