Skip to content

Commit

Permalink
refactor: migrate level table virtualization
Browse files Browse the repository at this point in the history
  • Loading branch information
paring-chan committed Jun 17, 2024
1 parent ac2afd1 commit 8f31b94
Show file tree
Hide file tree
Showing 8 changed files with 394 additions and 494 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"@sveltejs/kit": "^2.0.2",
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"@tanstack/svelte-query": "^5.45.0",
"@tanstack/svelte-table": "^8.17.3",
"@tanstack/svelte-virtual": "^3.5.1",
"@types/compression": "^1.7.5",
"@types/express": "^4.17.21",
Expand Down Expand Up @@ -131,7 +132,7 @@
"*.{js,ts,jsx,tsx,svelte}": "eslint --cache --fix",
"*.{js,ts,jsx,tsx,svelte,css,scss,md}": "prettier --ignore-path .gitignore --write"
},
"packageManager": "pnpm@8.12.1",
"packageManager": "pnpm@9.3.0",
"pnpm": {
"patchedDependencies": {
"@fontsource/[email protected]": "patches/@[email protected]"
Expand Down
18 changes: 18 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

171 changes: 82 additions & 89 deletions src/components/atoms/table/TableCell.svelte
Original file line number Diff line number Diff line change
@@ -1,143 +1,136 @@
<script lang="ts">
import { getContext } from 'svelte';
import type { Readable } from 'svelte/store';
export let leftSideBorder = false;
export let border = false;
let focus = false;
let target: HTMLTableCellElement;
const focusHandle: Readable<HTMLDivElement | null> = getContext('focusHandle');
// const focusHandle: Readable<HTMLDivElement | null> = getContext('focusHandle');
const onCopy = (e: ClipboardEvent | KeyboardEvent) => {
const sel = window.getSelection();
if (sel && !sel.isCollapsed) return;
console.log(e);
e.preventDefault();
e.stopPropagation();
navigator.clipboard.writeText((<HTMLElement>e.currentTarget).innerText);
};
// const onCopy = (e: ClipboardEvent | KeyboardEvent) => {
// const sel = window.getSelection();
// if (sel && !sel.isCollapsed) return;
// console.log(e);
// e.preventDefault();
// e.stopPropagation();
// navigator.clipboard.writeText((<HTMLElement>e.currentTarget).innerText);
// };
const onFocus = () => {
focus = true;
// const onFocus = () => {
// focus = true;
if ($focusHandle) {
const handle = $focusHandle;
// if ($focusHandle) {
// const handle = $focusHandle;
const root = document.getElementById('root') as HTMLDivElement;
// const root = document.getElementById('root') as HTMLDivElement;
handle.classList.add('active');
// handle.classList.add('active');
const rect = target.getBoundingClientRect();
// const rect = target.getBoundingClientRect();
handle.style.width = rect.width + 'px';
handle.style.height = rect.height + 'px';
// handle.style.width = rect.width + 'px';
// handle.style.height = rect.height + 'px';
handle.style.left = rect.left + root.scrollLeft + 'px';
handle.style.top = rect.top + root.scrollTop + 'px';
}
};
// handle.style.left = rect.left + root.scrollLeft + 'px';
// handle.style.top = rect.top + root.scrollTop + 'px';
// }
// };
const onBlur = () => {
focus = false;
// const onBlur = () => {
// focus = false;
if ($focusHandle) {
const handle = $focusHandle;
// if ($focusHandle) {
// const handle = $focusHandle;
handle.classList.remove('active');
}
};
// handle.classList.remove('active');
// }
// };
const onKeyDown = (e: KeyboardEvent) => {
if (e.ctrlKey && e.key === 'c') onCopy(e);
else if (!e.ctrlKey && !e.altKey && !e.metaKey && !e.shiftKey) {
switch (e.key) {
case 'ArrowLeft': {
const toFocus = target.previousElementSibling as HTMLElement;
// const onKeyDown = (e: KeyboardEvent) => {
// if (e.ctrlKey && e.key === 'c') onCopy(e);
// else if (!e.ctrlKey && !e.altKey && !e.metaKey && !e.shiftKey) {
// switch (e.key) {
// case 'ArrowLeft': {
// const toFocus = target.previousElementSibling as HTMLElement;
if (!toFocus || !(toFocus instanceof HTMLTableCellElement)) break;
// if (!toFocus || !(toFocus instanceof HTMLTableCellElement)) break;
e.preventDefault();
// e.preventDefault();
toFocus.focus();
// toFocus.focus();
break;
}
case 'ArrowRight': {
const toFocus = target.nextElementSibling as HTMLElement;
// break;
// }
// case 'ArrowRight': {
// const toFocus = target.nextElementSibling as HTMLElement;
if (!toFocus || !(toFocus instanceof HTMLTableCellElement)) break;
// if (!toFocus || !(toFocus instanceof HTMLTableCellElement)) break;
e.preventDefault();
// e.preventDefault();
toFocus.focus();
// toFocus.focus();
break;
}
case 'ArrowUp': {
const targetRow = target.parentElement?.previousElementSibling;
// break;
// }
// case 'ArrowUp': {
// const targetRow = target.parentElement?.previousElementSibling;
if (!targetRow || !(targetRow instanceof HTMLTableRowElement)) break;
const targetCellIndex = target.cellIndex;
// if (!targetRow || !(targetRow instanceof HTMLTableRowElement)) break;
// const targetCellIndex = target.cellIndex;
for (let i = 0; i < targetRow.children.length; i++) {
const element = targetRow.children.item(i);
// for (let i = 0; i < targetRow.children.length; i++) {
// const element = targetRow.children.item(i);
if (!(element instanceof HTMLTableCellElement)) continue;
// if (!(element instanceof HTMLTableCellElement)) continue;
if (element.cellIndex === targetCellIndex) {
e.preventDefault();
element.focus();
break;
}
}
// if (element.cellIndex === targetCellIndex) {
// e.preventDefault();
// element.focus();
// break;
// }
// }
break;
}
case 'ArrowDown': {
const targetRow = target.parentElement?.nextElementSibling;
// break;
// }
// case 'ArrowDown': {
// const targetRow = target.parentElement?.nextElementSibling;
if (!targetRow || !(targetRow instanceof HTMLTableRowElement)) break;
const targetCellIndex = target.cellIndex;
// if (!targetRow || !(targetRow instanceof HTMLTableRowElement)) break;
// const targetCellIndex = target.cellIndex;
for (let i = 0; i < targetRow.children.length; i++) {
const element = targetRow.children.item(i);
// for (let i = 0; i < targetRow.children.length; i++) {
// const element = targetRow.children.item(i);
if (!(element instanceof HTMLTableCellElement)) continue;
// if (!(element instanceof HTMLTableCellElement)) continue;
if (element.cellIndex === targetCellIndex) {
e.preventDefault();
element.focus();
break;
}
}
// if (element.cellIndex === targetCellIndex) {
// e.preventDefault();
// element.focus();
// break;
// }
// }
break;
}
}
}
};
// break;
// }
// }
// }
// };
</script>

<td
bind:this={target}
on:focus={onFocus}
on:blur={onBlur}
on:copy={(e) => onCopy(e)}
on:keydown={onKeyDown}
class:focus
class:col-border={border}
class:left-border={leftSideBorder}
tabindex="-1"
{...$$restProps}
>
<slot />
</td>

<style lang="scss">
td {
padding: 8px;
padding-right: 8px;
padding-left: 8px;
&:focus {
outline: none;
Expand Down
Loading

0 comments on commit 8f31b94

Please sign in to comment.