clxx 3.0.2 → 3.0.4
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/AGENTS.md +49 -3
- package/build/Alert/style.js +15 -14
- package/build/CarouselNotice/style.js +2 -1
- package/build/CitySelect/style.js +40 -39
- package/build/Container/index.js +21 -1
- package/build/DatePicker/style.d.ts +1 -1
- package/build/DatePicker/style.js +25 -24
- package/build/Indicator/index.js +2 -1
- package/build/Loading/Wrapper.js +3 -2
- package/build/Loading/style.js +7 -6
- package/build/MapLocationSelection/buildSelectedLocation.d.ts +16 -0
- package/build/MapLocationSelection/buildSelectedLocation.js +123 -0
- package/build/MapLocationSelection/createProvider.d.ts +8 -0
- package/build/MapLocationSelection/createProvider.js +33 -0
- package/build/MapLocationSelection/getLocation.d.ts +8 -0
- package/build/MapLocationSelection/getLocation.js +112 -0
- package/build/MapLocationSelection/index.d.ts +16 -0
- package/build/MapLocationSelection/index.js +985 -0
- package/build/MapLocationSelection/loader.amap.d.ts +48 -0
- package/build/MapLocationSelection/loader.amap.js +125 -0
- package/build/MapLocationSelection/loader.bmap.d.ts +8 -0
- package/build/MapLocationSelection/loader.bmap.js +60 -0
- package/build/MapLocationSelection/provider.amap.d.ts +38 -0
- package/build/MapLocationSelection/provider.amap.js +659 -0
- package/build/MapLocationSelection/provider.bmap.d.ts +36 -0
- package/build/MapLocationSelection/provider.bmap.js +837 -0
- package/build/MapLocationSelection/provider.d.ts +45 -0
- package/build/MapLocationSelection/provider.js +10 -0
- package/build/MapLocationSelection/style.d.ts +4 -0
- package/build/MapLocationSelection/style.js +442 -0
- package/build/MapLocationSelection/types.d.ts +29 -0
- package/build/MapLocationSelection/types.js +22 -0
- package/build/MapLocationSelection/userMarker.d.ts +2 -0
- package/build/MapLocationSelection/userMarker.js +95 -0
- package/build/RegionPicker/style.js +34 -33
- package/build/ScrollView/style.js +5 -4
- package/build/Toast/style.js +6 -5
- package/build/index.d.ts +3 -0
- package/build/index.js +8 -2
- package/build/utils/rem.d.ts +1 -0
- package/build/utils/rem.js +48 -0
- package/package.json +2 -2
- package/test/src/index/index.jsx +5 -0
- package/test/src/index.jsx +1 -0
- package/test/src/map-location-selection/index.jsx +192 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 高德地图 SDK 动态加载器
|
|
3
|
+
*
|
|
4
|
+
* 设计目标:
|
|
5
|
+
* - clxx 库被静态 import 时绝不携带高德地图 SDK;
|
|
6
|
+
* - 只有用户真正使用 MapLocationSelection 时才通过运行时 import 触发拉取;
|
|
7
|
+
* - 同一密钥在同一个页面只加载一次,多次调用复用同一个 Promise。
|
|
8
|
+
*
|
|
9
|
+
* 实现方式:
|
|
10
|
+
* 通过动态 `import` 一个由 Blob URL 包装的远程脚本(loader.js),
|
|
11
|
+
* 等价于在页面里插入 `<script src="https://webapi.amap.com/loader.js"></script>`。
|
|
12
|
+
* 这样既满足“动态 import”的语义(不会进入 clxx 的静态依赖图),
|
|
13
|
+
* 又避免了对 `@amap/amap-jsapi-loader` npm 包的硬依赖。
|
|
14
|
+
*/
|
|
15
|
+
interface AMapNamespace {
|
|
16
|
+
Map: any;
|
|
17
|
+
Geocoder: any;
|
|
18
|
+
AutoComplete: any;
|
|
19
|
+
PlaceSearch: any;
|
|
20
|
+
Geolocation: any;
|
|
21
|
+
LngLat: any;
|
|
22
|
+
Pixel: any;
|
|
23
|
+
[key: string]: any;
|
|
24
|
+
}
|
|
25
|
+
interface AMapLoaderLike {
|
|
26
|
+
load(opts: {
|
|
27
|
+
key: string;
|
|
28
|
+
version?: string;
|
|
29
|
+
plugins?: string[];
|
|
30
|
+
}): Promise<AMapNamespace>;
|
|
31
|
+
}
|
|
32
|
+
declare global {
|
|
33
|
+
interface Window {
|
|
34
|
+
AMapLoader?: AMapLoaderLike;
|
|
35
|
+
_AMapSecurityConfig?: {
|
|
36
|
+
securityJsCode?: string;
|
|
37
|
+
serviceHost?: string;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export interface LoadAMapOptions {
|
|
42
|
+
key: string;
|
|
43
|
+
securityJsCode?: string;
|
|
44
|
+
version?: string;
|
|
45
|
+
plugins?: string[];
|
|
46
|
+
}
|
|
47
|
+
export declare function loadAMap(opts: LoadAMapOptions): Promise<AMapNamespace>;
|
|
48
|
+
export type { AMapNamespace };
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 高德地图 SDK 动态加载器
|
|
4
|
+
*
|
|
5
|
+
* 设计目标:
|
|
6
|
+
* - clxx 库被静态 import 时绝不携带高德地图 SDK;
|
|
7
|
+
* - 只有用户真正使用 MapLocationSelection 时才通过运行时 import 触发拉取;
|
|
8
|
+
* - 同一密钥在同一个页面只加载一次,多次调用复用同一个 Promise。
|
|
9
|
+
*
|
|
10
|
+
* 实现方式:
|
|
11
|
+
* 通过动态 `import` 一个由 Blob URL 包装的远程脚本(loader.js),
|
|
12
|
+
* 等价于在页面里插入 `<script src="https://webapi.amap.com/loader.js"></script>`。
|
|
13
|
+
* 这样既满足“动态 import”的语义(不会进入 clxx 的静态依赖图),
|
|
14
|
+
* 又避免了对 `@amap/amap-jsapi-loader` npm 包的硬依赖。
|
|
15
|
+
*/
|
|
16
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
17
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
18
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
19
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
20
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
21
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
22
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.loadAMap = loadAMap;
|
|
27
|
+
const LOADER_URL = "https://webapi.amap.com/loader.js";
|
|
28
|
+
let scriptPromise = null;
|
|
29
|
+
/**
|
|
30
|
+
* Chrome 对「2D Canvas 上反复 getImageData」会告警,建议在 getContext('2d') 时传入
|
|
31
|
+
* `{ willReadFrequently: true }`。高德 JSAPI 2.x 内部地图/定位插件未带该属性,控制台会刷
|
|
32
|
+
* “Canvas2D: Multiple readback operations...”——功能无碍,但干扰调试。
|
|
33
|
+
*
|
|
34
|
+
* 在首次拉取高德脚本**之前**打一次原型补丁,合并 willReadFrequently;全页只对 2d 上下文生效,
|
|
35
|
+
* 与 HTML 标准对该 hint 的语义一致(读回频繁时更应设为 true)。
|
|
36
|
+
*/
|
|
37
|
+
let didPatchCanvasGetContext = false;
|
|
38
|
+
function patchCanvasGetContextForAMapHint() {
|
|
39
|
+
if (didPatchCanvasGetContext)
|
|
40
|
+
return;
|
|
41
|
+
if (typeof HTMLCanvasElement === "undefined")
|
|
42
|
+
return;
|
|
43
|
+
didPatchCanvasGetContext = true;
|
|
44
|
+
const proto = HTMLCanvasElement.prototype;
|
|
45
|
+
const orig = proto.getContext;
|
|
46
|
+
function patchedGetContext(type, contextAttributes) {
|
|
47
|
+
if (type === "2d") {
|
|
48
|
+
const base = contextAttributes && typeof contextAttributes === "object"
|
|
49
|
+
? Object.assign({}, contextAttributes) : {};
|
|
50
|
+
base.willReadFrequently = true;
|
|
51
|
+
return orig.call(this, "2d", base);
|
|
52
|
+
}
|
|
53
|
+
return orig.call(this, type, contextAttributes);
|
|
54
|
+
}
|
|
55
|
+
// 包装后无法同时满足 lib.dom 对 getContext 的全部重载签名,运行期委托给原生实现即可。
|
|
56
|
+
proto.getContext = patchedGetContext;
|
|
57
|
+
}
|
|
58
|
+
function ensureLoaderScript() {
|
|
59
|
+
if (typeof window === "undefined") {
|
|
60
|
+
return Promise.reject(new Error("AMap loader requires a browser env"));
|
|
61
|
+
}
|
|
62
|
+
if (window.AMapLoader)
|
|
63
|
+
return Promise.resolve(window.AMapLoader);
|
|
64
|
+
if (scriptPromise)
|
|
65
|
+
return scriptPromise;
|
|
66
|
+
scriptPromise = new Promise((resolve, reject) => {
|
|
67
|
+
// 复用已存在的 script 标签(同一文档内多处使用时)
|
|
68
|
+
const existed = document.querySelector(`script[src="${LOADER_URL}"]`);
|
|
69
|
+
const onReady = () => {
|
|
70
|
+
if (window.AMapLoader)
|
|
71
|
+
resolve(window.AMapLoader);
|
|
72
|
+
else
|
|
73
|
+
reject(new Error("AMapLoader not found after loader.js loaded"));
|
|
74
|
+
};
|
|
75
|
+
if (existed) {
|
|
76
|
+
if (window.AMapLoader) {
|
|
77
|
+
resolve(window.AMapLoader);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
existed.addEventListener("load", onReady, { once: true });
|
|
81
|
+
existed.addEventListener("error", () => reject(new Error("Failed to load AMap loader.js")), { once: true });
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const script = document.createElement("script");
|
|
85
|
+
script.src = LOADER_URL;
|
|
86
|
+
script.async = true;
|
|
87
|
+
script.onload = onReady;
|
|
88
|
+
script.onerror = () => {
|
|
89
|
+
scriptPromise = null;
|
|
90
|
+
reject(new Error("Failed to load AMap loader.js"));
|
|
91
|
+
};
|
|
92
|
+
document.head.appendChild(script);
|
|
93
|
+
});
|
|
94
|
+
return scriptPromise;
|
|
95
|
+
}
|
|
96
|
+
const namespacePromiseMap = new Map();
|
|
97
|
+
function loadAMap(opts) {
|
|
98
|
+
const { key, securityJsCode, version = "2.0", plugins = [
|
|
99
|
+
"AMap.Geocoder",
|
|
100
|
+
"AMap.AutoComplete",
|
|
101
|
+
"AMap.PlaceSearch",
|
|
102
|
+
"AMap.Geolocation",
|
|
103
|
+
], } = opts;
|
|
104
|
+
// 不同的 key 视为不同实例缓存(同一 key 下复用)
|
|
105
|
+
const cacheKey = `${key}::${version}::${plugins.join(",")}`;
|
|
106
|
+
const cached = namespacePromiseMap.get(cacheKey);
|
|
107
|
+
if (cached)
|
|
108
|
+
return cached;
|
|
109
|
+
const promise = (() => __awaiter(this, void 0, void 0, function* () {
|
|
110
|
+
var _a;
|
|
111
|
+
patchCanvasGetContextForAMapHint();
|
|
112
|
+
if (securityJsCode) {
|
|
113
|
+
// 必须在 loader.load 之前注入
|
|
114
|
+
window._AMapSecurityConfig = Object.assign(Object.assign({}, ((_a = window._AMapSecurityConfig) !== null && _a !== void 0 ? _a : {})), { securityJsCode });
|
|
115
|
+
}
|
|
116
|
+
const loader = yield ensureLoaderScript();
|
|
117
|
+
return loader.load({ key, version, plugins });
|
|
118
|
+
}))().catch((err) => {
|
|
119
|
+
// 失败后允许下次重试
|
|
120
|
+
namespacePromiseMap.delete(cacheKey);
|
|
121
|
+
throw err;
|
|
122
|
+
});
|
|
123
|
+
namespacePromiseMap.set(cacheKey, promise);
|
|
124
|
+
return promise;
|
|
125
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// 百度地图 BMapGL SDK 动态加载器。
|
|
3
|
+
//
|
|
4
|
+
// 设计目标:
|
|
5
|
+
// - clxx 库被静态 import 时绝不携带百度地图 SDK;
|
|
6
|
+
// - 只有用户真正使用 MapLocationSelection 且选择 provider="bmap" 时才注入 <script>;
|
|
7
|
+
// - 同一 ak 在同一个页面只加载一次,多次调用复用同一个 Promise;
|
|
8
|
+
// - SDK 加载完成的判定靠 `callback` 查询参数(百度官方支持),脚本执行完会调用我们
|
|
9
|
+
// 注入的全局函数,避免使用 onload 但 BMapGL 还未挂载的竞态。
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.loadBMap = loadBMap;
|
|
12
|
+
const SCRIPT_URL_BASE = "https://api.map.baidu.com/api?v=1.0&type=webgl&ak=";
|
|
13
|
+
const cachedPromiseMap = new Map();
|
|
14
|
+
function loadBMap(opts) {
|
|
15
|
+
const { ak } = opts;
|
|
16
|
+
if (!ak) {
|
|
17
|
+
return Promise.reject(new Error("BMap ak is required"));
|
|
18
|
+
}
|
|
19
|
+
if (typeof window === "undefined") {
|
|
20
|
+
return Promise.reject(new Error("BMap loader requires a browser env"));
|
|
21
|
+
}
|
|
22
|
+
// 已有完整加载的 BMapGL,直接返回
|
|
23
|
+
if (window.BMapGL) {
|
|
24
|
+
const ready = Promise.resolve(window.BMapGL);
|
|
25
|
+
cachedPromiseMap.set(ak, ready);
|
|
26
|
+
return ready;
|
|
27
|
+
}
|
|
28
|
+
const cached = cachedPromiseMap.get(ak);
|
|
29
|
+
if (cached)
|
|
30
|
+
return cached;
|
|
31
|
+
const cbName = `__clxxBMapInit_${Date.now()}_${Math.random()
|
|
32
|
+
.toString(36)
|
|
33
|
+
.slice(2)}`;
|
|
34
|
+
const promise = new Promise((resolve, reject) => {
|
|
35
|
+
window[cbName] = () => {
|
|
36
|
+
delete window[cbName];
|
|
37
|
+
if (window.BMapGL) {
|
|
38
|
+
resolve(window.BMapGL);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
// 极端情况:脚本回调被触发但 BMapGL 仍未挂载(一般是 ak 错误的兜底)
|
|
42
|
+
reject(new Error("BMapGL not available after script callback"));
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const script = document.createElement("script");
|
|
46
|
+
script.src = `${SCRIPT_URL_BASE}${encodeURIComponent(ak)}&callback=${cbName}`;
|
|
47
|
+
script.async = true;
|
|
48
|
+
script.onerror = () => {
|
|
49
|
+
delete window[cbName];
|
|
50
|
+
cachedPromiseMap.delete(ak);
|
|
51
|
+
reject(new Error("Failed to load BMapGL SDK"));
|
|
52
|
+
};
|
|
53
|
+
document.head.appendChild(script);
|
|
54
|
+
}).catch((err) => {
|
|
55
|
+
cachedPromiseMap.delete(ak);
|
|
56
|
+
throw err;
|
|
57
|
+
});
|
|
58
|
+
cachedPromiseMap.set(ak, promise);
|
|
59
|
+
return promise;
|
|
60
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Coord, type POIItem } from "./types";
|
|
2
|
+
import { type GeolocateOptions, type MapProvider, type MapProviderInitOptions, type SearchAroundResult, type SearchOptions, type ReverseGeocodeResult } from "./provider";
|
|
3
|
+
export interface AMapProviderOptions {
|
|
4
|
+
amapKey: string;
|
|
5
|
+
securityJsCode?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class AMapProvider implements MapProvider {
|
|
8
|
+
private opts;
|
|
9
|
+
private AMap;
|
|
10
|
+
private map;
|
|
11
|
+
private placeSearch;
|
|
12
|
+
private keywordPlaceSearchNear;
|
|
13
|
+
private keywordPlaceSearchFull;
|
|
14
|
+
private geocoder;
|
|
15
|
+
private geolocation;
|
|
16
|
+
private userMarker;
|
|
17
|
+
private pendingGeolocate;
|
|
18
|
+
private aroundSeq;
|
|
19
|
+
private keywordSeq;
|
|
20
|
+
private flying;
|
|
21
|
+
private flyToTimers;
|
|
22
|
+
constructor(opts: AMapProviderOptions);
|
|
23
|
+
private initServices;
|
|
24
|
+
init(o: MapProviderInitOptions): Promise<void>;
|
|
25
|
+
initHeadless(opts?: Pick<MapProviderInitOptions, "initialCity">): Promise<void>;
|
|
26
|
+
destroy(): void;
|
|
27
|
+
getCenter(): Coord;
|
|
28
|
+
setCenter(center: Coord, zoom?: number): void;
|
|
29
|
+
private flyTo;
|
|
30
|
+
upsertUserMarker(center: Coord): void;
|
|
31
|
+
searchAround(center: Coord, options: SearchOptions): Promise<SearchAroundResult>;
|
|
32
|
+
searchByKeyword(center: Coord, keyword: string, options: SearchOptions): Promise<POIItem[]>;
|
|
33
|
+
geolocate(options?: GeolocateOptions): Promise<Coord | null>;
|
|
34
|
+
reverseGeocode(center: Coord): Promise<ReverseGeocodeResult | null>;
|
|
35
|
+
on(event: "movestart", handler: () => void): void;
|
|
36
|
+
on(event: "moveend", handler: () => void): void;
|
|
37
|
+
on(event: "click", handler: (lng: number, lat: number) => void): void;
|
|
38
|
+
}
|