raintee-maputils 1.0.36 → 1.0.37

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/dist/index.js CHANGED
@@ -7195,325 +7195,78 @@ class CustomOptionsControl {
7195
7195
  }
7196
7196
  }
7197
7197
 
7198
- // 自定义控件类:ToggleControl(带搜索过滤功能)
7198
+ // 自定义控件类:ToggleControl
7199
7199
  class CustomToggleControl {
7200
7200
  /**
7201
7201
  * 构造函数
7202
7202
  * @param {Object} options
7203
- * @param {string} options.name - 控件名称
7204
- * @param {string} options.field - 控制的字段名
7205
- * @param {boolean} options.defaultValue - 默认值
7206
- * @param {string} options.svgIcon - SVG 图标字符串
7207
- * @param {Function} [options.onToggle] - 状态切换回调
7208
- * @param {Array} [options.options] - 可选项目数组 [{id, name, icon?}]
7209
- * @param {Function} [options.onOptionSelect] - 选项选择回调
7210
- * @param {boolean} [options.showSearch] - 是否显示搜索框,默认 true
7203
+ * @param {string} options.name - 控件名称(用于识别,可选展示)
7204
+ * @param {string} options.field - 控制的字段名,对应 map.SourceMap[field]
7205
+ * @param {boolean} options.defaultValue - 默认值(当 field 未定义时使用)
7206
+ * @param {string} options.svgIcon - SVG 图标字符串,例如 '<svg>...</svg>'
7207
+ * @param {Function} [options.onToggle] - 可选的回调函数,状态切换后调用,参数为最新的布尔值
7211
7208
  */
7212
- constructor({
7213
- name,
7214
- field,
7215
- defaultValue = false,
7216
- svgIcon,
7217
- onToggle,
7218
- options = [],
7219
- onOptionSelect,
7220
- showSearch = true
7221
- }) {
7209
+ constructor({ name, field, defaultValue = false, svgIcon, onToggle }) {
7222
7210
  this.name = name;
7223
7211
  this.field = field;
7224
7212
  this.defaultValue = defaultValue;
7225
7213
  this.svgIcon = svgIcon;
7226
- this.onToggle = onToggle;
7227
- this.options = options; // 可选项目
7228
- this.onOptionSelect = onOptionSelect; // 选项选择回调
7229
- this.showSearch = showSearch; // 是否显示搜索框
7214
+ this.onToggle = onToggle; // ✅ 新增:回调函数
7230
7215
 
7231
- // 控件状态
7216
+ // 控件容器
7232
7217
  this._container = null;
7233
7218
  this._button = null;
7234
- this._dropdown = null;
7235
- this._searchInput = null;
7236
- this._optionsList = null;
7237
- this.isActive = false;
7238
- this.isDropdownOpen = false;
7239
- this.filteredOptions = [...options]; // 过滤后的选项
7240
-
7241
- // 绑定事件处理函数
7242
- this._boundHandleClickOutside = this._handleClickOutside.bind(this);
7219
+ this.isActive = false; // 当前是否为激活状态(高亮/true)
7243
7220
  }
7244
7221
 
7245
7222
  // Mapbox 要求的 onAdd 方法
7246
7223
  onAdd(map) {
7247
7224
  this.map = map;
7248
7225
 
7249
- // 创建外层容器
7226
+ // 创建外层容器 div
7250
7227
  this._container = document.createElement('div');
7251
- this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group custom-toggle-control';
7228
+ this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group';
7252
7229
 
7253
- // 创建主按钮
7230
+ // 创建 button 元素
7254
7231
  this._button = document.createElement('button');
7255
7232
  this._button.type = 'button';
7256
7233
  this._button.innerHTML = this.svgIcon;
7257
- this._button.title = this.name;
7258
7234
 
7259
7235
  // 设置按钮样式
7260
- this._setupButtonStyles();
7236
+ this._button.style.cursor = 'pointer';
7237
+ this._button.style.border = 'none';
7238
+ this._button.style.background = 'none';
7239
+ this._button.style.padding = '0';
7240
+ this._button.style.display = 'flex';
7241
+ this._button.style.alignItems = 'center';
7242
+ this._button.style.justifyContent = 'center';
7261
7243
 
7262
7244
  // 初始化状态
7263
7245
  this.updateStatus();
7264
7246
 
7265
- // 绑定事件
7266
- this._button.addEventListener('click', (e) => {
7267
- e.stopPropagation();
7247
+ // 绑定点击事件
7248
+ this._button.addEventListener('click', () => {
7268
7249
  this.toggle();
7269
7250
  });
7270
7251
 
7271
7252
  this._container.appendChild(this._button);
7272
7253
 
7273
- // 创建下拉菜单(如果有选项)
7274
- if (this.options.length > 0) {
7275
- this._createDropdown();
7276
- }
7277
-
7278
7254
  return this._container;
7279
7255
  }
7280
7256
 
7281
- // 设置按钮样式
7282
- _setupButtonStyles() {
7283
- Object.assign(this._button.style, {
7284
- cursor: 'pointer',
7285
- border: 'none',
7286
- background: 'none',
7287
- padding: '8px',
7288
- display: 'flex',
7289
- alignItems: 'center',
7290
- justifyContent: 'center',
7291
- borderRadius: '4px',
7292
- transition: 'all 0.2s ease'
7293
- });
7294
- }
7295
-
7296
- // 创建下拉菜单
7297
- _createDropdown() {
7298
- // 创建下拉容器
7299
- this._dropdown = document.createElement('div');
7300
- this._dropdown.className = 'custom-toggle-dropdown';
7301
- Object.assign(this._dropdown.style, {
7302
- position: 'absolute',
7303
- top: '100%',
7304
- right: '0',
7305
- backgroundColor: 'white',
7306
- border: '1px solid #ccc',
7307
- borderRadius: '4px',
7308
- boxShadow: '0 2px 10px rgba(0,0,0,0.1)',
7309
- zIndex: '1000',
7310
- minWidth: '200px',
7311
- maxWidth: '300px',
7312
- display: 'none',
7313
- marginTop: '4px'
7314
- });
7315
-
7316
- // 创建搜索框(如果需要)
7317
- if (this.showSearch && this.options.length > 5) {
7318
- this._createSearchBox();
7319
- }
7320
-
7321
- // 创建选项列表
7322
- this._createOptionsList();
7323
-
7324
- this._container.appendChild(this._dropdown);
7325
- }
7326
-
7327
- // 创建搜索框
7328
- _createSearchBox() {
7329
- const searchContainer = document.createElement('div');
7330
- Object.assign(searchContainer.style, {
7331
- padding: '8px',
7332
- borderBottom: '1px solid #eee'
7333
- });
7334
-
7335
- this._searchInput = document.createElement('input');
7336
- this._searchInput.type = 'text';
7337
- this._searchInput.placeholder = '搜索...';
7338
- this._searchInput.style.cssText = `
7339
- width: 100%;
7340
- padding: 6px 8px;
7341
- border: 1px solid #ddd;
7342
- border-radius: 4px;
7343
- fontSize: 12px;
7344
- outline: none;
7345
- box-sizing: border-box;
7346
- `;
7347
-
7348
- // 绑定搜索事件
7349
- this._searchInput.addEventListener('input', (e) => {
7350
- this._filterOptions(e.target.value);
7351
- });
7352
-
7353
- // 阻止下拉菜单关闭
7354
- this._searchInput.addEventListener('click', (e) => {
7355
- e.stopPropagation();
7356
- });
7357
-
7358
- searchContainer.appendChild(this._searchInput);
7359
- this._dropdown.appendChild(searchContainer);
7360
- }
7361
-
7362
- // 创建选项列表
7363
- _createOptionsList() {
7364
- this._optionsList = document.createElement('div');
7365
- Object.assign(this._optionsList.style, {
7366
- maxHeight: '200px',
7367
- overflowY: 'auto',
7368
- padding: '4px 0'
7369
- });
7370
-
7371
- this._renderOptionsList();
7372
- this._dropdown.appendChild(this._optionsList);
7373
- }
7374
-
7375
- // 渲染选项列表
7376
- _renderOptionsList() {
7377
- if (!this._optionsList) return;
7378
-
7379
- this._optionsList.innerHTML = '';
7380
-
7381
- this.filteredOptions.forEach(option => {
7382
- const optionItem = document.createElement('div');
7383
- optionItem.className = 'custom-toggle-option';
7384
- optionItem.dataset.id = option.id;
7385
-
7386
- Object.assign(optionItem.style, {
7387
- padding: '8px 12px',
7388
- cursor: 'pointer',
7389
- display: 'flex',
7390
- alignItems: 'center',
7391
- gap: '8px',
7392
- fontSize: '13px',
7393
- transition: 'background-color 0.2s'
7394
- });
7395
-
7396
- // 添加图标(如果有)
7397
- if (option.icon) {
7398
- const icon = document.createElement('span');
7399
- icon.innerHTML = option.icon;
7400
- icon.style.fontSize = '14px';
7401
- optionItem.appendChild(icon);
7402
- }
7403
-
7404
- // 添加文本
7405
- const text = document.createElement('span');
7406
- text.textContent = option.name;
7407
- optionItem.appendChild(text);
7408
-
7409
- // 绑定点击事件
7410
- optionItem.addEventListener('click', (e) => {
7411
- e.stopPropagation();
7412
- this._selectOption(option);
7413
- });
7414
-
7415
- // 鼠标悬停效果
7416
- optionItem.addEventListener('mouseenter', () => {
7417
- optionItem.style.backgroundColor = '#f5f5f5';
7418
- });
7419
-
7420
- optionItem.addEventListener('mouseleave', () => {
7421
- optionItem.style.backgroundColor = 'transparent';
7422
- });
7423
-
7424
- this._optionsList.appendChild(optionItem);
7425
- });
7426
-
7427
- // 如果没有匹配的选项
7428
- if (this.filteredOptions.length === 0) {
7429
- const noResults = document.createElement('div');
7430
- noResults.textContent = '无匹配项';
7431
- Object.assign(noResults.style, {
7432
- padding: '12px',
7433
- textAlign: 'center',
7434
- color: '#999',
7435
- fontSize: '12px'
7436
- });
7437
- this._optionsList.appendChild(noResults);
7438
- }
7439
- }
7440
-
7441
- // 过滤选项
7442
- _filterOptions(searchTerm) {
7443
- const term = searchTerm.toLowerCase().trim();
7444
-
7445
- if (!term) {
7446
- this.filteredOptions = [...this.options];
7447
- } else {
7448
- this.filteredOptions = this.options.filter(option =>
7449
- option.name.toLowerCase().includes(term) ||
7450
- (option.id && option.id.toString().toLowerCase().includes(term))
7451
- );
7452
- }
7453
-
7454
- this._renderOptionsList();
7455
- }
7456
-
7457
- // 选择选项
7458
- _selectOption(option) {
7459
- // 调用选项选择回调
7460
- if (this.onOptionSelect) {
7461
- this.onOptionSelect(option);
7462
- }
7463
-
7464
- // 关闭下拉菜单
7465
- this.closeDropdown();
7466
- }
7467
-
7468
- // 切换下拉菜单显示状态
7469
- toggle() {
7470
- if (this.isDropdownOpen) {
7471
- this.closeDropdown();
7472
- } else {
7473
- this.openDropdown();
7474
- }
7475
- }
7476
-
7477
- // 打开下拉菜单
7478
- openDropdown() {
7479
- if (!this._dropdown || this.options.length === 0) return;
7480
-
7481
- this.isDropdownOpen = true;
7482
- this._dropdown.style.display = 'block';
7483
-
7484
- // 添加全局点击监听
7485
- document.addEventListener('click', this._boundHandleClickOutside);
7486
-
7487
- // 聚焦搜索框
7488
- if (this._searchInput) {
7489
- setTimeout(() => {
7490
- this._searchInput.focus();
7491
- this._searchInput.value = '';
7492
- this._filterOptions('');
7493
- }, 100);
7494
- }
7495
- }
7496
-
7497
- // 关闭下拉菜单
7498
- closeDropdown() {
7499
- if (!this._dropdown) return;
7500
-
7501
- this.isDropdownOpen = false;
7502
- this._dropdown.style.display = 'none';
7503
-
7504
- // 移除全局点击监听
7505
- document.removeEventListener('click', this._boundHandleClickOutside);
7506
- }
7507
-
7508
- // 处理外部点击
7509
- _handleClickOutside(event) {
7510
- if (!this._container.contains(event.target)) {
7511
- this.closeDropdown();
7257
+ // Mapbox 要求的 onRemove 方法
7258
+ onRemove() {
7259
+ if (this._container && this._container.parentNode) {
7260
+ this._container.parentNode.removeChild(this._container);
7512
7261
  }
7262
+ this.map = null;
7263
+ this._container = null;
7264
+ this._button = null;
7513
7265
  }
7514
7266
 
7515
- // 更新控件状态
7267
+ // 更新控件状态(根据当前 field 值)
7516
7268
  updateStatus() {
7269
+ // 从 map.SourceMap 中获取当前 field 的值,如果不存在则使用 defaultValue
7517
7270
  let currentValue = this.defaultValue;
7518
7271
 
7519
7272
  if (
@@ -7524,22 +7277,21 @@ class CustomToggleControl {
7524
7277
  currentValue = this.map.SourceMap[this.field];
7525
7278
  }
7526
7279
 
7527
- this.isActive = currentValue;
7280
+ this.isActive = currentValue; // true 表示激活,false 表示未激活
7528
7281
 
7529
7282
  // 更新按钮样式
7530
7283
  if (this.isActive) {
7531
7284
  this._button.style.opacity = '1';
7532
7285
  this._button.style.filter = 'none';
7533
- this._button.style.backgroundColor = '#e6f3ff';
7534
7286
  } else {
7535
- this._button.style.opacity = '0.7';
7287
+ this._button.style.opacity = '0.4';
7536
7288
  this._button.style.filter = 'grayscale(100%)';
7537
- this._button.style.backgroundColor = 'transparent';
7538
7289
  }
7539
7290
  }
7540
7291
 
7541
- // 切换状态(保持原有功能)
7542
- toggleState() {
7292
+ // 切换状态
7293
+ toggle() {
7294
+ // 获取当前值
7543
7295
  let currentValue = this.defaultValue;
7544
7296
 
7545
7297
  if (
@@ -7550,34 +7302,22 @@ class CustomToggleControl {
7550
7302
  currentValue = this.map.SourceMap[this.field];
7551
7303
  }
7552
7304
 
7305
+ // 切换值
7553
7306
  const newValue = !currentValue;
7554
7307
 
7308
+ // 更新到 map.SourceMap 中
7555
7309
  if (this.map && this.map.SourceMap) {
7556
7310
  this.map.SourceMap[this.field] = newValue;
7557
7311
  }
7558
7312
 
7313
+ // 更新内部状态
7559
7314
  this.isActive = newValue;
7560
- this.updateStatus();
7561
7315
 
7562
- if (this.onToggle) {
7563
- this.onToggle(newValue);
7564
- }
7565
- }
7566
-
7567
- // Mapbox 要求的 onRemove 方法
7568
- onRemove() {
7569
- this.closeDropdown();
7570
-
7571
- if (this._container && this._container.parentNode) {
7572
- this._container.parentNode.removeChild(this._container);
7573
- }
7316
+ // 更新 UI 样式
7317
+ this.updateStatus();
7574
7318
 
7575
- this.map = null;
7576
- this._container = null;
7577
- this._button = null;
7578
- this._dropdown = null;
7579
- this._searchInput = null;
7580
- this._optionsList = null;
7319
+ // 调用回调函数(如果传入了 onToggle),并传入最新的值
7320
+ this.onToggle?.(newValue); // 安全调用,仅当函数存在时才执行
7581
7321
  }
7582
7322
  }
7583
7323