Skip to content

Commit 1b3af23

Browse files
committed
Add custom map text/bg overrides
1 parent 7250abb commit 1b3af23

2 files changed

Lines changed: 27 additions & 23 deletions

File tree

packages/react/src/components/StationsMap.tsx

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import { keepPreviousData } from "@tanstack/react-query";
2222
import { useStation } from "../hooks/use-station.js";
2323
import { useStations } from "../hooks/use-stations.js";
2424
import { useDebouncedCallback } from "../hooks/use-debounced-callback.js";
25-
import { useDarkMode } from "../hooks/use-dark-mode.js";
2625
import { useThemeColors } from "../hooks/use-theme-colors.js";
2726
import { TideConditions } from "./TideConditions.js";
2827
import type { StationSummary } from "../types.js";
@@ -31,8 +30,6 @@ import type { StationSummary } from "../types.js";
3130
type ManagedMapProps = "onMove" | "onClick" | "interactiveLayerIds" | "style" | "cursor";
3231

3332
export interface StationsMapProps extends Omit<ComponentProps<typeof Map>, ManagedMapProps> {
34-
/** Optional dark mode style URL. Switches automatically based on .dark class or prefers-color-scheme. */
35-
darkMapStyle?: string;
3633
onStationSelect?: (station: StationSummary) => void;
3734
onBoundsChange?: (bounds: { north: number; south: number; east: number; west: number }) => void;
3835
/** Whether to show the geolocation button. Defaults to true. */
@@ -77,8 +74,6 @@ function StationPreviewCard({ stationId }: { stationId: string }) {
7774

7875
export const StationsMap = forwardRef<MapRef, StationsMapProps>(function StationsMap(
7976
{
80-
mapStyle,
81-
darkMapStyle,
8277
onStationSelect,
8378
onBoundsChange,
8479
focusStation,
@@ -98,9 +93,7 @@ export const StationsMap = forwardRef<MapRef, StationsMapProps>(function Station
9893
const debouncedSetBbox = useDebouncedCallback(setBbox, 200);
9994
const [selectedStation, setSelectedStation] = useState<StationSummary | null>(null);
10095

101-
const isDarkMode = useDarkMode();
10296
const colors = useThemeColors();
103-
const effectiveMapStyle = isDarkMode && darkMapStyle ? darkMapStyle : mapStyle;
10497

10598
const {
10699
data: stations = [],
@@ -218,7 +211,6 @@ export const StationsMap = forwardRef<MapRef, StationsMapProps>(function Station
218211
onMove={handleMove}
219212
onClick={handleMapClick}
220213
interactiveLayerIds={["clusters", "unclustered-point"]}
221-
mapStyle={effectiveMapStyle}
222214
style={{ width: "100%", height: "100%" }}
223215
cursor="pointer"
224216
attributionControl={false}
@@ -291,17 +283,18 @@ export const StationsMap = forwardRef<MapRef, StationsMapProps>(function Station
291283
id="station-labels"
292284
type="symbol"
293285
filter={["!", ["has", "point_count"]]}
294-
minzoom={8}
286+
minzoom={7}
295287
layout={{
296288
"text-field": ["get", "name"],
297-
"text-size": 11,
289+
"text-size": 13,
298290
"text-offset": [0, 1.5],
299291
"text-anchor": "top",
300292
"text-max-width": 10,
293+
"text-font": ["Open Sans Bold", "Arial Unicode MS Bold"],
301294
}}
302295
paint={{
303-
"text-color": colors.text,
304-
"text-halo-color": colors.bg,
296+
"text-color": colors.mapText,
297+
"text-halo-color": colors.mapBg,
305298
"text-halo-width": 1.5,
306299
}}
307300
/>
@@ -325,15 +318,15 @@ export const StationsMap = forwardRef<MapRef, StationsMapProps>(function Station
325318
type="symbol"
326319
layout={{
327320
"text-field": ["get", "name"],
328-
"text-size": 12,
321+
"text-size": 14,
329322
"text-offset": [0, 1.8],
330323
"text-anchor": "top",
331324
"text-max-width": 10,
332325
"text-font": ["Open Sans Bold", "Arial Unicode MS Bold"],
333326
}}
334327
paint={{
335-
"text-color": colors.text,
336-
"text-halo-color": colors.bg,
328+
"text-color": colors.mapText,
329+
"text-halo-color": colors.mapBg,
337330
"text-halo-width": 2,
338331
}}
339332
/>

packages/react/src/hooks/use-theme-colors.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export interface ThemeColors {
1313
text: string;
1414
textMuted: string;
1515
border: string;
16+
mapText: string;
17+
mapBg: string;
1618
}
1719

1820
const FALLBACKS: ThemeColors = {
@@ -26,6 +28,8 @@ const FALLBACKS: ThemeColors = {
2628
text: "#0f172a",
2729
textMuted: "#64748b",
2830
border: "#e2e8f0",
31+
mapText: "#0f172a",
32+
mapBg: "#ffffff",
2933
};
3034

3135
/**
@@ -63,23 +67,30 @@ export function withAlpha(color: string, alpha: number): string {
6367

6468
/**
6569
* Reads resolved `--neaps-*` CSS custom property values from the DOM.
66-
* Re-computes when dark mode toggles so Chart.js (canvas) gets correct colors.
70+
* Re-computes when dark mode toggles.
71+
*
72+
* `--neaps-map-text` and `--neaps-map-bg` default to `--neaps-text` and `--neaps-bg`
73+
* respectively, so consumers only need to set them when the map background differs
74+
* from the app theme (e.g. satellite imagery).
6775
*/
6876
export function useThemeColors(): ThemeColors {
6977
const isDark = useDarkMode();
70-
return useMemo(
71-
() => ({
78+
return useMemo(() => {
79+
const text = readCSSVar("--neaps-text", FALLBACKS.text);
80+
const bg = readCSSVar("--neaps-bg", FALLBACKS.bg);
81+
return {
7282
primary: readCSSVar("--neaps-primary", FALLBACKS.primary),
7383
secondary: readCSSVar("--neaps-secondary", FALLBACKS.secondary),
7484
high: readCSSVar("--neaps-high", FALLBACKS.high),
7585
low: readCSSVar("--neaps-low", FALLBACKS.low),
7686
danger: readCSSVar("--neaps-danger", FALLBACKS.danger),
77-
bg: readCSSVar("--neaps-bg", FALLBACKS.bg),
87+
bg,
7888
bgSubtle: readCSSVar("--neaps-bg-subtle", FALLBACKS.bgSubtle),
79-
text: readCSSVar("--neaps-text", FALLBACKS.text),
89+
text,
8090
textMuted: readCSSVar("--neaps-text-muted", FALLBACKS.textMuted),
8191
border: readCSSVar("--neaps-border", FALLBACKS.border),
82-
}),
83-
[isDark],
84-
);
92+
mapText: readCSSVar("--neaps-map-text", text),
93+
mapBg: readCSSVar("--neaps-map-bg", bg),
94+
};
95+
}, [isDark]);
8596
}

0 commit comments

Comments
 (0)