@kahwee/sf-map-svg 1.5.2 → 2.1.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/CHANGELOG.md +46 -0
- package/README.md +160 -6
- package/SOURCES.md +34 -0
- package/dist/data/README.md +5 -1
- package/dist/data/candidates/2016-11-08.json +1 -0
- package/dist/data/candidates/2018-11-06.json +1 -0
- package/dist/data/candidates/2020-11-03.json +1 -0
- package/dist/data/candidates/2022-11-08.json +1 -0
- package/dist/data/candidates/2024-11-05.json +1 -0
- package/dist/data/candidates/2026-06-02.json +1 -0
- package/dist/data/candidates/README.md +43 -0
- package/dist/data/candidates/catalog.json +40 -0
- package/dist/data/types.d.ts +4 -1
- package/dist/src/api.d.ts +3 -0
- package/dist/src/api.js +3 -0
- package/dist/src/camera.d.ts +16 -0
- package/dist/src/camera.js +55 -0
- package/dist/src/clusters.d.ts +7 -0
- package/dist/src/clusters.js +33 -0
- package/dist/src/configuration.d.ts +5 -0
- package/dist/src/configuration.js +73 -0
- package/dist/src/controller-types.d.ts +84 -0
- package/dist/src/controller-types.js +1 -0
- package/dist/src/explorer-core.d.ts +1 -1
- package/dist/src/explorer-core.js +570 -145
- package/dist/src/features.d.ts +24 -0
- package/dist/src/features.js +99 -0
- package/dist/src/guide-data.js +3 -2
- package/dist/src/guide-detailed.js +3 -2
- package/dist/src/guide-map.d.ts +4 -0
- package/dist/src/guide-map.js +35 -10
- package/dist/src/guide-shell.d.ts +2 -0
- package/dist/src/guide-shell.js +16 -0
- package/dist/src/guide-static.d.ts +9 -0
- package/dist/src/guide-static.js +26 -0
- package/dist/src/guide.d.ts +2 -1
- package/dist/src/guide.js +1 -1
- package/dist/src/interactive-data.d.ts +1 -1
- package/dist/src/interactive-data.js +2 -0
- package/dist/src/interactive.d.ts +1 -1
- package/dist/src/interactive.js +2 -0
- package/dist/src/layers.js +3 -1
- package/dist/src/map-core.js +3 -8
- package/dist/src/map.d.ts +7 -0
- package/dist/src/map.js +106 -0
- package/dist/src/presets.d.ts +3 -0
- package/dist/src/presets.js +17 -0
- package/dist/src/static.d.ts +10 -0
- package/dist/src/static.js +5 -0
- package/dist/src/types.d.ts +73 -9
- package/dist/src/validation.d.ts +7 -0
- package/dist/src/validation.js +226 -0
- package/dist/src/viewport.js +9 -2
- package/docs/EXAMPLES.md +11 -1
- package/docs/api-audit.md +80 -0
- package/docs/consumer-integration.md +165 -0
- package/docs/guide-bundle-report.md +19 -0
- package/docs/migration-v2.md +238 -0
- package/package.json +40 -11
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { controlKeys, layerKeys, normalizeFeatures, validateSwitchPatch } from './features.js';
|
|
2
|
+
import { assertOptions, validateExplorerOptions } from './validation.js';
|
|
3
|
+
const appearanceKeys = [
|
|
4
|
+
'theme',
|
|
5
|
+
'colors',
|
|
6
|
+
'labelStyle',
|
|
7
|
+
'areaStyle',
|
|
8
|
+
'labelSize',
|
|
9
|
+
'style',
|
|
10
|
+
'markerRadius',
|
|
11
|
+
'markerHitSize',
|
|
12
|
+
'markerColor',
|
|
13
|
+
'selectedMarkerColor',
|
|
14
|
+
];
|
|
15
|
+
const featureKeys = [
|
|
16
|
+
'motion',
|
|
17
|
+
'markerEntrance',
|
|
18
|
+
'selectedMarkerRing',
|
|
19
|
+
'clustering',
|
|
20
|
+
'northArrow',
|
|
21
|
+
'scaleBar',
|
|
22
|
+
];
|
|
23
|
+
export function expandMapOptions(options) {
|
|
24
|
+
const record = assertOptions(options, 'map');
|
|
25
|
+
for (const key of [
|
|
26
|
+
...appearanceKeys,
|
|
27
|
+
...featureKeys,
|
|
28
|
+
'interface',
|
|
29
|
+
'onMarkerActivate',
|
|
30
|
+
'onOverlayActivate',
|
|
31
|
+
])
|
|
32
|
+
if (key in record)
|
|
33
|
+
throw new TypeError(`Use the v2 grouped options or map.on() instead of ${key}.`);
|
|
34
|
+
if (options.appearance !== undefined)
|
|
35
|
+
assertOptions(options.appearance, 'appearance', appearanceKeys);
|
|
36
|
+
if (options.features !== undefined)
|
|
37
|
+
normalizeFeatures(options.features);
|
|
38
|
+
const { features, appearance, ...rest } = options;
|
|
39
|
+
const expanded = { ...rest, ...appearance, ...features };
|
|
40
|
+
validateExplorerOptions(expanded);
|
|
41
|
+
return expanded;
|
|
42
|
+
}
|
|
43
|
+
/** Prepare the entire configuration before any DOM mutation. */
|
|
44
|
+
export function prepareConfiguration(current, patch) {
|
|
45
|
+
assertOptions(patch, 'configuration', ['features', 'layers', 'controls']);
|
|
46
|
+
const features = 'features' in patch
|
|
47
|
+
? normalizeFeatures(patch.features === undefined
|
|
48
|
+
? {}
|
|
49
|
+
: { ...current.features, ...checkedFeatures(patch.features) })
|
|
50
|
+
: current.features;
|
|
51
|
+
const switches = (key, previous, keys) => {
|
|
52
|
+
if (!(key in patch))
|
|
53
|
+
return previous;
|
|
54
|
+
const value = patch[key];
|
|
55
|
+
if (value === undefined)
|
|
56
|
+
return {};
|
|
57
|
+
validateSwitchPatch(value, keys);
|
|
58
|
+
const next = { ...previous, ...value };
|
|
59
|
+
for (const property of Object.keys(next))
|
|
60
|
+
if (next[property] === undefined)
|
|
61
|
+
delete next[property];
|
|
62
|
+
return next;
|
|
63
|
+
};
|
|
64
|
+
return structuredClone({
|
|
65
|
+
features,
|
|
66
|
+
layers: switches('layers', current.layers, layerKeys),
|
|
67
|
+
controls: switches('controls', current.controls, controlKeys),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function checkedFeatures(value) {
|
|
71
|
+
normalizeFeatures(value);
|
|
72
|
+
return value;
|
|
73
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { Geometry, NeighborhoodSource } from '../data/types.js';
|
|
2
|
+
import type { CameraOptions, InteractiveLayers, MapFeatures, MapMarker, MapOverlay, MapPadding, MapViewport, NeighborhoodExplorerOptions, NeighborhoodSelection } from './types.js';
|
|
3
|
+
export type MapAppearance = Pick<NeighborhoodExplorerOptions, 'theme' | 'colors' | 'labelStyle' | 'areaStyle' | 'labelSize' | 'style' | 'markerRadius' | 'markerHitSize' | 'markerColor' | 'selectedMarkerColor'>;
|
|
4
|
+
export type MapControls = NonNullable<NeighborhoodExplorerOptions['controls']>;
|
|
5
|
+
/** Omitted groups/keys retain their values; undefined groups reset all keys in that group. */
|
|
6
|
+
export interface MapConfiguration {
|
|
7
|
+
features?: MapFeatures;
|
|
8
|
+
layers?: InteractiveLayers;
|
|
9
|
+
controls?: MapControls;
|
|
10
|
+
}
|
|
11
|
+
export interface MapOptions extends Omit<NeighborhoodExplorerOptions, keyof MapFeatures | keyof MapAppearance | 'interface' | 'onMarkerActivate' | 'onOverlayActivate'> {
|
|
12
|
+
features?: MapFeatures;
|
|
13
|
+
appearance?: MapAppearance;
|
|
14
|
+
}
|
|
15
|
+
export interface MapConfigurationSnapshot {
|
|
16
|
+
features: MapFeatures;
|
|
17
|
+
/** Explicit overrides; absent values continue to follow the current mode. */
|
|
18
|
+
layers: InteractiveLayers;
|
|
19
|
+
controls: MapControls;
|
|
20
|
+
}
|
|
21
|
+
export interface MapEvents {
|
|
22
|
+
markerchange: {
|
|
23
|
+
id: string | null;
|
|
24
|
+
marker: MapMarker | null;
|
|
25
|
+
};
|
|
26
|
+
neighborhoodchange: NeighborhoodSelection | {
|
|
27
|
+
id: null;
|
|
28
|
+
name: null;
|
|
29
|
+
source: NeighborhoodSource;
|
|
30
|
+
feature: null;
|
|
31
|
+
};
|
|
32
|
+
overlayactivate: {
|
|
33
|
+
overlay: MapOverlay;
|
|
34
|
+
};
|
|
35
|
+
clusteractivate: {
|
|
36
|
+
markers: MapMarker[];
|
|
37
|
+
};
|
|
38
|
+
viewportchange: {
|
|
39
|
+
viewport: MapViewport;
|
|
40
|
+
};
|
|
41
|
+
mapresize: undefined;
|
|
42
|
+
}
|
|
43
|
+
export interface MapCamera {
|
|
44
|
+
get(): MapViewport;
|
|
45
|
+
set(view: MapViewport, options?: CameraOptions): void;
|
|
46
|
+
fit(geometry: Geometry, options?: CameraOptions & {
|
|
47
|
+
padding?: number | MapPadding;
|
|
48
|
+
}): void;
|
|
49
|
+
pan(x: number, y: number, options?: CameraOptions): void;
|
|
50
|
+
zoom(factor: number, options?: CameraOptions): void;
|
|
51
|
+
reset(options?: CameraOptions): void;
|
|
52
|
+
stop(): void;
|
|
53
|
+
}
|
|
54
|
+
/** Owns the map lifecycle separately from its mountable DOM element. */
|
|
55
|
+
export interface MapController {
|
|
56
|
+
readonly element: HTMLElement;
|
|
57
|
+
readonly overlayElement: HTMLDivElement;
|
|
58
|
+
readonly camera: MapCamera;
|
|
59
|
+
readonly destroyed: boolean;
|
|
60
|
+
configure(patch: MapConfiguration): void;
|
|
61
|
+
getConfiguration(): MapConfigurationSnapshot;
|
|
62
|
+
on<K extends keyof MapEvents>(type: K, listener: (detail: MapEvents[K]) => void): () => void;
|
|
63
|
+
setMarkers(markers: readonly MapMarker[]): void;
|
|
64
|
+
setOverlays(overlays: readonly MapOverlay[]): void;
|
|
65
|
+
selectMarker(id: string | null, options?: CameraOptions & {
|
|
66
|
+
fit?: boolean;
|
|
67
|
+
}): boolean;
|
|
68
|
+
getSelectedMarker(): MapMarker | null;
|
|
69
|
+
selectNeighborhood(name: string | null, options?: CameraOptions & {
|
|
70
|
+
fit?: boolean;
|
|
71
|
+
}): boolean;
|
|
72
|
+
getSelectedNeighborhood(): NeighborhoodSelection | null;
|
|
73
|
+
setSource(source: NeighborhoodSource): void;
|
|
74
|
+
setMode(mode: NonNullable<MapOptions['mode']>): void;
|
|
75
|
+
setLabels(visible: boolean): void;
|
|
76
|
+
setTouchNavigation(enabled: boolean): void;
|
|
77
|
+
projectToScreen(lng: number, lat: number): {
|
|
78
|
+
x: number;
|
|
79
|
+
y: number;
|
|
80
|
+
visible: boolean;
|
|
81
|
+
};
|
|
82
|
+
/** Idempotent; stops work and managed subscriptions. Does not remove host-owned DOM. */
|
|
83
|
+
destroy(): void;
|
|
84
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -2,4 +2,4 @@ import type { InteractiveSFMapData } from './explorer-data.js';
|
|
|
2
2
|
import type { NeighborhoodExplorerElement, NeighborhoodExplorerOptions } from './types.js';
|
|
3
3
|
export type { ExplorerMode, NeighborhoodExplorerElement, NeighborhoodExplorerOptions, } from './types.js';
|
|
4
4
|
/** Create an offline, browser-only neighborhood explorer. Call destroy() before disposal. */
|
|
5
|
-
export declare function createNeighborhoodExplorerCore(
|
|
5
|
+
export declare function createNeighborhoodExplorerCore(options: NeighborhoodExplorerOptions | undefined, data: InteractiveSFMapData): NeighborhoodExplorerElement;
|