Skip to content

Commit 7fcc38a

Browse files
frozenheliumsamshara
authored andcommitted
Improve styling of local unit maps
1 parent 6d25748 commit 7fcc38a

File tree

9 files changed

+165
-78
lines changed

9 files changed

+165
-78
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { useMemo } from 'react';
2+
import { MapLayer } from '@togglecorp/re-map';
3+
import {
4+
FillLayer,
5+
LineLayer,
6+
SymbolLayer,
7+
} from 'mapbox-gl';
8+
9+
import {
10+
COLOR_ACTIVE_REGION,
11+
COLOR_LIGHT_GREY,
12+
COLOR_WHITE,
13+
} from '#utils/constants';
14+
15+
interface Props {
16+
activeCountryIso3: string | undefined | null;
17+
}
18+
19+
function ActiveCountryBaseMapLayer(props: Props) {
20+
const { activeCountryIso3 } = props;
21+
22+
const adminZeroHighlightLayerOptions = useMemo<Omit<FillLayer, 'id'>>(
23+
() => ({
24+
type: 'fill',
25+
layout: { visibility: 'visible' },
26+
paint: {
27+
'fill-color': [
28+
'match',
29+
['get', 'iso3'],
30+
activeCountryIso3,
31+
COLOR_ACTIVE_REGION,
32+
COLOR_LIGHT_GREY,
33+
],
34+
},
35+
}),
36+
[activeCountryIso3],
37+
);
38+
39+
const adminOneBoundaryLayerOptions = useMemo<Omit<LineLayer, 'id'>>(
40+
() => ({
41+
type: 'line',
42+
layout: { visibility: 'visible' },
43+
paint: {
44+
'line-color': [
45+
'match',
46+
['get', 'country_iso3'],
47+
activeCountryIso3,
48+
COLOR_WHITE,
49+
COLOR_LIGHT_GREY,
50+
],
51+
'line-opacity': 1,
52+
},
53+
}),
54+
[activeCountryIso3],
55+
);
56+
57+
const adminOneLabelLayerOptions = useMemo<Omit<SymbolLayer, 'id'>>(
58+
() => ({
59+
type: 'symbol',
60+
layout: {
61+
visibility: 'visible',
62+
'text-size': 12,
63+
},
64+
paint: {
65+
'text-opacity': [
66+
'match',
67+
['get', 'country_iso3'],
68+
activeCountryIso3,
69+
1.0,
70+
0,
71+
],
72+
},
73+
}),
74+
[activeCountryIso3],
75+
);
76+
77+
return (
78+
<>
79+
<MapLayer
80+
layerKey="admin-0"
81+
layerOptions={adminZeroHighlightLayerOptions}
82+
/>
83+
<MapLayer
84+
layerKey="admin-1-boundary"
85+
layerOptions={adminOneBoundaryLayerOptions}
86+
/>
87+
<MapLayer
88+
layerKey="admin-1-label"
89+
layerOptions={adminOneLabelLayerOptions}
90+
/>
91+
<MapLayer
92+
layerKey="admin-1-label-selected"
93+
layerOptions={adminOneLabelLayerOptions}
94+
/>
95+
</>
96+
);
97+
}
98+
99+
export default ActiveCountryBaseMapLayer;

app/src/utils/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ export const COLOR_DARK_RED = '#730413';
6969
export const COLOR_PRIMARY_BLUE = '#011e41';
7070
export const COLOR_PRIMARY_RED = '#f5333f';
7171

72+
export const COLOR_ACTIVE_REGION = '#7d8b9d';
73+
7274
// Three W
7375

7476
type OperationTypeEnum = components<'read'>['schemas']['DeploymentsProjectOperationTypeEnumKey'];

app/src/views/CountryNsOverviewContextAndStructure/NationalSocietyLocalUnits/LocalUnitsMap/index.tsx

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import {
2-
useCallback,
3-
useMemo,
4-
useState,
5-
} from 'react';
1+
import react from 'react';
62
import { useOutletContext } from 'react-router-dom';
73
import {
84
LocationIcon,
@@ -30,10 +26,10 @@ import {
3026
import getBbox from '@turf/bbox';
3127
import type {
3228
CircleLayer,
33-
FillLayer,
3429
SymbolLayer,
3530
} from 'mapbox-gl';
3631

32+
import ActiveCountryBaseMapLayer from '#components/domain/ActiveCountryBaseMapLayer';
3733
import BaseMap from '#components/domain/BaseMap';
3834
import Link, { type Props as LinkProps } from '#components/Link';
3935
import MapContainerWithDisclaimer from '#components/MapContainerWithDisclaimer';
@@ -119,7 +115,7 @@ function LocalUnitsMap() {
119115
pageSize: 9999,
120116
});
121117

122-
const urlQuery = useMemo<GoApiUrlQuery<'/api/v2/public-local-units/'>>(
118+
const urlQuery = react.useMemo<GoApiUrlQuery<'/api/v2/public-local-units/'>>(
123119
() => ({
124120
limit,
125121
type__code: filter.type,
@@ -160,11 +156,11 @@ function LocalUnitsMap() {
160156
const [
161157
clickedPointProperties,
162158
setClickedPointProperties,
163-
] = useState<ClickedPoint | undefined>();
159+
] = react.useState<ClickedPoint | undefined>();
164160

165-
const [loadedIcons, setLoadedIcons] = useState<Record<string, boolean>>({});
161+
const [loadedIcons, setLoadedIcons] = react.useState<Record<string, boolean>>({});
166162

167-
const handleIconLoad = useCallback(
163+
const handleIconLoad = react.useCallback(
168164
(loaded: boolean, key: string) => {
169165
setLoadedIcons((prevValue) => ({
170166
...prevValue,
@@ -174,7 +170,7 @@ function LocalUnitsMap() {
174170
[],
175171
);
176172

177-
const allIconsLoaded = useMemo(
173+
const allIconsLoaded = react.useMemo(
178174
() => (
179175
Object.values(loadedIcons).filter(Boolean).length === sumSafe([
180176
localUnitsOptions?.type.length,
@@ -184,7 +180,7 @@ function LocalUnitsMap() {
184180
[loadedIcons, localUnitsOptions],
185181
);
186182

187-
const localUnitPointLayerOptions: Omit<CircleLayer, 'id'> = useMemo(() => ({
183+
const localUnitPointLayerOptions: Omit<CircleLayer, 'id'> = react.useMemo(() => ({
188184
layout: {
189185
visibility: 'visible',
190186
},
@@ -213,7 +209,7 @@ function LocalUnitsMap() {
213209
},
214210
}), [localUnitsOptions]);
215211

216-
const countryBounds = useMemo(() => (
212+
const countryBounds = react.useMemo(() => (
217213
countryResponse ? getBbox(countryResponse.bbox) : undefined
218214
), [countryResponse]);
219215

@@ -255,7 +251,7 @@ function LocalUnitsMap() {
255251
? superLocalUnitDetailError
256252
: publicLocalUnitDetailError;
257253

258-
const localUnitsGeoJson = useMemo<GeoJSON.FeatureCollection<GeoJSON.Geometry>>(
254+
const localUnitsGeoJson = react.useMemo<GeoJSON.FeatureCollection<GeoJSON.Geometry>>(
259255
() => ({
260256
type: 'FeatureCollection' as const,
261257
features: localUnits?.results?.map(
@@ -284,20 +280,7 @@ function LocalUnitsMap() {
284280
[localUnits],
285281
);
286282

287-
const adminZeroHighlightLayerOptions = useMemo<Omit<FillLayer, 'id'>>(
288-
() => ({
289-
type: 'fill',
290-
layout: { visibility: 'visible' },
291-
filter: isDefined(countryResponse) ? [
292-
'!in',
293-
'country_id',
294-
countryResponse.id,
295-
] : undefined,
296-
}),
297-
[countryResponse],
298-
);
299-
300-
const handlePointClick = useCallback(
283+
const handlePointClick = react.useCallback(
301284
(feature: mapboxgl.MapboxGeoJSONFeature, lngLat: mapboxgl.LngLat) => {
302285
setClickedPointProperties({
303286
id: feature.properties?.id,
@@ -309,14 +292,14 @@ function LocalUnitsMap() {
309292
[setClickedPointProperties],
310293
);
311294

312-
const handlePointClose = useCallback(
295+
const handlePointClose = react.useCallback(
313296
() => {
314297
setClickedPointProperties(undefined);
315298
},
316299
[setClickedPointProperties],
317300
);
318301

319-
const emailRendererParams = useCallback(
302+
const emailRendererParams = react.useCallback(
320303
(_: string, email: string): LinkProps => ({
321304
className: styles.email,
322305
withUnderline: true,
@@ -354,10 +337,10 @@ function LocalUnitsMap() {
354337
>
355338
<div className={styles.mapContainerWithContactDetails}>
356339
<BaseMap
340+
withoutLabel
357341
baseLayers={(
358-
<MapLayer
359-
layerKey="admin-0-highlight"
360-
layerOptions={adminZeroHighlightLayerOptions}
342+
<ActiveCountryBaseMapLayer
343+
activeCountryIso3={countryResponse?.iso3}
361344
/>
362345
)}
363346
mapOptions={{ bounds: countryBounds }}
@@ -411,6 +394,7 @@ function LocalUnitsMap() {
411394
/>
412395
{isDefined(clickedPointProperties) && clickedPointProperties.lngLat && (
413396
<MapPopup
397+
popupClassName={styles.mapPopup}
414398
coordinates={clickedPointProperties.lngLat}
415399
onCloseButtonClick={handlePointClose}
416400
heading={isTruthyString(localUnitDetail?.english_branch_name)
@@ -420,6 +404,8 @@ function LocalUnitsMap() {
420404
pending={localUnitDetailPending}
421405
errored={isDefined(localUnitDetailError)}
422406
errorMessage={localUnitDetailError?.value.messageForNotification}
407+
compactMessage
408+
ellipsizeHeading
423409
>
424410
<TextOutput
425411
label={strings.localUnitDetailLastUpdate}

app/src/views/CountryNsOverviewContextAndStructure/NationalSocietyLocalUnits/LocalUnitsMap/styles.module.css

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
position: relative;
44

55
.map-container {
6-
height: 40rem;
6+
height: 45rem;
77
}
88

99
.contact-detail {
@@ -30,5 +30,8 @@
3030
.legend-icon {
3131
filter: invert(1);
3232
}
33+
}
3334

35+
.map-popup {
36+
height: 16rem;
3437
}

packages/ui/src/components/Header/index.tsx

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,13 @@ function Header(props: Props) {
7070
<>
7171
<Heading
7272
level={headingLevel}
73-
className={_cs(styles.heading, headingClassName)}
73+
className={headingClassName}
74+
ellipsize={ellipsizeHeading}
7475
>
7576
{heading}
7677
</Heading>
7778
{headingDescription && (
78-
<div
79-
className={_cs(
80-
styles.headingDescription,
81-
headingDescriptionContainerClassName,
82-
)}
83-
>
79+
<div className={headingDescriptionContainerClassName}>
8480
{headingDescription}
8581
</div>
8682
)}
@@ -89,6 +85,7 @@ function Header(props: Props) {
8985
},
9086
[
9187
heading,
88+
ellipsizeHeading,
9289
headingDescription,
9390
headingClassName,
9491
headingDescriptionContainerClassName,
@@ -103,7 +100,7 @@ function Header(props: Props) {
103100
actions,
104101
actionsContainerClassName,
105102
children: headingChildren,
106-
childrenContainerClassName: _cs(styles.headingContainer, headingContainerClassName),
103+
childrenContainerClassName: headingContainerClassName,
107104
className: headingSectionClassName,
108105
icons,
109106
iconsContainerClassName,
@@ -125,14 +122,13 @@ function Header(props: Props) {
125122
<div
126123
className={_cs(
127124
styles.header,
128-
ellipsizeHeading && styles.headingEllipsized,
129125
gapSpacing,
130126
className,
131127
)}
132128
ref={elementRef}
133129
>
134130
{content && (
135-
<div className={_cs(styles.headingSection, containerClassName)}>
131+
<div className={containerClassName}>
136132
{content}
137133
</div>
138134
)}
Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,4 @@
11
.header {
22
display: flex;
33
flex-direction: column;
4-
5-
.heading-section {
6-
display: flex;
7-
8-
.heading-container {
9-
display: flex;
10-
flex-wrap: wrap;
11-
overflow-x: auto;
12-
13-
.heading {
14-
display: flex;
15-
flex-grow: 1;
16-
overflow-x: auto;
17-
overflow-y: hidden;
18-
}
19-
}
20-
}
21-
22-
&.heading-ellipsized {
23-
.heading-section {
24-
.heading-container {
25-
min-width: 0;
26-
27-
.heading {
28-
overflow: hidden;
29-
text-overflow: ellipsis;
30-
white-space: nowrap;
31-
}
32-
}
33-
}
34-
}
354
}

0 commit comments

Comments
 (0)