@macrostrat/map-interface 1.0.8 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/package.json +4 -2
- package/src/container.ts +3 -3
- package/src/context-panel/index.ts +52 -9
- package/src/context-panel/main.module.sass +10 -2
- package/src/dev/map-page.ts +9 -6
- package/src/helpers.ts +20 -2
- package/src/main.module.sass +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format
|
|
|
4
4
|
is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this
|
|
5
5
|
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [1.0.10] - 2024-11-05
|
|
8
|
+
|
|
9
|
+
- Add documentation and examples of map easing
|
|
10
|
+
- Improve floating navigation
|
|
11
|
+
- Improve map padding management component
|
|
12
|
+
- Improve styles
|
|
13
|
+
|
|
7
14
|
## [1.0.8] - 2024-10-26
|
|
8
15
|
|
|
9
16
|
- Fix inspector colors with new version of `chroma-js`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@macrostrat/map-interface",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "Map interface for Macrostrat",
|
|
5
5
|
"main": "dist/main.cjs",
|
|
6
6
|
"module": "dist/module.mjs",
|
|
@@ -50,7 +50,9 @@
|
|
|
50
50
|
"src"
|
|
51
51
|
],
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"parcel": "^2.12.0"
|
|
53
|
+
"parcel": "^2.12.0",
|
|
54
|
+
"postcss": "^8.0.0",
|
|
55
|
+
"postcss-modules": "^4.3.0"
|
|
54
56
|
},
|
|
55
57
|
"repository": {
|
|
56
58
|
"type": "git",
|
package/src/container.ts
CHANGED
|
@@ -32,6 +32,9 @@ export enum DetailPanelStyle {
|
|
|
32
32
|
FLOATING = "floating",
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
export const MapAreaContainer = (props) =>
|
|
36
|
+
h(MapProviders, h(_MapAreaContainer, props));
|
|
37
|
+
|
|
35
38
|
function _MapAreaContainer({
|
|
36
39
|
children,
|
|
37
40
|
className,
|
|
@@ -144,9 +147,6 @@ function ContextStack(props: ContextStackProps) {
|
|
|
144
147
|
const MapProviders = ({ children }) =>
|
|
145
148
|
h(ToasterContext, h(MapboxMapProvider, children));
|
|
146
149
|
|
|
147
|
-
export const MapAreaContainer = (props) =>
|
|
148
|
-
h(MapProviders, h(_MapAreaContainer, props));
|
|
149
|
-
|
|
150
150
|
interface MapContainerProps {
|
|
151
151
|
className?: string;
|
|
152
152
|
children?: ReactNode;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
|
-
import { Navbar, Button,
|
|
2
|
+
import { Navbar, Button, Spinner, Card, Text } from "@blueprintjs/core";
|
|
3
3
|
import hyper from "@macrostrat/hyper";
|
|
4
4
|
import styles from "./main.module.sass";
|
|
5
5
|
import { useMapStatus } from "@macrostrat/mapbox-react";
|
|
6
|
+
import { Spacer } from "@macrostrat/ui-components";
|
|
6
7
|
|
|
7
8
|
const h = hyper.styled(styles);
|
|
8
9
|
|
|
@@ -12,15 +13,18 @@ export function LoadingButton({
|
|
|
12
13
|
isLoading = false,
|
|
13
14
|
onClick,
|
|
14
15
|
active = false,
|
|
16
|
+
large = false,
|
|
15
17
|
icon = "menu",
|
|
18
|
+
style,
|
|
16
19
|
}) {
|
|
17
20
|
return h(Button, {
|
|
18
21
|
className: "loading-button",
|
|
19
22
|
icon: isLoading ? spinnerElement : icon,
|
|
20
|
-
large
|
|
23
|
+
large,
|
|
21
24
|
minimal: true,
|
|
22
25
|
onClick,
|
|
23
26
|
active: active && !isLoading,
|
|
27
|
+
style,
|
|
24
28
|
});
|
|
25
29
|
}
|
|
26
30
|
|
|
@@ -32,18 +36,57 @@ export function MapLoadingButton(props) {
|
|
|
32
36
|
|
|
33
37
|
type AnyChildren = React.ReactNode | React.ReactFragment;
|
|
34
38
|
|
|
39
|
+
export interface FloatingNavbarProps {
|
|
40
|
+
className?: string;
|
|
41
|
+
children: AnyChildren;
|
|
42
|
+
headerElement?: AnyChildren;
|
|
43
|
+
title?: AnyChildren;
|
|
44
|
+
statusElement?: AnyChildren;
|
|
45
|
+
rightElement?: AnyChildren;
|
|
46
|
+
height: number | string;
|
|
47
|
+
width: number | string;
|
|
48
|
+
style?: object;
|
|
49
|
+
}
|
|
50
|
+
|
|
35
51
|
export function FloatingNavbar({
|
|
36
52
|
className,
|
|
37
53
|
children,
|
|
54
|
+
headerElement = null,
|
|
55
|
+
title = null,
|
|
38
56
|
statusElement = null,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}) {
|
|
44
|
-
|
|
57
|
+
rightElement = null,
|
|
58
|
+
height,
|
|
59
|
+
width,
|
|
60
|
+
style = {},
|
|
61
|
+
}: FloatingNavbarProps) {
|
|
62
|
+
let _rightElement: React.ReactNode | null = null;
|
|
63
|
+
if (rightElement != null) {
|
|
64
|
+
_rightElement = h("div.right-element", rightElement);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let _headerElement: React.ReactNode | null = headerElement;
|
|
68
|
+
if (title != null && _headerElement == null) {
|
|
69
|
+
if (typeof title === "string") {
|
|
70
|
+
_headerElement = h(Text, { tagName: "h2", ellipsize: true }, title);
|
|
71
|
+
} else {
|
|
72
|
+
_headerElement = title;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (_headerElement != null) {
|
|
77
|
+
_headerElement = h([_headerElement, h(Spacer)]);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return h("div.searchbar-holder", { className, style: { width } }, [
|
|
45
81
|
h("div.navbar-holder", [
|
|
46
|
-
h(
|
|
82
|
+
h(
|
|
83
|
+
Navbar,
|
|
84
|
+
{
|
|
85
|
+
className: "searchbar navbar panel",
|
|
86
|
+
style: { height, ...style },
|
|
87
|
+
},
|
|
88
|
+
[_headerElement, children, _rightElement]
|
|
89
|
+
),
|
|
47
90
|
]),
|
|
48
91
|
h.if(statusElement != null)(
|
|
49
92
|
Card,
|
|
@@ -3,32 +3,40 @@
|
|
|
3
3
|
display: flex
|
|
4
4
|
flex-direction: column
|
|
5
5
|
margin: 0
|
|
6
|
+
|
|
6
7
|
.navbar-holder
|
|
7
8
|
display: flex
|
|
8
9
|
flex-direction: row
|
|
10
|
+
|
|
9
11
|
.searchbar
|
|
10
12
|
width: 100%
|
|
11
13
|
background-color: var(--panel-background-color)
|
|
12
14
|
border-radius: 5px
|
|
13
|
-
padding:
|
|
15
|
+
padding: var(--navbar-padding, 10px)
|
|
14
16
|
display: flex
|
|
15
17
|
flex-direction: row
|
|
16
18
|
align-items: center
|
|
17
19
|
gap: 5px
|
|
20
|
+
|
|
18
21
|
:global(.bp5-input-group)
|
|
19
22
|
flex-grow: 1
|
|
20
23
|
cursor: text
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
.navbar
|
|
26
|
+
min-height: 50px
|
|
27
|
+
|
|
28
|
+
:global(.bp5-navbar) > .loading-button
|
|
23
29
|
width: 40px
|
|
24
30
|
height: 40px
|
|
25
31
|
|
|
26
32
|
.status-tongue
|
|
27
33
|
background-color: var(--panel-background-color)
|
|
28
34
|
margin: 5px
|
|
35
|
+
margin-bottom: 0
|
|
29
36
|
margin-top: -12px
|
|
30
37
|
padding: 0
|
|
31
38
|
padding-top: 12px
|
|
39
|
+
overflow: hidden
|
|
32
40
|
|
|
33
41
|
@media screen and (max-width: 768px)
|
|
34
42
|
.status-tongue
|
package/src/dev/map-page.ts
CHANGED
|
@@ -33,7 +33,6 @@ export function MapInspector({
|
|
|
33
33
|
focusedSource = null,
|
|
34
34
|
focusedSourceTitle = null,
|
|
35
35
|
fitViewport = true,
|
|
36
|
-
projection = null,
|
|
37
36
|
}: {
|
|
38
37
|
headerElement?: React.ReactElement;
|
|
39
38
|
transformRequest?: mapboxgl.TransformRequestFunction;
|
|
@@ -127,14 +126,18 @@ export function MapInspector({
|
|
|
127
126
|
return h(
|
|
128
127
|
MapAreaContainer,
|
|
129
128
|
{
|
|
130
|
-
navbar: h(FloatingNavbar,
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
h(MapLoadingButton, {
|
|
129
|
+
navbar: h(FloatingNavbar, {
|
|
130
|
+
rightElement: h(MapLoadingButton, {
|
|
131
|
+
large: true,
|
|
134
132
|
active: isOpen,
|
|
135
133
|
onClick: () => setOpen(!isOpen),
|
|
134
|
+
style: {
|
|
135
|
+
marginRight: "-5px",
|
|
136
|
+
},
|
|
136
137
|
}),
|
|
137
|
-
|
|
138
|
+
headerElement,
|
|
139
|
+
title,
|
|
140
|
+
}),
|
|
138
141
|
contextPanel: h(PanelCard, [
|
|
139
142
|
h(Switch, {
|
|
140
143
|
checked: xRay,
|
package/src/helpers.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
useMapDispatch,
|
|
5
5
|
useMapStatus,
|
|
6
6
|
} from "@macrostrat/mapbox-react";
|
|
7
|
-
import { useRef } from "react";
|
|
7
|
+
import { useMemo, useRef } from "react";
|
|
8
8
|
import { debounce } from "underscore";
|
|
9
9
|
import useResizeObserver from "use-resize-observer";
|
|
10
10
|
|
|
@@ -12,6 +12,7 @@ import { getMapPosition } from "@macrostrat/mapbox-utils";
|
|
|
12
12
|
import mapboxgl from "mapbox-gl";
|
|
13
13
|
import { useCallback, useEffect, useState } from "react";
|
|
14
14
|
import { getMapPadding, useMapMarker } from "./utils";
|
|
15
|
+
import { useInDarkMode } from "@macrostrat/ui-components";
|
|
15
16
|
|
|
16
17
|
export function MapResizeManager({ containerRef }) {
|
|
17
18
|
const mapRef = useMapRef();
|
|
@@ -34,12 +35,14 @@ interface MapPaddingManagerProps {
|
|
|
34
35
|
containerRef: React.RefObject<HTMLDivElement>;
|
|
35
36
|
parentRef: React.RefObject<HTMLDivElement>;
|
|
36
37
|
infoMarkerPosition: mapboxgl.LngLatLike;
|
|
38
|
+
debounceTime?: number;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
export function MapPaddingManager({
|
|
40
42
|
containerRef,
|
|
41
43
|
parentRef,
|
|
42
44
|
infoMarkerPosition,
|
|
45
|
+
debounceTime = 200,
|
|
43
46
|
}: MapPaddingManagerProps) {
|
|
44
47
|
const mapRef = useMapRef();
|
|
45
48
|
|
|
@@ -47,11 +50,16 @@ export function MapPaddingManager({
|
|
|
47
50
|
getMapPadding(containerRef, parentRef)
|
|
48
51
|
);
|
|
49
52
|
|
|
50
|
-
const
|
|
53
|
+
const _updateMapPadding = useCallback(() => {
|
|
51
54
|
const newPadding = getMapPadding(containerRef, parentRef);
|
|
52
55
|
setPadding(newPadding);
|
|
53
56
|
}, [containerRef.current, parentRef.current]);
|
|
54
57
|
|
|
58
|
+
const updateMapPadding = useMemo(
|
|
59
|
+
() => debounce(_updateMapPadding, debounceTime),
|
|
60
|
+
[_updateMapPadding, debounceTime]
|
|
61
|
+
);
|
|
62
|
+
|
|
55
63
|
useEffect(() => {
|
|
56
64
|
const map = mapRef.current;
|
|
57
65
|
if (map == null) return;
|
|
@@ -64,6 +72,9 @@ export function MapPaddingManager({
|
|
|
64
72
|
onResize(sz) {
|
|
65
73
|
updateMapPadding();
|
|
66
74
|
},
|
|
75
|
+
round(n) {
|
|
76
|
+
return Math.round(n);
|
|
77
|
+
},
|
|
67
78
|
});
|
|
68
79
|
|
|
69
80
|
// Ideally, we would not have to do this when we know the infobox is loaded
|
|
@@ -170,3 +181,10 @@ export function MapMarker({ position, setPosition, centerMarker = true }) {
|
|
|
170
181
|
|
|
171
182
|
return null;
|
|
172
183
|
}
|
|
184
|
+
|
|
185
|
+
export function useBasicStylePair() {
|
|
186
|
+
const inDarkMode = useInDarkMode();
|
|
187
|
+
return inDarkMode
|
|
188
|
+
? "mapbox://styles/mapbox/dark-v10"
|
|
189
|
+
: "mapbox://styles/mapbox/light-v10";
|
|
190
|
+
}
|
package/src/main.module.sass
CHANGED
|
@@ -101,6 +101,10 @@
|
|
|
101
101
|
position: absolute
|
|
102
102
|
|
|
103
103
|
|
|
104
|
+
.context-panel-holder>:global(.bp5-card)
|
|
105
|
+
padding: 10px
|
|
106
|
+
background-color: var(--panel-background-color)
|
|
107
|
+
|
|
104
108
|
.panel-card
|
|
105
109
|
padding: 10px
|
|
106
110
|
background-color: var(--panel-background-color)
|
|
@@ -522,7 +526,8 @@
|
|
|
522
526
|
.spacer
|
|
523
527
|
flex: 1
|
|
524
528
|
|
|
525
|
-
|
|
529
|
+
|
|
530
|
+
// Shift UI around to center elements if we're in the global view
|
|
526
531
|
@media only screen and (min-width: 768px)
|
|
527
532
|
.map-container.detail-panel-leave .map-view-container
|
|
528
533
|
margin-right: -14em
|