initiall commit

This commit is contained in:
Tomas Dvorak committed 2026-04-10 12:03:31 +02:00
commit 7ddfb1f52b
276 files changed
+37629

No files matched your search

@@ -0,0 +1,68 @@
import { createSignal, onMount, onCleanup, Accessor } from "solid-js";
interface UseIntersectionObserverOptions extends IntersectionObserverInit {
freezeOnceVisible?: boolean;
}
/**
* Hook to observe element visibility using Intersection Observer API
* Useful for lazy loading, infinite scroll, and animations on scroll
*/
export function useIntersectionObserver(
elementRef: Accessor<HTMLElement | undefined>,
options: UseIntersectionObserverOptions = {}
): Accessor<IntersectionObserverEntry | undefined> {
const [entry, setEntry] = createSignal<IntersectionObserverEntry>();
const { freezeOnceVisible = false, ...observerOptions } = options;
onMount(() => {
const element = elementRef();
if (!element) return;
const observer = new IntersectionObserver(
([entry]) => {
setEntry(entry);
if (freezeOnceVisible && entry.isIntersecting) {
observer.disconnect();
}
},
observerOptions
);
observer.observe(element);
onCleanup(() => {
observer.disconnect();
});
});
return entry;
}
/**
* Hook for lazy loading images
*/
export function useLazyImage(
imageRef: Accessor<HTMLImageElement | undefined>,
src: string
): Accessor<boolean> {
const [loaded, setLoaded] = createSignal(false);
const entry = useIntersectionObserver(imageRef, {
threshold: 0.1,
freezeOnceVisible: true,
});
createSignal(() => {
const img = imageRef();
const isVisible = entry()?.isIntersecting;
if (img && isVisible && !loaded()) {
img.src = src;
img.onload = () => setLoaded(true);
}
});
return loaded;
}
@@ -0,0 +1,86 @@
import { onCleanup, onMount } from "solid-js";
export interface KeyboardShortcut {
key: string;
ctrl?: boolean;
shift?: boolean;
alt?: boolean;
meta?: boolean;
description?: string;
action: (event: KeyboardEvent) => void;
preventDefault?: boolean;
}
/**
* Hook for registering keyboard shortcuts
*/
export function useKeyboardShortcuts(shortcuts: KeyboardShortcut[]) {
const handleKeyDown = (event: KeyboardEvent) => {
for (const shortcut of shortcuts) {
const keyMatches = event.key.toLowerCase() === shortcut.key.toLowerCase();
const ctrlMatches = shortcut.ctrl === undefined || event.ctrlKey === shortcut.ctrl;
const shiftMatches = shortcut.shift === undefined || event.shiftKey === shortcut.shift;
const altMatches = shortcut.alt === undefined || event.altKey === shortcut.alt;
const metaMatches = shortcut.meta === undefined || event.metaKey === shortcut.meta;
if (keyMatches && ctrlMatches && shiftMatches && altMatches && metaMatches) {
if (shortcut.preventDefault !== false) {
event.preventDefault();
}
shortcut.action(event);
break;
}
}
};
onMount(() => {
document.addEventListener("keydown", handleKeyDown);
});
onCleanup(() => {
document.removeEventListener("keydown", handleKeyDown);
});
}
/**
* Format shortcut for display
*/
export function formatShortcut(shortcut: KeyboardShortcut): string {
const parts: string[] = [];
const isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0;
if (shortcut.ctrl) parts.push(isMac ? "⌃" : "Ctrl");
if (shortcut.alt) parts.push(isMac ? "⌥" : "Alt");
if (shortcut.shift) parts.push(isMac ? "⇧" : "Shift");
if (shortcut.meta) parts.push(isMac ? "⌘" : "Win");
parts.push(shortcut.key.toUpperCase());
return parts.join(isMac ? "" : "+");
}
/**
* Common keyboard shortcuts
*/
export const commonShortcuts = {
save: { key: "s", ctrl: true, meta: true, description: "Save" },
copy: { key: "c", ctrl: true, meta: true, description: "Copy" },
paste: { key: "v", ctrl: true, meta: true, description: "Paste" },
cut: { key: "x", ctrl: true, meta: true, description: "Cut" },
undo: { key: "z", ctrl: true, meta: true, description: "Undo" },
redo: { key: "z", ctrl: true, meta: true, shift: true, description: "Redo" },
selectAll: { key: "a", ctrl: true, meta: true, description: "Select All" },
find: { key: "f", ctrl: true, meta: true, description: "Find" },
newTab: { key: "t", ctrl: true, meta: true, description: "New Tab" },
closeTab: { key: "w", ctrl: true, meta: true, description: "Close Tab" },
refresh: { key: "r", ctrl: true, meta: true, description: "Refresh" },
commandPalette: { key: "k", ctrl: true, meta: true, description: "Command Palette" },
settings: { key: ",", ctrl: true, meta: true, description: "Settings" },
escape: { key: "Escape", description: "Cancel/Close" },
enter: { key: "Enter", description: "Confirm/Submit" },
arrowUp: { key: "ArrowUp", description: "Move Up" },
arrowDown: { key: "ArrowDown", description: "Move Down" },
arrowLeft: { key: "ArrowLeft", description: "Move Left" },
arrowRight: { key: "ArrowRight", description: "Move Right" },
};