Skip to content

Commit

Permalink
improve examples
Browse files Browse the repository at this point in the history
  • Loading branch information
KingSora committed Aug 21, 2023
1 parent 43a6f79 commit d568667
Show file tree
Hide file tree
Showing 16 changed files with 402 additions and 37 deletions.
2 changes: 1 addition & 1 deletion examples/angular/src/styles.scss
Expand Up @@ -138,7 +138,7 @@ img {
justify-content: center;
align-items: center;
padding: 0.75rem;
background: rgba(0, 0, 0, 0.25);
backdrop-filter: brightness(88%) contrast(1.012);
border-radius: 12px;
}

Expand Down
69 changes: 54 additions & 15 deletions examples/overlayscrollbars/index.html
@@ -1,26 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" data-overlayscrollbars-initialize>
<head>
<meta charset="UTF-8" />
<link rel="icon" href="favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles.css" />
<link rel="icon" href="favicon.ico" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=DM+Sans&family=Inter:wght@400;500;600&display=swap"
rel="stylesheet"
/>
<title>OverlayScrollbars</title>
</head>
<body>
<body data-overlayscrollbars-initialize>
<div id="app">
<a href="https://www.npmjs.com/package/overlayscrollbars" target="_blank">
<h1>OverlayScrollbars</h1>
</a>
<div
data-overlayscrollbars-initialize=""
class="overlayscrollbars"
style="width: 222px; height: 222px"
>
<div class="logo">
<img alt="Logo" src="logo.png" width="333" height="333" />
</div>
</div>
<main>
<h1>
<a href="https://www.npmjs.com/package/overlayscrollbars" target="_blank">
OverlayScrollbars
</a>
</h1>
<section class="slot">
<div id="target" class="overlayscrollbars">
<div id="targetContent" class="logo">
<img alt="Logo" src="logo.png" width="333" height="333" />
</div>
</div>
<div id="impostor" class="overlayscrollbars" style="display: none">
<div class="logo">
<img alt="Logo" src="logo.png" width="333" height="333" />
</div>
</div>
</section>
<section>
<p class="title">Actions:</p>
<div class="items">
<button id="scrollButton">Scroll</button>
<button id="toggleContentButton"></button>
<button id="toggleElementButton"></button>
<button id="toggleOverlayScrollbarsButton"></button>
</div>
</section>
<section id="eventsSection" style="display: none">
<p class="title">Events:</p>
<div id="events" class="items"></div>
</section>
</main>
<footer>
<section id="toggleBodyOverlayScrollbarsSection" style="display: none">
<div class="items">
<button id="toggleBodyOverlayScrollbarsButton" style="display: none"></button>
</div>
</section>
<a
href="https://github.com/KingSora/OverlayScrollbars/tree/master/examples/overlayscrollbars"
target="_blank"
>
Open source code of this example.
</a>
</footer>
</div>
<script type="module" src="/src/index.ts"></script>
</body>
Expand Down
1 change: 1 addition & 0 deletions examples/overlayscrollbars/package-lock.json

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

102 changes: 102 additions & 0 deletions examples/overlayscrollbars/src/actions.ts
@@ -0,0 +1,102 @@
import { OverlayScrollbars } from 'overlayscrollbars';
import { eventObserver } from './events';

let osInstance: OverlayScrollbars | undefined;
let contentHidden = false;
let elementHidden = false;
let useOverlayScrollbars = true;
const activateEvent = eventObserver();

const target = document.querySelector('#target') as HTMLElement;
const targetContent = document.querySelector('#targetContent') as HTMLElement;
const impostor = document.querySelector('#impostor') as HTMLElement;
const scrollButton = document.querySelector('#scrollButton') as HTMLButtonElement;
const toggleContentButton = document.querySelector('#toggleContentButton') as HTMLButtonElement;
const toggleElementButton = document.querySelector('#toggleElementButton') as HTMLButtonElement;
const toggleOverlayScrollbarsButton = document.querySelector(
'#toggleOverlayScrollbarsButton'
) as HTMLButtonElement;

const updateToggleContent = () => {
if (contentHidden) {
targetContent.style.display = 'none';
toggleContentButton.textContent = 'Show Content';
} else {
targetContent.style.display = '';
toggleContentButton.textContent = 'Hide Content';
}
};
const updateToggleElement = () => {
if (elementHidden) {
target.style.display = 'none';
toggleElementButton.textContent = 'Show Element';
} else {
target.style.display = '';
toggleElementButton.textContent = 'Hide Element';
}
};
const updateUseOverlayScrollbars = () => {
if (useOverlayScrollbars) {
impostor.parentElement?.append(target);
impostor.remove();

scrollButton.style.display = '';
toggleContentButton.style.display = '';
toggleElementButton.style.display = '';
toggleOverlayScrollbarsButton.textContent = 'Destroy OverlayScrollbars';

osInstance = OverlayScrollbars(
target,
{},
{
initialized: () => activateEvent('initialized'),
destroyed: () => activateEvent('destroyed'),
updated: () => activateEvent('updated'),
scroll: () => activateEvent('scroll'),
}
);
} else {
osInstance?.destroy();

target.parentElement?.append(impostor);
target.remove();

impostor.style.display = '';
scrollButton.style.display = 'none';
toggleContentButton.style.display = 'none';
toggleElementButton.style.display = 'none';
toggleOverlayScrollbarsButton.textContent = 'Initialize OverlayScrollbars';
}
};

scrollButton.addEventListener('click', () => {
if (!osInstance) {
return;
}

const { overflowAmount } = osInstance.state();
const { scrollOffsetElement } = osInstance.elements();
const { scrollLeft, scrollTop } = scrollOffsetElement;

scrollOffsetElement.scrollTo({
behavior: 'smooth',
left: Math.round((overflowAmount.x - scrollLeft) / overflowAmount.x) * overflowAmount.x,
top: Math.round((overflowAmount.y - scrollTop) / overflowAmount.y) * overflowAmount.y,
});
});
toggleContentButton.addEventListener('click', () => {
contentHidden = !contentHidden;
updateToggleContent();
});
toggleElementButton.addEventListener('click', () => {
elementHidden = !elementHidden;
updateToggleElement();
});
toggleOverlayScrollbarsButton.addEventListener('click', () => {
useOverlayScrollbars = !useOverlayScrollbars;
updateUseOverlayScrollbars();
});

updateToggleContent();
updateToggleElement();
updateUseOverlayScrollbars();
46 changes: 46 additions & 0 deletions examples/overlayscrollbars/src/bodyOverlayScrollbars.ts
@@ -0,0 +1,46 @@
import { OverlayScrollbars } from 'overlayscrollbars';

let useBodyOverlayScrollbars: boolean | null = null;

const initBodyOverlayScrollbars = (force?: boolean) =>
OverlayScrollbars(
{
target: document.body,
cancel: {
body: force ? false : null,
},
},
{}
).state().destroyed;

const toggleBodyOverlayScrollbarsSection = document.querySelector(
'#toggleBodyOverlayScrollbarsSection'
) as HTMLElement;
const toggleBodyOverlayScrollbarsButton = document.querySelector(
'#toggleBodyOverlayScrollbarsButton'
) as HTMLButtonElement;

const updateToggleBodyOverlayScrollbarsSection = () => {
if (useBodyOverlayScrollbars !== null) {
toggleBodyOverlayScrollbarsSection.style.display = '';
}
toggleBodyOverlayScrollbarsButton.style.display = '';
toggleBodyOverlayScrollbarsButton.textContent = `${
useBodyOverlayScrollbars ? 'Destroy' : 'Initialize'
} Body OverlayScrollbars`;
};

toggleBodyOverlayScrollbarsButton.addEventListener('click', () => {
const bodyOsInstance = OverlayScrollbars(document.body);
if (bodyOsInstance) {
bodyOsInstance.destroy();
} else {
initBodyOverlayScrollbars(true);
}

useBodyOverlayScrollbars = !useBodyOverlayScrollbars;
updateToggleBodyOverlayScrollbarsSection();
});

useBodyOverlayScrollbars = !initBodyOverlayScrollbars();
updateToggleBodyOverlayScrollbarsSection();
61 changes: 61 additions & 0 deletions examples/overlayscrollbars/src/events.ts
@@ -0,0 +1,61 @@
import type { EventListenerArgs } from 'overlayscrollbars';

type OverlayScrollbarsEvents = keyof EventListenerArgs;

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

const eventsSection = document.querySelector('#eventsSection') as HTMLElement;
const events = document.querySelector('#events') as HTMLElement;

const onEventsChanged = (changedEvents: Record<OverlayScrollbarsEvents, EventObserverEvent>) => {
eventsSection.style.display = '';
events.innerHTML = '';

Object.entries(changedEvents).forEach(([eventName, event]) => {
const eventElement = document.createElement('div');
eventElement.className = `event ${event.active ? 'active' : ''}`;
eventElement.textContent = `${eventName} (${event.count})`;

events.append(eventElement);
});
};

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

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

const updateActiveEvents = (newActiveEvents: OverlayScrollbarsEvents[]) => {
activeEvents = newActiveEvents;
onEventsChanged({
initialized: getEventObj('initialized'),
destroyed: getEventObj('destroyed'),
updated: getEventObj('updated'),
scroll: getEventObj('scroll'),
});
};

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

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

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

return activateEvent;
};
5 changes: 2 additions & 3 deletions examples/overlayscrollbars/src/index.ts
@@ -1,4 +1,3 @@
import 'overlayscrollbars/overlayscrollbars.css';
import { OverlayScrollbars } from 'overlayscrollbars';

OverlayScrollbars(document.querySelector('.overlayscrollbars'), {});
import './actions';
import './bodyOverlayScrollbars';

0 comments on commit d568667

Please sign in to comment.