Ver código fonte

refac/enh: notification toast click behaviour

Timothy Jaeryang Baek 3 semanas atrás
pai
commit
621e7679c4
1 arquivos alterados com 52 adições e 6 exclusões
  1. 52 6
      src/lib/components/NotificationToast.svelte

+ 52 - 6
src/lib/components/NotificationToast.svelte

@@ -12,6 +12,43 @@
 	export let title: string = 'HI';
 	export let content: string;
 
+	let startX = 0,
+		startY = 0;
+	let moved = false;
+	const DRAG_THRESHOLD_PX = 6;
+
+	const clickHandler = () => {
+		onClick();
+		dispatch('closeToast');
+	};
+
+	function onPointerDown(e: PointerEvent) {
+		startX = e.clientX;
+		startY = e.clientY;
+		moved = false;
+		// Ensure we continue to get events even if the toast moves under the pointer.
+		(e.currentTarget as HTMLElement).setPointerCapture?.(e.pointerId);
+	}
+
+	function onPointerMove(e: PointerEvent) {
+		if (moved) return;
+		const dx = e.clientX - startX;
+		const dy = e.clientY - startY;
+		if (dx * dx + dy * dy > DRAG_THRESHOLD_PX * DRAG_THRESHOLD_PX) {
+			moved = true;
+		}
+	}
+
+	function onPointerUp(e: PointerEvent) {
+		// Release capture if taken
+		(e.currentTarget as HTMLElement).releasePointerCapture?.(e.pointerId);
+
+		// Only treat as a click if there wasn't a drag
+		if (!moved) {
+			clickHandler();
+		}
+	}
+
 	onMount(() => {
 		if (!navigator.userActivation.hasBeenActive) {
 			return;
@@ -31,11 +68,20 @@
 	});
 </script>
 
-<button
-	class="flex gap-2.5 text-left min-w-[var(--width)] w-full dark:bg-gray-850 dark:text-white bg-white text-black border border-gray-100 dark:border-gray-850 rounded-3xl px-3.5 py-3"
-	on:click={() => {
-		onClick();
-		dispatch('closeToast');
+<!-- svelte-ignore a11y-click-events-have-key-events -->
+<!-- svelte-ignore a11y-no-static-element-interactions -->
+<div
+	class="flex gap-2.5 text-left min-w-[var(--width)] w-full dark:bg-gray-850 dark:text-white bg-white text-black border border-gray-100 dark:border-gray-850 rounded-3xl px-3.5 py-3 cursor-pointer select-none"
+	on:dragstart|preventDefault
+	on:pointerdown={onPointerDown}
+	on:pointermove={onPointerMove}
+	on:pointerup={onPointerUp}
+	on:pointercancel={() => (moved = true)}
+	on:keydown={(e) => {
+		if (e.key === 'Enter' || e.key === ' ') {
+			e.preventDefault();
+			clickHandler();
+		}
 	}}
 >
 	<div class="shrink-0 self-top -translate-y-0.5">
@@ -51,4 +97,4 @@
 			{@html DOMPurify.sanitize(marked(content))}
 		</div>
 	</div>
-</button>
+</div>