@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.
Files changed (122) hide show
  1. package/components/affix/index.md +1 -0
  2. package/components/affix/index.ts +2 -0
  3. package/components/affix/useStyle.ts +38 -35
  4. package/components/datepicker/basepicker.ts +3 -3
  5. package/components/dialog/styles.ts +2 -2
  6. package/components/dropdown/useKeyboard.ts +3 -0
  7. package/components/layout/styles.ts +1 -0
  8. package/components/select/base.ts +2 -0
  9. package/components/select/base.vdt +0 -2
  10. package/components/select/demos/group.md +1 -1
  11. package/components/select/demos/virtual.md +47 -0
  12. package/components/select/group.vdt +3 -2
  13. package/components/select/index.md +1 -0
  14. package/components/select/menu.vdt +5 -4
  15. package/components/select/select.vdt +1 -1
  16. package/components/select/useFilterable.ts +2 -2
  17. package/components/select/useInput.ts +6 -1
  18. package/components/table/demos/fixHeader.md +25 -5
  19. package/components/table/demos/virtual.md +105 -0
  20. package/components/table/index.md +1 -0
  21. package/components/table/index.spec.ts +2 -1
  22. package/components/table/row.ts +2 -1
  23. package/components/table/styles.ts +4 -0
  24. package/components/table/table.ts +6 -4
  25. package/components/table/table.vdt +15 -11
  26. package/components/treeSelect/index.ts +1 -1
  27. package/components/virtualList/container.ts +36 -0
  28. package/components/virtualList/container.vdt +30 -0
  29. package/components/virtualList/demos/basic.md +67 -0
  30. package/components/virtualList/demos/combined.md +57 -0
  31. package/components/virtualList/demos/delete.md +70 -0
  32. package/components/virtualList/index.md +19 -0
  33. package/components/virtualList/index.spec.ts +263 -0
  34. package/components/virtualList/index.ts +5 -0
  35. package/components/virtualList/phantom.ts +18 -0
  36. package/components/virtualList/phantom.vdt +28 -0
  37. package/components/virtualList/rows.ts +13 -0
  38. package/components/virtualList/rows.vdt +20 -0
  39. package/components/virtualList/styles.ts +29 -0
  40. package/components/virtualList/useRows.ts +24 -0
  41. package/components/virtualList/useVirtualRows.ts +145 -0
  42. package/components/virtualList/virtual.ts +19 -0
  43. package/components/virtualList/virtual.vdt +17 -0
  44. package/components/virtualList/wrapper.ts +17 -0
  45. package/components/virtualList/wrapper.vdt +24 -0
  46. package/es/components/affix/index.d.ts +1 -0
  47. package/es/components/affix/index.js +2 -1
  48. package/es/components/affix/useStyle.js +50 -47
  49. package/es/components/datepicker/basepicker.js +3 -3
  50. package/es/components/dialog/styles.js +2 -2
  51. package/es/components/dropdown/useKeyboard.js +3 -0
  52. package/es/components/input/index.spec.js +4 -2
  53. package/es/components/layout/styles.js +1 -1
  54. package/es/components/select/base.d.ts +1 -0
  55. package/es/components/select/base.js +2 -1
  56. package/es/components/select/base.vdt.js +2 -4
  57. package/es/components/select/group.vdt.js +8 -3
  58. package/es/components/select/menu.vdt.js +12 -3
  59. package/es/components/select/select.vdt.js +2 -1
  60. package/es/components/select/useFilterable.js +7 -5
  61. package/es/components/select/useInput.js +6 -2
  62. package/es/components/table/index.spec.js +7 -6
  63. package/es/components/table/styles.js +1 -1
  64. package/es/components/table/table.d.ts +1 -0
  65. package/es/components/table/table.js +3 -2
  66. package/es/components/table/table.vdt.js +126 -114
  67. package/es/components/treeSelect/index.js +4 -3
  68. package/es/components/virtualList/container.d.ts +10 -0
  69. package/es/components/virtualList/container.js +26 -0
  70. package/es/components/virtualList/container.vdt.js +39 -0
  71. package/es/components/virtualList/index.d.ts +5 -0
  72. package/es/components/virtualList/index.js +5 -0
  73. package/es/components/virtualList/index.spec.d.ts +1 -0
  74. package/es/components/virtualList/index.spec.js +372 -0
  75. package/es/components/virtualList/phantom.d.ts +9 -0
  76. package/es/components/virtualList/phantom.js +24 -0
  77. package/es/components/virtualList/phantom.vdt.js +33 -0
  78. package/es/components/virtualList/rows.d.ts +8 -0
  79. package/es/components/virtualList/rows.js +20 -0
  80. package/es/components/virtualList/rows.vdt.js +32 -0
  81. package/es/components/virtualList/styles.d.ts +13 -0
  82. package/es/components/virtualList/styles.js +34 -0
  83. package/es/components/virtualList/useRows.d.ts +2 -0
  84. package/es/components/virtualList/useRows.js +19 -0
  85. package/es/components/virtualList/useVirtualRows.d.ts +20 -0
  86. package/es/components/virtualList/useVirtualRows.js +120 -0
  87. package/es/components/virtualList/virtual.d.ts +8 -0
  88. package/es/components/virtualList/virtual.js +15 -0
  89. package/es/components/virtualList/virtual.vdt.js +26 -0
  90. package/es/components/virtualList/wrapper.d.ts +9 -0
  91. package/es/components/virtualList/wrapper.js +24 -0
  92. package/es/components/virtualList/wrapper.vdt.js +34 -0
  93. package/es/index.d.ts +3 -2
  94. package/es/index.js +3 -2
  95. package/es/site/data/components/select/demos/virtual/index.d.ts +11 -0
  96. package/es/site/data/components/select/demos/virtual/index.js +32 -0
  97. package/es/site/data/components/select/demos/virtual/react.d.ts +11 -0
  98. package/es/site/data/components/select/demos/virtual/react.js +53 -0
  99. package/es/site/data/components/table/demos/fixHeader/index.d.ts +6 -0
  100. package/es/site/data/components/table/demos/fixHeader/index.js +14 -0
  101. package/es/site/data/components/table/demos/fixHeader/react.d.ts +6 -0
  102. package/es/site/data/components/table/demos/fixHeader/react.js +28 -11
  103. package/es/site/data/components/table/demos/virtual/index.d.ts +13 -0
  104. package/es/site/data/components/table/demos/virtual/index.js +76 -0
  105. package/es/site/data/components/table/demos/virtual/react.d.ts +14 -0
  106. package/es/site/data/components/table/demos/virtual/react.js +114 -0
  107. package/es/site/data/components/virtualList/demos/basic/index.d.ts +12 -0
  108. package/es/site/data/components/virtualList/demos/basic/index.js +42 -0
  109. package/es/site/data/components/virtualList/demos/basic/react.d.ts +12 -0
  110. package/es/site/data/components/virtualList/demos/basic/react.js +67 -0
  111. package/es/site/data/components/virtualList/demos/combined/index.d.ts +11 -0
  112. package/es/site/data/components/virtualList/demos/combined/index.js +32 -0
  113. package/es/site/data/components/virtualList/demos/combined/react.d.ts +11 -0
  114. package/es/site/data/components/virtualList/demos/combined/react.js +50 -0
  115. package/es/site/data/components/virtualList/demos/delete/index.d.ts +13 -0
  116. package/es/site/data/components/virtualList/demos/delete/index.js +51 -0
  117. package/es/site/data/components/virtualList/demos/delete/react.d.ts +13 -0
  118. package/es/site/data/components/virtualList/demos/delete/react.js +75 -0
  119. package/es/site/data/components/virtualList/index.d.ts +57 -0
  120. package/es/site/data/components/virtualList/index.js +32 -0
  121. package/index.ts +3 -2
  122. package/package.json +1 -1
@@ -13,6 +13,7 @@ sidebar: doc
13
13
  | bottom | 指定元素固定距离底部的位置 | `number` | `undefined` |
14
14
  | shouldFix | 自定义元素固定规则 | `Function` | `undefined` |
15
15
  | exclude | 排除某些固定的情况 | `Function` | `undefined` |
16
+ | disabled | 是否禁用 | `Boolean` | `false` |
16
17
 
17
18
  # 事件
18
19
 
@@ -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 (isNullOrUndefined(offsetTop) && isNullOrUndefined(offsetBottom)) {
36
- offsetTop = 0;
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
- if (!isNullOrUndefined(offsetTop)) {
40
- if (
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
- } else {
47
- const viewportHeight = document.documentElement.clientHeight;
48
- if (
49
- shouldFix && shouldFix({offsetTop, offsetBottom, viewportHeight}) ||
50
- !shouldFix && !isNullOrUndefined(offsetBottom) && viewportHeight - bottom <= offsetBottom
51
- ) {
52
- return setStyle({bottom: `${offsetBottom}px`});
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.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.Dayjs],
65
- max: [String, Date, Number, dayjs.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: '24px',
56
- tipIconLineHeight: '24px',
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,
@@ -123,6 +123,7 @@ export const makeAsideStyles = cache(function makeAsideStyles(k: string) {
123
123
  }
124
124
  .${k}-menu {
125
125
  width: auto !important;
126
+ border-right: none !important;
126
127
  }
127
128
  `
128
129
  });
@@ -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` &#124; `"left"` &#124; `"bottom"` &#124; `"right"` &#124; `"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
- keywords.set(value.trim());
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
- data={[{a: '表头固定啦'}, {a: '下拉'}, {a: 'yeah!'}]}
23
- fixHeader="100"
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> &#124; 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;
@@ -5,7 +5,8 @@ import {
5
5
  VNodeComponentClass,
6
6
  Props,
7
7
  Key,
8
- IntactDom
8
+ IntactDom,
9
+ RefObject
9
10
  } from 'intact';
10
11
  import template from './row.vdt';
11
12
  import type {TableColumnProps} from './column';
@@ -401,6 +401,10 @@ export const makeStyles = cache(function makeStyles(k: string) {
401
401
  bottom: 0;
402
402
  }
403
403
  }
404
+
405
+ .${k}-table-phantom {
406
+ position: static;
407
+ }
404
408
  `;
405
409
  });
406
410
 
@@ -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
- spreadArrowIndex?: number
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 - headerHeight;
261
+ const offsetTop = tr.offsetTop;
260
262
  const top = offsetTop - scrollTop;
261
263
  const topOneFrame = top / 60 / (100 / 1000);
262
264
  const step = () => {