Skip to content

Commit

Permalink
Merge pull request #1 from rezapex/add-mobile-support
Browse files Browse the repository at this point in the history
Add mobile support
  • Loading branch information
Spikeysanju authored Nov 10, 2024
2 parents bdab8a7 + c8c62bd commit 9548c71
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 15 deletions.
12 changes: 12 additions & 0 deletions src/app.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';

/* Mobile-specific styles and media queries for better responsiveness */
@media (max-width: 600px) {
/* Adjust layout and styling for smaller screens */
.draggable-item {
width: 100%;
}

.droppable-container {
padding: 10px;
}
}
21 changes: 18 additions & 3 deletions src/lib/actions/draggable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import { dndState } from '$lib/stores/dnd.svelte.js';
import type { DragDropOptions, DragDropState } from '$lib/types/index.js';

export function draggable<T>(node: HTMLElement, options: DragDropOptions<T>) {
function handleDragStart(event: DragEvent) {
function handleDragStart(event: DragEvent | TouchEvent) {

if (options.disabled) return;

dndState.isDragging = true;
dndState.draggedItem = options.dragData;
dndState.sourceContainer = options.container;
dndState.targetContainer = null;

if (event.dataTransfer) {
if (event instanceof DragEvent && event.dataTransfer) {
event.dataTransfer.effectAllowed = 'move';
event.dataTransfer.setData('text/plain', JSON.stringify(options.dragData));
}
Expand All @@ -19,7 +20,7 @@ export function draggable<T>(node: HTMLElement, options: DragDropOptions<T>) {
options.callbacks?.onDragStart?.(dndState as DragDropState<T>);
}

function handleDragEnd() {
function handleDragEnd(event: DragEvent | TouchEvent) {
node.classList.remove('dragging');
options.callbacks?.onDragEnd?.(dndState as DragDropState<T>);

Expand All @@ -30,9 +31,21 @@ export function draggable<T>(node: HTMLElement, options: DragDropOptions<T>) {
dndState.targetContainer = null;
}

function handleTouchStart(event: TouchEvent) {
event.preventDefault();
handleDragStart(event);
}

function handleTouchEnd(event: TouchEvent) {
event.preventDefault();
handleDragEnd(event);
}

node.draggable = !options.disabled;
node.addEventListener('dragstart', handleDragStart);
node.addEventListener('dragend', handleDragEnd);
node.addEventListener('touchstart', handleTouchStart);
node.addEventListener('touchend', handleTouchEnd);

return {
update(newOptions: DragDropOptions<T>) {
Expand All @@ -43,6 +56,8 @@ export function draggable<T>(node: HTMLElement, options: DragDropOptions<T>) {
destroy() {
node.removeEventListener('dragstart', handleDragStart);
node.removeEventListener('dragend', handleDragEnd);
node.removeEventListener('touchstart', handleTouchStart);
node.removeEventListener('touchend', handleTouchEnd);
}
};
}
28 changes: 22 additions & 6 deletions src/lib/actions/droppable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { dndState } from '$lib/stores/dnd.svelte.js';
import type { DragDropOptions, DragDropState } from '$lib/types/index.js';

export function droppable<T>(node: HTMLElement, options: DragDropOptions<T>) {
function handleDragEnter(event: DragEvent) {
let touchTimeout: number | null = null;

function handleDragEnter(event: DragEvent | TouchEvent) {

if (options.disabled) return;
event.preventDefault();

Expand All @@ -11,7 +14,7 @@ export function droppable<T>(node: HTMLElement, options: DragDropOptions<T>) {
options.callbacks?.onDragEnter?.(dndState as DragDropState<T>);
}

function handleDragLeave(event: DragEvent) {
function handleDragLeave(event: DragEvent | TouchEvent) {
if (options.disabled) return;

const target = event.target as HTMLElement;
Expand All @@ -22,25 +25,26 @@ export function droppable<T>(node: HTMLElement, options: DragDropOptions<T>) {
}
}

function handleDragOver(event: DragEvent) {
function handleDragOver(event: DragEvent | TouchEvent) {
if (options.disabled) return;
event.preventDefault();

if (event.dataTransfer) {
if (event instanceof DragEvent && event.dataTransfer) {
event.dataTransfer.dropEffect = 'move';
}

options.callbacks?.onDragOver?.(dndState as DragDropState<T>);
}

async function handleDrop(event: DragEvent) {
async function handleDrop(event: DragEvent | TouchEvent) {
if (options.disabled) return;
event.preventDefault();

node.classList.remove('drag-over');

try {
if (event.dataTransfer) {

if (event instanceof DragEvent && event.dataTransfer) {
const dragData = JSON.parse(event.dataTransfer.getData('text/plain')) as T;
dndState.draggedItem = dragData;
}
Expand All @@ -51,10 +55,21 @@ export function droppable<T>(node: HTMLElement, options: DragDropOptions<T>) {
}
}

function handleTouchMove(event: TouchEvent) {
if (touchTimeout) {
clearTimeout(touchTimeout);
}

touchTimeout = window.setTimeout(() => {
handleDragOver(event);
}, 100);
}

node.addEventListener('dragenter', handleDragEnter);
node.addEventListener('dragleave', handleDragLeave);
node.addEventListener('dragover', handleDragOver);
node.addEventListener('drop', handleDrop);
node.addEventListener('touchmove', handleTouchMove);

return {
update(newOptions: DragDropOptions<T>) {
Expand All @@ -66,6 +81,7 @@ export function droppable<T>(node: HTMLElement, options: DragDropOptions<T>) {
node.removeEventListener('dragleave', handleDragLeave);
node.removeEventListener('dragover', handleDragOver);
node.removeEventListener('drop', handleDrop);
node.removeEventListener('touchmove', handleTouchMove);
}
};
}
18 changes: 18 additions & 0 deletions src/lib/styles/dnd.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,21 @@
opacity: 0.3;
border: 2px dashed #9e9e9e;
}

/* Visual feedback for touch interactions */
.svelte-dnd-touch-feedback {
opacity: 0.7;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border-color: #2196f3;
}

/* Media queries for responsive design */
@media (max-width: 600px) {
.svelte-dnd-draggable {
width: 100%;
}

.svelte-dnd-droppable {
padding: 10px;
}
}
2 changes: 1 addition & 1 deletion src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
in:fade={{ duration: 150 }}
out:fade={{ duration: 150 }}
class="cursor-move rounded-lg bg-white p-3 shadow-sm ring-1 ring-gray-200
transition-all duration-200 hover:shadow-md hover:ring-2 hover:ring-blue-200"
transition-all duration-200 hover:shadow-md hover:ring-2 hover:ring-blue-200 svelte-dnd-touch-feedback"
>
<div class="mb-2 flex items-start justify-between gap-2">
<h3 class="font-medium text-gray-900">
Expand Down
2 changes: 1 addition & 1 deletion src/routes/grid-sort/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
container: index.toString(),
dragData: card
}}
class={`h-full w-full cursor-move rounded-lg bg-gradient-to-br ${card.color} shadow-lg transition-all duration-300 hover:scale-[1.02] hover:shadow-xl active:scale-95 active:brightness-110`}
class={`h-full w-full cursor-move rounded-lg bg-gradient-to-br ${card.color} shadow-lg transition-all duration-300 hover:scale-[1.02] hover:shadow-xl active:scale-95 active:brightness-110 svelte-dnd-touch-feedback`}
>
<div class="flex h-full items-center justify-center">
<span class="text-4xl">{card.icon}</span>
Expand Down
2 changes: 1 addition & 1 deletion src/routes/horizontal-scroll/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
dragData: image
}}
class="group relative h-[300px] w-[200px] cursor-move overflow-hidden rounded-xl
transition-transform hover:scale-105"
transition-transform hover:scale-105 svelte-dnd-touch-feedback"
>
<img
src={image.url}
Expand Down
4 changes: 2 additions & 2 deletions src/routes/nested/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
container: groupIndex.toString(),
dragData: group
}}
class="rounded-xl bg-white p-4 shadow-sm ring-1 ring-gray-200"
class="rounded-xl bg-white p-4 shadow-sm ring-1 ring-gray-200 svelte-dnd-touch-feedback"
in:fade={{ duration: 150 }}
out:fade={{ duration: 150 }}
>
Expand Down Expand Up @@ -160,7 +160,7 @@
dragData: item
}}
class="cursor-move rounded-lg bg-white p-3 shadow-sm ring-1 ring-gray-200
transition-all duration-200 hover:shadow-md hover:ring-2 hover:ring-blue-200"
transition-all duration-200 hover:shadow-md hover:ring-2 hover:ring-blue-200 svelte-dnd-touch-feedback"
>
<div class="mb-2 flex items-start justify-between gap-2">
<h3 class="font-medium text-gray-900">{item.title}</h3>
Expand Down
2 changes: 1 addition & 1 deletion src/routes/simple-list/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
in:fade={{ duration: 150 }}
out:fade={{ duration: 150 }}
class="cursor-move rounded-lg bg-white p-3 shadow-sm ring-1 ring-gray-200
transition-all duration-200 hover:shadow-md hover:ring-2 hover:ring-blue-200"
transition-all duration-200 hover:shadow-md hover:ring-2 hover:ring-blue-200 svelte-dnd-touch-feedback"
>
<div class="mb-2 flex items-start justify-between gap-2">
<h3 class="font-medium text-gray-900">
Expand Down

0 comments on commit 9548c71

Please sign in to comment.