Skip to content

Commit 54d0984

Browse files
wip
1 parent 0b0d92e commit 54d0984

File tree

22 files changed

+456
-38
lines changed

22 files changed

+456
-38
lines changed

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,13 @@
6161
},
6262
"dependencies": {
6363
"@floating-ui/react": "^0.27.9",
64+
"@turf/bbox-polygon": "^7.2.0",
65+
"@turf/boolean-within": "^7.2.0",
6466
"@turf/helpers": "^7.2.0",
6567
"@turf/length": "^7.2.0",
6668
"camelize-object-keys": "^3.0.0",
6769
"clsx": "^2.1.1",
70+
"lodash": "^4.17.21",
6871
"query-string": "^9.1.2",
6972
"react-use": "^17.6.0",
7073
"startijenn-rem": "^1.1.1",

src/components/button/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ const ButtonMemoized = memo(function Button({
107107
{badge != `` && <span className={style.badge}>{badge}</span>}
108108

109109
{IconExtra && (
110-
<span className={style.icon} aria-hidden="true">
110+
<span className={clsx(style.icon, `--icon-extra`)} aria-hidden="true">
111111
<IconExtra />
112112
</span>
113113
)}

src/components/button/index.module.css

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@
7272

7373
.icon {
7474
flex-shrink: 0;
75-
rotate: var(--fu-component-button-icon-rotate);
7675

7776
&:global {
7877
transition: rotate 0.4s var(--easing-out-back);
@@ -82,6 +81,14 @@
8281
}
8382
}
8483

84+
&:global(.--icon) {
85+
rotate: var(--fu-component-button-icon-rotate);
86+
}
87+
88+
&:global(.--icon-extra) {
89+
rotate: var(--fu-component-button-icon-extra-rotate);
90+
}
91+
8592
.text ~ & {
8693
.container:global(.--align-left) & {
8794
margin-left: auto;

src/components/floater/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {
55
useFloating,
66
autoUpdate as autoUpdateFui,
77
offset as offsetFui,
8+
shift as shiftFui,
9+
flip as flipFui,
810
} from "@floating-ui/react"
911
import clsx from "clsx"
1012

@@ -23,7 +25,7 @@ export default function Floater({
2325
}) {
2426
const { refs, floatingStyles } = useFloating({
2527
placement,
26-
middleware: [offsetFui(offset)],
28+
middleware: [offsetFui(offset), shiftFui({ padding: offset }), flipFui()],
2729
whileElementsMounted: autoUpdateFui,
2830
})
2931

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { useState } from "react"
2+
import style from "./index.module.css"
3+
4+
export default function InputRange({ onChange, initialValue, min, max, step }) {
5+
const [value, setValue] = useState(initialValue || 0)
6+
7+
const change = (e) => {
8+
const { value, min, max } = e.currentTarget
9+
setValue(value)
10+
onChange?.(value)
11+
12+
const progress = Math.round(((value - min) / (max - min)) * 100)
13+
e.currentTarget.style.background = `linear-gradient(to right, var(--fu-component-input-range-color-progress) ${progress}%, var(--fu-component-input-range-color-track) ${progress}%)`
14+
}
15+
16+
return (
17+
<input
18+
className={style.input}
19+
type="range"
20+
step={step}
21+
min={min}
22+
max={max}
23+
value={value}
24+
onChange={change}
25+
/>
26+
)
27+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
https://blog.logrocket.com/creating-custom-css-range-slider-javascript-upgrades/
3+
*/
4+
5+
.input {
6+
appearance: none;
7+
width: 100%;
8+
height: emify(6);
9+
cursor: pointer;
10+
outline: none;
11+
border-radius: emify(99);
12+
background-color: var(--fu-component-input-range-color-track);
13+
14+
&::-webkit-slider-thumb,
15+
&::-moz-range-thumb {
16+
appearance: none;
17+
width: emify(16);
18+
height: emify(16);
19+
background-color: var(--fu-component-input-range-color-thumb);
20+
border-radius: 50%;
21+
border: none;
22+
transition: all 0.2s var(--easing-out-back);
23+
}
24+
25+
&::-webkit-slider-thumb:hover,
26+
&:focus::-webkit-slider-thumb,
27+
&::-moz-range-thumb:hover,
28+
&:focus::-moz-range-thumb {
29+
box-shadow: emify(0 0 0 8)
30+
color-opacity(var(--fu-component-input-range-color-thumb), 0.2);
31+
}
32+
33+
&:active::-webkit-slider-thumb,
34+
&:active::-moz-range-thumb {
35+
box-shadow: emify(0 0 0 12)
36+
color-opacity(var(--fu-component-input-range-color-thumb), 0.3);
37+
}
38+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { Map } from "react-map-gl/maplibre"
2+
import { featureCollection as turfFeatureCollection } from "@turf/helpers"
3+
import { chunk } from "lodash"
4+
5+
import { mapStyleDefault, mapSwedenBounds } from "../../js/map"
6+
7+
const EMPTY_FEATURE_COLLECTION = turfFeatureCollection([])
8+
9+
export default function MaplibreMap({
10+
zoom,
11+
center: mapCenter,
12+
bounds,
13+
onLoad,
14+
children,
15+
}) {
16+
const mapZoom = zoom ? [zoom] : undefined
17+
const mapBounds = bounds ? chunk(bounds, 2) : mapSwedenBounds
18+
19+
return (
20+
<Map
21+
id="map"
22+
onLoad={onLoad}
23+
zoom={mapZoom}
24+
center={mapCenter}
25+
bounds={!mapCenter ? mapBounds : undefined}
26+
fitBoundsOptions={{ duration: 0 }}
27+
// canvasContextAttributes={{ preserveDrawingBuffer: true }}
28+
attributionControl={false}
29+
mapStyle={{
30+
version: 8,
31+
id: `naturkartan`,
32+
name: `Naturkartan`,
33+
pitch: 0,
34+
bearing: 0,
35+
sprite: `https://om-map-cdn.b-cdn.net/sprite/sprite`,
36+
glyphs: `https://om-map-cdn.b-cdn.net/glyphs/{fontstack}/{range}.pbf`,
37+
layers: [
38+
{
39+
id: `tileset`,
40+
source: `tileset`,
41+
type: `raster`,
42+
},
43+
{
44+
id: `base`,
45+
source: `base`,
46+
type: `symbol`,
47+
},
48+
],
49+
sources: {
50+
tileset: {
51+
type: mapStyleDefault.type,
52+
tiles: mapStyleDefault.tiles,
53+
tileSize: mapStyleDefault.tileSize,
54+
},
55+
base: {
56+
type: `geojson`,
57+
data: EMPTY_FEATURE_COLLECTION,
58+
},
59+
},
60+
}}
61+
// mapStyle="https://demotiles.maplibre.org/style.json"
62+
>
63+
{children}
64+
</Map>
65+
)
66+
}

src/components/maplibre-ruler/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import {
1313
import useCssCustomProperties from "../../js/use-css-custom-properties"
1414
import { generateMapLibreId } from "../../js/maplibre"
1515

16+
const EMPTY_FEATURE_COLLECTION = turfFeatureCollection([])
17+
1618
export default function MaplibreRuler({ onLengthUpdate }) {
1719
const { map } = useMap()
1820
const [geojson, setGeojson] = useState(turfFeatureCollection([]))
@@ -109,7 +111,7 @@ export default function MaplibreRuler({ onLengthUpdate }) {
109111
<Source
110112
id="fu-ruler-projection"
111113
type="geojson"
112-
data={turfFeatureCollection([])}
114+
data={EMPTY_FEATURE_COLLECTION}
113115
/>
114116

115117
<Source id="fu-ruler" type="geojson" data={geojson} />
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { useCallback, useEffect, useState } from "react"
2+
import { Source, Layer, useMap } from "react-map-gl/maplibre"
3+
import turfBboxPolygon from "@turf/bbox-polygon"
4+
import turfBooleanWithin from "@turf/boolean-within"
5+
6+
import { mapStyles } from "../../js/map"
7+
8+
export default function Tileset({ storeStyle }) {
9+
const { map } = useMap()
10+
const [styleName, setStyleName] = useState(storeStyle)
11+
12+
const autoset = useCallback(() => {
13+
let newStyleName = storeStyle
14+
const currentStyle = mapStyles[storeStyle]
15+
16+
if (map && currentStyle.zoomFallbackTileset) {
17+
if (currentStyle.minZoom && currentStyle.minZoom >= map.getZoom())
18+
newStyleName = currentStyle.zoomFallbackTileset
19+
20+
if (currentStyle.maxZoom && currentStyle.maxZoom <= map.getZoom())
21+
newStyleName = currentStyle.zoomFallbackTileset
22+
23+
if (newStyleName == storeStyle && currentStyle.bounds) {
24+
const mapBounds = map.getBounds()
25+
const mapBoundsPolygon = turfBboxPolygon([
26+
mapBounds._ne.lng,
27+
mapBounds._ne.lat,
28+
mapBounds._sw.lng,
29+
mapBounds._sw.lat,
30+
])
31+
32+
const styleBoundsPolygon = turfBboxPolygon(currentStyle.bounds.flat())
33+
if (!turfBooleanWithin(mapBoundsPolygon, styleBoundsPolygon))
34+
newStyleName = currentStyle.zoomFallbackTileset
35+
}
36+
}
37+
38+
setStyleName(newStyleName)
39+
}, [map, storeStyle])
40+
41+
useEffect(() => {
42+
autoset()
43+
}, [autoset, storeStyle])
44+
45+
useEffect(() => {
46+
map.on(`move`, autoset)
47+
48+
return () => {
49+
map.off(`move`, autoset)
50+
}
51+
}, [autoset, map])
52+
53+
const style = mapStyles[styleName]
54+
55+
return (
56+
<>
57+
<Source
58+
id="tileset"
59+
type={style.type}
60+
tiles={style.tiles}
61+
tileSize={style.tileSize}
62+
/>
63+
64+
<Layer beforeId="base" source="tileset" type={style.type} />
65+
</>
66+
)
67+
}

0 commit comments

Comments
 (0)