168 lines
10 KiB
HTML
168 lines
10 KiB
HTML
<h2>GIF Category Pills — Full Design</h2>
|
|
<p class="subtitle">Horizontal scrollable pill row on the idle GIF picker screen</p>
|
|
|
|
<div class="section">
|
|
<h3>Interaction Flow</h3>
|
|
<div style="display:flex;gap:16px;flex-wrap:wrap">
|
|
<!-- State 1: Idle / Trending selected -->
|
|
<div style="flex:1;min-width:220px">
|
|
<div class="mockup">
|
|
<div class="mockup-header">1. Idle — "Trending" active</div>
|
|
<div class="mockup-body" style="padding:12px;font-family:system-ui;background:#1a1a2e;color:#e0e0e0;font-size:13px">
|
|
<div style="background:#2a2a4a;border-radius:8px;padding:8px 12px;display:flex;align-items:center;gap:8px;margin-bottom:8px">
|
|
<span style="opacity:0.4">🔍</span>
|
|
<span style="opacity:0.4">Search GIFs</span>
|
|
</div>
|
|
<div style="display:flex;gap:6px;margin-bottom:10px;overflow-x:auto;font-size:12px">
|
|
<div style="background:#4a4a7a;border-radius:16px;padding:5px 12px;white-space:nowrap">🔥 Trending</div>
|
|
<div style="background:#2a2a4a;border:1px solid #444;border-radius:16px;padding:5px 12px;white-space:nowrap">❤️ Love</div>
|
|
<div style="background:#2a2a4a;border:1px solid #444;border-radius:16px;padding:5px 12px;white-space:nowrap">😄 Happy</div>
|
|
<div style="background:#2a2a4a;border:1px solid #444;border-radius:16px;padding:5px 12px;white-space:nowrap;opacity:0.5">...</div>
|
|
</div>
|
|
<div style="display:flex;gap:6px">
|
|
<div style="flex:1;background:#444;border-radius:6px;height:50px"></div>
|
|
<div style="flex:1;background:#444;border-radius:6px;height:40px"></div>
|
|
</div>
|
|
<div style="text-align:center;margin-top:6px;font-size:10px;opacity:0.4">Featured GIFs</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- State 2: Category selected -->
|
|
<div style="flex:1;min-width:220px">
|
|
<div class="mockup">
|
|
<div class="mockup-header">2. "Happy" tapped</div>
|
|
<div class="mockup-body" style="padding:12px;font-family:system-ui;background:#1a1a2e;color:#e0e0e0;font-size:13px">
|
|
<div style="background:#2a2a4a;border-radius:8px;padding:8px 12px;display:flex;align-items:center;gap:8px;margin-bottom:8px">
|
|
<span style="opacity:0.4">🔍</span>
|
|
<span style="opacity:0.4">Search GIFs</span>
|
|
</div>
|
|
<div style="display:flex;gap:6px;margin-bottom:10px;overflow-x:auto;font-size:12px">
|
|
<div style="background:#2a2a4a;border:1px solid #444;border-radius:16px;padding:5px 12px;white-space:nowrap">🔥 Trending</div>
|
|
<div style="background:#2a2a4a;border:1px solid #444;border-radius:16px;padding:5px 12px;white-space:nowrap">❤️ Love</div>
|
|
<div style="background:#4a4a7a;border-radius:16px;padding:5px 12px;white-space:nowrap">😄 Happy</div>
|
|
<div style="background:#2a2a4a;border:1px solid #444;border-radius:16px;padding:5px 12px;white-space:nowrap;opacity:0.5">...</div>
|
|
</div>
|
|
<div style="display:flex;gap:6px">
|
|
<div style="flex:1;background:#555;border-radius:6px;height:50px"></div>
|
|
<div style="flex:1;background:#555;border-radius:6px;height:40px"></div>
|
|
</div>
|
|
<div style="text-align:center;margin-top:6px;font-size:10px;opacity:0.4">Search results for "happy"</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- State 3: User typing -->
|
|
<div style="flex:1;min-width:220px">
|
|
<div class="mockup">
|
|
<div class="mockup-header">3. Typing — pills hidden</div>
|
|
<div class="mockup-body" style="padding:12px;font-family:system-ui;background:#1a1a2e;color:#e0e0e0;font-size:13px">
|
|
<div style="background:#2a2a4a;border-radius:8px;padding:8px 12px;display:flex;align-items:center;gap:8px;margin-bottom:8px">
|
|
<span style="opacity:0.4">🔍</span>
|
|
<span>sponge<span style="opacity:0.3">|</span></span>
|
|
</div>
|
|
<div style="display:flex;gap:6px">
|
|
<div style="flex:1;display:flex;flex-direction:column;gap:6px">
|
|
<div style="background:#555;border-radius:6px;height:50px"></div>
|
|
<div style="background:#555;border-radius:6px;height:40px"></div>
|
|
</div>
|
|
<div style="flex:1;display:flex;flex-direction:column;gap:6px">
|
|
<div style="background:#555;border-radius:6px;height:40px"></div>
|
|
<div style="background:#555;border-radius:6px;height:50px"></div>
|
|
</div>
|
|
</div>
|
|
<div style="text-align:center;margin-top:6px;font-size:10px;opacity:0.4">Search results</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h3>Architecture</h3>
|
|
<div class="mockup">
|
|
<div class="mockup-header">Component & Data Flow</div>
|
|
<div class="mockup-body" style="padding:20px;font-family:system-ui;font-size:14px;line-height:1.6">
|
|
<div style="display:flex;gap:32px;flex-wrap:wrap">
|
|
<div style="flex:1;min-width:280px">
|
|
<div style="font-weight:600;margin-bottom:10px;color:#7c7cff;text-transform:uppercase;font-size:11px;letter-spacing:1px">Component Tree</div>
|
|
<div style="font-family:monospace;font-size:13px;line-height:2">
|
|
<div>GifPickerBody</div>
|
|
<div style="padding-left:20px">├─ GifPickerHeader</div>
|
|
<div style="padding-left:40px">│ └─ TextField.Input</div>
|
|
<div style="padding-left:20px">├─ <span style="color:#5cdb5c;font-weight:600">GifCategoryPills</span> <span style="color:#5cdb5c;opacity:0.7">← NEW</span></div>
|
|
<div style="padding-left:40px">│ <span style="opacity:0.5">(hidden when typing)</span></div>
|
|
<div style="padding-left:20px">├─ GifPickerPlaceholder</div>
|
|
<div style="padding-left:20px">└─ GifPickerGrid</div>
|
|
</div>
|
|
</div>
|
|
<div style="flex:1;min-width:280px">
|
|
<div style="font-weight:600;margin-bottom:10px;color:#ff7c7c;text-transform:uppercase;font-size:11px;letter-spacing:1px">Data Flow</div>
|
|
<div style="font-family:monospace;font-size:13px;line-height:2">
|
|
<div><span style="opacity:0.5">1.</span> Idle → "Trending" active → featured endpoint</div>
|
|
<div><span style="opacity:0.5">2.</span> Tap pill → set search to pill's searchterm</div>
|
|
<div><span style="opacity:0.5">3.</span> useGifPickerData sees search → fires GIF search</div>
|
|
<div><span style="opacity:0.5">4.</span> User types → pills hide, search takes over</div>
|
|
<div><span style="opacity:0.5">5.</span> User clears input → pills reappear, "Trending" resets</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h3>File Changes</h3>
|
|
<div style="font-family:monospace;font-size:13px;line-height:2.2;padding:0 8px">
|
|
<div><span style="color:#5cdb5c">+</span> <strong>src/features/gifPicker/components/GifCategoryPills.tsx</strong> — pill row component</div>
|
|
<div><span style="color:#ffcc00">~</span> <strong>src/features/gifPicker/GifPickerDialog.tsx</strong> — add category state, render pills in header, connect to search</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h3>Curated Categories</h3>
|
|
<div style="display:flex;gap:8px;flex-wrap:wrap;margin-top:8px">
|
|
<div style="background:#2a2a4a;border:1px solid #555;border-radius:20px;padding:6px 14px;font-size:13px;font-family:system-ui">🔥 Trending</div>
|
|
<div style="background:#2a2a4a;border:1px solid #555;border-radius:20px;padding:6px 14px;font-size:13px;font-family:system-ui">❤️ Love</div>
|
|
<div style="background:#2a2a4a;border:1px solid #555;border-radius:20px;padding:6px 14px;font-size:13px;font-family:system-ui">😄 Happy</div>
|
|
<div style="background:#2a2a4a;border:1px solid #555;border-radius:20px;padding:6px 14px;font-size:13px;font-family:system-ui">😢 Sad</div>
|
|
<div style="background:#2a2a4a;border:1px solid #555;border-radius:20px;padding:6px 14px;font-size:13px;font-family:system-ui">🎉 Party</div>
|
|
<div style="background:#2a2a4a;border:1px solid #555;border-radius:20px;padding:6px 14px;font-size:13px;font-family:system-ui">👍 Yes</div>
|
|
<div style="background:#2a2a4a;border:1px solid #555;border-radius:20px;padding:6px 14px;font-size:13px;font-family:system-ui">😂 LOL</div>
|
|
<div style="background:#2a2a4a;border:1px solid #555;border-radius:20px;padding:6px 14px;font-size:13px;font-family:system-ui">🤩 Excited</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h3>Key Design Decisions</h3>
|
|
<div style="font-family:system-ui;font-size:14px;line-height:1.8;padding:0 8px">
|
|
<div><strong>No new API endpoint needed</strong> — tapping a category pill just sets the search query to the category's searchterm and uses the existing search flow</div>
|
|
<div><strong>"Trending" = featured endpoint</strong> — the default active pill uses the existing featured GIFs, no search query</div>
|
|
<div><strong>Pills hide while typing</strong> — simple visibility toggle based on whether rawSearch has content</div>
|
|
<div><strong>Clearing input resets to Trending</strong> — pills reappear with "Trending" active again</div>
|
|
<div><strong>Hardcoded category list</strong> — curated for quality, no extra API call needed</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="section">
|
|
<h3>Scope</h3>
|
|
<div class="pros-cons">
|
|
<div class="pros">
|
|
<h4>In Scope</h4>
|
|
<ul>
|
|
<li>GifCategoryPills component (horizontal scroll, active state)</li>
|
|
<li>8 curated category pills with emoji + label</li>
|
|
<li>Tap pill → search GIFs for that category</li>
|
|
<li>Pills hide when typing, reappear when cleared</li>
|
|
<li>Active pill highlight styling</li>
|
|
</ul>
|
|
</div>
|
|
<div class="cons">
|
|
<h4>Out of Scope</h4>
|
|
<ul>
|
|
<li>Recent / Favorited (needs client-side persistence)</li>
|
|
<li>Dynamic categories from API</li>
|
|
<li>Category GIF thumbnails on the pills</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|