Skip to content

Commit

Permalink
refactor(VirtualList): ts & docs & test tools
Browse files Browse the repository at this point in the history
  • Loading branch information
eamonzym authored and eternalsky committed Aug 20, 2024
1 parent d9130bb commit 0d51216
Show file tree
Hide file tree
Showing 13 changed files with 185 additions and 185 deletions.
5 changes: 2 additions & 3 deletions components/cascader/menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default class CascaderMenu extends Component<CascaderMenuProps> {
useVirtual: PropTypes.bool,
children: PropTypes.node,
};
virtualEl: VirtualList | null;
virtualEl: InstanceType<typeof VirtualList> | null;
menuEl: HTMLDivElement;

componentDidMount() {
Expand All @@ -42,7 +42,6 @@ export default class CascaderMenu extends Component<CascaderMenuProps> {
}

if (useVirtual) {
// @ts-expect-error VirtualList 尚未做优化,因此无法取得 getInstance
const instance = this.virtualEl!.getInstance();
setTimeout(() => instance.scrollTo(selectedIndex), 0);
} else {
Expand Down Expand Up @@ -89,7 +88,7 @@ export default class CascaderMenu extends Component<CascaderMenuProps> {
this.menuEl = ref;
};

saveVirtualRef = (ref: VirtualList) => {
saveVirtualRef = (ref: InstanceType<typeof VirtualList>) => {
this.virtualEl = ref;
};

Expand Down
2 changes: 1 addition & 1 deletion components/tree/view/tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ export class Tree extends Component<TreeProps, TreeState> {
dragNodesKeys: Key[];

normalListRef: React.MutableRefObject<HTMLUListElement | null>;
virtualListRef: React.RefObject<VirtualList>;
virtualListRef: React.RefObject<InstanceType<typeof VirtualList>>;

constructor(props: TreeProps) {
super(props);
Expand Down
3 changes: 1 addition & 2 deletions components/virtual-list/__docs__/demo/basic/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { VirtualList } from '@alifd/next';

const dataSource = [];

const generateLi = (index = 'index') => {
const data = [];
const generateLi = (index: number) => {
if (index % 3 === 0) {
return (
<li
Expand Down
8 changes: 4 additions & 4 deletions components/virtual-list/__docs__/demo/initial-index/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import React from 'react';
import React, { type ReactElement } from 'react';
import ReactDOM from 'react-dom';
import { VirtualList } from '@alifd/next';

const dataSource = [];
const dataSource: Array<ReactElement> = [];

function generateLi(index) {
function generateLi(index: number) {
return (
<li key={`key-${index}`} style={{ lineHeight: '20px' }}>
key-{index}
</li>
);
}
function generateData(len) {
function generateData(len: number) {
for (let i = 0; i < len; i++) {
dataSource.push(generateLi(i));
}
Expand Down
19 changes: 11 additions & 8 deletions components/virtual-list/__docs__/demo/item-size-getter/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import React, { type ReactElement, createRef } from 'react';
import ReactDOM from 'react-dom';
import { VirtualList } from '@alifd/next';

const dataSource = [];
const dataSource: Array<ReactElement> = [];

function generateLi(index) {
function generateLi(index: number) {
if (index % 3 === 0) {
return (
<li
Expand All @@ -22,26 +22,29 @@ function generateLi(index) {
);
}
}
function generateData(len) {
function generateData(len: number) {
for (let i = 0; i < len; i++) {
dataSource.push(generateLi(i));
}
}

class App extends React.Component {
virtualListRef: React.RefObject<InstanceType<typeof VirtualList>> = createRef();

state = {
initial: 20,
dataSource: generateData(1000),
};

componentDidMount() {
setTimeout(() => {
const instance = this.refs.virtual.getInstance();
instance.scrollTo(50);
const instance =
this.virtualListRef.current && this.virtualListRef.current.getInstance();
instance && instance.scrollTo(50);
}, 200);
}

getHeight(index) {
getHeight(index: number) {
return index % 3 === 0 ? 30 : 20;
}

Expand All @@ -59,7 +62,7 @@ class App extends React.Component {
<br />
<div className={'virtual-box'}>
<VirtualList
ref="virtual"
ref={this.virtualListRef}
jumpIndex={this.state.initial}
itemSizeGetter={this.getHeight.bind(this)}
>
Expand Down
18 changes: 9 additions & 9 deletions components/virtual-list/__docs__/index.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@

### VirtualList

| 参数 | 说明 | 类型 | 默认值 |
| ------------- | ----------------------------------------------------------------------------------------- | -------- | ------------------------------------------------ |
| children | child node to be rendered | any | - |
| minSize | min count of items to be loaded | Number | 1 |
| pageSize | the number of items in one page | Number | 10 |
| itemsRenderer | items parent dom,by default (items, ref) => <ul ref={ref}>{items}</ul><br><br>**signature**:<br>Function() => void | Function | (items, ref) => &lt;ul ref={ref}>{items}&lt;/ul> |
| threshold | height of threshold | Number | 100 |
| itemSizeGetter | get item's height<br><br>**signature**:<br>Function() => void | Function | - |
| jumpIndex | the index you want to jump to, set itemSizeGetter if the height of items vary | Number | 0 |
| Param | Description | Type | Default Value | Required |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -------- |
| children | Children of the virtual list component | React.ReactElement \| Array\<React.ReactElement \| undefined \| null> | - | |
| minSize | The minimum number of items to be loaded | number | 1 | |
| pageSize | The number of items to be rendered in one screen | number | 10 | |
| itemsRenderer | The parent render function | (<br/> items: React.ReactNodeArray,<br/> ref: (instance: React.ReactInstance \| null) => React.ReactInstance \| null<br/> ) => React.ReactNode | `(items, ref) => <ul ref={ref}>{items}</ul>` | |
| threshold | The height of the buffer | number | 100 | |
| itemSizeGetter | The function to get the height of the item | (index?: number) => void | - | |
| jumpIndex | Set the jump position, need to set itemSizeGetter to take effect, if not set, the element is assumed to be of equal height and the height of the first element is taken as the default height | number | 0 | |
18 changes: 9 additions & 9 deletions components/virtual-list/__docs__/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@

### VirtualList

| 参数 | 说明 | 类型 | 默认值 |
| -------------- | -------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------ |
| children | 渲染的子节点 | any | - |
| minSize | 最小加载数量 | Number | 1 |
| pageSize | 一屏数量 | Number | 10 |
| itemsRenderer | 父渲染函数,默认为 (items, ref) => <ul ref={ref}>{items}</ul><br/><br/>**签名**:<br/>Function() => void | Function | (items, ref) => &lt;ul ref={ref}>{items}&lt;/ul> |
| threshold | 缓冲区高度 | Number | 100 |
| itemSizeGetter | 获取item高度的函数<br/><br/>**签名**:<br/>Function() => void | Function | - |
| jumpIndex | 设置跳转位置,需要设置 itemSizeGetter 才能生效, 不设置认为元素等高并取第一个元素高度作为默认高 | Number | 0 |
| 参数 | 说明 | 类型 | 默认值 | 是否必填 |
| -------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -------- |
| children | 渲染的子节点 | React.ReactElement \| Array\<React.ReactElement \| undefined \| null> | - | |
| minSize | 最小加载数量 | number | 1 | |
| pageSize | 一屏数量 | number | 10 | |
| itemsRenderer | 父渲染函数 | (<br/> items: React.ReactNodeArray,<br/> ref: (instance: React.ReactInstance \| null) => React.ReactInstance \| null<br/> ) => React.ReactNode | `(items, ref) => <ul ref={ref}>{items}</ul>` | |
| threshold | 缓冲区高度 | number | 100 | |
| itemSizeGetter | 获取item高度的函数 | (index?: number) => void | - | |
| jumpIndex | 设置跳转位置,需要设置 itemSizeGetter 才能生效, 不设置认为元素等高并取第一个元素高度作为默认高 | number | 0 | |
25 changes: 4 additions & 21 deletions components/virtual-list/__tests__/a11y-spec.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import React from 'react';
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import VirtualList from '../index';
import '../style';
import { unmount, testReact } from '../../util/__tests__/legacy/a11y/validate';
import { testReact } from '../../util/__tests__/a11y/validate';

Enzyme.configure({ adapter: new Adapter() });

const generateData = len => {
const generateData = (len: number) => {
const dataSource = [];

for (let i = 0; i < len; i++) {
Expand All @@ -17,25 +13,12 @@ const generateData = len => {
return dataSource;
};

/* eslint-disable no-undef, react/jsx-filename-extension */
describe('VirtualList A11y', () => {
let wrapper;

afterEach(() => {
if (wrapper) {
wrapper.unmount();
wrapper = null;
}
unmount();
});

it('should not have any violations', async () => {
wrapper = await testReact(<VirtualList>{generateData(10)}</VirtualList>);
return wrapper;
await testReact(<VirtualList>{generateData(10)}</VirtualList>);
});

it('should not have any violations for jump index', async () => {
wrapper = await testReact(<VirtualList jumpIndex={50}>{generateData(10)}</VirtualList>);
return wrapper;
await testReact(<VirtualList jumpIndex={50}>{generateData(10)}</VirtualList>);
});
});
96 changes: 45 additions & 51 deletions components/virtual-list/__tests__/index-spec.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,8 @@
import React from 'react';
import ReactDOM from 'react-dom';
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import assert from 'power-assert';
import VirtualList from '../index';
import '../style';

Enzyme.configure({ adapter: new Adapter() });

const render = element => {
let inc;
const container = document.createElement('div');
document.body.appendChild(container);
ReactDOM.render(element, container, function () {
inc = this;
});
return {
setProps: props => {
const clonedElement = React.cloneElement(element, props);
ReactDOM.render(clonedElement, container);
},
unmount: () => {
ReactDOM.unmountComponentAtNode(container);
document.body.removeChild(container);
},
instance: () => {
return inc;
},
find: selector => {
return container.querySelectorAll(selector);
},
};
};

const generateData = len => {
const generateData = (len: number) => {
const dataSource = [];

for (let i = 0; i < len; i++) {
Expand All @@ -48,15 +17,6 @@ const generateData = len => {
};

describe('VirtualList', () => {
let wrapper;

afterEach(() => {
if (wrapper) {
wrapper.unmount();
wrapper = null;
}
});

it('should render', () => {
function App() {
return (
Expand All @@ -72,8 +32,8 @@ describe('VirtualList', () => {
);
}

wrapper = render(<App />);
assert(wrapper.find('li').length === 10);
cy.mount(<App />);
cy.get('li').should('have.length', 10);
});

it('should render much more', () => {
Expand All @@ -91,11 +51,11 @@ describe('VirtualList', () => {
);
}

wrapper = render(<App />);
assert(wrapper.find('li').length < 20);
cy.mount(<App />);
cy.get('li').should('have.length.at.most', 20);
});

it('should support jumpIndex', done => {
it('should support jumpIndex', () => {
function App() {
return (
<div
Expand All @@ -117,10 +77,44 @@ describe('VirtualList', () => {
);
}

wrapper = render(<App />);
setTimeout(() => {
assert(wrapper.find('li')[0].innerText > 40);
done();
}, 100);
cy.mount(<App />);

cy.get('li')
.should('be.visible')
.first()
.invoke('text')
.then(text => {
expect(parseInt(text, 10)).to.be.above(40);
});
});

it('should render single item', () => {
const singleItem = (
<li key={`${0}-test`} style={{ lineHeight: '20px' }}>
{0}
</li>
);
function App() {
return (
<div
style={{
height: '200px',
width: '200px',
overflow: 'auto',
}}
>
<VirtualList
jumpIndex={50}
itemSizeGetter={() => {
return 20;
}}
>
{singleItem}
</VirtualList>
</div>
);
}

cy.mount(<App />);
});
});
3 changes: 3 additions & 0 deletions components/virtual-list/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import ConfigProvider from '../config-provider';
import { type VirtualListProps } from './types';
import VirtualList from './virtual-list';

export type { VirtualListProps };

export default ConfigProvider.config(VirtualList);
1 change: 1 addition & 0 deletions components/virtual-list/mobile/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-expect-error meet-react does not export VirtualList
import { VirtualList as MeetVirtualList } from '@alifd/meet-react';
import NextVirtualList from '../index';

Expand Down
Loading

0 comments on commit 0d51216

Please sign in to comment.