Skip to content

Commit bddc542

Browse files
💄 fix(flight-map): better LnF
1 parent 585601a commit bddc542

File tree

4 files changed

+72
-19
lines changed

4 files changed

+72
-19
lines changed
3.37 KB
Loading

‎src/components/pages/about/flight-map.tsx

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1+
import { AnimatePresence, motion, useMotionValue, useSpring, useTransform } from 'framer-motion';
12
import 'leaflet/dist/leaflet.css';
23
import { useTheme } from 'next-themes';
34
import dynamic from 'next/dynamic';
45
import { useState } from 'react';
56

67
import { Airline, Flight } from 'services/content/flights';
78

8-
import { airportCoordinates, getAirlineColor } from 'utils/flights';
9+
import { airportCoordinates, getAirlineColor, getTileUrl } from 'utils/flights';
910
import { classNames } from 'utils/styles';
1011

12+
import Typography from 'components/shared/typography';
13+
1114
const MapContainer = dynamic(() => import('react-leaflet').then((mod) => mod.MapContainer), { ssr: false });
1215
const TileLayer = dynamic(() => import('react-leaflet').then((mod) => mod.TileLayer), { ssr: false });
1316
const Polyline = dynamic(() => import('react-leaflet').then((mod) => mod.Polyline), { ssr: false });
@@ -57,15 +60,16 @@ interface MapProps {
5760

5861
function Map({ flights, airports, isDarkMode }: MapProps) {
5962
const [hoveredFlight, setHoveredFlight] = useState<number | null>(null);
63+
const x = useMotionValue(0);
64+
65+
const config = { damping: 5, stiffness: 100 };
66+
const rotate = useSpring(useTransform(x, [-100, 100], [-45, 45]), config);
67+
const translateX = useSpring(useTransform(x, [-100, 100], [-47, 47]), config);
6068

6169
return (
6270
<MapContainer center={[20, 0]} zoom={2} className="absolute inset-0 w-full h-full">
6371
<TileLayer
64-
url={
65-
isDarkMode
66-
? 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png'
67-
: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
68-
}
72+
url={getTileUrl(isDarkMode)}
6973
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
7074
/>
7175
{flights.map((flight, index) => {
@@ -106,15 +110,39 @@ function Map({ flights, airports, isDarkMode }: MapProps) {
106110
weight={1}
107111
fillOpacity={1}
108112
>
109-
<Tooltip direction="top" offset={[0, -5]} opacity={1} permanent>
110-
<div
111-
className={classNames('px-2 py-1 rounded-full text-xs font-semibold', {
112-
'bg-gray-800 text-white': isDarkMode,
113-
'bg-white text-gray-800 shadow-md border border-gray-200': !isDarkMode,
114-
})}
115-
>
116-
{airport}
117-
</div>
113+
<Tooltip
114+
direction="auto"
115+
offset={[0, -5]}
116+
opacity={1}
117+
className="absolute inset-0 w-full h-full"
118+
noArrow
119+
sticky
120+
>
121+
<AnimatePresence mode="popLayout">
122+
<motion.div
123+
initial={{ opacity: 0, scale: 0.6, y: 20 }}
124+
animate={{
125+
opacity: 1,
126+
scale: 1,
127+
transition: { damping: 10, stiffness: 260, type: 'spring' },
128+
y: 0,
129+
}}
130+
exit={{ opacity: 0, scale: 0.6, y: 20 }}
131+
style={{
132+
left: '50%',
133+
rotate,
134+
transform: 'translateX(50%)',
135+
translateX: '-50%',
136+
whiteSpace: 'nowrap',
137+
x: translateX,
138+
}}
139+
className="absolute -top-10 z-50 flex flex-col items-center justify-center rounded-md bg-primary px-4 py-2 text-xs shadow-xl"
140+
>
141+
<Typography.small className="relative z-30 text-base font-bold text-secondary">
142+
{airport}
143+
</Typography.small>
144+
</motion.div>
145+
</AnimatePresence>
118146
</Tooltip>
119147
</CircleMarker>
120148
);
@@ -154,7 +182,7 @@ export default function FlightMap({ flights, airlines, airports }: FlightMapProp
154182
setSelectedAirline={setSelectedAirline}
155183
isDarkMode={isDarkMode}
156184
/>
157-
<span
185+
<Typography.small
158186
className={classNames('text-sm', {
159187
'text-gray-300': isDarkMode,
160188
'text-gray-600': !isDarkMode,
@@ -163,11 +191,11 @@ export default function FlightMap({ flights, airlines, airports }: FlightMapProp
163191
{selectedAirline
164192
? `${filteredFlights.length} of ${flights.length} flights`
165193
: `${flights.length} total flights`}
166-
</span>
194+
</Typography.small>
167195
</div>
168196
</div>
169197
</div>
170-
<div className="relative h-[60vh] mx-4 mt-4 rounded-lg overflow-hidden shadow-lg">
198+
<div className="relative h-[60vh] w-full mt-4 rounded-lg overflow-hidden shadow-lg">
171199
<Map flights={filteredFlights} airports={airports} isDarkMode={isDarkMode} />
172200
</div>
173201
</div>

‎src/css/tailwind.css

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,23 @@
108108
.print-force-new-page {
109109
page-break-before: always;
110110
}
111+
112+
/* ---------------------------------------------------------------------------
113+
Tooltip overrides
114+
--------------------------------------------------------------------------- */
115+
116+
.leaflet-tooltip {
117+
background-color: transparent !important;
118+
border: none !important;
119+
box-shadow: none !important;
120+
}
121+
122+
.leaflet-tooltip-top:before,
123+
.leaflet-tooltip-bottom:before,
124+
.leaflet-tooltip-left:before,
125+
.leaflet-tooltip-right:before {
126+
background: transparent;
127+
content: '';
128+
border: none !important;
129+
display: none !important;
130+
}

‎src/utils/flights.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,9 @@ export const airlineNames = {
111111
O6: 'Avianca Brasil',
112112
} as const;
113113

114-
export const getAirlineColor = (airline: string) => airlineColors[airline] || '#9E9E9E'; // Default to a neutral gray
114+
export const getAirlineColor = (airline: string) => airlineColors[airline] || '#9E9E9E';
115+
116+
export const getTileUrl = (isDarkMode: boolean) =>
117+
isDarkMode
118+
? 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png'
119+
: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';

0 commit comments

Comments
 (0)