# advanced-ui-patterns > Advanced patterns like infinite scroll, drag-and-drop, virtualization, modals, portals, toast notifications, and complex interactions. Use when implementing advanced UI features, optimizing long lists, or creating rich interactions. - Author: Nir - Repository: Nirkoso/Nir-Claude - Version: 20260126102449 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-07 - Source: https://github.com/Nirkoso/Nir-Claude - Web: https://mule.run/skillshub/@@Nirkoso/Nir-Claude~advanced-ui-patterns:20260126102449 --- --- name: advanced-ui-patterns description: Advanced patterns like infinite scroll, drag-and-drop, virtualization, modals, portals, toast notifications, and complex interactions. Use when implementing advanced UI features, optimizing long lists, or creating rich interactions. --- # Advanced UI Patterns Implement sophisticated user interface patterns. ## 1. Infinite Scroll ```typescript import { useInfiniteQuery } from '@tanstack/react-query'; import { useInView } from 'react-intersection-observer'; function InfiniteScroll() { const { ref, inView } = useInView(); const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = useInfiniteQuery({ queryKey: ['posts'], queryFn: ({ pageParam = 0 }) => fetchPosts(pageParam), getNextPageParam: (lastPage, pages) => lastPage.nextCursor }); useEffect(() => { if (inView && hasNextPage) { fetchNextPage(); } }, [inView, hasNextPage, fetchNextPage]); return (
{data?.pages.map(page => page.items.map(item => ) )}
{isFetchingNextPage ? 'Loading...' : hasNextPage ? 'Load More' : 'No more items'}
); } ``` ## 2. Virtual Scrolling ```typescript import { useVirtualizer } from '@tanstack/react-virtual'; function VirtualList({ items }: { items: any[] }) { const parentRef = useRef(null); const virtualizer = useVirtualizer({ count: items.length, getScrollElement: () => parentRef.current, estimateSize: () => 50, overscan: 5 }); return (
{virtualizer.getVirtualItems().map(virtualItem => (
))}
); } ``` ## 3. Drag and Drop ```typescript import { DndContext, useDraggable, useDroppable } from '@dnd-kit/core'; function Draggable({ id, children }: { id: string; children: React.ReactNode }) { const { attributes, listeners, setNodeRef, transform } = useDraggable({ id }); const style = transform ? { transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`, } : undefined; return (
{children}
); } function Droppable({ id, children }: { id: string; children: React.ReactNode }) { const { setNodeRef } = useDroppable({ id }); return
{children}
; } function DragDropExample() { const [items, setItems] = useState(['A', 'B', 'C']); const handleDragEnd = (event: any) => { const { active, over } = event; if (over && active.id !== over.id) { // Reorder items const oldIndex = items.indexOf(active.id); const newIndex = items.indexOf(over.id); const newItems = arrayMove(items, oldIndex, newIndex); setItems(newItems); } }; return ( {items.map(item => (
{item}
))}
); } ``` ## 4. Modal / Dialog with Portal ```typescript import { createPortal } from 'react-dom'; function Modal({ isOpen, onClose, children }: ModalProps) { const modalRef = useRef(null); useEffect(() => { if (!isOpen) return; // Focus trap const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); if (e.key === 'Tab') { const focusable = modalRef.current?.querySelectorAll( 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' ); // Handle focus trap logic } }; document.addEventListener('keydown', handleKeyDown); document.body.style.overflow = 'hidden'; return () => { document.removeEventListener('keydown', handleKeyDown); document.body.style.overflow = ''; }; }, [isOpen, onClose]); if (!isOpen) return null; return createPortal(
e.stopPropagation()} > {children}
, document.body ); } ``` ## 5. Toast Notifications ```typescript import { toast, Toaster } from 'react-hot-toast'; function App() { return ( <> ); } // Custom toast function CustomToast() { return ( ); } ``` ## 6. Command Palette ```typescript import { useEffect, useState } from 'react'; function CommandPalette() { const [isOpen, setIsOpen] = useState(false); const [query, setQuery] = useState(''); useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); setIsOpen(true); } }; document.addEventListener('keydown', handleKeyDown); return () => document.removeEventListener('keydown', handleKeyDown); }, []); const commands = [ { name: 'New Post', action: () => {} }, { name: 'Settings', action: () => {} }, { name: 'Logout', action: () => {} } ]; const filtered = commands.filter(cmd => cmd.name.toLowerCase().includes(query.toLowerCase()) ); if (!isOpen) return null; return (
setQuery(e.target.value)} className="w-full p-4 border-b" autoFocus />
{filtered.map(cmd => ( ))}
); } ``` ## 7. Skeleton Loading ```typescript function SkeletonCard() { return (
); } function ContentWithSkeleton() { const { data, isLoading } = useQuery({ queryKey: ['content'], queryFn: fetchContent }); if (isLoading) return ; return ; } ``` ## Best Practices 1. **Virtual scrolling for large lists** - Render only visible items 2. **Intersection Observer** - Better than scroll events 3. **Portal for modals** - Avoid z-index issues 4. **Focus management** - Trap focus in modals 5. **Keyboard shortcuts** - Cmd+K for command palette 6. **Optimistic updates** - Update UI before server response 7. **Skeleton screens** - Better than spinners for content 8. **Debounce search** - Reduce API calls