@mailwoman/react 8.1.0 → 8.3.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/common/ClientOnly.tsx +6 -2
- package/common/CopyButton.tsx +9 -3
- package/common/KindBadge.tsx +1 -1
- package/common/LoadingIndicator.tsx +22 -7
- package/common/PresetChips.tsx +6 -2
- package/common/cx.ts +3 -1
- package/common/useClipboard.ts +7 -2
- package/index.ts +5 -0
- package/map/BackendControl.tsx +12 -4
- package/map/CompareToggle.tsx +27 -9
- package/map/DemoControls.tsx +31 -11
- package/map/DemoMap.tsx +33 -11
- package/map/GeocoderDemo.tsx +25 -8
- package/map/OverlayLayers.tsx +7 -3
- package/map/PlaceAutocomplete.tsx +25 -9
- package/map/PlaceMarker.tsx +18 -6
- package/map/ResolvedPlaceLayers.tsx +15 -5
- package/map/ResultCamera.tsx +6 -2
- package/map/ResultOverlay.tsx +18 -6
- package/map/ResultPanel.tsx +21 -7
- package/map/VersionPicker.tsx +18 -6
- package/map/geometry.ts +28 -8
- package/map/index.ts +3 -0
- package/map/place-render.ts +36 -12
- package/map/types.ts +132 -44
- package/map/useCompareState.ts +15 -5
- package/map/useDemoGeocode.ts +12 -4
- package/map/useMapPlaceRender.ts +3 -1
- package/map/usePlaceAutocomplete.ts +52 -18
- package/out/common/ClientOnly.d.ts +6 -2
- package/out/common/ClientOnly.d.ts.map +1 -1
- package/out/common/ClientOnly.js.map +1 -1
- package/out/common/CopyButton.d.ts +9 -3
- package/out/common/CopyButton.d.ts.map +1 -1
- package/out/common/CopyButton.js.map +1 -1
- package/out/common/KindBadge.js +1 -1
- package/out/common/KindBadge.js.map +1 -1
- package/out/common/LoadingIndicator.d.ts +21 -6
- package/out/common/LoadingIndicator.d.ts.map +1 -1
- package/out/common/LoadingIndicator.js +4 -1
- package/out/common/LoadingIndicator.js.map +1 -1
- package/out/common/PresetChips.d.ts +6 -2
- package/out/common/PresetChips.d.ts.map +1 -1
- package/out/common/PresetChips.js.map +1 -1
- package/out/common/cx.d.ts +3 -1
- package/out/common/cx.d.ts.map +1 -1
- package/out/common/cx.js +3 -1
- package/out/common/cx.js.map +1 -1
- package/out/common/useClipboard.d.ts +3 -1
- package/out/common/useClipboard.d.ts.map +1 -1
- package/out/common/useClipboard.js +6 -2
- package/out/common/useClipboard.js.map +1 -1
- package/out/index.d.ts.map +1 -1
- package/out/index.js.map +1 -1
- package/out/map/BackendControl.d.ts +12 -4
- package/out/map/BackendControl.d.ts.map +1 -1
- package/out/map/BackendControl.js +3 -1
- package/out/map/BackendControl.js.map +1 -1
- package/out/map/CompareToggle.d.ts +27 -9
- package/out/map/CompareToggle.d.ts.map +1 -1
- package/out/map/CompareToggle.js +3 -1
- package/out/map/CompareToggle.js.map +1 -1
- package/out/map/DemoControls.d.ts +30 -10
- package/out/map/DemoControls.d.ts.map +1 -1
- package/out/map/DemoControls.js +4 -2
- package/out/map/DemoControls.js.map +1 -1
- package/out/map/DemoMap.d.ts +33 -11
- package/out/map/DemoMap.d.ts.map +1 -1
- package/out/map/DemoMap.js.map +1 -1
- package/out/map/GeocoderDemo.d.ts +16 -6
- package/out/map/GeocoderDemo.d.ts.map +1 -1
- package/out/map/GeocoderDemo.js +9 -3
- package/out/map/GeocoderDemo.js.map +1 -1
- package/out/map/OverlayLayers.d.ts +6 -2
- package/out/map/OverlayLayers.d.ts.map +1 -1
- package/out/map/OverlayLayers.js +4 -2
- package/out/map/OverlayLayers.js.map +1 -1
- package/out/map/PlaceAutocomplete.d.ts +24 -8
- package/out/map/PlaceAutocomplete.d.ts.map +1 -1
- package/out/map/PlaceAutocomplete.js +4 -2
- package/out/map/PlaceAutocomplete.js.map +1 -1
- package/out/map/PlaceMarker.d.ts +15 -5
- package/out/map/PlaceMarker.d.ts.map +1 -1
- package/out/map/PlaceMarker.js +6 -2
- package/out/map/PlaceMarker.js.map +1 -1
- package/out/map/ResolvedPlaceLayers.d.ts +15 -5
- package/out/map/ResolvedPlaceLayers.d.ts.map +1 -1
- package/out/map/ResolvedPlaceLayers.js +3 -1
- package/out/map/ResolvedPlaceLayers.js.map +1 -1
- package/out/map/ResultCamera.d.ts +6 -2
- package/out/map/ResultCamera.d.ts.map +1 -1
- package/out/map/ResultCamera.js +3 -1
- package/out/map/ResultCamera.js.map +1 -1
- package/out/map/ResultOverlay.d.ts +15 -5
- package/out/map/ResultOverlay.d.ts.map +1 -1
- package/out/map/ResultOverlay.js +3 -1
- package/out/map/ResultOverlay.js.map +1 -1
- package/out/map/ResultPanel.d.ts +21 -7
- package/out/map/ResultPanel.d.ts.map +1 -1
- package/out/map/ResultPanel.js +3 -1
- package/out/map/ResultPanel.js.map +1 -1
- package/out/map/VersionPicker.d.ts +18 -6
- package/out/map/VersionPicker.d.ts.map +1 -1
- package/out/map/VersionPicker.js +3 -1
- package/out/map/VersionPicker.js.map +1 -1
- package/out/map/geometry.d.ts +12 -4
- package/out/map/geometry.d.ts.map +1 -1
- package/out/map/geometry.js +17 -5
- package/out/map/geometry.js.map +1 -1
- package/out/map/index.d.ts.map +1 -1
- package/out/map/index.js.map +1 -1
- package/out/map/place-render.d.ts +27 -9
- package/out/map/place-render.d.ts.map +1 -1
- package/out/map/place-render.js +9 -3
- package/out/map/place-render.js.map +1 -1
- package/out/map/types.d.ts +132 -44
- package/out/map/types.d.ts.map +1 -1
- package/out/map/useCompareState.d.ts +15 -5
- package/out/map/useCompareState.d.ts.map +1 -1
- package/out/map/useCompareState.js.map +1 -1
- package/out/map/useDemoGeocode.d.ts +12 -4
- package/out/map/useDemoGeocode.d.ts.map +1 -1
- package/out/map/useDemoGeocode.js.map +1 -1
- package/out/map/useMapPlaceRender.d.ts +3 -1
- package/out/map/useMapPlaceRender.d.ts.map +1 -1
- package/out/map/useMapPlaceRender.js +3 -1
- package/out/map/useMapPlaceRender.js.map +1 -1
- package/out/map/usePlaceAutocomplete.d.ts +45 -15
- package/out/map/usePlaceAutocomplete.d.ts.map +1 -1
- package/out/map/usePlaceAutocomplete.js +7 -3
- package/out/map/usePlaceAutocomplete.js.map +1 -1
- package/out/pipeline/ConfidenceCell.d.ts.map +1 -1
- package/out/pipeline/ConfidenceCell.js +9 -1
- package/out/pipeline/ConfidenceCell.js.map +1 -1
- package/out/pipeline/PipelineExplorer.d.ts +12 -4
- package/out/pipeline/PipelineExplorer.d.ts.map +1 -1
- package/out/pipeline/PipelineExplorer.js +6 -2
- package/out/pipeline/PipelineExplorer.js.map +1 -1
- package/out/pipeline/QueryForm.d.ts +6 -2
- package/out/pipeline/QueryForm.d.ts.map +1 -1
- package/out/pipeline/QueryForm.js +1 -1
- package/out/pipeline/QueryForm.js.map +1 -1
- package/out/pipeline/ResolvedPlace.js +1 -1
- package/out/pipeline/ResolvedPlace.js.map +1 -1
- package/out/pipeline/presets.d.ts +7 -0
- package/out/pipeline/presets.d.ts.map +1 -1
- package/out/pipeline/presets.js +7 -0
- package/out/pipeline/presets.js.map +1 -1
- package/out/pipeline/types.d.ts +60 -20
- package/out/pipeline/types.d.ts.map +1 -1
- package/out/pipeline/useParsePipeline.d.ts +12 -4
- package/out/pipeline/useParsePipeline.d.ts.map +1 -1
- package/out/pipeline/useParsePipeline.js +2 -2
- package/out/pipeline/useParsePipeline.js.map +1 -1
- package/out/poi/LiveResultsBlock.d.ts +6 -2
- package/out/poi/LiveResultsBlock.d.ts.map +1 -1
- package/out/poi/LiveResultsBlock.js +1 -1
- package/out/poi/LiveResultsBlock.js.map +1 -1
- package/out/poi/POIExplorer.d.ts +12 -4
- package/out/poi/POIExplorer.d.ts.map +1 -1
- package/out/poi/POIExplorer.js.map +1 -1
- package/out/poi/SubjectPanel.d.ts.map +1 -1
- package/out/poi/SubjectPanel.js +4 -2
- package/out/poi/SubjectPanel.js.map +1 -1
- package/out/poi/runtime.d.ts +9 -2
- package/out/poi/runtime.d.ts.map +1 -1
- package/out/poi/runtime.js +10 -3
- package/out/poi/runtime.js.map +1 -1
- package/out/poi/types.d.ts +40 -15
- package/out/poi/types.d.ts.map +1 -1
- package/out/poi/usePOISearch.d.ts +27 -9
- package/out/poi/usePOISearch.d.ts.map +1 -1
- package/out/poi/usePOISearch.js +5 -3
- package/out/poi/usePOISearch.js.map +1 -1
- package/out/runtime/useDemoRuntime.d.ts +81 -27
- package/out/runtime/useDemoRuntime.d.ts.map +1 -1
- package/out/runtime/useDemoRuntime.js.map +1 -1
- package/package.json +4 -4
- package/pipeline/ConfidenceCell.tsx +11 -1
- package/pipeline/PipelineExplorer.tsx +19 -6
- package/pipeline/QueryForm.tsx +7 -3
- package/pipeline/ResolvedPlace.tsx +2 -2
- package/pipeline/presets.ts +7 -0
- package/pipeline/types.ts +60 -20
- package/pipeline/useParsePipeline.ts +14 -6
- package/poi/LiveResultsBlock.tsx +7 -3
- package/poi/POIExplorer.tsx +14 -4
- package/poi/SubjectPanel.tsx +4 -2
- package/poi/runtime.ts +11 -3
- package/poi/types.ts +41 -15
- package/poi/usePOISearch.ts +34 -12
- package/runtime/useDemoRuntime.ts +82 -27
package/common/ClientOnly.tsx
CHANGED
|
@@ -15,9 +15,13 @@
|
|
|
15
15
|
import { type ReactNode, useEffect, useState } from "react"
|
|
16
16
|
|
|
17
17
|
export interface ClientOnlyProps {
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Rendered once mounted in the browser. A thunk so its (browser-only) imports never run on the server.
|
|
20
|
+
*/
|
|
19
21
|
children: () => ReactNode
|
|
20
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Rendered on the server and until the first client mount.
|
|
24
|
+
*/
|
|
21
25
|
fallback?: ReactNode
|
|
22
26
|
}
|
|
23
27
|
|
package/common/CopyButton.tsx
CHANGED
|
@@ -12,11 +12,17 @@ import type { ReactNode } from "react"
|
|
|
12
12
|
import { useClipboard } from "./useClipboard.ts"
|
|
13
13
|
|
|
14
14
|
export interface CopyButtonProps {
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* The text to copy. If a thunk, it's evaluated at click time (so callers can copy the latest value).
|
|
17
|
+
*/
|
|
16
18
|
value: string | (() => string)
|
|
17
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Label in the idle state. @default "Copy"
|
|
21
|
+
*/
|
|
18
22
|
label?: ReactNode
|
|
19
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Label shown briefly after a successful copy. @default "✓ Copied"
|
|
25
|
+
*/
|
|
20
26
|
copiedLabel?: ReactNode
|
|
21
27
|
className?: string
|
|
22
28
|
disabled?: boolean
|
package/common/KindBadge.tsx
CHANGED
|
@@ -30,7 +30,7 @@ export function KindBadge({ kindResult }: KindBadgeProps): ReactNode {
|
|
|
30
30
|
<strong>Kind:</strong> <code>{kindResult.kind}</code>{" "}
|
|
31
31
|
<span className="mw-kind__confidence">({formatPct(kindResult.confidence)})</span>
|
|
32
32
|
</summary>
|
|
33
|
-
{kindResult.alternatives.length
|
|
33
|
+
{kindResult.alternatives.length ? (
|
|
34
34
|
<ul className="mw-kind__alternatives">
|
|
35
35
|
{kindResult.alternatives.map((alt) => (
|
|
36
36
|
<li key={alt.kind}>
|
|
@@ -16,17 +16,29 @@ import { cx } from "./cx.ts"
|
|
|
16
16
|
export type LoadingMode = "pulse" | "spinner" | "staged"
|
|
17
17
|
|
|
18
18
|
export interface LoadingIndicatorProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
19
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* @default "spinner"
|
|
21
|
+
*/
|
|
20
22
|
mode?: LoadingMode
|
|
21
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Optional label; in staged mode it renders above the step list.
|
|
25
|
+
*/
|
|
22
26
|
label?: string
|
|
23
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Number of skeleton bars (pulse mode). @default 3
|
|
29
|
+
*/
|
|
24
30
|
barCount?: number
|
|
25
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Spinner ring size. @default "medium"
|
|
33
|
+
*/
|
|
26
34
|
size?: "small" | "medium" | "large"
|
|
27
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Step labels (staged mode) — one row each.
|
|
37
|
+
*/
|
|
28
38
|
steps?: string[]
|
|
29
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* 0-based index of the active step; earlier steps are complete, later ones pending. @default -1
|
|
41
|
+
*/
|
|
30
42
|
activeStep?: number
|
|
31
43
|
}
|
|
32
44
|
|
|
@@ -36,6 +48,9 @@ const SIZE_CLASS: Record<NonNullable<LoadingIndicatorProps["size"]>, string> = {
|
|
|
36
48
|
large: "mw-spinner--large",
|
|
37
49
|
}
|
|
38
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Spinner, pulse or staged progress, depending on how long the caller expects to wait.
|
|
53
|
+
*/
|
|
39
54
|
export const LoadingIndicator = memo<LoadingIndicatorProps>(function LoadingIndicator({
|
|
40
55
|
mode = "spinner",
|
|
41
56
|
label,
|
|
@@ -71,7 +86,7 @@ const SpinnerRing = memo<{ size: NonNullable<LoadingIndicatorProps["size"]> }>(f
|
|
|
71
86
|
})
|
|
72
87
|
|
|
73
88
|
const StagedProgress = memo<{ steps?: string[]; activeStep: number }>(function StagedProgress({ steps, activeStep }) {
|
|
74
|
-
if (!steps || steps.length
|
|
89
|
+
if (!steps || !steps.length) return null
|
|
75
90
|
|
|
76
91
|
return (
|
|
77
92
|
<ul className="mw-staged">
|
package/common/PresetChips.tsx
CHANGED
|
@@ -25,9 +25,13 @@ export interface PresetChipsProps {
|
|
|
25
25
|
presets: ReadonlyArray<Preset>
|
|
26
26
|
onPick: (value: string) => void
|
|
27
27
|
disabled?: boolean
|
|
28
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Leading label. @default "Try:"
|
|
30
|
+
*/
|
|
29
31
|
caption?: string
|
|
30
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Optional trailing content rendered inside the chip row after the presets (e.g. an inline permalink button).
|
|
34
|
+
*/
|
|
31
35
|
trailing?: ReactNode
|
|
32
36
|
}
|
|
33
37
|
|
package/common/cx.ts
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
|
|
11
11
|
export type ClassValue = string | number | false | null | undefined | Record<string, boolean>
|
|
12
12
|
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Join truthy class tokens; object entries contribute their key when the value is truthy.
|
|
15
|
+
*/
|
|
14
16
|
export function cx(...values: ClassValue[]): string {
|
|
15
17
|
const out: string[] = []
|
|
16
18
|
|
package/common/useClipboard.ts
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
|
|
11
11
|
import { useCallback, useEffect, useRef, useState } from "react"
|
|
12
12
|
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Best-effort clipboard write: async Clipboard API first, hidden-textarea `execCommand` fallback.
|
|
15
|
+
*/
|
|
14
16
|
async function writeToClipboard(value: string): Promise<void> {
|
|
15
17
|
try {
|
|
16
18
|
await navigator.clipboard.writeText(value)
|
|
@@ -41,7 +43,9 @@ export interface UseClipboard {
|
|
|
41
43
|
copy: (value: string) => Promise<void>
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* @param resetMs - How long the `copied` flag stays true after a successful copy.
|
|
48
|
+
*/
|
|
45
49
|
export function useClipboard(resetMs = 1500): UseClipboard {
|
|
46
50
|
const [copied, setCopied] = useState(false)
|
|
47
51
|
const timer = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
@@ -64,6 +68,7 @@ export function useClipboard(resetMs = 1500): UseClipboard {
|
|
|
64
68
|
if (timer.current) {
|
|
65
69
|
clearTimeout(timer.current)
|
|
66
70
|
}
|
|
71
|
+
|
|
67
72
|
timer.current = setTimeout(() => setCopied(false), resetMs)
|
|
68
73
|
},
|
|
69
74
|
[resetMs]
|
package/index.ts
CHANGED
|
@@ -47,6 +47,7 @@ export type { QueryInputProps } from "./poi/QueryInput.tsx"
|
|
|
47
47
|
export { formatDistance, loadPOIRuntime, POI_DEFAULT_TEXT, POI_PRESETS } from "./poi/runtime.ts"
|
|
48
48
|
export { SubjectPanel } from "./poi/SubjectPanel.tsx"
|
|
49
49
|
export type { SubjectPanelProps } from "./poi/SubjectPanel.tsx"
|
|
50
|
+
|
|
50
51
|
export type {
|
|
51
52
|
CategoryRecord,
|
|
52
53
|
LiveSearchState,
|
|
@@ -62,6 +63,7 @@ export type {
|
|
|
62
63
|
POISubjectBase,
|
|
63
64
|
TaxonomyLookup,
|
|
64
65
|
} from "./poi/types.ts"
|
|
66
|
+
|
|
65
67
|
export { usePOISearch } from "./poi/usePOISearch.ts"
|
|
66
68
|
export type { UsePOISearch, UsePOISearchOptions } from "./poi/usePOISearch.ts"
|
|
67
69
|
|
|
@@ -80,6 +82,7 @@ export { QueryForm } from "./pipeline/QueryForm.tsx"
|
|
|
80
82
|
export type { QueryFormProps } from "./pipeline/QueryForm.tsx"
|
|
81
83
|
export { ResolvedPlace } from "./pipeline/ResolvedPlace.tsx"
|
|
82
84
|
export type { ResolvedPlaceProps } from "./pipeline/ResolvedPlace.tsx"
|
|
85
|
+
|
|
83
86
|
export type {
|
|
84
87
|
DualRoleView,
|
|
85
88
|
FSTProvenance,
|
|
@@ -91,11 +94,13 @@ export type {
|
|
|
91
94
|
ResolvedPlaceView,
|
|
92
95
|
StageTiming,
|
|
93
96
|
} from "./pipeline/types.ts"
|
|
97
|
+
|
|
94
98
|
export { useParsePipeline } from "./pipeline/useParsePipeline.ts"
|
|
95
99
|
export type { UseParsePipeline, UseParsePipelineOptions } from "./pipeline/useParsePipeline.ts"
|
|
96
100
|
|
|
97
101
|
// ── Demo runtime (shared load orchestration; node-safe — no onnx/httpvfs/maplibre) ──
|
|
98
102
|
export { useDemoRuntime } from "./runtime/useDemoRuntime.ts"
|
|
103
|
+
|
|
99
104
|
export type {
|
|
100
105
|
DemoAssetsLoadContext,
|
|
101
106
|
DemoLoaderState,
|
package/map/BackendControl.tsx
CHANGED
|
@@ -14,15 +14,23 @@
|
|
|
14
14
|
import type { ReactNode } from "react"
|
|
15
15
|
|
|
16
16
|
export interface BackendControlProps {
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* The backend the runtime resolved to (e.g. `webgpu (28 MB int8)`); empty before it is known.
|
|
19
|
+
*/
|
|
18
20
|
activeBackend?: string
|
|
19
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Whether the CPU/WASM backend is currently forced.
|
|
23
|
+
*/
|
|
20
24
|
forceWASM: boolean
|
|
21
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* Fired when the visitor toggles the "Force WASM" checkbox.
|
|
27
|
+
*/
|
|
22
28
|
onForceWASMChange: (forceWASM: boolean) => void
|
|
23
29
|
}
|
|
24
30
|
|
|
25
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* The backend indicator + WASM opt-out.
|
|
33
|
+
*/
|
|
26
34
|
export function BackendControl({ activeBackend, forceWASM, onForceWASMChange }: BackendControlProps): ReactNode {
|
|
27
35
|
return (
|
|
28
36
|
<div className="mw-demo-backend">
|
package/map/CompareToggle.tsx
CHANGED
|
@@ -16,25 +16,43 @@ import type { ReactNode } from "react"
|
|
|
16
16
|
import type { DemoVersionOption } from "./types.ts"
|
|
17
17
|
|
|
18
18
|
export interface CompareToggleProps {
|
|
19
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* The selectable model bundles (the primary version is filtered out of the compare list).
|
|
21
|
+
*/
|
|
20
22
|
versions: ReadonlyArray<DemoVersionOption>
|
|
21
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* The primary version, excluded from the compare options.
|
|
25
|
+
*/
|
|
22
26
|
primaryVersion: string | null
|
|
23
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Whether compare mode is on.
|
|
29
|
+
*/
|
|
24
30
|
compareMode: boolean
|
|
25
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Fired when the visitor flips compare mode.
|
|
33
|
+
*/
|
|
26
34
|
onCompareModeChange: (compareMode: boolean) => void
|
|
27
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* The version chosen to compare against, or `null` when none is chosen.
|
|
37
|
+
*/
|
|
28
38
|
compareVersion: string | null
|
|
29
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* Fired with the chosen compare version (or `null` when the empty option is picked).
|
|
41
|
+
*/
|
|
30
42
|
onCompareVersionChange: (version: string | null) => void
|
|
31
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Disable the compare-version select (e.g. while a parse or compare load runs).
|
|
45
|
+
*/
|
|
32
46
|
disabled?: boolean
|
|
33
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* A status line rendered under the select (e.g. the compare backend, or a "Loading…" line).
|
|
49
|
+
*/
|
|
34
50
|
status?: ReactNode
|
|
35
51
|
}
|
|
36
52
|
|
|
37
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* The compare toggle + (when on) the compare-version selector. Renders `null` with fewer than two versions.
|
|
55
|
+
*/
|
|
38
56
|
export function CompareToggle({
|
|
39
57
|
versions,
|
|
40
58
|
primaryVersion,
|
package/map/DemoControls.tsx
CHANGED
|
@@ -30,27 +30,47 @@ import type { UsePlaceAutocomplete } from "./usePlaceAutocomplete.ts"
|
|
|
30
30
|
import { VersionPicker } from "./VersionPicker.tsx"
|
|
31
31
|
|
|
32
32
|
export interface DemoControlsProps {
|
|
33
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* The injected demo runtime.
|
|
35
|
+
*/
|
|
34
36
|
runtime: DemoRuntime
|
|
35
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* The parse+resolve state machine.
|
|
39
|
+
*/
|
|
36
40
|
geocode: UseDemoGeocode
|
|
37
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* The place-autocomplete combobox state.
|
|
43
|
+
*/
|
|
38
44
|
autocomplete: UsePlaceAutocomplete
|
|
39
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* The compare-mode state.
|
|
47
|
+
*/
|
|
40
48
|
compare: UseCompareState
|
|
41
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Host-injected panels (about, release blurb, compare, permalink, extras, failure).
|
|
51
|
+
*/
|
|
42
52
|
panels: DemoPanels
|
|
43
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Example chips.
|
|
55
|
+
*/
|
|
44
56
|
presets: ReadonlyArray<Preset>
|
|
45
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* Input placeholder.
|
|
59
|
+
*/
|
|
46
60
|
placeholder: string
|
|
47
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* Select a model version (the composed demo also clears a now-colliding compare selection).
|
|
63
|
+
*/
|
|
48
64
|
onSelectVersion: (version: string) => void
|
|
49
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* Toggle the forced WASM backend.
|
|
67
|
+
*/
|
|
50
68
|
onForceWASMChange: (forceWASM: boolean) => void
|
|
51
69
|
}
|
|
52
70
|
|
|
53
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* The floating control panel.
|
|
73
|
+
*/
|
|
54
74
|
export function DemoControls({
|
|
55
75
|
runtime,
|
|
56
76
|
geocode,
|
|
@@ -130,7 +150,7 @@ export function DemoControls({
|
|
|
130
150
|
{loading && !runtime.ready ? (
|
|
131
151
|
<LoadingIndicator
|
|
132
152
|
mode="staged"
|
|
133
|
-
steps={loading.stepLabels.length
|
|
153
|
+
steps={loading.stepLabels.length ? loading.stepLabels : undefined}
|
|
134
154
|
activeStep={loading.stepIndex}
|
|
135
155
|
label={loading.progress}
|
|
136
156
|
/>
|
package/map/DemoMap.tsx
CHANGED
|
@@ -25,7 +25,9 @@ import type { CSSProperties, ReactNode, Ref } from "react"
|
|
|
25
25
|
import { Map } from "react-map-gl/maplibre"
|
|
26
26
|
import type { MapProps, MapRef, ViewStateChangeEvent } from "react-map-gl/maplibre"
|
|
27
27
|
|
|
28
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* The style a `<DemoMap>` renders — a style URL or an inline/composed `StyleSpecification`.
|
|
30
|
+
*/
|
|
29
31
|
export type DemoMapStyle = NonNullable<MapProps["mapStyle"]>
|
|
30
32
|
|
|
31
33
|
/**
|
|
@@ -37,25 +39,45 @@ export type DemoMapExtraProps = Partial<
|
|
|
37
39
|
>
|
|
38
40
|
|
|
39
41
|
export interface DemoMapProps {
|
|
40
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* The map style — host-composed `StyleSpecification` or a style URL.
|
|
44
|
+
*/
|
|
41
45
|
mapStyle: DemoMapStyle
|
|
42
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Uncontrolled initial camera. Use this OR `viewState`, not both.
|
|
48
|
+
*/
|
|
43
49
|
initialViewState?: MapProps["initialViewState"]
|
|
44
|
-
/**
|
|
50
|
+
/**
|
|
51
|
+
* Controlled camera. Pair with `onMove` to persist it.
|
|
52
|
+
*/
|
|
45
53
|
viewState?: MapProps["viewState"]
|
|
46
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* Fired on every camera change (drag/zoom/rotate) — the seam for viewport-bias persistence.
|
|
56
|
+
*/
|
|
47
57
|
onMove?: (event: ViewStateChangeEvent) => void
|
|
48
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* Map projection. @default "globe" (matches the docs `DashboardMap`).
|
|
60
|
+
*/
|
|
49
61
|
projection?: MapProps["projection"]
|
|
50
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* Forwarded to the underlying `<Map>` for imperative access (`useMap`/`flyTo` in later phases).
|
|
64
|
+
*/
|
|
51
65
|
mapRef?: Ref<MapRef>
|
|
52
|
-
/**
|
|
66
|
+
/**
|
|
67
|
+
* Overlays, markers, and controls — rendered as `<Map>` children. Empty in phase 1.
|
|
68
|
+
*/
|
|
53
69
|
children?: ReactNode
|
|
54
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* Class on the wrapper element.
|
|
72
|
+
*/
|
|
55
73
|
className?: string
|
|
56
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Inline style on the wrapper element (sizing lives here or on `.mw-demo-map`).
|
|
76
|
+
*/
|
|
57
77
|
style?: CSSProperties
|
|
58
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* Remaining `<Map>` props DemoMap does not surface explicitly.
|
|
80
|
+
*/
|
|
59
81
|
mapProps?: DemoMapExtraProps
|
|
60
82
|
}
|
|
61
83
|
|
package/map/GeocoderDemo.tsx
CHANGED
|
@@ -23,7 +23,7 @@ import { type ReactNode, useCallback, useRef } from "react"
|
|
|
23
23
|
import type { MapRef } from "react-map-gl/maplibre"
|
|
24
24
|
|
|
25
25
|
import { ClientOnly } from "../common/ClientOnly.tsx"
|
|
26
|
-
import {
|
|
26
|
+
import type { Preset } from "../common/PresetChips.tsx"
|
|
27
27
|
import { DemoControls } from "./DemoControls.tsx"
|
|
28
28
|
import { DemoMap } from "./DemoMap.tsx"
|
|
29
29
|
import { OverlayLayers } from "./OverlayLayers.tsx"
|
|
@@ -35,13 +35,21 @@ import { useMapPlaceRender } from "./useMapPlaceRender.ts"
|
|
|
35
35
|
import { usePlaceAutocomplete } from "./usePlaceAutocomplete.ts"
|
|
36
36
|
|
|
37
37
|
export interface GeocoderDemoProps {
|
|
38
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* The injected demo runtime (map style + overlays + parse + version/backend).
|
|
40
|
+
*/
|
|
39
41
|
runtime: DemoRuntime
|
|
40
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* Host-injected panels (about, release blurb, compare, permalink, debug drawer, map controls, …).
|
|
44
|
+
*/
|
|
41
45
|
panels?: DemoPanels
|
|
42
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Address to pre-fill.
|
|
48
|
+
*/
|
|
43
49
|
defaultAddress?: string
|
|
44
|
-
/**
|
|
50
|
+
/**
|
|
51
|
+
* Example chips. @default the empty set (host supplies its own).
|
|
52
|
+
*/
|
|
45
53
|
presets?: ReadonlyArray<Preset>
|
|
46
54
|
/**
|
|
47
55
|
* Only hint the viewport bias once the visitor has zoomed past the global view — a whole-globe center is noise.
|
|
@@ -89,6 +97,7 @@ function GeocoderDemoInner({
|
|
|
89
97
|
|
|
90
98
|
const geocode = useDemoGeocode({ runtime, defaultText: defaultAddress, getBias })
|
|
91
99
|
const compare = useCompareState()
|
|
100
|
+
|
|
92
101
|
const autocomplete = usePlaceAutocomplete({
|
|
93
102
|
text: geocode.text,
|
|
94
103
|
setText: geocode.setText,
|
|
@@ -146,12 +155,20 @@ function GeocoderDemoInner({
|
|
|
146
155
|
)
|
|
147
156
|
}
|
|
148
157
|
|
|
149
|
-
/**
|
|
158
|
+
/**
|
|
159
|
+
* Stable empty defaults — a fresh `{}`/`[]` per render would churn every downstream memo dep.
|
|
160
|
+
*/
|
|
161
|
+
const NO_PANELS: DemoPanels = {}
|
|
162
|
+
const NO_PRESETS: ReadonlyArray<Preset> = []
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* The composed geocoder demo, behind a `ClientOnly` SSR boundary (the map is intrinsically a client component).
|
|
166
|
+
*/
|
|
150
167
|
export function GeocoderDemo({
|
|
151
168
|
runtime,
|
|
152
|
-
panels =
|
|
169
|
+
panels = NO_PANELS,
|
|
153
170
|
defaultAddress = "",
|
|
154
|
-
presets =
|
|
171
|
+
presets = NO_PRESETS,
|
|
155
172
|
minBiasZoom = 4,
|
|
156
173
|
applyResultCamera = true,
|
|
157
174
|
}: GeocoderDemoProps): ReactNode {
|
package/map/OverlayLayers.tsx
CHANGED
|
@@ -19,13 +19,17 @@ import { Layer, Source } from "react-map-gl/maplibre"
|
|
|
19
19
|
import type { OverlaySpec } from "./types.ts"
|
|
20
20
|
|
|
21
21
|
export interface OverlayLayersProps {
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* The overlays to render, in draw order (first is drawn first / lowest).
|
|
24
|
+
*/
|
|
23
25
|
overlays?: OverlaySpec[]
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Render each overlay as one `<Source>` and its `<Layer>`s, honoring the `visible` flag via `visibility`.
|
|
30
|
+
*/
|
|
27
31
|
export function OverlayLayers({ overlays }: OverlayLayersProps): ReactNode {
|
|
28
|
-
if (!overlays || overlays.length
|
|
32
|
+
if (!overlays || !overlays.length) return null
|
|
29
33
|
|
|
30
34
|
return (
|
|
31
35
|
<>
|
|
@@ -18,23 +18,39 @@ import { cx } from "../common/cx.ts"
|
|
|
18
18
|
import type { Suggestion } from "./types.ts"
|
|
19
19
|
|
|
20
20
|
export interface PlaceAutocompleteProps {
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* The suggestions to render (from {@link usePlaceAutocomplete}).
|
|
23
|
+
*/
|
|
22
24
|
suggestions: Suggestion[]
|
|
23
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* The keyboard-highlighted index; `-1` for none.
|
|
27
|
+
*/
|
|
24
28
|
activeIndex: number
|
|
25
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Fired (with the suggestion `value`) when one is clicked.
|
|
31
|
+
*/
|
|
26
32
|
onPick: (value: string) => void
|
|
27
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Fired with the index a pointer entered, so hover matches keyboard highlight.
|
|
35
|
+
*/
|
|
28
36
|
onHover?: (index: number) => void
|
|
29
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* The listbox element id — pass `listboxId` from the hook (matches the input's `aria-controls`).
|
|
39
|
+
*/
|
|
30
40
|
listboxId: string
|
|
31
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* Build the option element id — pass `optionId` from the hook.
|
|
43
|
+
*/
|
|
32
44
|
optionId: (index: number) => string
|
|
33
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* Leading label. @default "Did you mean:"
|
|
47
|
+
*/
|
|
34
48
|
caption?: string
|
|
35
49
|
}
|
|
36
50
|
|
|
37
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* The suggestion listbox.
|
|
53
|
+
*/
|
|
38
54
|
export function PlaceAutocomplete({
|
|
39
55
|
suggestions,
|
|
40
56
|
activeIndex,
|
|
@@ -44,7 +60,7 @@ export function PlaceAutocomplete({
|
|
|
44
60
|
optionId,
|
|
45
61
|
caption = "Did you mean:",
|
|
46
62
|
}: PlaceAutocompleteProps): ReactNode {
|
|
47
|
-
if (suggestions.length
|
|
63
|
+
if (!suggestions.length) return null
|
|
48
64
|
|
|
49
65
|
return (
|
|
50
66
|
<div className="mw-demo-suggest" id={listboxId} role="listbox" aria-label="Place suggestions">
|
package/map/PlaceMarker.tsx
CHANGED
|
@@ -15,21 +15,33 @@
|
|
|
15
15
|
import type { ReactNode } from "react"
|
|
16
16
|
import { Marker } from "react-map-gl/maplibre"
|
|
17
17
|
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* The house pink the demo has always drawn the resolved-place marker in.
|
|
20
|
+
*/
|
|
19
21
|
const MARKER_COLOR = "#e0367c"
|
|
20
22
|
|
|
21
23
|
export interface PlaceMarkerProps {
|
|
22
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* Marker longitude.
|
|
26
|
+
*/
|
|
23
27
|
longitude: number
|
|
24
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Marker latitude.
|
|
30
|
+
*/
|
|
25
31
|
latitude: number
|
|
26
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Pin color. @default the house pink.
|
|
34
|
+
*/
|
|
27
35
|
color?: string
|
|
28
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Which part of the marker sits on the coordinate. @default "center" (a symmetric dot).
|
|
38
|
+
*/
|
|
29
39
|
anchor?: "center" | "top" | "bottom" | "left" | "right"
|
|
30
40
|
}
|
|
31
41
|
|
|
32
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* A single resolved-place marker. Wraps `react-map-gl`'s `<Marker>` with the demo's default color.
|
|
44
|
+
*/
|
|
33
45
|
export function PlaceMarker({
|
|
34
46
|
longitude,
|
|
35
47
|
latitude,
|
|
@@ -21,22 +21,32 @@ import { ResultCamera } from "./ResultCamera.tsx"
|
|
|
21
21
|
import { ResultOverlay } from "./ResultOverlay.tsx"
|
|
22
22
|
|
|
23
23
|
export interface ResolvedPlaceLayersProps {
|
|
24
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* The render spec (from {@link useMapPlaceRender}); `null` renders nothing.
|
|
26
|
+
*/
|
|
25
27
|
spec: MapPlaceRenderSpec | null
|
|
26
28
|
/**
|
|
27
29
|
* Apply the computed camera target via {@link ResultCamera}. @default true. Set false when the consumer drives the
|
|
28
30
|
* camera itself (e.g. a controlled `<DemoMap viewState>` fed by {@link cameraToViewState}).
|
|
29
31
|
*/
|
|
30
32
|
applyCamera?: boolean
|
|
31
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Animate the camera move. Forwarded to {@link ResultCamera}. @default true
|
|
35
|
+
*/
|
|
32
36
|
animateCamera?: boolean
|
|
33
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Source/layer id prefix for the outline. @default "mw-result"
|
|
39
|
+
*/
|
|
34
40
|
outlineId?: string
|
|
35
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* Marker color. @default the house pink.
|
|
43
|
+
*/
|
|
36
44
|
markerColor?: string
|
|
37
45
|
}
|
|
38
46
|
|
|
39
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Render the marker(s), outline, and (optional) camera move for one resolved place.
|
|
49
|
+
*/
|
|
40
50
|
export function ResolvedPlaceLayers({
|
|
41
51
|
spec,
|
|
42
52
|
applyCamera = true,
|
package/map/ResultCamera.tsx
CHANGED
|
@@ -25,7 +25,9 @@ import { useMap } from "react-map-gl/maplibre"
|
|
|
25
25
|
import type { MapCameraTarget } from "./place-render.ts"
|
|
26
26
|
|
|
27
27
|
export interface ResultCameraProps {
|
|
28
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* The camera target to animate to. `null` leaves the camera untouched (no result yet).
|
|
30
|
+
*/
|
|
29
31
|
target: MapCameraTarget | null
|
|
30
32
|
/**
|
|
31
33
|
* Animate (`flyTo`/`fitBounds`) vs jump. @default true. When false, a `center` target jumps with `jumpTo`; a `bounds`
|
|
@@ -34,7 +36,9 @@ export interface ResultCameraProps {
|
|
|
34
36
|
animate?: boolean
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* Drive the live map to `target`. No DOM of its own — it is a behavior mounted as a `<Map>` child.
|
|
41
|
+
*/
|
|
38
42
|
export function ResultCamera({ target, animate = true }: ResultCameraProps): ReactNode {
|
|
39
43
|
const map = useMap()
|
|
40
44
|
|