66} from "@components/UI/Popover.tsx" ;
77import { cn } from "@core/utils/cn.ts" ;
88import { LayersIcon } from "lucide-react" ;
9- import type { ReactNode } from "react" ;
9+ import { type ReactNode , useMemo } from "react" ;
1010import { useTranslation } from "react-i18next" ;
1111
1212export interface VisibilityState {
@@ -62,13 +62,36 @@ export function MapLayerTool({
6262} : MapLayerToolProps ) : ReactNode {
6363 const { t } = useTranslation ( "map" ) ;
6464
65+ const enabledCount = useMemo ( ( ) => {
66+ return Object . values ( visibilityState ) . filter ( Boolean ) . length ;
67+ } , [ visibilityState ] ) ;
68+
69+ const handleCheckboxChange = ( key : keyof VisibilityState ) => {
70+ setVisibilityState ( {
71+ ...visibilityState ,
72+ [ key ] : ! visibilityState [ key ] ,
73+ } ) ;
74+ } ;
75+
76+ const layers = useMemo (
77+ ( ) => [
78+ { key : "nodeMarkers" , label : t ( "layerTool.nodeMarkers" ) } ,
79+ { key : "waypoints" , label : t ( "layerTool.waypoints" ) } ,
80+ { key : "directNeighbors" , label : t ( "layerTool.directNeighbors" ) } ,
81+ { key : "remoteNeighbors" , label : t ( "layerTool.remoteNeighbors" ) } ,
82+ { key : "positionPrecision" , label : t ( "layerTool.positionPrecision" ) } ,
83+ // { key: "traceroutes", label: t("layerTool.traceroutes") },
84+ ] ,
85+ [ t ] ,
86+ ) ;
87+
6588 return (
6689 < Popover >
6790 < PopoverTrigger asChild >
6891 < button
6992 type = "button"
7093 className = { cn (
71- "rounded align-center" ,
94+ "relative rounded align-center" ,
7295 "w-[29px] px-1 py-1 shadow-l outline-[2px] outline-stone-600/20" ,
7396 "bg-stone-50 hover:bg-stone-200 dark:bg-stone-200 dark:hover:bg-stone-300 " ,
7497 "text-slate-600 hover:text-slate-700 active:bg-slate-300" ,
@@ -77,6 +100,21 @@ export function MapLayerTool({
77100 aria-label = { t ( "mapMenu.layersAria" ) }
78101 >
79102 < LayersIcon className = "w-[21px]" />
103+ { enabledCount > 0 && (
104+ < span
105+ className = { cn (
106+ "absolute -bottom-2 -right-2" ,
107+ "min-w-4 h-4 px-[3px]" ,
108+ "rounded-full text-[10px] leading-4" ,
109+ "bg-blue-500 text-white" ,
110+ "flex items-center justify-center" ,
111+ "ring-2 ring-white dark:ring-stone-200" ,
112+ ) }
113+ aria-hidden = "true"
114+ >
115+ { enabledCount }
116+ </ span >
117+ ) }
80118 </ button >
81119 </ PopoverTrigger >
82120 < PopoverContent
@@ -85,50 +123,14 @@ export function MapLayerTool({
85123 align = "end"
86124 sideOffset = { 7 }
87125 >
88- < CheckboxItem
89- label = { t ( "layerTool.nodeMarkers" ) }
90- checked = { visibilityState . nodeMarkers }
91- onChange = { ( checked ) => {
92- setVisibilityState ( { ...visibilityState , nodeMarkers : checked } ) ;
93- } }
94- />
95- < CheckboxItem
96- label = { t ( "layerTool.waypoints" ) }
97- checked = { visibilityState . waypoints }
98- onChange = { ( checked ) => {
99- setVisibilityState ( { ...visibilityState , waypoints : checked } ) ;
100- } }
101- />
102- < CheckboxItem
103- label = { t ( "layerTool.directNeighbors" ) }
104- checked = { visibilityState . directNeighbors }
105- onChange = { ( checked ) => {
106- setVisibilityState ( {
107- ...visibilityState ,
108- directNeighbors : checked ,
109- } ) ;
110- } }
111- />
112- < CheckboxItem
113- label = { t ( "layerTool.remoteNeighbors" ) }
114- checked = { visibilityState . remoteNeighbors }
115- onChange = { ( checked ) => {
116- setVisibilityState ( {
117- ...visibilityState ,
118- remoteNeighbors : checked ,
119- } ) ;
120- } }
121- />
122- < CheckboxItem
123- label = { t ( "layerTool.positionPrecision" ) }
124- checked = { visibilityState . positionPrecision }
125- onChange = { ( checked ) => {
126- setVisibilityState ( {
127- ...visibilityState ,
128- positionPrecision : checked ,
129- } ) ;
130- } }
131- />
126+ { layers . map ( ( { key, label } ) => (
127+ < CheckboxItem
128+ key = { key }
129+ label = { label }
130+ checked = { visibilityState [ key as keyof VisibilityState ] }
131+ onChange = { ( ) => handleCheckboxChange ( key as keyof VisibilityState ) }
132+ />
133+ ) ) }
132134 { /*<CheckboxItem
133135 key="traceroutes"
134136 label={t("layerTool.traceroutes")}
0 commit comments