update options table with virtual list for performance boost
This commit is contained in:
parent
5c842c9f3d
commit
c8e88d33d3
6
package-lock.json
generated
6
package-lock.json
generated
@ -53,6 +53,7 @@
|
|||||||
"svelte-range-slider-pips": "^2.3.1",
|
"svelte-range-slider-pips": "^2.3.1",
|
||||||
"svelte-sonner": "^0.3.27",
|
"svelte-sonner": "^0.3.27",
|
||||||
"svelte-tags-input": "^6.0.0",
|
"svelte-tags-input": "^6.0.0",
|
||||||
|
"svelte-tiny-virtual-list": "^2.1.2",
|
||||||
"tailwind-merge": "^2.4.0",
|
"tailwind-merge": "^2.4.0",
|
||||||
"tailwind-variants": "^0.2.1",
|
"tailwind-variants": "^0.2.1",
|
||||||
"tslib": "^2.6.2",
|
"tslib": "^2.6.2",
|
||||||
@ -7640,6 +7641,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/svelte-tags-input/-/svelte-tags-input-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/svelte-tags-input/-/svelte-tags-input-6.0.1.tgz",
|
||||||
"integrity": "sha512-3X5qomFSXe6E8H7Lq0oce7096tr6u06pWvTNgNoeNVIXCrRLxRYOk4Ujkte7z5WaAit47EUsZZP1TSJ2HR9ixA=="
|
"integrity": "sha512-3X5qomFSXe6E8H7Lq0oce7096tr6u06pWvTNgNoeNVIXCrRLxRYOk4Ujkte7z5WaAit47EUsZZP1TSJ2HR9ixA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/svelte-tiny-virtual-list": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/svelte-tiny-virtual-list/-/svelte-tiny-virtual-list-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-jeP/WMvgFUR4mYXHGPiCexjX5DuzSO+3xzHNhxfcsFyy+uYPtnqI5UGb383swpzQAyXB0OBqYfzpYihD/5gxnA=="
|
||||||
|
},
|
||||||
"node_modules/svelte-writable-derived": {
|
"node_modules/svelte-writable-derived": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/svelte-writable-derived/-/svelte-writable-derived-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/svelte-writable-derived/-/svelte-writable-derived-3.1.1.tgz",
|
||||||
|
|||||||
@ -95,6 +95,7 @@
|
|||||||
"svelte-range-slider-pips": "^2.3.1",
|
"svelte-range-slider-pips": "^2.3.1",
|
||||||
"svelte-sonner": "^0.3.27",
|
"svelte-sonner": "^0.3.27",
|
||||||
"svelte-tags-input": "^6.0.0",
|
"svelte-tags-input": "^6.0.0",
|
||||||
|
"svelte-tiny-virtual-list": "^2.1.2",
|
||||||
"tailwind-merge": "^2.4.0",
|
"tailwind-merge": "^2.4.0",
|
||||||
"tailwind-variants": "^0.2.1",
|
"tailwind-variants": "^0.2.1",
|
||||||
"tslib": "^2.6.2",
|
"tslib": "^2.6.2",
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
import { abbreviateNumber } from '$lib/utils';
|
import { abbreviateNumber } from '$lib/utils';
|
||||||
import { onMount, onDestroy } from 'svelte';
|
import { onMount, onDestroy } from 'svelte';
|
||||||
import toast from 'svelte-french-toast';
|
import toast from 'svelte-french-toast';
|
||||||
|
import VirtualList from 'svelte-tiny-virtual-list';
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
@ -22,7 +22,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let optionList = []
|
|
||||||
let rawData = [];
|
let rawData = [];
|
||||||
let filterList = [];
|
let filterList = [];
|
||||||
|
|
||||||
@ -159,11 +158,9 @@ function handleViewData(optionData) {
|
|||||||
rawData = listFilteredData;
|
rawData = listFilteredData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update optionList and notFound status
|
|
||||||
if (rawData?.length !== 0 && newIncomingData === true) {
|
if (rawData?.length !== 0 && newIncomingData === true) {
|
||||||
notFound = false;
|
notFound = false;
|
||||||
newIncomingData = false;
|
newIncomingData = false;
|
||||||
optionList = rawData?.slice(0, 50);
|
|
||||||
} else if (!newIncomingData) {
|
} else if (!newIncomingData) {
|
||||||
notFound = false;
|
notFound = false;
|
||||||
newIncomingData = false;
|
newIncomingData = false;
|
||||||
@ -171,7 +168,6 @@ function handleViewData(optionData) {
|
|||||||
notFound = true;
|
notFound = true;
|
||||||
newIncomingData = false;
|
newIncomingData = false;
|
||||||
rawData = data?.getOptionsFlowFeed ?? [];
|
rawData = data?.getOptionsFlowFeed ?? [];
|
||||||
optionList = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateStats(rawData);
|
calculateStats(rawData);
|
||||||
@ -206,7 +202,6 @@ function handleViewData(optionData) {
|
|||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
audio = new Audio(notifySound);
|
audio = new Audio(notifySound);
|
||||||
rawData = data?.getOptionsFlowFeed;
|
rawData = data?.getOptionsFlowFeed;
|
||||||
optionList = rawData?.slice(0, 100);
|
|
||||||
calculateStats(rawData);
|
calculateStats(rawData);
|
||||||
isLoaded = true;
|
isLoaded = true;
|
||||||
|
|
||||||
@ -214,32 +209,11 @@ function handleViewData(optionData) {
|
|||||||
await websocketRealtimeData();
|
await websocketRealtimeData();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data?.user?.tier === 'Pro') {
|
|
||||||
const attachScrollListener = () => {
|
|
||||||
if (scrollContainer) {
|
|
||||||
scrollContainer.addEventListener('scroll', handleScroll);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!attachScrollListener()) {
|
|
||||||
const observer = new MutationObserver(() => {
|
|
||||||
if (attachScrollListener()) {
|
|
||||||
observer.disconnect();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
observer.observe(document.body, { childList: true, subtree: true });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(async() => {
|
onDestroy(async() => {
|
||||||
|
|
||||||
if (scrollContainer && data?.user?.tier === 'Pro') {
|
|
||||||
scrollContainer.removeEventListener('scroll', handleScroll);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (typeof window !== 'undefined')
|
if (typeof window !== 'undefined')
|
||||||
{
|
{
|
||||||
@ -252,18 +226,7 @@ onDestroy(async() => {
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
async function handleScroll() {
|
|
||||||
if (!scrollContainer) return;
|
|
||||||
const scrollThreshold = scrollContainer.scrollHeight * 0.8; // 80% of the div height
|
|
||||||
const isBottom = scrollContainer.scrollTop + scrollContainer.clientHeight >= scrollThreshold;
|
|
||||||
if (isBottom && optionList?.length !== rawData?.length) {
|
|
||||||
const nextIndex = optionList?.length;
|
|
||||||
const filteredNewResults = rawData?.slice(nextIndex, nextIndex + 25);
|
|
||||||
optionList = [...optionList, ...filteredNewResults];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async function assetSelector(symbol, assetType)
|
async function assetSelector(symbol, assetType)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -287,8 +250,8 @@ onDestroy(async() => {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
function calculateStats(optionList) {
|
function calculateStats(data) {
|
||||||
const { callVolumeSum, putVolumeSum, bullishCount, bearishCount } = optionList?.reduce((acc, item) => {
|
const { callVolumeSum, putVolumeSum, bullishCount, bearishCount } = data?.reduce((acc, item) => {
|
||||||
const volume = parseInt(item?.volume);
|
const volume = parseInt(item?.volume);
|
||||||
|
|
||||||
if (item?.put_call === "Calls") {
|
if (item?.put_call === "Calls") {
|
||||||
@ -414,19 +377,15 @@ function handleInput(event) {
|
|||||||
if (newData?.length !== 0) {
|
if (newData?.length !== 0) {
|
||||||
rawData = newData;
|
rawData = newData;
|
||||||
|
|
||||||
optionList = [...rawData?.slice(0, 100)];
|
|
||||||
|
|
||||||
|
|
||||||
notFound = false;
|
notFound = false;
|
||||||
} else {
|
} else {
|
||||||
notFound = true;
|
notFound = true;
|
||||||
rawData = data?.getOptionsFlowFeed;
|
rawData = data?.getOptionsFlowFeed;
|
||||||
optionList = rawData?.slice(0, 100);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
notFound = false;
|
notFound = false;
|
||||||
rawData = data?.getOptionsFlowFeed;
|
rawData = data?.getOptionsFlowFeed;
|
||||||
optionList = rawData?.slice(0, 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateStats(rawData);
|
calculateStats(rawData);
|
||||||
@ -487,24 +446,23 @@ $: {
|
|||||||
const newData = filterExpiringSoon(rawData, Math.max(...filterList));
|
const newData = filterExpiringSoon(rawData, Math.max(...filterList));
|
||||||
if (newData?.length !== 0) {
|
if (newData?.length !== 0) {
|
||||||
rawData = newData;
|
rawData = newData;
|
||||||
optionList = rawData?.slice(0, 50);
|
|
||||||
notFound = false;
|
notFound = false;
|
||||||
} else {
|
} else {
|
||||||
notFound = true;
|
notFound = true;
|
||||||
rawData = data?.getOptionsFlowFeed;
|
rawData = data?.getOptionsFlowFeed;
|
||||||
optionList = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (filterQuery?.length === 0) {
|
else if (filterQuery?.length === 0) {
|
||||||
rawData = data?.getOptionsFlowFeed;
|
rawData = data?.getOptionsFlowFeed;
|
||||||
optionList = rawData?.slice(0,100);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
calculateStats(rawData);
|
calculateStats(rawData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:options immutable={true} />
|
<svelte:options immutable={true} />
|
||||||
@ -551,7 +509,7 @@ $: {
|
|||||||
|
|
||||||
{#if !$isOpen}
|
{#if !$isOpen}
|
||||||
<div class="text-white text-sm sm:text-md italic text-center sm:text-start w-full ml-2 mb-3">
|
<div class="text-white text-sm sm:text-md italic text-center sm:text-start w-full ml-2 mb-3">
|
||||||
Live flow of {new Date(optionList?.at(0)?.date ?? null)?.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })} (NYSE Time)
|
Live flow of {new Date(rawData?.at(0)?.date ?? null)?.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })} (NYSE Time)
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
@ -829,95 +787,92 @@ $: {
|
|||||||
|
|
||||||
|
|
||||||
<!-- Content area -->
|
<!-- Content area -->
|
||||||
<div bind:this={scrollContainer} class="mt-4 w-full overflow-x-auto overflow-y-auto h-[900px] rounded-lg">
|
<div class="mt-4 w-full overflow-x-auto overflow-y-auto h-[900px] rounded-lg">
|
||||||
<table class="table table-pin-cols table-pin-rows table-sm table-compact">
|
<div class="table-container">
|
||||||
<thead>
|
<div class="table">
|
||||||
<tr class="">
|
<VirtualList
|
||||||
<td class="bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Time</td>
|
width="100%"
|
||||||
<th class="bg-[#161618] font-bold text-slate-300 text-xs text-start uppercase">Symbol</th>
|
height={900}
|
||||||
<td class="bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Expiry</td>
|
itemCount={rawData.length}
|
||||||
<td class="bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Strike</td>
|
itemSize={40}
|
||||||
<td class="bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">C/P</td>
|
>
|
||||||
<td class="bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Sent.</td>
|
<div slot="header" class="tr th sticky z-40 top-0">
|
||||||
<td class="bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Spot</td>
|
<div class="td bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Time</div>
|
||||||
<td class="bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Price</td>
|
<td class="td bg-[#161618] font-bold text-slate-300 text-xs text-start uppercase">Symbol</td>
|
||||||
<td class="bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Prem.</td>
|
<div class="td bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Expiry</div>
|
||||||
<td class="bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Type</td>
|
<div class="td bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Strike</div>
|
||||||
<td class="bg-[#161618] text-slate-300 font-bold text-xs text-end uppercase">Vol</td>
|
<div class="td bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">C/P</div>
|
||||||
<td class="bg-[#161618] text-slate-300 font-bold text-xs text-end uppercase">OI</td>
|
<div class="td bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Sent.</div>
|
||||||
</tr>
|
<div class="td bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Spot</div>
|
||||||
</thead>
|
<div class="td bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Price</div>
|
||||||
<tbody>
|
<div class="td bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Prem.</div>
|
||||||
{#each optionList as item,index}
|
<div class="td bg-[#161618] text-slate-300 font-bold text-xs text-start uppercase">Type</div>
|
||||||
<!-- row -->
|
<div class="td bg-[#161618] text-slate-300 font-bold text-xs text-end uppercase">Vol</div>
|
||||||
<tr on:click={() => handleViewData(item)} class="w-full odd:bg-[#27272A] cursor-pointer {index+1 === optionList?.length && data?.user?.tier !== 'Pro' ? 'opacity-[0.1]' : ''}">
|
<div class="td bg-[#161618] text-slate-300 font-bold text-xs text-end uppercase">OI</div>
|
||||||
|
</div>
|
||||||
<td class="text-white pb-3 text-xs sm:text-sm text-start">
|
|
||||||
{formatTime(item?.time)}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<th on:click|stopPropagation={() => assetSelector(item?.ticker, item?.assetType)} class="{index % 2 ? 'bg-[#09090B]' : 'bg-[#27272A]'} text-blue-400 text-start font-normal">
|
|
||||||
{item?.ticker}
|
|
||||||
</th>
|
|
||||||
|
|
||||||
<td class="text-white text-start">
|
|
||||||
{reformatDate(item?.date_expiration)}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="text-white text-start">
|
|
||||||
{item?.strike_price}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="{item?.put_call === 'Calls' ? 'text-[#00FC50]' : 'text-[#FC2120]'} text-start">
|
|
||||||
{item?.put_call}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="{item?.sentiment === 'Bullish' ? 'text-[#00FC50]' : item?.sentiment === 'Bearish' ? 'text-[#FC2120]' : 'text-[#C6A755]'} text-start">
|
|
||||||
{item?.sentiment}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="text-sm text-start text-white">
|
|
||||||
{item?.underlying_price}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="text-sm text-start text-white">
|
|
||||||
{item?.price}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="text-sm text-start font-semibold {item?.put_call === 'Puts' ? 'text-[#CB281C]' : 'text-[#0FB307]'} ">
|
|
||||||
{abbreviateNumber(item?.cost_basis)}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="text-sm text-start {item?.type === 'Sweep' ? 'text-[#C6A755]' : 'text-[#976DB7]'}">
|
|
||||||
{item?.type}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<td class="text-white text-end">
|
|
||||||
{new Intl.NumberFormat("en", {
|
|
||||||
minimumFractionDigits: 0,
|
|
||||||
maximumFractionDigits: 0
|
|
||||||
}).format(item?.volume)}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="text-white text-end">
|
|
||||||
{new Intl.NumberFormat("en", {
|
|
||||||
minimumFractionDigits: 0,
|
|
||||||
maximumFractionDigits: 0
|
|
||||||
}).format(item?.open_interest)}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
|
|
||||||
|
<div on:click={() => handleViewData(rawData[index])} slot="item" let:index let:style {style} class="tr cursor-pointer">
|
||||||
|
|
||||||
</tr>
|
|
||||||
|
<div style="justify-content: center;" class="td text-white pb-3 text-sm text-start">
|
||||||
|
{formatTime(rawData[index]?.time)}
|
||||||
{/each}
|
</div>
|
||||||
</tbody>
|
|
||||||
</table>
|
<div on:click|stopPropagation={() => assetSelector(rawData[index]?.ticker, rawData[index]?.assetType)} style="justify-content: center;" class="td text-sm text-blue-400 font-normal">
|
||||||
|
{rawData[index]?.ticker}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="justify-content: center;" class="td text-sm text-white text-start">
|
||||||
|
{reformatDate(rawData[index]?.date_expiration)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="justify-content: center;" class="td text-sm text-white text-start">
|
||||||
|
{rawData[index]?.strike_price}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="justify-content: center;" class="td text-sm {rawData[index]?.put_call === 'Calls' ? 'text-[#00FC50]' : 'text-[#FC2120]'} text-start">
|
||||||
|
{rawData[index]?.put_call}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="justify-content: center;" class="td text-sm {rawData[index]?.sentiment === 'Bullish' ? 'text-[#00FC50]' : rawData[index]?.sentiment === 'Bearish' ? 'text-[#FC2120]' : 'text-[#C6A755]'} text-start">
|
||||||
|
{rawData[index]?.sentiment}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="justify-content: center;" class="td text-sm text-start text-white">
|
||||||
|
{rawData[index]?.underlying_price}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="justify-content: center;" class="td text-sm text-start text-white">
|
||||||
|
{rawData[index]?.price}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="justify-content: center;" class="td text-sm text-start font-semibold {rawData[index]?.put_call === 'Puts' ? 'text-[#CB281C]' : 'text-[#0FB307]'} ">
|
||||||
|
{abbreviateNumber(rawData[index]?.cost_basis)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="justify-content: center;" class="td text-sm text-start {rawData[index]?.type === 'Sweep' ? 'text-[#C6A755]' : 'text-[#976DB7]'}">
|
||||||
|
{rawData[index]?.type}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="justify-content: center;" class="td text-sm text-white text-end">
|
||||||
|
{new Intl.NumberFormat("en", {
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
maximumFractionDigits: 0
|
||||||
|
}).format(rawData[index]?.volume)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="justify-content: center;" class="td text-sm text-white text-end">
|
||||||
|
{new Intl.NumberFormat("en", {
|
||||||
|
minimumFractionDigits: 0,
|
||||||
|
maximumFractionDigits: 0
|
||||||
|
}).format(rawData[index]?.open_interest)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</VirtualList>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!--<InfiniteLoading on:infinite={infiniteHandler} />-->
|
<!--<InfiniteLoading on:infinite={infiniteHandler} />-->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -1044,7 +999,7 @@ $: {
|
|||||||
|
|
||||||
|
|
||||||
<!-- svelte-ignore a11y-label-has-associated-control -->
|
<!-- svelte-ignore a11y-label-has-associated-control -->
|
||||||
<label class="modal-box w-full relative bg-[#09090B] h-auto max-h-[900px] overflow-y-scroll">
|
<label class="modal-box w-full relative bg-[#09090B] h-auto max-h-[900px] border border-gray-800 overflow-y-scroll">
|
||||||
<label for="optionDetailsDesktopModal" class="cursor-pointer absolute right-5 top-2 bg-[#09090B] text-2xl text-white">
|
<label for="optionDetailsDesktopModal" class="cursor-pointer absolute right-5 top-2 bg-[#09090B] text-2xl text-white">
|
||||||
✕
|
✕
|
||||||
</label>
|
</label>
|
||||||
@ -1191,3 +1146,73 @@ $: {
|
|||||||
</div>
|
</div>
|
||||||
<!--End Options Detail Modal-->
|
<!--End Options Detail Modal-->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.table-container {
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table :global(.virtual-list-inner) {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.table {
|
||||||
|
width: 1000px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table .virtual-list-inner {
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
font-size: .8rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.th {
|
||||||
|
display: none;
|
||||||
|
font-weight: 700;
|
||||||
|
background-color: #09090B;
|
||||||
|
}
|
||||||
|
|
||||||
|
.th > .td {
|
||||||
|
white-space: normal;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tr {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tr:nth-of-type(even) {
|
||||||
|
background-color: #27272A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tr:nth-of-type(odd) {
|
||||||
|
background-color: #09090B;
|
||||||
|
}
|
||||||
|
|
||||||
|
.td {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-basis: 0;
|
||||||
|
padding: 0.5em;
|
||||||
|
word-break: break-word;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
min-width: 0px;
|
||||||
|
white-space: nowrap;
|
||||||
|
border-bottom: 1px solid #09090B;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="table-container">
|
||||||
|
<div class="table">
|
||||||
|
<!-- Your table content here -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user