custom scrollbar implemented
Some checks failed
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Failing after 0s
Some checks failed
Rebuild signaller for deprived.dev to rebuild site / test_service (push) Failing after 0s
This commit is contained in:
parent
c099b9ce9f
commit
7a8d61d598
3 changed files with 116 additions and 83 deletions
|
|
@ -7,7 +7,7 @@
|
|||
<div class="flex flex-col items-center justify-center w-full h-full">
|
||||
<div class="flex flex-col w-72">
|
||||
<div class="w-full h-72 bg-lime-200"></div>
|
||||
<CustomScrollBar overflowX="scroll" overflowY="hidden" Class="h-26">
|
||||
<CustomScrollBar overflowX="scroll" overflowY="hidden" Class="">
|
||||
<div class="flex w-full gap-4">
|
||||
{#each { length: 4 } as i}
|
||||
<img
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
import DeprivedLogo from "$lib/images/DeprivedLogo.svelte";
|
||||
import HamburgerMenuIcon from "$lib/images/HamburgerMenuIcon.svelte";
|
||||
|
||||
const footerCollapseThreshold: string = "1000px";
|
||||
const headerCollapseThreshold: string = "1000px";
|
||||
const footerCollapseThreshold: string = "40rem";
|
||||
const headerCollapseThreshold: string = "40rem";
|
||||
let footerCollapse: boolean;
|
||||
let isMobile: boolean = $state(false);
|
||||
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
import { onMount } from "svelte";
|
||||
import Zooter from "./comps/Zooter.svelte";
|
||||
import CustomScrollBar from "./comps/CustomScrollBar.svelte";
|
||||
|
||||
onMount(async () => {
|
||||
const lock = document.createElement("meta");
|
||||
|
|
@ -82,6 +83,13 @@
|
|||
bind:matches={isMobile}
|
||||
/>
|
||||
|
||||
<CustomScrollBar
|
||||
overflowX="hidden"
|
||||
overflowY="auto"
|
||||
Class="h-screen"
|
||||
requireAbsolute={true}
|
||||
hideOnMobile={true}
|
||||
>
|
||||
<div class="flex flex-col justify-between min-h-screen bg-base-200 p-0">
|
||||
<header class="{hideOnPrint ? 'hide-on-print' : ''} bg-base-300">
|
||||
<div class="nav-bar pr-4">
|
||||
|
|
@ -162,6 +170,7 @@
|
|||
|
||||
<Zooter bind:hideOnPrint />
|
||||
</div>
|
||||
</CustomScrollBar>
|
||||
|
||||
{#if footerCollapse}
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,18 @@
|
|||
<script lang="ts">
|
||||
import { onMount, onDestroy } from "svelte";
|
||||
import MediaQuery from "svelte-media-queries";
|
||||
|
||||
// Public props
|
||||
export let overflowX: "auto" | "scroll" | "hidden" = "hidden";
|
||||
export let overflowY: "auto" | "scroll" | "hidden" = "auto";
|
||||
|
||||
export let hideOnMobile = false; // True if hide scrollbar when mobile detected
|
||||
|
||||
// Visual tuning
|
||||
export let thickness = 12; // px
|
||||
export let padding = 0; // px, space around track inside the overlay
|
||||
export let minThumb = 24; // px
|
||||
export let contentPadding = 16; // px, inner padding for your content
|
||||
export let minThumb = 10; // px
|
||||
export let contentPadding = 0; // px, inner padding for your content
|
||||
export let Class = ""; // Extra classes for the scrollbar
|
||||
|
||||
// Styling (customize freely)
|
||||
|
|
@ -18,9 +21,11 @@
|
|||
export let trackOpacity = 0.55;
|
||||
|
||||
export let thumbClass =
|
||||
"bg-black border-x-1 opacity-50 border-white text-xs text-center text-opacity-50 overflow-hidden flex items-center text-nowrap justify-center";
|
||||
"bg-black opacity-50 border-white text-xs text-center text-opacity-50 overflow-hidden flex items-center text-nowrap justify-center";
|
||||
export let thumbLength = 20; // px. doesn't work for some reason, idk
|
||||
|
||||
export let requireAbsolute = false; // Some needs absolute for some reason. idk
|
||||
|
||||
let viewport: HTMLDivElement;
|
||||
let vBar: HTMLDivElement; // vertical bar container
|
||||
let hBar: HTMLDivElement; // horizontal bar container
|
||||
|
|
@ -29,6 +34,7 @@
|
|||
|
||||
let showBarY = false;
|
||||
let showBarX = false;
|
||||
let isMobile = false;
|
||||
|
||||
// ——— utils
|
||||
const sMaxY = () =>
|
||||
|
|
@ -41,9 +47,13 @@
|
|||
|
||||
function updateVisibility() {
|
||||
showBarY =
|
||||
overflowY !== "hidden" && viewport.scrollHeight > viewport.clientHeight;
|
||||
overflowY !== "hidden" &&
|
||||
viewport.scrollHeight > viewport.clientHeight &&
|
||||
!(hideOnMobile && isMobile);
|
||||
showBarX =
|
||||
overflowX !== "hidden" && viewport.scrollWidth > viewport.clientWidth;
|
||||
overflowX !== "hidden" &&
|
||||
viewport.scrollWidth > viewport.clientWidth &&
|
||||
!(hideOnMobile && isMobile);
|
||||
}
|
||||
|
||||
function updateVerticalThumb() {
|
||||
|
|
@ -268,15 +278,25 @@
|
|||
$: pb = contentPadding + (showBarX ? thickness + padding * 2 : 0);
|
||||
</script>
|
||||
|
||||
<MediaQuery query="(max-width: 40rem)" bind:matches={isMobile} />
|
||||
|
||||
<!-- svelte-ignore element_invalid_self_closing_tag -->
|
||||
<!-- svelte-ignore a11y_role_has_required_aria_props -->
|
||||
|
||||
<!-- Wrapper -->
|
||||
<div class="relative overflow-hidden {Class}">
|
||||
<div
|
||||
class="relative {overflowY == 'hidden'
|
||||
? ''
|
||||
: 'overflow-y-hidden'} {overflowX == 'hidden'
|
||||
? ''
|
||||
: 'overflow-x-hidden'} {Class}"
|
||||
>
|
||||
<!-- The real, native scrolling area (we hide its native scrollbar) -->
|
||||
<div
|
||||
bind:this={viewport}
|
||||
class="csb-viewport absolute inset-0 overflow-auto focus:outline-none"
|
||||
class="csb-viewport {requireAbsolute
|
||||
? 'absolute'
|
||||
: ''} inset-0 overflow-auto focus:outline-none"
|
||||
style="
|
||||
padding: {contentPadding}px {pr}px {pb}px {contentPadding}px;
|
||||
overscroll-behavior: contain;
|
||||
|
|
@ -292,7 +312,7 @@
|
|||
{#if showBarY}
|
||||
<div
|
||||
bind:this={vBar}
|
||||
class="absolute"
|
||||
class="absolute bg-base-200"
|
||||
style="
|
||||
top: {padding}px;
|
||||
bottom: {padding}px;
|
||||
|
|
@ -304,7 +324,7 @@
|
|||
>
|
||||
<div class="absolute inset-0 corner-border-container">
|
||||
<div
|
||||
class="transition-opacity {trackClass} w-full"
|
||||
class="transition-opacity {trackClass} w-full h-full"
|
||||
style="
|
||||
pointer-events: auto;
|
||||
{trackStyle}
|
||||
|
|
@ -318,14 +338,18 @@
|
|||
role="scrollbar"
|
||||
aria-orientation="vertical"
|
||||
tabindex="0"
|
||||
class={`absolute left-[2px] right-[2px] rounded-full cursor-grab active:cursor-grabbing focus-visible:outline focus-visible:outline-2 focus-visible:outline-sky-500 ${thumbClass}`}
|
||||
class={`absolute border-y-2 left-0 right-0 rounded-none cursor-grab active:cursor-grabbing focus-visible:outline focus-visible:outline-2 focus-visible:outline-sky-500 ${thumbClass}`}
|
||||
style="height: {thumbLength}px; pointer-events: auto; touch-action: none;"
|
||||
on:pointerdown={onVPointerDown}
|
||||
on:pointermove={onVPointerMove}
|
||||
on:pointerup={endVDrag}
|
||||
on:pointercancel={endVDrag}
|
||||
on:keydown={onVKeyDown}
|
||||
></div>
|
||||
>
|
||||
<span class="rotate-90">
|
||||
-------------------------------------------------Scroll-------------------------------------------------
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
|
@ -358,7 +382,7 @@
|
|||
role="scrollbar"
|
||||
aria-orientation="horizontal"
|
||||
tabindex="0"
|
||||
class={`absolute top-0 bottom-0 rounded-none cursor-grab active:cursor-grabbing focus-visible:outline focus-visible:outline-2 focus-visible:outline-sky-500 ${thumbClass}`}
|
||||
class={`absolute border-x-2 top-0 bottom-0 rounded-none cursor-grab active:cursor-grabbing focus-visible:outline focus-visible:outline-2 focus-visible:outline-sky-500 ${thumbClass}`}
|
||||
style="width: {thumbLength}px; pointer-events: auto; touch-action: none;"
|
||||
on:pointerdown={onHPointerDown}
|
||||
on:pointermove={onHPointerMove}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue