@king-design/intact 3.5.0-beta.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/affix/index.md +1 -0
- package/components/affix/index.ts +2 -0
- package/components/affix/useStyle.ts +38 -35
- package/components/datepicker/basepicker.ts +3 -3
- package/components/dialog/styles.ts +2 -2
- package/components/dropdown/useKeyboard.ts +3 -0
- package/components/layout/styles.ts +1 -0
- package/components/select/base.ts +2 -0
- package/components/select/base.vdt +0 -2
- package/components/select/demos/group.md +1 -1
- package/components/select/demos/virtual.md +47 -0
- package/components/select/group.vdt +3 -2
- package/components/select/index.md +1 -0
- package/components/select/menu.vdt +5 -4
- package/components/select/select.vdt +1 -1
- package/components/select/useFilterable.ts +2 -2
- package/components/select/useInput.ts +6 -1
- package/components/table/demos/fixHeader.md +25 -5
- package/components/table/demos/virtual.md +105 -0
- package/components/table/index.md +1 -0
- package/components/table/index.spec.ts +2 -1
- package/components/table/row.ts +2 -1
- package/components/table/styles.ts +4 -0
- package/components/table/table.ts +6 -4
- package/components/table/table.vdt +15 -11
- package/components/treeSelect/index.ts +1 -1
- package/components/virtualList/container.ts +36 -0
- package/components/virtualList/container.vdt +30 -0
- package/components/virtualList/demos/basic.md +67 -0
- package/components/virtualList/demos/combined.md +57 -0
- package/components/virtualList/demos/delete.md +70 -0
- package/components/virtualList/index.md +19 -0
- package/components/virtualList/index.spec.ts +263 -0
- package/components/virtualList/index.ts +5 -0
- package/components/virtualList/phantom.ts +18 -0
- package/components/virtualList/phantom.vdt +28 -0
- package/components/virtualList/rows.ts +13 -0
- package/components/virtualList/rows.vdt +20 -0
- package/components/virtualList/styles.ts +29 -0
- package/components/virtualList/useRows.ts +24 -0
- package/components/virtualList/useVirtualRows.ts +145 -0
- package/components/virtualList/virtual.ts +19 -0
- package/components/virtualList/virtual.vdt +17 -0
- package/components/virtualList/wrapper.ts +17 -0
- package/components/virtualList/wrapper.vdt +24 -0
- package/es/components/affix/index.d.ts +1 -0
- package/es/components/affix/index.js +2 -1
- package/es/components/affix/useStyle.js +50 -47
- package/es/components/datepicker/basepicker.js +3 -3
- package/es/components/dialog/styles.js +2 -2
- package/es/components/dropdown/useKeyboard.js +3 -0
- package/es/components/input/index.spec.js +4 -2
- package/es/components/layout/styles.js +1 -1
- package/es/components/select/base.d.ts +1 -0
- package/es/components/select/base.js +2 -1
- package/es/components/select/base.vdt.js +2 -4
- package/es/components/select/group.vdt.js +8 -3
- package/es/components/select/menu.vdt.js +12 -3
- package/es/components/select/select.vdt.js +2 -1
- package/es/components/select/useFilterable.js +7 -5
- package/es/components/select/useInput.js +6 -2
- package/es/components/table/index.spec.js +7 -6
- package/es/components/table/styles.js +1 -1
- package/es/components/table/table.d.ts +1 -0
- package/es/components/table/table.js +3 -2
- package/es/components/table/table.vdt.js +126 -114
- package/es/components/treeSelect/index.js +4 -3
- package/es/components/virtualList/container.d.ts +10 -0
- package/es/components/virtualList/container.js +26 -0
- package/es/components/virtualList/container.vdt.js +39 -0
- package/es/components/virtualList/index.d.ts +5 -0
- package/es/components/virtualList/index.js +5 -0
- package/es/components/virtualList/index.spec.d.ts +1 -0
- package/es/components/virtualList/index.spec.js +372 -0
- package/es/components/virtualList/phantom.d.ts +9 -0
- package/es/components/virtualList/phantom.js +24 -0
- package/es/components/virtualList/phantom.vdt.js +33 -0
- package/es/components/virtualList/rows.d.ts +8 -0
- package/es/components/virtualList/rows.js +20 -0
- package/es/components/virtualList/rows.vdt.js +32 -0
- package/es/components/virtualList/styles.d.ts +13 -0
- package/es/components/virtualList/styles.js +34 -0
- package/es/components/virtualList/useRows.d.ts +2 -0
- package/es/components/virtualList/useRows.js +19 -0
- package/es/components/virtualList/useVirtualRows.d.ts +20 -0
- package/es/components/virtualList/useVirtualRows.js +120 -0
- package/es/components/virtualList/virtual.d.ts +8 -0
- package/es/components/virtualList/virtual.js +15 -0
- package/es/components/virtualList/virtual.vdt.js +26 -0
- package/es/components/virtualList/wrapper.d.ts +9 -0
- package/es/components/virtualList/wrapper.js +24 -0
- package/es/components/virtualList/wrapper.vdt.js +34 -0
- package/es/index.d.ts +3 -2
- package/es/index.js +3 -2
- package/es/site/data/components/select/demos/virtual/index.d.ts +11 -0
- package/es/site/data/components/select/demos/virtual/index.js +32 -0
- package/es/site/data/components/select/demos/virtual/react.d.ts +11 -0
- package/es/site/data/components/select/demos/virtual/react.js +53 -0
- package/es/site/data/components/table/demos/fixHeader/index.d.ts +6 -0
- package/es/site/data/components/table/demos/fixHeader/index.js +14 -0
- package/es/site/data/components/table/demos/fixHeader/react.d.ts +6 -0
- package/es/site/data/components/table/demos/fixHeader/react.js +28 -11
- package/es/site/data/components/table/demos/virtual/index.d.ts +13 -0
- package/es/site/data/components/table/demos/virtual/index.js +76 -0
- package/es/site/data/components/table/demos/virtual/react.d.ts +14 -0
- package/es/site/data/components/table/demos/virtual/react.js +114 -0
- package/es/site/data/components/virtualList/demos/basic/index.d.ts +12 -0
- package/es/site/data/components/virtualList/demos/basic/index.js +42 -0
- package/es/site/data/components/virtualList/demos/basic/react.d.ts +12 -0
- package/es/site/data/components/virtualList/demos/basic/react.js +67 -0
- package/es/site/data/components/virtualList/demos/combined/index.d.ts +11 -0
- package/es/site/data/components/virtualList/demos/combined/index.js +32 -0
- package/es/site/data/components/virtualList/demos/combined/react.d.ts +11 -0
- package/es/site/data/components/virtualList/demos/combined/react.js +50 -0
- package/es/site/data/components/virtualList/demos/delete/index.d.ts +13 -0
- package/es/site/data/components/virtualList/demos/delete/index.js +51 -0
- package/es/site/data/components/virtualList/demos/delete/react.d.ts +13 -0
- package/es/site/data/components/virtualList/demos/delete/react.js +75 -0
- package/es/site/data/components/virtualList/index.d.ts +57 -0
- package/es/site/data/components/virtualList/index.js +32 -0
- package/index.ts +3 -2
- package/package.json +1 -1
|
@@ -8,6 +8,7 @@ export interface AffixProps {
|
|
|
8
8
|
bottom?: number
|
|
9
9
|
exclude?: (data: ExcludeParam) => boolean
|
|
10
10
|
shouldFix?: (data: ShouldFixParam) => boolean
|
|
11
|
+
disabled?: boolean
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export interface AffixEvents {
|
|
@@ -34,6 +35,7 @@ const typeDefs: Required<TypeDefs<AffixProps>> = {
|
|
|
34
35
|
bottom: Number,
|
|
35
36
|
exclude: Function,
|
|
36
37
|
shouldFix: Function,
|
|
38
|
+
disabled: Boolean,
|
|
37
39
|
};
|
|
38
40
|
|
|
39
41
|
export class Affix extends Component<AffixProps, AffixEvents> {
|
|
@@ -12,44 +12,47 @@ export function useStyle(elementRef: RefObject<HTMLElement>) {
|
|
|
12
12
|
let ro: ResizeObserver | null = null;
|
|
13
13
|
|
|
14
14
|
function genStyle() {
|
|
15
|
-
let {top: offsetTop, bottom: offsetBottom, exclude, shouldFix} = instance.get();
|
|
16
|
-
const {top, bottom, width, height} = elementRef.value!.getBoundingClientRect();
|
|
17
|
-
|
|
18
|
-
const setStyle = (styles: Record<string, string>) => {
|
|
19
|
-
if (!exclude || exclude && !exclude({
|
|
20
|
-
offsetTop, offsetBottom, top, bottom, width, height
|
|
21
|
-
})) {
|
|
22
|
-
style.set({
|
|
23
|
-
position: 'fixed',
|
|
24
|
-
width: `${width}px`,
|
|
25
|
-
...styles,
|
|
26
|
-
});
|
|
27
|
-
containerStyle.set({
|
|
28
|
-
height: `${height}px`,
|
|
29
|
-
});
|
|
30
|
-
} else {
|
|
31
|
-
resetStyle();
|
|
32
|
-
}
|
|
33
|
-
};
|
|
15
|
+
let {top: offsetTop, bottom: offsetBottom, exclude, shouldFix, disabled} = instance.get();
|
|
34
16
|
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
|
|
17
|
+
if (!disabled) {
|
|
18
|
+
const {top, bottom, width, height} = elementRef.value!.getBoundingClientRect();
|
|
19
|
+
|
|
20
|
+
const setStyle = (styles: Record<string, string>) => {
|
|
21
|
+
if (!exclude || exclude && !exclude({
|
|
22
|
+
offsetTop, offsetBottom, top, bottom, width, height
|
|
23
|
+
})) {
|
|
24
|
+
style.set({
|
|
25
|
+
position: 'fixed',
|
|
26
|
+
width: `${width}px`,
|
|
27
|
+
...styles,
|
|
28
|
+
});
|
|
29
|
+
containerStyle.set({
|
|
30
|
+
height: `${height}px`,
|
|
31
|
+
});
|
|
32
|
+
} else {
|
|
33
|
+
resetStyle();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
38
36
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
shouldFix && shouldFix({offsetTop, offsetBottom}) ||
|
|
42
|
-
!shouldFix && top < offsetTop
|
|
43
|
-
) {
|
|
44
|
-
return setStyle({top: `${offsetTop}px`});
|
|
37
|
+
if (isNullOrUndefined(offsetTop) && isNullOrUndefined(offsetBottom)) {
|
|
38
|
+
offsetTop = 0;
|
|
45
39
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
40
|
+
|
|
41
|
+
if (!isNullOrUndefined(offsetTop)) {
|
|
42
|
+
if (
|
|
43
|
+
shouldFix && shouldFix({offsetTop, offsetBottom}) ||
|
|
44
|
+
!shouldFix && top < offsetTop
|
|
45
|
+
) {
|
|
46
|
+
return setStyle({top: `${offsetTop}px`});
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
const viewportHeight = document.documentElement.clientHeight;
|
|
50
|
+
if (
|
|
51
|
+
shouldFix && shouldFix({offsetTop, offsetBottom, viewportHeight}) ||
|
|
52
|
+
!shouldFix && !isNullOrUndefined(offsetBottom) && viewportHeight - bottom <= offsetBottom
|
|
53
|
+
) {
|
|
54
|
+
return setStyle({bottom: `${offsetBottom}px`});
|
|
55
|
+
}
|
|
53
56
|
}
|
|
54
57
|
}
|
|
55
58
|
|
|
@@ -56,13 +56,13 @@ export type Value = string | Date | number | Dayjs;
|
|
|
56
56
|
|
|
57
57
|
const typeDefs: Required<TypeDefs<BasePickerProps<Value>>> = {
|
|
58
58
|
...BaseSelect.typeDefs,
|
|
59
|
-
value: [String, Array, Date, Number, dayjs
|
|
59
|
+
value: [String, Array, Date, Number, dayjs],
|
|
60
60
|
range: Boolean,
|
|
61
61
|
format: String,
|
|
62
62
|
valueFormat: String,
|
|
63
63
|
showFormat: String,
|
|
64
|
-
min: [String, Date, Number, dayjs
|
|
65
|
-
max: [String, Date, Number, dayjs
|
|
64
|
+
min: [String, Date, Number, dayjs],
|
|
65
|
+
max: [String, Date, Number, dayjs],
|
|
66
66
|
disabledDate: Function,
|
|
67
67
|
};
|
|
68
68
|
|
|
@@ -52,8 +52,8 @@ const defaults = {
|
|
|
52
52
|
padding: `0 24px`,
|
|
53
53
|
bodyMarginTop: `-25px`,
|
|
54
54
|
tipIconMarginBottom: '10px',
|
|
55
|
-
tipIconFontSize: '
|
|
56
|
-
tipIconLineHeight: '
|
|
55
|
+
tipIconFontSize: '40px',
|
|
56
|
+
tipIconLineHeight: '40px',
|
|
57
57
|
|
|
58
58
|
// with title
|
|
59
59
|
titleFontWeight: '500',
|
|
@@ -140,6 +140,7 @@ export function useMenuKeyboard() {
|
|
|
140
140
|
const item = items[focusIndex];
|
|
141
141
|
|
|
142
142
|
if (focusIndex > -1 && item) {
|
|
143
|
+
// TODO(find bug)
|
|
143
144
|
itemEvents.get(item)!.onFocusout();
|
|
144
145
|
focusIndex = -1;
|
|
145
146
|
}
|
|
@@ -203,6 +204,8 @@ export function useItemKeyboard(itemEvents: Omit<ItemEvents, 'onFocusin' | 'onFo
|
|
|
203
204
|
onMouseLeave(e: MouseEvent) {
|
|
204
205
|
instance.trigger('mouseleave', e);
|
|
205
206
|
keyboard.reset();
|
|
207
|
+
// If it is a virtual item, it needs to be reset manually because the DOM is reused.
|
|
208
|
+
isFocus.set(false);
|
|
206
209
|
},
|
|
207
210
|
|
|
208
211
|
isFocus,
|
|
@@ -42,6 +42,7 @@ export interface BaseSelectProps<V, Multipe extends boolean = boolean, Attach =
|
|
|
42
42
|
flat?: boolean
|
|
43
43
|
nowrap?: boolean
|
|
44
44
|
draggable?: boolean
|
|
45
|
+
virtual?: boolean
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
export interface BaseSelectEvents {
|
|
@@ -78,6 +79,7 @@ const typeDefs: Required<TypeDefs<BaseSelectProps<any>>> = {
|
|
|
78
79
|
flat: Boolean,
|
|
79
80
|
nowrap: Boolean,
|
|
80
81
|
draggable: Boolean,
|
|
82
|
+
virtual: Boolean,
|
|
81
83
|
};
|
|
82
84
|
|
|
83
85
|
const defaults = (): Partial<BaseSelectProps<any>> => ({
|
|
@@ -54,7 +54,6 @@ const filterInput = <Input v-if={filterable}
|
|
|
54
54
|
readonly={!show}
|
|
55
55
|
waveDisabled={true}
|
|
56
56
|
flat={flat}
|
|
57
|
-
frozenOnInput
|
|
58
57
|
/>
|
|
59
58
|
|
|
60
59
|
<ErrorContext.Consumer defaultValue={false}>
|
|
@@ -96,7 +95,6 @@ const filterInput = <Input v-if={filterable}
|
|
|
96
95
|
readonly={!show}
|
|
97
96
|
waveDisabled={true}
|
|
98
97
|
flat={flat}
|
|
99
|
-
frozenOnInput
|
|
100
98
|
/>
|
|
101
99
|
<div class={`${k}-select-placeholder c-ellipsis`}
|
|
102
100
|
v-else-if={!filterable && !hasValue}
|
|
@@ -29,7 +29,7 @@ import {Select, Option, OptionGroup} from 'kpc';
|
|
|
29
29
|
<Option value="Tuesday">星期二</Option>
|
|
30
30
|
<Option value="Wednesday">星期三</Option>
|
|
31
31
|
<Option value="Thursday">星期四</Option>
|
|
32
|
-
<Option value="Friday">星期五</Option>
|
|
32
|
+
<Option value="Friday">星期五</Option>
|
|
33
33
|
</OptionGroup>
|
|
34
34
|
<OptionGroup>
|
|
35
35
|
<b:label><i class="ion-wineglass"></i>休息日</b:label>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 虚拟列表
|
|
3
|
+
order: 14
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`virtual`属性开启虚拟列表
|
|
7
|
+
|
|
8
|
+
```vdt
|
|
9
|
+
import {Select, Option} from 'kpc';
|
|
10
|
+
|
|
11
|
+
<div>
|
|
12
|
+
<Select v-model="day" virtual>
|
|
13
|
+
<Option v-for={this.get('data')} value={$value.value}>
|
|
14
|
+
{$value.label}
|
|
15
|
+
</Option>
|
|
16
|
+
</Select>
|
|
17
|
+
</div>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
interface Props {
|
|
22
|
+
day?: string | null
|
|
23
|
+
data: any[]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default class extends Component {
|
|
27
|
+
static template = template;
|
|
28
|
+
|
|
29
|
+
static defaults() {
|
|
30
|
+
return {
|
|
31
|
+
day: null,
|
|
32
|
+
data: []
|
|
33
|
+
} as Props;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
init() {
|
|
37
|
+
const arr = [];
|
|
38
|
+
for (let index = 0; index < 10000; index++) {
|
|
39
|
+
arr.push({
|
|
40
|
+
value: index,
|
|
41
|
+
label: `测试${index}`
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
this.set({data: arr});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {makeGroupStyles} from './styles';
|
|
2
2
|
import {getRestProps} from '../utils';
|
|
3
|
+
import { VirtualList } from '../virtualList';
|
|
3
4
|
|
|
4
5
|
const {children, label, className} = this.get();
|
|
5
|
-
const {card} = this.select.get();
|
|
6
|
+
const {card, virtual} = this.select.get();
|
|
6
7
|
const { k } = this.config;
|
|
7
8
|
|
|
8
9
|
const classNameObj = {
|
|
@@ -15,5 +16,5 @@ const classNameObj = {
|
|
|
15
16
|
<div class={`${k}-select-group-label`} v-if={!card}>
|
|
16
17
|
<b:label>{label}</b:label>
|
|
17
18
|
</div>
|
|
18
|
-
{children}
|
|
19
|
+
<VirtualList disabled={!virtual}>{children}</VirtualList>
|
|
19
20
|
</div>
|
|
@@ -35,6 +35,7 @@ sidebar: doc
|
|
|
35
35
|
| position | 菜单弹出的位置,默认与触发器左侧对齐向下偏移`8px`的地方 | `Position` | `"left"` | `"bottom"` | `"right"` | `"top"` | `{my: 'left top+8', 'left bottom'}` |
|
|
36
36
|
| flat | 是否展示扁平样式 | `boolean` | `false` |
|
|
37
37
|
| draggable | 多选值是否支持拖动排序 | `boolean` | `false` |
|
|
38
|
+
| virtual | 是否开启虚拟列表 | `boolean` | `false` |
|
|
38
39
|
|
|
39
40
|
```ts
|
|
40
41
|
type Position = {
|
|
@@ -9,9 +9,10 @@ import {Button} from '../button';
|
|
|
9
9
|
import {Icon} from '../icon';
|
|
10
10
|
import {context} from './useSearchable';
|
|
11
11
|
import {Tabs, Tab} from '../tabs';
|
|
12
|
+
import { VirtualList } from '../virtualList';
|
|
12
13
|
|
|
13
14
|
let {children, className} = this.get();
|
|
14
|
-
const {card, searchable, multiple} = this.select.get();
|
|
15
|
+
const {card, searchable, multiple, virtual} = this.select.get();
|
|
15
16
|
const { k } = this.config;
|
|
16
17
|
|
|
17
18
|
const classNameObj = {
|
|
@@ -38,14 +39,14 @@ if (card) {
|
|
|
38
39
|
{group}
|
|
39
40
|
</template>
|
|
40
41
|
);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (isEmptyChildren(children)) {
|
|
42
|
+
} else if (isEmptyChildren(children)) {
|
|
44
43
|
children = (
|
|
45
44
|
<div v-else class={`${k}-select-empty`}>
|
|
46
45
|
{_$('无数据')}
|
|
47
46
|
</div>
|
|
48
47
|
);
|
|
48
|
+
} else {
|
|
49
|
+
children = <VirtualList style={{maxHeight: '200px'}} disabled={!virtual}>{children}</VirtualList>
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
if (searchable) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {SelectMenu} from './menu';
|
|
2
2
|
import {isEmptyChildren} from '../utils';
|
|
3
3
|
|
|
4
|
-
const {className, children, autoDisableArrow, disabled, multiple, value} = this.get();
|
|
4
|
+
const {className, children, autoDisableArrow, disabled, multiple, value, virtual} = this.get();
|
|
5
5
|
const {getCreatedVNode, filter} = this.filterable;
|
|
6
6
|
const options = filter(children);
|
|
7
7
|
const allShowedValues = this.getAllShowedValues(options);
|
|
@@ -22,7 +22,7 @@ export function useFilterable(keywords: State<string>) {
|
|
|
22
22
|
|
|
23
23
|
function getCreatedVNode(children: (VNode | string | number)[]) {
|
|
24
24
|
const {creatable, filterable} = component.get();
|
|
25
|
-
const _keywords = keywords.value;
|
|
25
|
+
const _keywords = keywords.value.trim();
|
|
26
26
|
if (creatable && filterable && _keywords) {
|
|
27
27
|
if (!children.find(vNode => {
|
|
28
28
|
// TODO: create Option for OptionGroup
|
|
@@ -66,7 +66,7 @@ export function useFilterable(keywords: State<string>) {
|
|
|
66
66
|
vNode.key = value;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
if (filter!(keywords.value, vNode.props)) {
|
|
69
|
+
if (filter!(keywords.value.trim(), vNode.props)) {
|
|
70
70
|
_children.push(vNode);
|
|
71
71
|
}
|
|
72
72
|
} else if (isComponentVNode(vNode, OptionGroup)) {
|
|
@@ -23,7 +23,12 @@ export function useInput(resetKeywords: (keywords: State<string>) => void) {
|
|
|
23
23
|
const inputRef = createRef<Input>();
|
|
24
24
|
|
|
25
25
|
function onInput(value: string) {
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* can not trim the keywords, otherwise we can not input spaces
|
|
28
|
+
* https://github.com/ksc-fe/kpc/issues/1047
|
|
29
|
+
*/
|
|
30
|
+
// keywords.set(value.trim());
|
|
31
|
+
keywords.set(value);
|
|
27
32
|
|
|
28
33
|
const dropdown = component.dropdownRef.value!;
|
|
29
34
|
// the position may be flip, and the select input height may change height too,
|
|
@@ -18,11 +18,9 @@ import {Table, TableColumn} from 'kpc';
|
|
|
18
18
|
>
|
|
19
19
|
<TableColumn key="a" title="100px" />
|
|
20
20
|
</Table>
|
|
21
|
-
<Table
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
>
|
|
25
|
-
<TableColumn key="a" title="100px" />
|
|
21
|
+
<Table data={this.get('data')} fixHeader="300">
|
|
22
|
+
<TableColumn title="Name" key="name" fixed="left" />
|
|
23
|
+
<TableColumn title="IP" key="ip" />
|
|
26
24
|
</Table>
|
|
27
25
|
</div>
|
|
28
26
|
```
|
|
@@ -30,7 +28,29 @@ import {Table, TableColumn} from 'kpc';
|
|
|
30
28
|
```styl
|
|
31
29
|
.wrapper
|
|
32
30
|
display flex
|
|
31
|
+
align-items flex-start
|
|
33
32
|
.k-table
|
|
34
33
|
margin-left: 20px
|
|
35
34
|
flex: 1
|
|
36
35
|
```
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import {range, bind} from 'kpc/components/utils';
|
|
39
|
+
|
|
40
|
+
const data = range(1, 100).map(item => {
|
|
41
|
+
return {
|
|
42
|
+
name: 'name ' + item,
|
|
43
|
+
ip: '127.0.0.' + item
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export default class extends Component {
|
|
48
|
+
static template = template;
|
|
49
|
+
|
|
50
|
+
static defaults() {
|
|
51
|
+
return {
|
|
52
|
+
data: data
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 虚拟表格
|
|
3
|
+
order: 36
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
添加`virtual`属性,并且指定滚动元素的高度(通过`fixHeader`指定)即可开启虚拟滚动模式
|
|
7
|
+
|
|
8
|
+
> 虚拟列表内部需要根据rowKey做缓存,不指定rowKey可能存在奇怪问题(默认rowKey为索引值)
|
|
9
|
+
|
|
10
|
+
```vdt
|
|
11
|
+
import {Table, TableColumn} from 'kpc';
|
|
12
|
+
|
|
13
|
+
<div>
|
|
14
|
+
<h4>表格</h4>
|
|
15
|
+
<Table data={this.get('data')} virtual fixHeader="400">
|
|
16
|
+
<TableColumn key="a" title="Title 1" minWidth={200}/>
|
|
17
|
+
<TableColumn key="b" title="Title 2" minWidth={300} />
|
|
18
|
+
</Table>
|
|
19
|
+
<h4>树形表格</h4>
|
|
20
|
+
<Table ref="table" data={this.get('variableHeightData')} virtual rowKey={data => data.name} fixHeader="400">
|
|
21
|
+
<TableColumn key="name" title="Title 1" minWidth={200}/>
|
|
22
|
+
<TableColumn key="size" title="Title 2" minWidth={300} />
|
|
23
|
+
</Table>
|
|
24
|
+
</div>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```styl
|
|
28
|
+
.no-data-template
|
|
29
|
+
display: flex
|
|
30
|
+
gap: 10px
|
|
31
|
+
.icon
|
|
32
|
+
vertical-align middle
|
|
33
|
+
margin-right 10px
|
|
34
|
+
cursor pointer
|
|
35
|
+
.name
|
|
36
|
+
vertical-align middle
|
|
37
|
+
.expand
|
|
38
|
+
padding 16px
|
|
39
|
+
```
|
|
40
|
+
```ts
|
|
41
|
+
interface Props {
|
|
42
|
+
data: any[]
|
|
43
|
+
variableHeightData: any[]
|
|
44
|
+
}
|
|
45
|
+
import {range, bind} from 'kpc/components/utils';
|
|
46
|
+
export default class extends Component {
|
|
47
|
+
static template = template;
|
|
48
|
+
static defaults() {
|
|
49
|
+
return {
|
|
50
|
+
data: [],
|
|
51
|
+
variableHeightData: []
|
|
52
|
+
} as Props;
|
|
53
|
+
}
|
|
54
|
+
init() {
|
|
55
|
+
const arr = [];
|
|
56
|
+
for (let index = 0; index < 10000; index++) {
|
|
57
|
+
arr.push({
|
|
58
|
+
a: `Cell ${index}-1`,
|
|
59
|
+
b: `Cell ${index}-2`
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
this.set({data: arr});
|
|
63
|
+
|
|
64
|
+
const generateTreeData = (count: number) => {
|
|
65
|
+
const result = [];
|
|
66
|
+
|
|
67
|
+
for (let i = 0; i < count; i++) {
|
|
68
|
+
const hasChildren = Math.random() > 0.5;
|
|
69
|
+
const node: any = {
|
|
70
|
+
name: `Node-${i}`,
|
|
71
|
+
key: `node-${i}`,
|
|
72
|
+
size: Math.floor(Math.random() * 100),
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
if (hasChildren) {
|
|
76
|
+
node.children = Array.from({ length: 2 }, (_, j) => ({
|
|
77
|
+
name: `Node-${i}-${j}`,
|
|
78
|
+
key: `node-${i}-${j}`,
|
|
79
|
+
size: Math.floor(Math.random() * 100),
|
|
80
|
+
children: Math.random() > 0.5 ? [
|
|
81
|
+
{
|
|
82
|
+
name: `Node-${i}-${j}-0`,
|
|
83
|
+
key: `node-${i}-${j}-0`,
|
|
84
|
+
size: Math.floor(Math.random() * 100),
|
|
85
|
+
}
|
|
86
|
+
] : undefined
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
result.push(node);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return result;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const data = generateTreeData(10000);
|
|
97
|
+
this.set({ variableHeightData: data });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@bind
|
|
101
|
+
scrollToRowByKey() {
|
|
102
|
+
this.refs.table.scrollToRowByKey('Node-400');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
@@ -48,6 +48,7 @@ sidebar: doc
|
|
|
48
48
|
| fixFooter | `table`给定需要固定高度时,自定义footer固定 | `boolean` | `false` |
|
|
49
49
|
| load | 指定异步加载节点数据的函数,该函数通过`Promise`返回数组来添加子节点数据 | <code>(node: any) => Promise<void> | void</code> | `undefined` |
|
|
50
50
|
| spreadArrowIndex | 指定树形表格展开Icon的所在列,默认在第一列 | `number` | `0` |
|
|
51
|
+
| virtual | 是否开启虚拟列表 | `boolean` | `false` |
|
|
51
52
|
|
|
52
53
|
```ts
|
|
53
54
|
import {Props} from 'intact';
|
|
@@ -489,13 +489,14 @@ describe('Table', () => {
|
|
|
489
489
|
|
|
490
490
|
it('tree', async () => {
|
|
491
491
|
const [instance, element] = mount(TreeDemo);
|
|
492
|
-
const table = instance.$lastInput!.children as Table;
|
|
492
|
+
const table = (instance.$lastInput!.children as any)[0].children as Table;
|
|
493
493
|
|
|
494
494
|
// check all
|
|
495
495
|
const checkbox = element.querySelector('.k-checkbox') as HTMLElement;
|
|
496
496
|
checkbox.click();
|
|
497
497
|
await wait();
|
|
498
498
|
expect(element.innerHTML).to.matchSnapshot();
|
|
499
|
+
debugger;
|
|
499
500
|
expect(table.getCheckedData()).to.have.lengthOf(8);
|
|
500
501
|
|
|
501
502
|
const arrow = element.querySelector('.k-table-arrow') as HTMLElement;
|
package/components/table/row.ts
CHANGED
|
@@ -65,8 +65,9 @@ export interface TableProps<
|
|
|
65
65
|
animation?: boolean | [boolean, boolean]
|
|
66
66
|
hideHeader?: boolean
|
|
67
67
|
pagination?: boolean | PaginationProps
|
|
68
|
-
fixFooter?: boolean
|
|
69
|
-
|
|
68
|
+
fixFooter?: boolean
|
|
69
|
+
virtual?: boolean
|
|
70
|
+
spreadArrowIndex?: number;
|
|
70
71
|
load?: (value: T) => Promise<void> | void
|
|
71
72
|
}
|
|
72
73
|
|
|
@@ -135,6 +136,7 @@ const typeDefs: Required<TypeDefs<TableProps<unknown>>> = {
|
|
|
135
136
|
hideHeader: Boolean,
|
|
136
137
|
pagination: [Boolean, Object],
|
|
137
138
|
fixFooter: Boolean,
|
|
139
|
+
virtual: Boolean,
|
|
138
140
|
spreadArrowIndex: Number,
|
|
139
141
|
load: Function,
|
|
140
142
|
};
|
|
@@ -254,9 +256,9 @@ export class Table<
|
|
|
254
256
|
// we can not use scrollIntoView with smooth, because it can only operate one element
|
|
255
257
|
// at the same time
|
|
256
258
|
// elem.scrollIntoView({behavior: 'smooth'});
|
|
257
|
-
const headerHeight = (scrollElement.querySelector('thead') as HTMLElement).offsetHeight;
|
|
259
|
+
// const headerHeight = (scrollElement.querySelector('thead') as HTMLElement).offsetHeight;
|
|
258
260
|
let scrollTop = scrollElement.scrollTop;
|
|
259
|
-
const offsetTop = tr.offsetTop
|
|
261
|
+
const offsetTop = tr.offsetTop;
|
|
260
262
|
const top = offsetTop - scrollTop;
|
|
261
263
|
const topOneFrame = top / 60 / (100 / 1000);
|
|
262
264
|
const step = () => {
|