Skip to content

Commit

Permalink
upgrade svelte component wrapper to svelte 5 and improve tests & type…
Browse files Browse the repository at this point in the history
…s of other framework wrappers
  • Loading branch information
KingSora committed Feb 19, 2025
1 parent 6b0689b commit 824d940
Show file tree
Hide file tree
Showing 29 changed files with 7,991 additions and 11,973 deletions.
1,430 changes: 446 additions & 984 deletions examples/svelte/package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions examples/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
"overlayscrollbars-svelte": "file:../../packages/overlayscrollbars-svelte/dist"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"@tsconfig/svelte": "^5.0.2",
"svelte": "^4.2.12",
"svelte-check": "^3.6.2",
"@sveltejs/vite-plugin-svelte": "^5.0.3",
"@tsconfig/svelte": "^5.0.4",
"svelte": "^5.0.0",
"svelte-check": "^4.1.4",
"tslib": "^2.6.0",
"typescript": "^5.0.2",
"vite": "^5.2.11"
"vite": "^6.0.0"
},
"scripts": {
"dev": "vite",
Expand Down
130 changes: 48 additions & 82 deletions examples/svelte/src/App.svelte
Original file line number Diff line number Diff line change
@@ -1,70 +1,31 @@
<script lang="ts">
import { OverlayScrollbars, type EventListenerArgs } from 'overlayscrollbars';
import { OverlayScrollbarsComponent } from 'overlayscrollbars-svelte';
import { OverlayScrollbarsComponent, useOverlayScrollbars } from 'overlayscrollbars-svelte';
import { onMount } from 'svelte';
type OverlayScrollbarsEvents = keyof EventListenerArgs;
interface EventObserverEvent {
active: boolean;
count: number;
}
let osRef: OverlayScrollbarsComponent | undefined;
let contentHidden = false;
let elementHidden = false;
let useOverlayScrollbars = true;
let useBodyOverlayScrollbars: boolean | null = null;
let activeEventsArray: OverlayScrollbarsEvents[] = [];
const eventCount: Partial<Record<OverlayScrollbarsEvents, number>> = {};
const timeoutIds: Partial<Record<OverlayScrollbarsEvents, ReturnType<typeof setTimeout>>> = {};
const activateEvent = (event: OverlayScrollbarsEvents) => {
const currAmount = eventCount[event];
eventCount[event] = typeof currAmount === 'number' ? currAmount + 1 : 1;
activeEventsArray = Array.from(new Set([...activeEventsArray, event]));
clearTimeout(timeoutIds[event]);
timeoutIds[event] = setTimeout(() => {
const currActiveEventsSet = new Set(activeEventsArray);
currActiveEventsSet.delete(event);
activeEventsArray = Array.from(currActiveEventsSet);
}, 500);
};
const getEventObj = (
activeEventsArr: OverlayScrollbarsEvents[],
event: OverlayScrollbarsEvents
): EventObserverEvent => ({
active: activeEventsArr.includes(event),
count: eventCount[event] || 0,
});
$: activeEvents = {
initialized: getEventObj(activeEventsArray, 'initialized'),
destroyed: getEventObj(activeEventsArray, 'destroyed'),
updated: getEventObj(activeEventsArray, 'updated'),
scroll: getEventObj(activeEventsArray, 'scroll'),
};
const initBodyOverlayScrollbars = (force?: boolean) =>
OverlayScrollbars(
{
target: document.body,
cancel: {
body: force ? false : null,
},
import { useEventObserver } from './useEventObserver.svelte';
let osRef: OverlayScrollbarsComponent | undefined = $state();
let contentHidden = $state(false);
let elementHidden = $state(false);
let overlayScrollbarsApplied = $state(true);
let bodyOverlayScrollbarsApplied: boolean | null = $state(null);
const [activeEvents, activateEvent] = useEventObserver();
const [initBodyOverlayScrollbars, getBodyOverlayScrollbarsInstance] = useOverlayScrollbars({
defer: true,
events: {
initialized: () => {
bodyOverlayScrollbarsApplied = true;
},
{
scrollbars: {
theme: 'os-theme-light',
clickScroll: true,
},
}
).state().destroyed;
destroyed: () => {
bodyOverlayScrollbarsApplied = false;
},
},
options: {
scrollbars: {
theme: 'os-theme-light',
clickScroll: true,
},
},
});
const scrollContent = () => {
const osInstance = osRef?.osInstance();
Expand All @@ -90,17 +51,22 @@
elementHidden = !elementHidden;
};
const toggleBodyOverlayScrollbars = () => {
const bodyOsInstance = OverlayScrollbars(document.body);
if (bodyOsInstance) {
const bodyOsInstance = getBodyOverlayScrollbarsInstance();
if (bodyOsInstance && !bodyOsInstance.state().destroyed) {
bodyOsInstance.destroy();
useBodyOverlayScrollbars = false;
} else {
useBodyOverlayScrollbars = !initBodyOverlayScrollbars(true);
initBodyOverlayScrollbars({
target: document.body,
cancel: {
body: false,
},
});
}
};
onMount(async () => {
useBodyOverlayScrollbars = !initBodyOverlayScrollbars();
onMount(() => {
initBodyOverlayScrollbars(document.body);
});
</script>

Expand All @@ -111,7 +77,7 @@
</a>
</h1>
<section>
{#if useOverlayScrollbars}
{#if overlayScrollbarsApplied}
<OverlayScrollbarsComponent
bind:this={osRef}
class="overlayscrollbars-svelte"
Expand Down Expand Up @@ -142,24 +108,24 @@
<section>
<p class="title">Actions:</p>
<div class="items">
{#if useOverlayScrollbars}
<button on:click={scrollContent}>Scroll</button>
<button on:click={toggleContent}>{contentHidden ? 'Show' : 'Hide'} Content</button>
<button on:click={toggleElement}>{elementHidden ? 'Show' : 'Hide'} Element</button>
{#if overlayScrollbarsApplied}
<button onclick={scrollContent}>Scroll</button>
<button onclick={toggleContent}>{contentHidden ? 'Show' : 'Hide'} Content</button>
<button onclick={toggleElement}>{elementHidden ? 'Show' : 'Hide'} Element</button>
{/if}
<button
on:click={() => {
useOverlayScrollbars = !useOverlayScrollbars;
onclick={() => {
overlayScrollbarsApplied = !overlayScrollbarsApplied;
}}
>
{useOverlayScrollbars ? 'Destroy' : 'Initialize'} OverlayScrollbars
{overlayScrollbarsApplied ? 'Destroy' : 'Initialize'} OverlayScrollbars
</button>
</div>
</section>
<section>
<p class="title">Events:</p>
<div class="items">
{#each Object.entries(activeEvents) as [eventName, event]}
{#each Object.entries(activeEvents()) as [eventName, event]}
<div class={`event ${event.active ? 'active' : ''}`}>
{eventName} ({event.count})
</div>
Expand All @@ -168,11 +134,11 @@
</section>
</main>
<footer>
{#if useBodyOverlayScrollbars !== null}
{#if bodyOverlayScrollbarsApplied !== null}
<section>
<div class="items">
<button on:click={toggleBodyOverlayScrollbars}>
{useBodyOverlayScrollbars ? 'Destroy' : 'Initialize'} Body OverlayScrollbars
<button onclick={toggleBodyOverlayScrollbars}>
{bodyOverlayScrollbarsApplied ? 'Destroy' : 'Initialize'} Body OverlayScrollbars
</button>
</div>
</section>
Expand Down
5 changes: 2 additions & 3 deletions examples/svelte/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import 'overlayscrollbars/overlayscrollbars.css';
import { OverlayScrollbars, ClickScrollPlugin } from 'overlayscrollbars';
import './app.css';
import { mount } from 'svelte';
import App from './App.svelte';

OverlayScrollbars.plugin(ClickScrollPlugin);

const app = new App({
target: document.getElementById('app') as HTMLElement,
});
const app = mount(App, { target: document.getElementById('app') as HTMLElement });

export default app;
42 changes: 42 additions & 0 deletions examples/svelte/src/useEventObserver.svelte.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { EventListenerArgs } from 'overlayscrollbars';

export type OverlayScrollbarsEvents = keyof EventListenerArgs;

export interface EventObserverEvent {
active: boolean;
count: number;
}

export const useEventObserver = () => {
let activeEvents: OverlayScrollbarsEvents[] = $state([]);
const eventCountRef: Partial<Record<OverlayScrollbarsEvents, number>> = {};
const timeoutIds: Partial<Record<OverlayScrollbarsEvents, ReturnType<typeof setTimeout>>> = {};

const activateEvent = (event: OverlayScrollbarsEvents) => {
const currAmount = eventCountRef[event];
eventCountRef[event] = typeof currAmount === 'number' ? currAmount + 1 : 1;

activeEvents = Array.from(new Set([...activeEvents, event]));

clearTimeout(timeoutIds[event]);
timeoutIds[event] = setTimeout(() => {
const currActiveEventsSet = new Set(activeEvents);
currActiveEventsSet.delete(event);
activeEvents = Array.from(currActiveEventsSet);
}, 500);
};

const getEventObj = (event: OverlayScrollbarsEvents): EventObserverEvent => ({
active: activeEvents.includes(event),
count: eventCountRef[event] || 0,
});

const events: Record<OverlayScrollbarsEvents, EventObserverEvent> = $derived({
initialized: getEventObj('initialized'),
destroyed: getEventObj('destroyed'),
updated: getEventObj('updated'),
scroll: getEventObj('scroll'),
});

return [() => events, activateEvent] as const;
};
4 changes: 2 additions & 2 deletions examples/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
},
"devDependencies": {
"@types/node": "^20.10.5",
"@vitejs/plugin-vue": "^4.5.2",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@vitejs/plugin-vue": "^5.2.1",
"@vitejs/plugin-vue-jsx": "^4.1.1",
"@vue/tsconfig": "^0.5.1",
"typescript": "^5.0.2",
"vite": "^5.2.11",
Expand Down
Loading

0 comments on commit 824d940

Please sign in to comment.