diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md
index 6e485c0155c..b1a602ce3f6 100644
--- a/CHANGELOG.en-US.md
+++ b/CHANGELOG.en-US.md
@@ -16,6 +16,7 @@
- Fix `n-dropdown`'s `on-update:show` prop will be triggered twice, closes [#2905](https://github.com/TuSimple/naive-ui/issues/2905).
- Fix `n-select` can select option by pressing enter after options are cleared.
- Fix `n-data-table`'s `selection` and `expand` column can't set width.
+- Fix `n-checkbox` contains selectable whitespace.
### Feats
@@ -51,6 +52,7 @@
- `n-upload` adds `directory` prop.
- `n-upload` adds `directory-dnd` prop.
- `UploadFileInfo` adds `fullPath` and `batchId` attrs.
+- `DataTableBaseColumn` adds `tree` attr, closes [#2757](https://github.com/TuSimple/naive-ui/issues/2757).
## 2.28.2
diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md
index 87a90c5ee14..6cfaefc9993 100644
--- a/CHANGELOG.zh-CN.md
+++ b/CHANGELOG.zh-CN.md
@@ -16,6 +16,7 @@
- 修复 `n-dropdown` 的 `on-update:show` 会被触发两次,关闭 [#2905](https://github.com/TuSimple/naive-ui/issues/2905)
- 修复 `n-select` 在选情清空后依然可以通过 enter 键选中值
- 修复 `n-data-table` 的 `selection` 和 `expand` 列不能设置宽度
+- 修复 `n-checkbox` 中有可以被选中的空格
### Feats
@@ -52,6 +53,7 @@
- `n-upload` 新增 `directory` 属性
- `n-upload` 新增 `directory-dnd` 属性
- `UploadFileInfo` 新增 `fullPath` 和 `batchId` 属性
+- `DataTableBaseColumn` 新增 `tree` 属性,关闭 [#2757](https://github.com/TuSimple/naive-ui/issues/2757)
## 2.28.2
diff --git a/src/checkbox/src/styles/index.cssr.ts b/src/checkbox/src/styles/index.cssr.ts
index 17021bd1504..61eb3dfd0e8 100644
--- a/src/checkbox/src/styles/index.cssr.ts
+++ b/src/checkbox/src/styles/index.cssr.ts
@@ -141,6 +141,7 @@ export default c([
width: var(--n-size);
flex-shrink: 0;
flex-grow: 0;
+ user-select: none;
`),
cB('checkbox-box', `
position: absolute;
diff --git a/src/data-table/demos/enUS/index.demo-entry.md b/src/data-table/demos/enUS/index.demo-entry.md
index f5788a23367..a9146ee915f 100644
--- a/src/data-table/demos/enUS/index.demo-entry.md
+++ b/src/data-table/demos/enUS/index.demo-entry.md
@@ -39,7 +39,7 @@ custom-style
ajax-usage
virtual
custom-filter-menu.vue
-tree
+tree.vue
flex-height
striped
simple-editable
@@ -128,6 +128,7 @@ async-expand.vue
| rowSpan | `(rowData: object, rowIndex: number) => number` | `undefined` | The row span of the cell. | |
| sortOrder | `'descend' \| 'ascend' \| false` | `undefined` | The controlled sort order of the column. If multiple columns' sortOrder is set, the first one will affect. | |
| sorter | `boolean \| function \| 'default'` | `false` | The sorter of the column. If set `'default'`, it will use a basic builtin compare function. If set to `true`, it will only display sort icon on the column, which can be used in async status. Otherwise it works like `Array.sort`'s compare function. | |
+| tree | `boolean` | `false` | Whether to show tree data expand trigger in the column. | NEXT_VERSION |
| title | `string \| (() => VNodeChild)` | `undefined` | Column title, Can be a render function. | |
| titleRowSpan | `number` | `undefined` | The number of cells occupied by the title row. | |
| type | `'selection' \| 'expand'` | `undefined` | Column type. | |
diff --git a/src/data-table/demos/enUS/tree.demo.md b/src/data-table/demos/enUS/tree.demo.md
deleted file mode 100644
index 398d6149a65..00000000000
--- a/src/data-table/demos/enUS/tree.demo.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# Tree data
-
-Set `children` in row data to show tree data. If you want to use other key to get children, you can set another `children-key`.
-
-```html
-
-```
-
-```js
-import { defineComponent } from 'vue'
-
-export default defineComponent({
- setup () {
- return {
- rowKey: (row) => row.index,
- columns: [
- {
- type: 'selection'
- },
- {
- title: 'name',
- key: 'name'
- },
- {
- title: 'index',
- key: 'index'
- }
- ],
- data: [
- {
- name: '07akioni',
- index: '07',
- children: [
- {
- name: '08akioni',
- index: '08',
- children: [
- {
- name: '09akioni',
- index: '09'
- },
- {
- name: '10akioni',
- index: '10'
- }
- ]
- }
- ]
- },
- {
- name: '11akioni',
- index: '11'
- }
- ]
- }
- }
-})
-```
diff --git a/src/data-table/demos/enUS/tree.demo.vue b/src/data-table/demos/enUS/tree.demo.vue
new file mode 100644
index 00000000000..f60643a3457
--- /dev/null
+++ b/src/data-table/demos/enUS/tree.demo.vue
@@ -0,0 +1,68 @@
+
+# Tree data
+
+Set `children` in row data to show tree data. If you want to use other key to get children, you can set another `children-key`.
+
+
+
+
+
+
+
diff --git a/src/data-table/demos/zhCN/index.demo-entry.md b/src/data-table/demos/zhCN/index.demo-entry.md
index dbbee2624be..375dcffc3fa 100644
--- a/src/data-table/demos/zhCN/index.demo-entry.md
+++ b/src/data-table/demos/zhCN/index.demo-entry.md
@@ -39,7 +39,7 @@ custom-style
ajax-usage
virtual
custom-filter-menu.vue
-tree
+tree.vue
flex-height
striped
simple-editable
@@ -132,6 +132,7 @@ height-debug
| rowSpan | `(rowData: object, rowIndex: number) => number` | `undefined` | 该列单元格的 row span | |
| sortOrder | `'descend' \| 'ascend' \| false` | `undefined` | 受控状态下表格的排序方式。如果多列都设定了有效值,那么只有第一个会生效 | |
| sorter | `boolean \| function \| 'default'` | `undefined` | 这一列的排序方法。如果设为 `'default'` 表格将会使用一个内置的排序函数;如果设为 `true`,表格将只会在这列展示一个排序图标,在异步的时候可能有用。其他情况下它工作的方式类似 `Array.sort` 的对比函数 | |
+| tree | `boolean` | `false` | 是否在这一列展示树形数据的展开按钮 | NEXT_VERSION |
| title | `string \| (() => VNodeChild)` | `undefined` | 列的 title 信息,可以是渲染函数 | |
| titleRowSpan | `number` | `undefined` | title 行所占的单元格的个数 | |
| type | `'selection' \| 'expand'` | `undefined` | 列的类型 | |
diff --git a/src/data-table/demos/zhCN/tree.demo.md b/src/data-table/demos/zhCN/tree.demo.md
deleted file mode 100644
index c48936ecfe5..00000000000
--- a/src/data-table/demos/zhCN/tree.demo.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# 树型数据
-
-在行数据中设定 `children` 来展示树型数据。如果你想用别的 key 来获取 children,那么可以设定 `children-key`。
-
-```html
-
-```
-
-```js
-import { defineComponent } from 'vue'
-
-export default defineComponent({
- setup () {
- return {
- rowKey: (row) => row.index,
- columns: [
- {
- type: 'selection'
- },
- {
- title: 'name',
- key: 'name'
- },
- {
- title: 'index',
- key: 'index'
- }
- ],
- data: [
- {
- name: '07akioni',
- index: '07',
- children: [
- {
- name: '08akioni',
- index: '08',
- children: [
- {
- name: '09akioni',
- index: '09'
- },
- {
- name: '10akioni',
- index: '10'
- }
- ]
- }
- ]
- },
- {
- name: '11akioni',
- index: '11'
- }
- ]
- }
- }
-})
-```
diff --git a/src/data-table/demos/zhCN/tree.demo.vue b/src/data-table/demos/zhCN/tree.demo.vue
new file mode 100644
index 00000000000..fcbf7d75551
--- /dev/null
+++ b/src/data-table/demos/zhCN/tree.demo.vue
@@ -0,0 +1,68 @@
+
+# 树型数据
+
+在行数据中设定 `children` 来展示树型数据。如果你想用别的 key 来获取 children,那么可以设定 `children-key`。
+
+
+
+
+
+
+
diff --git a/src/data-table/src/DataTable.tsx b/src/data-table/src/DataTable.tsx
index 27a58e2e2d3..c3b6169a1f2 100644
--- a/src/data-table/src/DataTable.tsx
+++ b/src/data-table/src/DataTable.tsx
@@ -248,7 +248,7 @@ export default defineComponent({
mergedPaginationRef,
mergedFilterStateRef,
mergedSortStateRef,
- firstContentfulColIndexRef,
+ childTriggerColIndexRef,
doUpdatePage,
doUpdateFilters,
deriveNextSorter,
@@ -318,7 +318,7 @@ export default defineComponent({
loadingKeySetRef: ref(new Set()),
slots,
indentRef: toRef(props, 'indent'),
- firstContentfulColIndexRef,
+ childTriggerColIndexRef,
bodyWidthRef,
componentId: createId(),
hoverKeyRef,
diff --git a/src/data-table/src/TableParts/Body.tsx b/src/data-table/src/TableParts/Body.tsx
index 28753f9c43b..450b5b91001 100644
--- a/src/data-table/src/TableParts/Body.tsx
+++ b/src/data-table/src/TableParts/Body.tsx
@@ -164,7 +164,7 @@ export default defineComponent({
componentId,
scrollPartRef,
mergedTableLayoutRef,
- firstContentfulColIndexRef,
+ childTriggerColIndexRef,
indentRef,
rowPropsRef,
maxHeightRef,
@@ -445,7 +445,7 @@ export default defineComponent({
mergedSortState: mergedSortStateRef,
virtualScroll: virtualScrollRef,
mergedTableLayout: mergedTableLayoutRef,
- firstContentfulColIndex: firstContentfulColIndexRef,
+ childTriggerColIndex: childTriggerColIndexRef,
indent: indentRef,
rowProps: rowPropsRef,
maxHeight: maxHeightRef,
@@ -526,7 +526,7 @@ export default defineComponent({
mergedSortState,
mergedExpandedRowKeySet,
componentId,
- firstContentfulColIndex,
+ childTriggerColIndex,
rowProps,
handleMouseenterTable,
handleMouseleaveTable,
@@ -759,7 +759,7 @@ export default defineComponent({
}
]}
>
- {hasChildren && colIndex === firstContentfulColIndex
+ {hasChildren && colIndex === childTriggerColIndex
? [
repeat(
isSummary ? 0 : rowInfo.tmNode.level,
diff --git a/src/data-table/src/interface.ts b/src/data-table/src/interface.ts
index 5b03b8d04df..56326b18a7c 100644
--- a/src/data-table/src/interface.ts
+++ b/src/data-table/src/interface.ts
@@ -97,6 +97,8 @@ export type TableBaseColumn = {
type?: never
key: ColumnKey
+ tree?: boolean
+
sorter?: boolean | Sorter | 'default'
defaultSortOrder?: SortOrder
sortOrder?: SortOrder // controlled
@@ -165,7 +167,7 @@ export type DataTableSelectionOptions = Array<
export interface DataTableInjection {
slots: Slots
indentRef: Ref
- firstContentfulColIndexRef: Ref
+ childTriggerColIndexRef: Ref
componentId: string
checkOptionsRef: Ref
hoverKeyRef: Ref
diff --git a/src/data-table/src/styles/index.cssr.ts b/src/data-table/src/styles/index.cssr.ts
index 38589609fcc..8d918b38223 100644
--- a/src/data-table/src/styles/index.cssr.ts
+++ b/src/data-table/src/styles/index.cssr.ts
@@ -101,7 +101,6 @@ export default c([
})
])
]),
- cB('data-table-expand-trigger', 'cursor: pointer;'),
cB('data-table-expand-placeholder', `
margin-right: 8px;
display: inline-block;
diff --git a/src/data-table/src/use-table-data.ts b/src/data-table/src/use-table-data.ts
index 6924901ccbd..5735700c37a 100644
--- a/src/data-table/src/use-table-data.ts
+++ b/src/data-table/src/use-table-data.ts
@@ -63,15 +63,20 @@ export function useTableData (
})
})
- const firstContentfulColIndexRef = useMemo(() => {
+ const childTriggerColIndexRef = useMemo(() => {
const { columns } = props
const { length } = columns
+ let firstContentfulColIndex: number | null = null
for (let i = 0; i < length; ++i) {
- if (!columns[i].type) {
+ const col = columns[i]
+ if (!col.type && firstContentfulColIndex === null) {
+ firstContentfulColIndex = i
+ }
+ if ('tree' in col && col.tree) {
return i
}
}
- return 0
+ return firstContentfulColIndex || 0
})
const uncontrolledFilterStateRef = ref({})
@@ -377,7 +382,7 @@ export function useTableData (
mergedSortStateRef: mergedSortStateRef,
hoverKeyRef: ref(null),
selectionColumnRef,
- firstContentfulColIndexRef,
+ childTriggerColIndexRef,
doUpdateFilters,
deriveNextSorter,
doUpdatePageSize,