panelui-native 0.77.0 → 0.79.0
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/lib/module/components/area-chart/index.js +32 -25
- package/lib/module/components/area-chart/index.js.map +1 -1
- package/lib/module/components/bottom-sheet/index.js +97 -15
- package/lib/module/components/bottom-sheet/index.js.map +1 -1
- package/lib/module/components/funnel-chart/index.js +15 -2
- package/lib/module/components/funnel-chart/index.js.map +1 -1
- package/lib/module/components/heatmap-chart/index.js +19 -27
- package/lib/module/components/heatmap-chart/index.js.map +1 -1
- package/lib/module/components/hex-chart/index.js +2 -0
- package/lib/module/components/hex-chart/index.js.map +1 -1
- package/lib/module/components/line-chart/index.js +38 -31
- package/lib/module/components/line-chart/index.js.map +1 -1
- package/lib/module/components/map/index.js +63 -39
- package/lib/module/components/map/index.js.map +1 -1
- package/lib/module/components/map/map-children.js +54 -0
- package/lib/module/components/map/map-children.js.map +1 -0
- package/lib/module/components/map/maplibre.js +31 -3
- package/lib/module/components/map/maplibre.js.map +1 -1
- package/lib/module/components/markdown-editor/index.js +288 -34
- package/lib/module/components/markdown-editor/index.js.map +1 -1
- package/lib/module/components/markdown-editor/markdown-transforms.js +272 -9
- package/lib/module/components/markdown-editor/markdown-transforms.js.map +1 -1
- package/lib/module/components/marquee/index.js +205 -46
- package/lib/module/components/marquee/index.js.map +1 -1
- package/lib/module/components/panelside/index.js +162 -34
- package/lib/module/components/panelside/index.js.map +1 -1
- package/lib/module/components/pie-chart/index.js +15 -2
- package/lib/module/components/pie-chart/index.js.map +1 -1
- package/lib/module/components/plot/index.js +42 -44
- package/lib/module/components/plot/index.js.map +1 -1
- package/lib/module/components/progress-button/index.js +617 -0
- package/lib/module/components/progress-button/index.js.map +1 -0
- package/lib/module/components/progress-button/progress-button-hold.js +91 -0
- package/lib/module/components/progress-button/progress-button-hold.js.map +1 -0
- package/lib/module/components/scatter-chart/index.js +6 -25
- package/lib/module/components/scatter-chart/index.js.map +1 -1
- package/lib/module/components/section-rail/index.js +40 -17
- package/lib/module/components/section-rail/index.js.map +1 -1
- package/lib/module/components/split-view/index.js +54 -10
- package/lib/module/components/split-view/index.js.map +1 -1
- package/lib/module/components/theme-selector/index.js +239 -0
- package/lib/module/components/theme-selector/index.js.map +1 -0
- package/lib/module/components/theme-selector/theme-preview.js +320 -0
- package/lib/module/components/theme-selector/theme-preview.js.map +1 -0
- package/lib/module/components/timeline/index.js +145 -14
- package/lib/module/components/timeline/index.js.map +1 -1
- package/lib/module/components/toast/index.js +45 -11
- package/lib/module/components/toast/index.js.map +1 -1
- package/lib/module/components/treemap-chart/index.js +63 -6
- package/lib/module/components/treemap-chart/index.js.map +1 -1
- package/lib/module/components/waterfall-chart/index.js +20 -4
- package/lib/module/components/waterfall-chart/index.js.map +1 -1
- package/lib/module/hooks/index.js +1 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/use-scroll-sections.js +44 -2
- package/lib/module/hooks/use-scroll-sections.js.map +1 -1
- package/lib/module/hooks/use-skeleton-handoff.js +58 -0
- package/lib/module/hooks/use-skeleton-handoff.js.map +1 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/components/area-chart/index.d.ts +1 -1
- package/lib/typescript/src/components/area-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/src/components/funnel-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/heatmap-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/hex-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/line-chart/index.d.ts +1 -1
- package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/map/index.d.ts +8 -4
- package/lib/typescript/src/components/map/index.d.ts.map +1 -1
- package/lib/typescript/src/components/map/map-children.d.ts +41 -0
- package/lib/typescript/src/components/map/map-children.d.ts.map +1 -0
- package/lib/typescript/src/components/map/maplibre.d.ts +8 -4
- package/lib/typescript/src/components/map/maplibre.d.ts.map +1 -1
- package/lib/typescript/src/components/markdown-editor/index.d.ts +64 -5
- package/lib/typescript/src/components/markdown-editor/index.d.ts.map +1 -1
- package/lib/typescript/src/components/markdown-editor/markdown-transforms.d.ts +33 -5
- package/lib/typescript/src/components/markdown-editor/markdown-transforms.d.ts.map +1 -1
- package/lib/typescript/src/components/marquee/index.d.ts +55 -2
- package/lib/typescript/src/components/marquee/index.d.ts.map +1 -1
- package/lib/typescript/src/components/panelside/index.d.ts +79 -4
- package/lib/typescript/src/components/panelside/index.d.ts.map +1 -1
- package/lib/typescript/src/components/pie-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/plot/index.d.ts +1 -3
- package/lib/typescript/src/components/plot/index.d.ts.map +1 -1
- package/lib/typescript/src/components/progress-button/index.d.ts +311 -0
- package/lib/typescript/src/components/progress-button/index.d.ts.map +1 -0
- package/lib/typescript/src/components/progress-button/progress-button-hold.d.ts +60 -0
- package/lib/typescript/src/components/progress-button/progress-button-hold.d.ts.map +1 -0
- package/lib/typescript/src/components/scatter-chart/index.d.ts +1 -1
- package/lib/typescript/src/components/scatter-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/section-rail/index.d.ts.map +1 -1
- package/lib/typescript/src/components/split-view/index.d.ts +10 -1
- package/lib/typescript/src/components/split-view/index.d.ts.map +1 -1
- package/lib/typescript/src/components/theme-selector/index.d.ts +107 -0
- package/lib/typescript/src/components/theme-selector/index.d.ts.map +1 -0
- package/lib/typescript/src/components/theme-selector/theme-preview.d.ts +32 -0
- package/lib/typescript/src/components/theme-selector/theme-preview.d.ts.map +1 -0
- package/lib/typescript/src/components/timeline/index.d.ts +7 -0
- package/lib/typescript/src/components/timeline/index.d.ts.map +1 -1
- package/lib/typescript/src/components/toast/index.d.ts.map +1 -1
- package/lib/typescript/src/components/treemap-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/waterfall-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/index.d.ts +1 -0
- package/lib/typescript/src/hooks/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/use-scroll-sections.d.ts +1 -0
- package/lib/typescript/src/hooks/use-scroll-sections.d.ts.map +1 -1
- package/lib/typescript/src/hooks/use-skeleton-handoff.d.ts +11 -0
- package/lib/typescript/src/hooks/use-skeleton-handoff.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +6 -4
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/area-chart/index.tsx +49 -37
- package/src/components/bottom-sheet/index.tsx +109 -11
- package/src/components/funnel-chart/index.tsx +10 -2
- package/src/components/heatmap-chart/index.tsx +27 -22
- package/src/components/hex-chart/index.tsx +22 -6
- package/src/components/line-chart/index.tsx +57 -43
- package/src/components/map/index.tsx +63 -36
- package/src/components/map/map-children.ts +66 -0
- package/src/components/map/maplibre.ts +32 -4
- package/src/components/markdown-editor/index.tsx +413 -35
- package/src/components/markdown-editor/markdown-transforms.ts +274 -10
- package/src/components/marquee/index.tsx +254 -58
- package/src/components/panelside/index.tsx +179 -40
- package/src/components/pie-chart/index.tsx +10 -2
- package/src/components/plot/index.tsx +66 -50
- package/src/components/progress-button/index.tsx +684 -0
- package/src/components/progress-button/progress-button-hold.ts +88 -0
- package/src/components/scatter-chart/index.tsx +4 -25
- package/src/components/section-rail/index.tsx +39 -19
- package/src/components/split-view/index.tsx +53 -8
- package/src/components/theme-selector/index.tsx +281 -0
- package/src/components/theme-selector/theme-preview.tsx +205 -0
- package/src/components/timeline/index.tsx +143 -17
- package/src/components/toast/index.tsx +60 -11
- package/src/components/treemap-chart/index.tsx +65 -8
- package/src/components/waterfall-chart/index.tsx +14 -4
- package/src/hooks/index.ts +5 -0
- package/src/hooks/use-scroll-sections.ts +52 -3
- package/src/hooks/use-skeleton-handoff.ts +69 -0
- package/src/index.ts +25 -0
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
useState,
|
|
44
44
|
type ReactNode,
|
|
45
45
|
} from 'react';
|
|
46
|
-
import { Pressable, View, type PressableProps, type ViewProps } from 'react-native';
|
|
46
|
+
import { Pressable, StyleSheet, View, type PressableProps, type ViewProps } from 'react-native';
|
|
47
47
|
import { useCSSVariable } from 'uniwind';
|
|
48
48
|
import { tv } from 'tailwind-variants';
|
|
49
49
|
import { CompassIcon, CrosshairIcon, MinusIcon, PlusIcon } from '../../icons';
|
|
@@ -62,6 +62,7 @@ import {
|
|
|
62
62
|
type LngLat,
|
|
63
63
|
type LngLatBounds,
|
|
64
64
|
type MapRef,
|
|
65
|
+
type PixelPoint,
|
|
65
66
|
type StyleSpecification,
|
|
66
67
|
type ViewState,
|
|
67
68
|
} from './maplibre';
|
|
@@ -70,9 +71,10 @@ import {
|
|
|
70
71
|
type MapFeatureAccessibility,
|
|
71
72
|
type MapFeatureAccessibilityDescription,
|
|
72
73
|
} from './map-accessibility';
|
|
74
|
+
import { asMapLayer, partitionMapChildren } from './map-children';
|
|
73
75
|
|
|
74
76
|
export { hasMapLibre, CARTO_SOURCE };
|
|
75
|
-
export type { BasemapSource, BasemapTokens, LngLat, LngLatBounds, ViewState };
|
|
77
|
+
export type { BasemapSource, BasemapTokens, LngLat, LngLatBounds, PixelPoint, ViewState };
|
|
76
78
|
export type { MapFeatureAccessibility } from './map-accessibility';
|
|
77
79
|
|
|
78
80
|
const mapVariants = tv({
|
|
@@ -251,8 +253,12 @@ export interface MapProps extends Omit<ViewProps, 'children'> {
|
|
|
251
253
|
interactive?: boolean;
|
|
252
254
|
/** Fires continuously while the map moves. */
|
|
253
255
|
onViewStateChange?: (state: ViewState) => void;
|
|
254
|
-
/**
|
|
255
|
-
|
|
256
|
+
/**
|
|
257
|
+
* Fires when the map is pressed somewhere that is not a feature. The second
|
|
258
|
+
* argument is the same press in screen coordinates, for anchoring something
|
|
259
|
+
* of your own to where the finger landed.
|
|
260
|
+
*/
|
|
261
|
+
onPress?: (lngLat: LngLat, point: PixelPoint) => void;
|
|
256
262
|
/** Fires once the style has loaded and the first frame is drawn. */
|
|
257
263
|
onReady?: () => void;
|
|
258
264
|
}
|
|
@@ -386,9 +392,17 @@ const MapRoot = forwardRef<MapHandle, MapProps>(function MapRoot(
|
|
|
386
392
|
|
|
387
393
|
const { Map: MapLibreMap, Camera } = MapLibre;
|
|
388
394
|
|
|
395
|
+
/*
|
|
396
|
+
* Only what the renderer understands is handed to it. Controls and any other
|
|
397
|
+
* chrome are drawn as a sibling above the map instead, because the native map
|
|
398
|
+
* view lays its own children out and would stretch an ordinary view over the
|
|
399
|
+
* whole surface — see `map-children.ts`.
|
|
400
|
+
*/
|
|
401
|
+
const { layers, overlay } = partitionMapChildren(children);
|
|
402
|
+
|
|
389
403
|
return (
|
|
390
|
-
<
|
|
391
|
-
<
|
|
404
|
+
<MapContext.Provider value={context}>
|
|
405
|
+
<View className={slots.root({ className })} {...props}>
|
|
392
406
|
<MapLibreMap
|
|
393
407
|
ref={mapRef}
|
|
394
408
|
mapStyle={style}
|
|
@@ -417,7 +431,7 @@ const MapRoot = forwardRef<MapHandle, MapProps>(function MapRoot(
|
|
|
417
431
|
}
|
|
418
432
|
onPress={
|
|
419
433
|
onPress
|
|
420
|
-
? (event) => onPress(event.nativeEvent.
|
|
434
|
+
? (event) => onPress(event.nativeEvent.lngLat, event.nativeEvent.point)
|
|
421
435
|
: undefined
|
|
422
436
|
}
|
|
423
437
|
>
|
|
@@ -433,38 +447,43 @@ const MapRoot = forwardRef<MapHandle, MapProps>(function MapRoot(
|
|
|
433
447
|
: { center: center ?? [0, 20], zoom, bearing, pitch }
|
|
434
448
|
}
|
|
435
449
|
/>
|
|
436
|
-
{
|
|
450
|
+
{layers}
|
|
437
451
|
</MapLibreMap>
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
452
|
+
{overlay.length > 0 ? (
|
|
453
|
+
<View style={StyleSheet.absoluteFill} pointerEvents="box-none">
|
|
454
|
+
{textChildren(overlay)}
|
|
455
|
+
</View>
|
|
456
|
+
) : null}
|
|
457
|
+
<View
|
|
458
|
+
accessibilityRole="list"
|
|
459
|
+
style={{ position: 'absolute', width: 1, height: 1, overflow: 'hidden' }}
|
|
460
|
+
>
|
|
461
|
+
{[...accessibleFeatureGroups].flatMap(([groupId, group]) =>
|
|
462
|
+
group.features.map(({ feature, label, hint, state }, index) =>
|
|
463
|
+
group.onPress ? (
|
|
464
|
+
<Pressable
|
|
465
|
+
key={`${groupId}-${index}`}
|
|
466
|
+
accessibilityRole="button"
|
|
467
|
+
accessibilityLabel={label}
|
|
468
|
+
accessibilityHint={hint}
|
|
469
|
+
accessibilityState={state}
|
|
470
|
+
onPress={() => group.onPress?.(feature)}
|
|
471
|
+
/>
|
|
472
|
+
) : (
|
|
473
|
+
<View
|
|
474
|
+
key={`${groupId}-${index}`}
|
|
475
|
+
accessible
|
|
476
|
+
accessibilityRole="text"
|
|
477
|
+
accessibilityLabel={label}
|
|
478
|
+
accessibilityHint={hint}
|
|
479
|
+
accessibilityState={state}
|
|
480
|
+
/>
|
|
481
|
+
)
|
|
463
482
|
)
|
|
464
|
-
)
|
|
465
|
-
|
|
483
|
+
)}
|
|
484
|
+
</View>
|
|
466
485
|
</View>
|
|
467
|
-
</
|
|
486
|
+
</MapContext.Provider>
|
|
468
487
|
);
|
|
469
488
|
});
|
|
470
489
|
MapRoot.displayName = 'Map';
|
|
@@ -578,6 +597,7 @@ function MapMarker({
|
|
|
578
597
|
);
|
|
579
598
|
}
|
|
580
599
|
MapMarker.displayName = 'Map.Marker';
|
|
600
|
+
asMapLayer(MapMarker);
|
|
581
601
|
|
|
582
602
|
export interface MapLabelProps {
|
|
583
603
|
children?: ReactNode;
|
|
@@ -691,6 +711,7 @@ function MapPopup({ children, className, title, lngLat }: MapPopupProps) {
|
|
|
691
711
|
);
|
|
692
712
|
}
|
|
693
713
|
MapPopup.displayName = 'Map.Popup';
|
|
714
|
+
asMapLayer(MapPopup);
|
|
694
715
|
|
|
695
716
|
export interface MapControlsProps {
|
|
696
717
|
/** Which corner the stack sits in. */
|
|
@@ -889,6 +910,7 @@ function MapRoute({
|
|
|
889
910
|
);
|
|
890
911
|
}
|
|
891
912
|
MapRoute.displayName = 'Map.Route';
|
|
913
|
+
asMapLayer(MapRoute);
|
|
892
914
|
|
|
893
915
|
export interface MapArcProps {
|
|
894
916
|
/** Where the arc starts. */
|
|
@@ -968,6 +990,7 @@ function MapArc({
|
|
|
968
990
|
);
|
|
969
991
|
}
|
|
970
992
|
MapArc.displayName = 'Map.Arc';
|
|
993
|
+
asMapLayer(MapArc);
|
|
971
994
|
|
|
972
995
|
export interface MapGeoJSONProps {
|
|
973
996
|
/** A Feature, FeatureCollection, or the URL of one. */
|
|
@@ -1042,6 +1065,7 @@ function MapGeoJSON({
|
|
|
1042
1065
|
);
|
|
1043
1066
|
}
|
|
1044
1067
|
MapGeoJSON.displayName = 'Map.GeoJSON';
|
|
1068
|
+
asMapLayer(MapGeoJSON);
|
|
1045
1069
|
|
|
1046
1070
|
export interface MapClusterProps {
|
|
1047
1071
|
/** Point features to cluster. */
|
|
@@ -1140,6 +1164,7 @@ function MapCluster({
|
|
|
1140
1164
|
);
|
|
1141
1165
|
}
|
|
1142
1166
|
MapCluster.displayName = 'Map.Cluster';
|
|
1167
|
+
asMapLayer(MapCluster);
|
|
1143
1168
|
|
|
1144
1169
|
function useAccessibleMapFeatures(
|
|
1145
1170
|
id: string,
|
|
@@ -1379,6 +1404,7 @@ function MapHeatmap({
|
|
|
1379
1404
|
);
|
|
1380
1405
|
}
|
|
1381
1406
|
MapHeatmap.displayName = 'Map.Heatmap';
|
|
1407
|
+
asMapLayer(MapHeatmap);
|
|
1382
1408
|
|
|
1383
1409
|
export interface MapUserLocationProps {
|
|
1384
1410
|
/** Show which way the device is facing, not just where it is. */
|
|
@@ -1397,6 +1423,7 @@ function MapUserLocation({
|
|
|
1397
1423
|
return <UserLocation heading={heading} accuracy={accuracy} />;
|
|
1398
1424
|
}
|
|
1399
1425
|
MapUserLocation.displayName = 'Map.UserLocation';
|
|
1426
|
+
asMapLayer(MapUserLocation);
|
|
1400
1427
|
|
|
1401
1428
|
export const Map = Object.assign(MapRoot, {
|
|
1402
1429
|
Marker: MapMarker,
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which of a map's children belong to the renderer, and which belong to us.
|
|
3
|
+
*
|
|
4
|
+
* The native map view is not a React Native container. On Android it is a real
|
|
5
|
+
* `FrameLayout`, and it lays its children out itself — so an ordinary view
|
|
6
|
+
* handed to it loses the frame the layout engine computed, arrives stretched
|
|
7
|
+
* to the full size of the map, and covers the surface the map is drawn on. A
|
|
8
|
+
* control group written to sit in a corner ends up in the top-left, full
|
|
9
|
+
* bleed, with the map invisible behind it.
|
|
10
|
+
*
|
|
11
|
+
* So the children are split before they are mounted. Anything the renderer
|
|
12
|
+
* understands — a marker, a route, a layer — goes inside it. Everything else,
|
|
13
|
+
* including `Map.Controls` and any chrome written at the call site, is drawn
|
|
14
|
+
* as a sibling above the map, where the layout engine still owns it.
|
|
15
|
+
*
|
|
16
|
+
* Parts opt in by carrying `MAP_LAYER`, so the rule is a property of the part
|
|
17
|
+
* rather than a list kept somewhere else that a new part could be left out of.
|
|
18
|
+
*/
|
|
19
|
+
import { Children, isValidElement, type ReactNode } from 'react';
|
|
20
|
+
|
|
21
|
+
/** Marks a component that has to be mounted inside the native map view. */
|
|
22
|
+
export const MAP_LAYER = Symbol.for('panelui.map.layer');
|
|
23
|
+
|
|
24
|
+
type Layer = { [MAP_LAYER]?: true };
|
|
25
|
+
|
|
26
|
+
/** Tags a part as belonging inside the renderer, and hands it back. */
|
|
27
|
+
export function asMapLayer<T>(part: T): T {
|
|
28
|
+
(part as T & Layer)[MAP_LAYER] = true;
|
|
29
|
+
return part;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Whether an element type has been tagged with {@link asMapLayer}. */
|
|
33
|
+
export function isMapLayer(type: unknown): boolean {
|
|
34
|
+
return (
|
|
35
|
+
(typeof type === 'function' || typeof type === 'object') &&
|
|
36
|
+
type !== null &&
|
|
37
|
+
(type as Layer)[MAP_LAYER] === true
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface PartitionedMapChildren {
|
|
42
|
+
/** Mounted inside the native map view. */
|
|
43
|
+
layers: ReactNode[];
|
|
44
|
+
/** Drawn as a sibling above it, where React Native's layout still applies. */
|
|
45
|
+
overlay: ReactNode[];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Splits a map's children into the two halves above.
|
|
50
|
+
*
|
|
51
|
+
* A child that is not an element at all — a string, a number, a nullish branch
|
|
52
|
+
* — goes to the overlay. The renderer drops what it does not recognise, and
|
|
53
|
+
* drops it *silently*, which also puts its own child bookkeeping out of step
|
|
54
|
+
* with React's.
|
|
55
|
+
*/
|
|
56
|
+
export function partitionMapChildren(children: ReactNode): PartitionedMapChildren {
|
|
57
|
+
const layers: ReactNode[] = [];
|
|
58
|
+
const overlay: ReactNode[] = [];
|
|
59
|
+
|
|
60
|
+
Children.forEach(children, (child) => {
|
|
61
|
+
if (isValidElement(child) && isMapLayer(child.type)) layers.push(child);
|
|
62
|
+
else if (child !== null && child !== undefined && child !== false) overlay.push(child);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return { layers, overlay };
|
|
66
|
+
}
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
* below against the package rather than assuming they survived.
|
|
28
28
|
*/
|
|
29
29
|
import type { ComponentType, ReactElement, ReactNode, Ref } from 'react';
|
|
30
|
+
import { TurboModuleRegistry } from 'react-native';
|
|
30
31
|
|
|
31
32
|
/** `[longitude, latitude]` — the order the style spec uses, not the spoken one. */
|
|
32
33
|
export type LngLat = [number, number];
|
|
@@ -34,6 +35,9 @@ export type LngLat = [number, number];
|
|
|
34
35
|
/** `[west, south, east, north]`. */
|
|
35
36
|
export type LngLatBounds = [number, number, number, number];
|
|
36
37
|
|
|
38
|
+
/** `[x, y]` in points, measured from the map's own top-left corner. */
|
|
39
|
+
export type PixelPoint = [number, number];
|
|
40
|
+
|
|
37
41
|
/**
|
|
38
42
|
* A MapLibre style document. Left loose on purpose: the spec is large, it is
|
|
39
43
|
* versioned separately from this library, and the parts of it callers pass
|
|
@@ -121,7 +125,7 @@ interface MapLibreModule {
|
|
|
121
125
|
touchPitch?: boolean;
|
|
122
126
|
accessible?: boolean;
|
|
123
127
|
importantForAccessibility?: 'auto' | 'yes' | 'no' | 'no-hide-descendants';
|
|
124
|
-
onPress?: (event: NativeEvent<{
|
|
128
|
+
onPress?: (event: NativeEvent<{ lngLat: LngLat; point: PixelPoint }>) => void;
|
|
125
129
|
onDidFinishLoadingMap?: () => void;
|
|
126
130
|
onRegionDidChange?: (event: NativeEvent<ViewState>) => void;
|
|
127
131
|
children?: ReactNode;
|
|
@@ -172,12 +176,35 @@ interface MapLibreModule {
|
|
|
172
176
|
}>;
|
|
173
177
|
}
|
|
174
178
|
|
|
179
|
+
/**
|
|
180
|
+
* Whether the renderer's native half is actually in this binary.
|
|
181
|
+
*
|
|
182
|
+
* The JavaScript resolving is not the question. A project that installed the
|
|
183
|
+
* package and then ran in a client built without it — Expo Go being the one
|
|
184
|
+
* everybody meets — has the JavaScript and none of the native views, and a
|
|
185
|
+
* `require` that succeeds there is a `require` that lies. The component would
|
|
186
|
+
* then try to mount a view nothing has registered, which is a crash in native
|
|
187
|
+
* code where a `try` in JavaScript has nothing to catch.
|
|
188
|
+
*
|
|
189
|
+
* `TurboModuleRegistry.get` answers the real question and returns null instead
|
|
190
|
+
* of throwing, so the graceful fallback the component already draws is reached
|
|
191
|
+
* rather than skipped.
|
|
192
|
+
*/
|
|
193
|
+
function nativeRendererPresent(): boolean {
|
|
194
|
+
try {
|
|
195
|
+
return TurboModuleRegistry.get('MLRNMapViewModule') !== null;
|
|
196
|
+
} catch {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
175
201
|
/**
|
|
176
202
|
* The renderer, or null when it is not installed. Resolved once at module
|
|
177
203
|
* load — the require is cheap, and caching it keeps a try/catch out of render.
|
|
178
204
|
*/
|
|
179
205
|
const maplibre: MapLibreModule | null = (() => {
|
|
180
206
|
try {
|
|
207
|
+
if (!nativeRendererPresent()) return null;
|
|
181
208
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
182
209
|
return require('@maplibre/maplibre-react-native') as MapLibreModule;
|
|
183
210
|
} catch {
|
|
@@ -188,9 +215,10 @@ const maplibre: MapLibreModule | null = (() => {
|
|
|
188
215
|
/**
|
|
189
216
|
* True when a map can actually be drawn.
|
|
190
217
|
*
|
|
191
|
-
* False in any client that cannot load native modules
|
|
192
|
-
*
|
|
193
|
-
* whole content is a
|
|
218
|
+
* False in any client that cannot load native modules — Expo Go included, even
|
|
219
|
+
* with the package installed — and in any project that has not installed the
|
|
220
|
+
* renderer. Worth checking before routing somewhere whose whole content is a
|
|
221
|
+
* map.
|
|
194
222
|
*/
|
|
195
223
|
export const hasMapLibre = maplibre !== null;
|
|
196
224
|
|