Improve FAB menu: z-index, labels, clear all filters

- Fix z-index so FAB items appear above weather widget
- Add X button to clear all filters when FAB is open
- Add text labels for categories and subcategories
- Make labels readable with dark text on light background
- Update backdrop z-index hierarchy

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Sociowire Dev 2026-01-12 04:59:32 +00:00
parent 8e3f8c4859
commit 74ab0bd1f5
3 changed files with 88 additions and 30 deletions

View File

@ -2007,6 +2007,10 @@ export default function MapView({
onSubcategoryToggle={handleSubcategoryToggle}
onTime={(h) => setTimeHours(h)}
onWeather={() => setWeatherViewEnabled((prev) => !prev)}
onClearAllFilters={() => {
setMainFilters([]);
setSubFilters([]);
}}
activeCategories={mainFilters}
activeSubcategories={subFilters}
activeTime={timeHours}

View File

@ -7,7 +7,7 @@
background: rgba(0, 0, 0, 0.15);
backdrop-filter: blur(2px);
-webkit-backdrop-filter: blur(2px);
z-index: 398; /* Below search dropdown (500) */
z-index: 440; /* Above weather widget (300), below FAB items */
animation: fab-fade-in 0.2s ease;
}
@ -21,7 +21,7 @@
.fab-right {
position: fixed;
top: 180px;
z-index: 399; /* Below search dropdown (500) */
z-index: 450; /* Above weather widget (300), below search dropdown (500) */
}
.fab-left {
@ -46,10 +46,10 @@
align-items: center;
justify-content: center;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
transition: transform 0.2s ease, box-shadow 0.2s ease;
transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
-webkit-tap-highlight-color: transparent;
position: relative;
z-index: 400; /* Below search dropdown (500) */
z-index: 451; /* Above weather widget (300), below search dropdown (500) */
}
.fab-btn-right {
@ -81,16 +81,50 @@
transform: translateX(-50%);
font-size: 10px;
font-weight: 700;
color: #e2e8f0;
text-shadow: 0 1px 4px rgba(0,0,0,0.8);
color: #1e293b;
text-shadow: 0 1px 2px rgba(255,255,255,0.8);
white-space: nowrap;
pointer-events: none;
background: rgba(255, 255, 255, 0.85);
padding: 2px 6px;
border-radius: 4px;
max-width: 80px;
overflow: hidden;
text-overflow: ellipsis;
}
.fab-label-time {
background: rgba(15, 23, 42, 0.85);
padding: 2px 6px;
border-radius: 4px;
color: #e2e8f0;
text-shadow: 0 1px 4px rgba(0,0,0,0.8);
}
.fab-label-cat {
background: rgba(255, 255, 255, 0.9);
color: #1e293b;
}
/* Item labels (category/subcategory names) */
.fab-item-label {
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
margin-top: 4px;
font-size: 9px;
font-weight: 700;
color: #1e293b;
text-shadow: 0 1px 2px rgba(255,255,255,0.9);
white-space: nowrap;
pointer-events: none;
background: rgba(255, 255, 255, 0.9);
padding: 1px 5px;
border-radius: 3px;
}
.fab-sub-label {
font-size: 8px;
margin-top: 3px;
}
/* Ring containers */
@ -138,6 +172,7 @@
transform: translate(var(--x), var(--y)) scale(1);
pointer-events: auto;
transition-delay: var(--delay);
z-index: 452; /* Above weather widget when visible */
}
.fab-item:hover {
@ -175,6 +210,7 @@
animation: fab-pop-in 0.25s cubic-bezier(0.34, 1.56, 0.64, 1) backwards;
animation-delay: var(--delay);
--color: #64748b;
z-index: 453; /* Above category items */
}
.fab-sub.is-active {

View File

@ -2,34 +2,34 @@ import React, { useState, useCallback } from "react";
import "./RadialMenu.css";
const CATEGORIES = [
{ id: "News", icon: "fa-solid fa-newspaper", color: "#3b82f6" },
{ id: "Friends", icon: "fa-solid fa-users", color: "#10b981" },
{ id: "Events", icon: "fa-solid fa-calendar", color: "#f59e0b" },
{ id: "Market", icon: "fa-solid fa-store", color: "#8b5cf6" },
{ id: "News", icon: "fa-solid fa-newspaper", color: "#3b82f6", label: "News" },
{ id: "Friends", icon: "fa-solid fa-users", color: "#10b981", label: "Social" },
{ id: "Events", icon: "fa-solid fa-calendar", color: "#f59e0b", label: "Events" },
{ id: "Market", icon: "fa-solid fa-store", color: "#8b5cf6", label: "Market" },
];
const SUBCATEGORIES = {
News: [
{ id: "World", icon: "fa-solid fa-globe" },
{ id: "Politics", icon: "fa-solid fa-landmark" },
{ id: "Tech", icon: "fa-solid fa-microchip" },
{ id: "Finance", icon: "fa-solid fa-chart-line" },
{ id: "Local", icon: "fa-solid fa-location-dot" },
{ id: "World", icon: "fa-solid fa-globe", label: "World" },
{ id: "Politics", icon: "fa-solid fa-landmark", label: "Politics" },
{ id: "Tech", icon: "fa-solid fa-microchip", label: "Tech" },
{ id: "Finance", icon: "fa-solid fa-chart-line", label: "Finance" },
{ id: "Local", icon: "fa-solid fa-location-dot", label: "Local" },
],
Friends: [
{ id: "Nearby", icon: "fa-solid fa-location-crosshairs" },
{ id: "Chats", icon: "fa-solid fa-comments" },
{ id: "Groups", icon: "fa-solid fa-user-group" },
{ id: "Nearby", icon: "fa-solid fa-location-crosshairs", label: "Near" },
{ id: "Chats", icon: "fa-solid fa-comments", label: "Chats" },
{ id: "Groups", icon: "fa-solid fa-user-group", label: "Groups" },
],
Events: [
{ id: "Today", icon: "fa-solid fa-calendar-day" },
{ id: "Music", icon: "fa-solid fa-music" },
{ id: "Sports", icon: "fa-solid fa-football" },
{ id: "Today", icon: "fa-solid fa-calendar-day", label: "Today" },
{ id: "Music", icon: "fa-solid fa-music", label: "Music" },
{ id: "Sports", icon: "fa-solid fa-football", label: "Sports" },
],
Market: [
{ id: "Deals", icon: "fa-solid fa-tags" },
{ id: "Tech", icon: "fa-solid fa-laptop" },
{ id: "Auto", icon: "fa-solid fa-car" },
{ id: "Deals", icon: "fa-solid fa-tags", label: "Deals" },
{ id: "Tech", icon: "fa-solid fa-laptop", label: "Tech" },
{ id: "Auto", icon: "fa-solid fa-car", label: "Auto" },
],
};
@ -46,6 +46,7 @@ export default function RadialMenu({
onSubcategoryToggle,
onTime,
onWeather,
onClearAllFilters,
activeCategories = [],
activeSubcategories = [],
activeTime,
@ -59,6 +60,8 @@ export default function RadialMenu({
.filter(c => activeCategories.includes(c.id))
.map(c => c.color);
const hasActiveFilters = activeCategories.length > 0 || activeSubcategories.length > 0;
const handleLeftToggle = () => {
setLeftOpen(!leftOpen);
if (!leftOpen) setRightOpen(false);
@ -85,6 +88,15 @@ export default function RadialMenu({
onWeather?.();
};
const handleClearAll = () => {
// Clear all category filters
for (const cat of activeCategories) {
onCategoryToggle?.(cat);
}
setLeftOpen(false);
onClearAllFilters?.();
};
// Build gradient for multi-select FAB
const fabGradient = activeColors.length === 0
? "linear-gradient(135deg, #6366f1 0%, #4f46e5 100%)"
@ -129,12 +141,13 @@ export default function RadialMenu({
<React.Fragment key={cat.id}>
{/* Category button */}
<button
className={`fab-item ${leftOpen ? "is-visible" : ""} ${isActive ? "is-active" : ""}`}
className={`fab-item fab-cat ${leftOpen ? "is-visible" : ""} ${isActive ? "is-active" : ""}`}
style={{ "--x": `${x}px`, "--y": `${y}px`, "--delay": `${i * 40}ms`, "--color": cat.color }}
onClick={() => handleCategoryClick(cat.id)}
title={cat.id}
>
<i className={cat.icon} />
<span className="fab-item-label">{cat.label}</span>
</button>
{/* Subcategories - appear around the category when active */}
@ -162,6 +175,7 @@ export default function RadialMenu({
title={sub.id}
>
<i className={sub.icon} />
<span className="fab-item-label fab-sub-label">{sub.label}</span>
</button>
);
})}
@ -173,10 +187,13 @@ export default function RadialMenu({
{/* Main FAB - split colors */}
<button
className="fab-btn fab-btn-split"
onClick={handleLeftToggle}
style={{ background: fabGradient }}
onClick={leftOpen && hasActiveFilters ? handleClearAll : handleLeftToggle}
style={{ background: leftOpen ? "#ef4444" : fabGradient }}
title={leftOpen && hasActiveFilters ? "Clear all filters" : "Categories"}
>
{activeCategories.length === 0 ? (
{leftOpen ? (
<i className="fa-solid fa-xmark" />
) : activeCategories.length === 0 ? (
<i className="fa-solid fa-layer-group" />
) : activeCategories.length === 1 ? (
<i className={CATEGORIES.find(c => c.id === activeCategories[0])?.icon || "fa-solid fa-layer-group"} />
@ -184,6 +201,7 @@ export default function RadialMenu({
<span className="fab-count">{activeCategories.length}</span>
)}
</button>
<span className="fab-label fab-label-cat">{leftOpen ? "Clear" : activeCategories.length > 0 ? activeCategories.join(", ") : "Filter"}</span>
</div>
{/* RIGHT FAB - Time & Weather */}