Skip to content

Commit a2b6515

Browse files
authored
feat: added virtual list component (#295)
* feat: added virtual list component * chore: temp commit * chore: temp commit * chore: updated todo * chore: temp commit * chore: temp commit * chore: updated unocss * chore: added e2e test * chore: temp commit * chore: temp commit * test: added KVirtualList test * docs: added KVirtualList document * chore: updated code * ci: added e2e workflow * chore: updated lock file * chore: Delete useless files
1 parent 39c3f3c commit a2b6515

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2081
-163
lines changed

.github/workflows/release.yml

+8-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,14 @@ jobs:
3535
- name: Build
3636
run: pnpm run build
3737

38-
- name: unit test
39-
run: pnpm run test
38+
- name: Unit Test
39+
run: pnpm run test:unit
40+
41+
- name: Install Playwright
42+
run: pnpm exec playwright install
43+
44+
- name: E2E Test
45+
run: pnpm run test:e2e
4046

4147
- name: Set npmrc for components
4248
run: |

.github/workflows/unit-test.yml

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: 🌈 Unit Test
1+
name: 🌈 Unit & E2E Test
22

33
on:
44
push:
@@ -32,4 +32,10 @@ jobs:
3232
run: pnpm run build
3333

3434
- name: Unit Test
35-
run: pnpm run test
35+
run: pnpm run test:unit
36+
37+
- name: Install Playwright
38+
run: pnpm exec playwright install
39+
40+
- name: E2E Test
41+
run: pnpm run test:e2e
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`Test: KVirtualList > props: cls 1`] = `"<div class=\\"k-virtual-list k-virtual-list--test\\" style=\\"overflow-y: auto; height: inherit;\\"> <div class=\\"\\" style=\\"padding: 0px 0px 9700px;\\"><div class=\\"k-virtual-list--item\\" data-kv-key=\\"0\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"1\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"2\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"3\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"4\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"5\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"6\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"7\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"8\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"9\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"10\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"11\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"12\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"13\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"14\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"15\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"16\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"17\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"18\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"19\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"20\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"21\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"22\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"23\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"24\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"25\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"26\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"27\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"28\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"29\\"> </div></div> <div class=\\"shepherd\\" style=\\"width: 100%; height: 0px;\\"></div></div>"`;
4+
5+
exports[`Test: KVirtualList > props: isHorizontal 1`] = `"<div class=\\"k-virtual-list k-virtual-list--base\\" style=\\"overflow-y: auto; height: inherit;\\"> <div class=\\"k-virtual-list--wrapper\\" style=\\"padding: 0px 9700px 0px 0px;\\"><div class=\\"k-virtual-list--item\\" data-kv-key=\\"0\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"1\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"2\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"3\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"4\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"5\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"6\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"7\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"8\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"9\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"10\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"11\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"12\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"13\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"14\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"15\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"16\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"17\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"18\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"19\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"20\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"21\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"22\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"23\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"24\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"25\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"26\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"27\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"28\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"29\\"> </div></div> <div class=\\"shepherd\\" style=\\"width: 0px; height: 100%;\\"></div></div>"`;
6+
7+
exports[`Test: KVirtualList > props: keeps 1`] = `"<div class=\\"k-virtual-list\\" style=\\"overflow-y: auto; height: inherit;\\"> <div class=\\"\\" style=\\"padding: 0px 0px 9900px;\\"><div class=\\"k-virtual-list--item\\" data-kv-key=\\"0\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"1\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"2\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"3\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"4\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"5\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"6\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"7\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"8\\"> </div><div class=\\"k-virtual-list--item\\" data-kv-key=\\"9\\"> </div></div> <div class=\\"shepherd\\" style=\\"width: 100%; height: 0px;\\"></div></div>"`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { afterEach, expect, test, describe, beforeEach, vi } from 'vitest';
2+
import KVirtualList from '../src';
3+
let host: HTMLElement;
4+
const dataList: any = [];
5+
for (let i = 0; i < 1000; i++) {
6+
dataList.push({ id: i, label: `this is item ${i}` });
7+
}
8+
const initHost = () => {
9+
host = document.createElement('div');
10+
host.setAttribute('id', 'host');
11+
host.style.height = '50px';
12+
host.style.overflow = 'auto';
13+
document.body.appendChild(host);
14+
};
15+
beforeEach(() => {
16+
initHost();
17+
vi.useFakeTimers();
18+
});
19+
afterEach(() => {
20+
host.remove();
21+
vi.restoreAllMocks();
22+
});
23+
24+
describe('Test: KVirtualList', () => {
25+
vi.mock('svelte', async () => {
26+
const actual = (await vi.importActual('svelte')) as object;
27+
return {
28+
...actual,
29+
// @ts-ignore
30+
onMount: (await import('svelte/internal')).onMount,
31+
// @ts-ignore
32+
onDestroy: (await import('svelte/internal')).onDestroy,
33+
// @ts-ignore
34+
afterUpdate: (await import('svelte/internal')).afterUpdate
35+
};
36+
});
37+
38+
test('props: cls', async () => {
39+
const instance = new KVirtualList({
40+
target: host,
41+
props: {
42+
data: dataList,
43+
cls: 'k-virtual-list--test'
44+
}
45+
});
46+
expect(instance).toBeTruthy();
47+
expect((host as HTMLElement)!.innerHTML.includes('k-virtual-list--test')).toBeTruthy();
48+
expect(host.innerHTML).matchSnapshot();
49+
});
50+
51+
test('props: keeps', async () => {
52+
const instance = new KVirtualList({
53+
target: host,
54+
props: {
55+
data: dataList,
56+
keeps: 10
57+
}
58+
});
59+
expect(instance).toBeTruthy();
60+
expect(host.querySelectorAll('.k-virtual-list--item').length === 10).toBeTruthy();
61+
expect(host.innerHTML).matchSnapshot();
62+
});
63+
64+
test('props: isHorizontal', async () => {
65+
const instance = new KVirtualList({
66+
target: host,
67+
props: {
68+
data: dataList,
69+
isHorizontal: true
70+
}
71+
});
72+
expect(instance).toBeTruthy();
73+
expect(host.querySelectorAll('.k-virtual-list--item').length === 30).toBeTruthy();
74+
expect((host as HTMLElement)!.innerHTML.includes('k-virtual-list--base')).toBeTruthy();
75+
expect((host as HTMLElement)!.innerHTML.includes('k-virtual-list--wrapper')).toBeTruthy();
76+
expect(host.innerHTML).matchSnapshot();
77+
});
78+
});

components/VirtualList/package.json

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"name": "@ikun-ui/virtual-list",
3+
"version": "0.0.9",
4+
"type": "module",
5+
"main": "./src/index.ts",
6+
"types": "src/index.ts",
7+
"svelte": "dist/index.js",
8+
"keywords": [
9+
"svelte",
10+
"svelte3",
11+
"web component",
12+
"component",
13+
"react",
14+
"vue",
15+
"svelte-kit",
16+
"dx"
17+
],
18+
"scripts": {
19+
"build": "npm run build:js && npm run build:svelte",
20+
"build:js": "tsc -p . --outDir dist/ --rootDir src/",
21+
"build:svelte": "svelte-strip strip src/ dist",
22+
"publish:npm": "pnpm publish --no-git-checks --access public"
23+
},
24+
"publishConfig": {
25+
"access": "public",
26+
"main": "dist/index.js",
27+
"module": "dist/index.js",
28+
"svelte": "dist/index.js",
29+
"types": "src/index.ts"
30+
},
31+
"dependencies": {
32+
"@ikun-ui/icon": "workspace:*",
33+
"@ikun-ui/utils": "workspace:*",
34+
"baiwusanyu-utils": "^1.0.16",
35+
"clsx": "^2.0.0"
36+
},
37+
"devDependencies": {
38+
"@tsconfig/svelte": "^5.0.2",
39+
"svelte-strip": "^2.0.0",
40+
"tslib": "^2.6.2",
41+
"typescript": "^5.2.2"
42+
}
43+
}

0 commit comments

Comments
 (0)