diff --git a/src/app/globals.css b/src/app/globals.css index 50052b5..f4a1c4a 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -461,4 +461,88 @@ html { .how-it-works-popup::-webkit-scrollbar-thumb { background: var(--border-secondary); border-radius: 2px; +} + +/* ===== SLIDE-UP DRAWER ANIMATIONS ===== */ + +@keyframes fadeIn { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@keyframes slideUp { + 0% { + opacity: 0; + transform: translateY(100%); + } + + 100% { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes slideDown { + 0% { + opacity: 1; + transform: translateY(0); + } + + 100% { + opacity: 0; + transform: translateY(100%); + } +} + +@keyframes fadeOut { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + +@keyframes tooltipSlideUp { + 0% { + opacity: 0; + transform: translateY(8px); + } + + 100% { + opacity: 1; + transform: translateY(0); + } +} + +/* ===== COMMAND BAR SCROLLBAR ===== */ + +.command-scroll { + scrollbar-width: thin; + scrollbar-color: var(--text-muted) var(--bg-hover); + padding-bottom: 10px; +} + +.command-scroll::-webkit-scrollbar { + height: 6px; +} + +.command-scroll::-webkit-scrollbar-track { + background: var(--bg-hover); + border-radius: 6px; +} + +.command-scroll::-webkit-scrollbar-thumb { + background: var(--text-muted); + border-radius: 6px; +} + +.command-scroll::-webkit-scrollbar-thumb:hover { + background: var(--text-primary); } \ No newline at end of file diff --git a/src/app/page.tsx b/src/app/page.tsx index fe5825f..b73dd38 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -2,7 +2,7 @@ import { useState, useEffect, useMemo, useCallback, useRef, useLayoutEffect } from 'react'; import { createPortal } from 'react-dom'; -import { Check, Copy, ChevronDown, ChevronRight, X, Download, HelpCircle, Github, Heart } from 'lucide-react'; +import { Check, Copy, ChevronDown, ChevronRight, ChevronUp, X, Download, HelpCircle, Github, Heart } from 'lucide-react'; import { useLinuxInit } from '@/hooks/useLinuxInit'; import { distros, categories, getAppsByCategory, type DistroId, type AppData, type Category } from '@/lib/data'; import { generateInstallScript } from '@/lib/generateInstallScript'; @@ -664,6 +664,26 @@ function CommandFooter({ const [copied, setCopied] = useState(false); const [showCopyTooltip, setShowCopyTooltip] = useState(false); const [showDownloadTooltip, setShowDownloadTooltip] = useState(false); + const [drawerOpen, setDrawerOpen] = useState(false); + const [drawerClosing, setDrawerClosing] = useState(false); + + const closeDrawer = useCallback(() => { + setDrawerClosing(true); + setTimeout(() => { + setDrawerOpen(false); + setDrawerClosing(false); + }, 250); + }, []); + + // Close drawer on Escape key + useEffect(() => { + if (!drawerOpen) return; + const handleEscape = (e: KeyboardEvent) => { + if (e.key === 'Escape') closeDrawer(); + }; + document.addEventListener('keydown', handleEscape); + return () => document.removeEventListener('keydown', handleEscape); + }, [drawerOpen, closeDrawer]); const handleCopy = async () => { if (selectedCount === 0) return; @@ -764,23 +784,37 @@ function CommandFooter({ - {/* Command Bar */} + {/* Command Bar - Compact */}
{selectedCount} -
- 0 ? 'text-[var(--text-secondary)]' : 'text-[var(--text-muted)]'} style={{ transition: 'color 0.5s' }}>{command} +
selectedCount > 0 && setDrawerOpen(true)} + > +
+
+ 0 ? 'text-[var(--text-secondary)]' : 'text-[var(--text-muted)]'}`} style={{ transition: 'color 0.5s' }}>{command} +
+ {selectedCount > 0 && ( +
+ +
+ )} +
{/* Download Button with Tooltip */} -
selectedCount > 0 && setShowDownloadTooltip(true)} onMouseLeave={() => setShowDownloadTooltip(false)} > {showDownloadTooltip && (
{/* Copy Button with Tooltip */} -
+
+ + {/* Slide-up Drawer */} + {drawerOpen && ( + <> + {/* Backdrop */} +