raintee-maputils 1.0.35 → 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 +522 -366
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6561,13 +6561,14 @@ class RulerControl {
|
|
|
6561
6561
|
|
|
6562
6562
|
class CustomOptionsControl {
|
|
6563
6563
|
constructor(args) {
|
|
6564
|
-
const { title, options, onConfirm } = args;
|
|
6564
|
+
const { title, options, onConfirm, icon } = args;
|
|
6565
6565
|
|
|
6566
6566
|
this._map = null;
|
|
6567
6567
|
this._container = null;
|
|
6568
6568
|
|
|
6569
|
+
this._title = title || '';
|
|
6569
6570
|
this._options = options || [];
|
|
6570
|
-
this.
|
|
6571
|
+
this._icon = icon || null;
|
|
6571
6572
|
this._onConfirm = onConfirm || (() => { });
|
|
6572
6573
|
this._originalOptions = [...this._options];
|
|
6573
6574
|
this._selectedOptions = [];
|
|
@@ -6580,119 +6581,450 @@ class CustomOptionsControl {
|
|
|
6580
6581
|
this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group custom-options-control';
|
|
6581
6582
|
|
|
6582
6583
|
const mainButton = document.createElement('button');
|
|
6583
|
-
mainButton.textContent = this._title;
|
|
6584
6584
|
mainButton.style.cssText = `
|
|
6585
|
-
padding:
|
|
6585
|
+
padding: 0;
|
|
6586
6586
|
background: white;
|
|
6587
|
-
border:
|
|
6587
|
+
border: 0.0625rem solid #ccc;
|
|
6588
6588
|
cursor: pointer;
|
|
6589
|
+
display: flex;
|
|
6590
|
+
align-items: center;
|
|
6591
|
+
justify-content: center;
|
|
6592
|
+
gap: 0.375rem;
|
|
6589
6593
|
`;
|
|
6590
6594
|
|
|
6595
|
+
if (this._icon) {
|
|
6596
|
+
const iconWrapper = document.createElement('span');
|
|
6597
|
+
iconWrapper.style.cssText = `
|
|
6598
|
+
width: 1rem;
|
|
6599
|
+
height: 1rem;
|
|
6600
|
+
display: inline-flex;
|
|
6601
|
+
align-items: center;
|
|
6602
|
+
justify-content: center;
|
|
6603
|
+
`;
|
|
6604
|
+
|
|
6605
|
+
if (this._icon.trim().startsWith('<svg')) {
|
|
6606
|
+
iconWrapper.innerHTML = this._icon;
|
|
6607
|
+
} else {
|
|
6608
|
+
const img = document.createElement('img');
|
|
6609
|
+
img.src = this._icon;
|
|
6610
|
+
img.style.cssText = `width: 1rem; height: 1rem; object-fit: contain;`;
|
|
6611
|
+
iconWrapper.appendChild(img);
|
|
6612
|
+
}
|
|
6613
|
+
|
|
6614
|
+
mainButton.appendChild(iconWrapper);
|
|
6615
|
+
}
|
|
6616
|
+
|
|
6591
6617
|
mainButton.addEventListener('click', () => {
|
|
6592
6618
|
this._showModal();
|
|
6593
6619
|
});
|
|
6594
6620
|
|
|
6595
6621
|
this._container.appendChild(mainButton);
|
|
6622
|
+
|
|
6623
|
+
// 添加全局样式
|
|
6624
|
+
this._addGlobalStyles();
|
|
6625
|
+
|
|
6596
6626
|
return this._container;
|
|
6597
6627
|
}
|
|
6598
6628
|
|
|
6599
|
-
|
|
6629
|
+
_addGlobalStyles() {
|
|
6630
|
+
if (document.querySelector('#custom-options-styles')) return;
|
|
6631
|
+
|
|
6632
|
+
const styles = document.createElement('style');
|
|
6633
|
+
styles.id = 'custom-options-styles';
|
|
6634
|
+
styles.textContent = `
|
|
6635
|
+
@keyframes modalSlideIn {
|
|
6636
|
+
from {
|
|
6637
|
+
opacity: 0;
|
|
6638
|
+
transform: scale(0.95) translateY(-20px);
|
|
6639
|
+
}
|
|
6640
|
+
to {
|
|
6641
|
+
opacity: 1;
|
|
6642
|
+
transform: scale(1) translateY(0);
|
|
6643
|
+
}
|
|
6644
|
+
}
|
|
6645
|
+
|
|
6646
|
+
@keyframes modalBackdropFadeIn {
|
|
6647
|
+
from { opacity: 0; }
|
|
6648
|
+
to { opacity: 1; }
|
|
6649
|
+
}
|
|
6650
|
+
|
|
6651
|
+
@keyframes fadeInUp {
|
|
6652
|
+
from {
|
|
6653
|
+
opacity: 0;
|
|
6654
|
+
transform: translateY(20px);
|
|
6655
|
+
}
|
|
6656
|
+
to {
|
|
6657
|
+
opacity: 1;
|
|
6658
|
+
transform: translateY(0);
|
|
6659
|
+
}
|
|
6660
|
+
}
|
|
6661
|
+
|
|
6662
|
+
.custom-modal-overlay {
|
|
6663
|
+
animation: modalBackdropFadeIn 0.2s ease-out;
|
|
6664
|
+
}
|
|
6665
|
+
|
|
6666
|
+
.custom-modal {
|
|
6667
|
+
animation: modalSlideIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
6668
|
+
}
|
|
6669
|
+
|
|
6670
|
+
.custom-search-input:focus {
|
|
6671
|
+
border-color: #667eea !important;
|
|
6672
|
+
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
|
|
6673
|
+
}
|
|
6674
|
+
|
|
6675
|
+
.custom-checkbox {
|
|
6676
|
+
position: relative;
|
|
6677
|
+
appearance: none;
|
|
6678
|
+
width: 1rem;
|
|
6679
|
+
height: 1rem;
|
|
6680
|
+
border: 2px solid #d1d5db;
|
|
6681
|
+
border-radius: 0.25rem;
|
|
6682
|
+
background: white;
|
|
6683
|
+
cursor: pointer;
|
|
6684
|
+
transition: all 0.2s ease;
|
|
6685
|
+
margin-right: 0.75rem;
|
|
6686
|
+
}
|
|
6687
|
+
|
|
6688
|
+
.custom-checkbox:checked {
|
|
6689
|
+
background: linear-gradient(135deg, #667eea, #764ba2);
|
|
6690
|
+
border-color: #667eea;
|
|
6691
|
+
}
|
|
6692
|
+
|
|
6693
|
+
.custom-checkbox:checked::after {
|
|
6694
|
+
content: '✓';
|
|
6695
|
+
position: absolute;
|
|
6696
|
+
top: 50%;
|
|
6697
|
+
left: 50%;
|
|
6698
|
+
transform: translate(-50%, -50%);
|
|
6699
|
+
color: white;
|
|
6700
|
+
font-size: 0.75rem;
|
|
6701
|
+
font-weight: bold;
|
|
6702
|
+
}
|
|
6703
|
+
|
|
6704
|
+
.custom-checkbox:hover {
|
|
6705
|
+
border-color: #667eea;
|
|
6706
|
+
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
|
|
6707
|
+
}
|
|
6708
|
+
|
|
6709
|
+
.custom-list-item {
|
|
6710
|
+
transition: all 0.2s ease;
|
|
6711
|
+
}
|
|
6712
|
+
|
|
6713
|
+
.custom-list-item:hover {
|
|
6714
|
+
background-color: #f8fafc !important;
|
|
6715
|
+
border-color: #e2e8f0 !important;
|
|
6716
|
+
transform: translateX(4px) !important;
|
|
6717
|
+
}
|
|
6718
|
+
|
|
6719
|
+
.custom-modal::-webkit-scrollbar {
|
|
6720
|
+
width: 6px;
|
|
6721
|
+
}
|
|
6722
|
+
|
|
6723
|
+
.custom-modal::-webkit-scrollbar-track {
|
|
6724
|
+
background: #f1f5f9;
|
|
6725
|
+
border-radius: 3px;
|
|
6726
|
+
}
|
|
6727
|
+
|
|
6728
|
+
.custom-modal::-webkit-scrollbar-thumb {
|
|
6729
|
+
background: linear-gradient(135deg, #667eea, #764ba2);
|
|
6730
|
+
border-radius: 3px;
|
|
6731
|
+
}
|
|
6732
|
+
|
|
6733
|
+
.custom-modal::-webkit-scrollbar-thumb:hover {
|
|
6734
|
+
background: linear-gradient(135deg, #5a67d8, #6b46c1);
|
|
6735
|
+
}
|
|
6736
|
+
`;
|
|
6737
|
+
document.head.appendChild(styles);
|
|
6738
|
+
}
|
|
6739
|
+
|
|
6600
6740
|
_showModal() {
|
|
6601
|
-
// 创建遮罩层
|
|
6602
6741
|
this._overlay = document.createElement('div');
|
|
6603
6742
|
this._overlay.className = 'custom-modal-overlay';
|
|
6604
6743
|
this._overlay.style.cssText = `
|
|
6605
6744
|
position: fixed;
|
|
6606
6745
|
top: 0; left: 0; right: 0; bottom: 0;
|
|
6607
|
-
background: rgba(0,0,0,0.5);
|
|
6608
|
-
|
|
6746
|
+
background: rgba(0, 0, 0, 0.5);
|
|
6747
|
+
backdrop-filter: blur(4px);
|
|
6748
|
+
-webkit-backdrop-filter: blur(4px);
|
|
6749
|
+
z-index: 10000;
|
|
6609
6750
|
display: flex;
|
|
6610
6751
|
justify-content: center;
|
|
6611
6752
|
align-items: center;
|
|
6753
|
+
padding: 1rem;
|
|
6754
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
6612
6755
|
`;
|
|
6613
6756
|
|
|
6614
|
-
// 弹窗容器
|
|
6615
6757
|
this._modal = document.createElement('div');
|
|
6616
6758
|
this._modal.className = 'custom-modal';
|
|
6617
6759
|
this._modal.style.cssText = `
|
|
6618
|
-
width:
|
|
6760
|
+
width: 100%;
|
|
6761
|
+
max-width: 26rem;
|
|
6619
6762
|
max-height: 80vh;
|
|
6763
|
+
background: linear-gradient(145deg, #ffffff 0%, #f8fafc 100%);
|
|
6764
|
+
border-radius: 0.75rem;
|
|
6765
|
+
box-shadow:
|
|
6766
|
+
0 20px 25px -5px rgba(0, 0, 0, 0.1),
|
|
6767
|
+
0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
|
6768
|
+
border: 1px solid rgba(255, 255, 255, 0.8);
|
|
6620
6769
|
overflow: hidden;
|
|
6621
|
-
background: white;
|
|
6622
|
-
border-radius: 8px;
|
|
6623
|
-
padding: 20px;
|
|
6624
6770
|
display: flex;
|
|
6625
6771
|
flex-direction: column;
|
|
6626
6772
|
`;
|
|
6627
6773
|
|
|
6628
|
-
//
|
|
6774
|
+
// 创建头部
|
|
6775
|
+
const header = this._createHeader();
|
|
6776
|
+
this._modal.appendChild(header);
|
|
6777
|
+
|
|
6778
|
+
// 创建搜索区域
|
|
6779
|
+
const searchSection = this._createSearchSection();
|
|
6780
|
+
this._modal.appendChild(searchSection);
|
|
6781
|
+
|
|
6782
|
+
// 创建选项列表
|
|
6783
|
+
this._listBox = document.createElement('div');
|
|
6784
|
+
this._listBox.style.cssText = `
|
|
6785
|
+
flex: 1;
|
|
6786
|
+
overflow-y: auto;
|
|
6787
|
+
padding: 0 1.25rem 1.25rem 1.25rem;
|
|
6788
|
+
min-height: 10rem;
|
|
6789
|
+
`;
|
|
6790
|
+
this._modal.appendChild(this._listBox);
|
|
6791
|
+
|
|
6792
|
+
// 创建底部按钮
|
|
6793
|
+
const footer = this._createFooter();
|
|
6794
|
+
this._modal.appendChild(footer);
|
|
6795
|
+
|
|
6796
|
+
this._overlay.appendChild(this._modal);
|
|
6797
|
+
document.body.appendChild(this._overlay);
|
|
6798
|
+
|
|
6799
|
+
// 聚焦搜索框
|
|
6800
|
+
// setTimeout(() => {
|
|
6801
|
+
// const searchInput = this._modal.querySelector('.custom-search-input');
|
|
6802
|
+
// if (searchInput) {
|
|
6803
|
+
// searchInput.focus();
|
|
6804
|
+
// }
|
|
6805
|
+
// }, 100);
|
|
6806
|
+
|
|
6807
|
+
// 点击遮罩关闭
|
|
6808
|
+
this._overlay.addEventListener('click', (e) => {
|
|
6809
|
+
if (e.target === this._overlay) {
|
|
6810
|
+
this._closeModal();
|
|
6811
|
+
}
|
|
6812
|
+
});
|
|
6813
|
+
|
|
6814
|
+
// ESC 键关闭
|
|
6815
|
+
this._handleKeydown = (e) => {
|
|
6816
|
+
if (e.key === 'Escape') {
|
|
6817
|
+
this._closeModal();
|
|
6818
|
+
}
|
|
6819
|
+
};
|
|
6820
|
+
document.addEventListener('keydown', this._handleKeydown);
|
|
6821
|
+
|
|
6822
|
+
this._renderList('');
|
|
6823
|
+
}
|
|
6824
|
+
|
|
6825
|
+
_createHeader() {
|
|
6826
|
+
const header = document.createElement('div');
|
|
6827
|
+
header.style.cssText = `
|
|
6828
|
+
padding: 1.25rem 1.25rem 1rem 1.25rem;
|
|
6829
|
+
border-bottom: 1px solid #e2e8f0;
|
|
6830
|
+
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
|
|
6831
|
+
`;
|
|
6832
|
+
|
|
6833
|
+
const title = document.createElement('h2');
|
|
6834
|
+
title.textContent = this._title;
|
|
6835
|
+
title.style.cssText = `
|
|
6836
|
+
margin: 0 0 0.5rem 0;
|
|
6837
|
+
font-size: 1.125rem;
|
|
6838
|
+
font-weight: 600;
|
|
6839
|
+
color: #1e293b;
|
|
6840
|
+
display: flex;
|
|
6841
|
+
align-items: center;
|
|
6842
|
+
gap: 0.5rem;
|
|
6843
|
+
`;
|
|
6844
|
+
|
|
6845
|
+
// 添加图标
|
|
6846
|
+
const icon = document.createElement('span');
|
|
6847
|
+
icon.innerHTML = '📋';
|
|
6848
|
+
icon.style.fontSize = '1.25rem';
|
|
6849
|
+
title.insertBefore(icon, title.firstChild);
|
|
6850
|
+
|
|
6851
|
+
const subtitle = document.createElement('p');
|
|
6852
|
+
subtitle.textContent = `共 ${this._originalOptions.length} 个选项,已选择 ${this._selectedOptions.length} 个`;
|
|
6853
|
+
subtitle.style.cssText = `
|
|
6854
|
+
margin: 0;
|
|
6855
|
+
font-size: 0.8125rem;
|
|
6856
|
+
color: #64748b;
|
|
6857
|
+
`;
|
|
6858
|
+
|
|
6859
|
+
const closeBtn = document.createElement('button');
|
|
6860
|
+
closeBtn.innerHTML = '✕';
|
|
6861
|
+
closeBtn.style.cssText = `
|
|
6862
|
+
position: absolute;
|
|
6863
|
+
top: 1rem;
|
|
6864
|
+
right: 1rem;
|
|
6865
|
+
width: 1.75rem;
|
|
6866
|
+
height: 1.75rem;
|
|
6867
|
+
border: none;
|
|
6868
|
+
background: #f1f5f9;
|
|
6869
|
+
color: #64748b;
|
|
6870
|
+
border-radius: 50%;
|
|
6871
|
+
cursor: pointer;
|
|
6872
|
+
display: flex;
|
|
6873
|
+
align-items: center;
|
|
6874
|
+
justify-content: center;
|
|
6875
|
+
font-size: 0.875rem;
|
|
6876
|
+
transition: all 0.2s ease;
|
|
6877
|
+
font-weight: 500;
|
|
6878
|
+
`;
|
|
6879
|
+
closeBtn.addEventListener('mouseenter', () => {
|
|
6880
|
+
closeBtn.style.background = '#ef4444';
|
|
6881
|
+
closeBtn.style.color = 'white';
|
|
6882
|
+
closeBtn.style.transform = 'rotate(90deg)';
|
|
6883
|
+
});
|
|
6884
|
+
closeBtn.addEventListener('mouseleave', () => {
|
|
6885
|
+
closeBtn.style.background = '#f1f5f9';
|
|
6886
|
+
closeBtn.style.color = '#64748b';
|
|
6887
|
+
closeBtn.style.transform = 'rotate(0deg)';
|
|
6888
|
+
});
|
|
6889
|
+
closeBtn.addEventListener('click', () => this._closeModal());
|
|
6890
|
+
|
|
6891
|
+
header.style.position = 'relative';
|
|
6892
|
+
header.appendChild(title);
|
|
6893
|
+
header.appendChild(subtitle);
|
|
6894
|
+
header.appendChild(closeBtn);
|
|
6895
|
+
|
|
6896
|
+
return header;
|
|
6897
|
+
}
|
|
6898
|
+
|
|
6899
|
+
_createSearchSection() {
|
|
6900
|
+
const section = document.createElement('div');
|
|
6901
|
+
section.style.cssText = `
|
|
6902
|
+
padding: 1.25rem 1.25rem 1rem 1.25rem;
|
|
6903
|
+
`;
|
|
6904
|
+
|
|
6905
|
+
const searchContainer = document.createElement('div');
|
|
6906
|
+
searchContainer.style.cssText = `
|
|
6907
|
+
position: relative;
|
|
6908
|
+
`;
|
|
6909
|
+
|
|
6910
|
+
const searchIcon = document.createElement('div');
|
|
6911
|
+
searchIcon.innerHTML = '🔍';
|
|
6912
|
+
searchIcon.style.cssText = `
|
|
6913
|
+
position: absolute;
|
|
6914
|
+
left: 0.875rem;
|
|
6915
|
+
top: 50%;
|
|
6916
|
+
transform: translateY(-50%);
|
|
6917
|
+
font-size: 0.875rem;
|
|
6918
|
+
color: #94a3b8;
|
|
6919
|
+
pointer-events: none;
|
|
6920
|
+
`;
|
|
6921
|
+
|
|
6629
6922
|
const searchInput = document.createElement('input');
|
|
6630
6923
|
searchInput.placeholder = '搜索选项...';
|
|
6631
6924
|
searchInput.className = 'custom-search-input';
|
|
6632
6925
|
searchInput.style.cssText = `
|
|
6633
6926
|
width: 100%;
|
|
6634
|
-
padding:
|
|
6635
|
-
border:
|
|
6636
|
-
border-radius:
|
|
6637
|
-
|
|
6927
|
+
padding: 0.75rem 1rem 0.75rem 2.5rem;
|
|
6928
|
+
border: 2px solid #e2e8f0;
|
|
6929
|
+
border-radius: 0.5rem;
|
|
6930
|
+
font-size: 0.875rem;
|
|
6931
|
+
background: white;
|
|
6932
|
+
transition: all 0.3s ease;
|
|
6933
|
+
box-sizing: border-box;
|
|
6934
|
+
font-family: inherit;
|
|
6935
|
+
outline: none;
|
|
6638
6936
|
`;
|
|
6937
|
+
|
|
6938
|
+
searchInput.addEventListener('focus', () => {
|
|
6939
|
+
searchInput.style.borderColor = '#667eea';
|
|
6940
|
+
searchInput.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
|
|
6941
|
+
});
|
|
6942
|
+
|
|
6943
|
+
searchInput.addEventListener('blur', () => {
|
|
6944
|
+
searchInput.style.borderColor = '#e2e8f0';
|
|
6945
|
+
searchInput.style.boxShadow = 'none';
|
|
6946
|
+
});
|
|
6947
|
+
|
|
6639
6948
|
searchInput.addEventListener('input', (e) => {
|
|
6640
6949
|
this._renderList(e.target.value);
|
|
6641
6950
|
});
|
|
6642
6951
|
|
|
6643
|
-
|
|
6952
|
+
searchContainer.appendChild(searchIcon);
|
|
6953
|
+
searchContainer.appendChild(searchInput);
|
|
6954
|
+
section.appendChild(searchContainer);
|
|
6644
6955
|
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
this._listBox.style.cssText = `
|
|
6648
|
-
flex: 1;
|
|
6649
|
-
overflow-y: auto;
|
|
6650
|
-
padding-right: 4px;
|
|
6651
|
-
`;
|
|
6652
|
-
this._modal.appendChild(this._listBox);
|
|
6956
|
+
return section;
|
|
6957
|
+
}
|
|
6653
6958
|
|
|
6654
|
-
|
|
6959
|
+
_createFooter() {
|
|
6655
6960
|
const footer = document.createElement('div');
|
|
6656
6961
|
footer.style.cssText = `
|
|
6657
|
-
|
|
6962
|
+
padding: 1rem 1.25rem;
|
|
6963
|
+
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
|
|
6964
|
+
border-top: 1px solid #e2e8f0;
|
|
6658
6965
|
display: flex;
|
|
6659
6966
|
justify-content: flex-end;
|
|
6660
|
-
gap:
|
|
6967
|
+
gap: 0.75rem;
|
|
6661
6968
|
`;
|
|
6662
6969
|
|
|
6663
6970
|
const cancelBtn = document.createElement('button');
|
|
6664
6971
|
cancelBtn.textContent = '取消';
|
|
6665
6972
|
cancelBtn.style.cssText = `
|
|
6666
|
-
padding:
|
|
6667
|
-
background:
|
|
6668
|
-
border:
|
|
6669
|
-
border-radius:
|
|
6973
|
+
padding: 0.5rem 1rem;
|
|
6974
|
+
background: white;
|
|
6975
|
+
border: 1px solid #d1d5db;
|
|
6976
|
+
border-radius: 0.375rem;
|
|
6977
|
+
cursor: pointer;
|
|
6978
|
+
font-size: 0.875rem;
|
|
6979
|
+
font-weight: 500;
|
|
6980
|
+
color: #374151;
|
|
6981
|
+
transition: all 0.2s ease;
|
|
6982
|
+
font-family: inherit;
|
|
6670
6983
|
`;
|
|
6984
|
+
cancelBtn.addEventListener('mouseenter', () => {
|
|
6985
|
+
cancelBtn.style.borderColor = '#ef4444';
|
|
6986
|
+
cancelBtn.style.color = '#ef4444';
|
|
6987
|
+
cancelBtn.style.transform = 'translateY(-1px)';
|
|
6988
|
+
});
|
|
6989
|
+
cancelBtn.addEventListener('mouseleave', () => {
|
|
6990
|
+
cancelBtn.style.borderColor = '#d1d5db';
|
|
6991
|
+
cancelBtn.style.color = '#374151';
|
|
6992
|
+
cancelBtn.style.transform = 'translateY(0)';
|
|
6993
|
+
});
|
|
6671
6994
|
cancelBtn.addEventListener('click', () => this._closeModal());
|
|
6672
6995
|
|
|
6673
6996
|
const okBtn = document.createElement('button');
|
|
6674
6997
|
okBtn.textContent = '确定';
|
|
6675
6998
|
okBtn.style.cssText = `
|
|
6676
|
-
padding:
|
|
6999
|
+
padding: 0.5rem 1rem;
|
|
6677
7000
|
background: #007cba;
|
|
6678
7001
|
color: white;
|
|
6679
7002
|
border: none;
|
|
6680
|
-
border-radius:
|
|
7003
|
+
border-radius: 0.375rem;
|
|
7004
|
+
cursor: pointer;
|
|
7005
|
+
font-size: 0.875rem;
|
|
7006
|
+
font-weight: 500;
|
|
7007
|
+
transition: all 0.2s ease;
|
|
7008
|
+
font-family: inherit;
|
|
7009
|
+
box-shadow: 0 2px 4px rgba(0, 124, 186, 0.2);
|
|
6681
7010
|
`;
|
|
7011
|
+
okBtn.addEventListener('mouseenter', () => {
|
|
7012
|
+
okBtn.style.background = '#005a87';
|
|
7013
|
+
okBtn.style.transform = 'translateY(-1px)';
|
|
7014
|
+
okBtn.style.boxShadow = '0 4px 8px rgba(0, 124, 186, 0.3)';
|
|
7015
|
+
});
|
|
7016
|
+
okBtn.addEventListener('mouseleave', () => {
|
|
7017
|
+
okBtn.style.background = '#007cba';
|
|
7018
|
+
okBtn.style.transform = 'translateY(0)';
|
|
7019
|
+
okBtn.style.boxShadow = '0 2px 4px rgba(0, 124, 186, 0.2)';
|
|
7020
|
+
});
|
|
6682
7021
|
okBtn.addEventListener('click', () => this._confirm());
|
|
6683
7022
|
|
|
6684
7023
|
footer.appendChild(cancelBtn);
|
|
6685
7024
|
footer.appendChild(okBtn);
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
this._overlay.appendChild(this._modal);
|
|
6689
|
-
document.body.appendChild(this._overlay);
|
|
6690
|
-
|
|
6691
|
-
// 初始化列表
|
|
6692
|
-
this._renderList('');
|
|
7025
|
+
return footer;
|
|
6693
7026
|
}
|
|
6694
7027
|
|
|
6695
|
-
/** 搜索过滤 */
|
|
6696
7028
|
_renderList(keyword) {
|
|
6697
7029
|
this._listBox.innerHTML = '';
|
|
6698
7030
|
|
|
@@ -6706,53 +7038,126 @@ class CustomOptionsControl {
|
|
|
6706
7038
|
|
|
6707
7039
|
if (list.length === 0) {
|
|
6708
7040
|
const empty = document.createElement('div');
|
|
6709
|
-
empty.
|
|
6710
|
-
|
|
6711
|
-
|
|
7041
|
+
empty.style.cssText = `
|
|
7042
|
+
text-align: center;
|
|
7043
|
+
padding: 2.5rem 1rem;
|
|
7044
|
+
color: #94a3b8;
|
|
7045
|
+
`;
|
|
7046
|
+
empty.innerHTML = `
|
|
7047
|
+
<div style="font-size: 2.5rem; margin-bottom: 0.75rem; opacity: 0.6;">🔍</div>
|
|
7048
|
+
<div style="font-size: 1rem; font-weight: 500; margin-bottom: 0.25rem; color: #64748b;">未找到相关结果</div>
|
|
7049
|
+
<div style="font-size: 0.8125rem;">尝试使用其他关键词搜索</div>
|
|
7050
|
+
`;
|
|
6712
7051
|
this._listBox.appendChild(empty);
|
|
6713
7052
|
return;
|
|
6714
7053
|
}
|
|
6715
7054
|
|
|
6716
|
-
|
|
7055
|
+
// 添加选项统计
|
|
7056
|
+
const stats = document.createElement('div');
|
|
7057
|
+
stats.style.cssText = `
|
|
7058
|
+
padding: 0.5rem 0;
|
|
7059
|
+
font-size: 0.8125rem;
|
|
7060
|
+
color: #64748b;
|
|
7061
|
+
border-bottom: 1px solid #f1f5f9;
|
|
7062
|
+
margin-bottom: 0.5rem;
|
|
7063
|
+
`;
|
|
7064
|
+
stats.textContent = `找到 ${list.length} 个相关选项`;
|
|
7065
|
+
this._listBox.appendChild(stats);
|
|
7066
|
+
|
|
7067
|
+
list.forEach((opt, index) => {
|
|
6717
7068
|
const item = document.createElement('label');
|
|
7069
|
+
item.className = 'custom-list-item';
|
|
6718
7070
|
item.style.cssText = `
|
|
6719
7071
|
display: flex;
|
|
6720
7072
|
align-items: center;
|
|
6721
|
-
padding:
|
|
7073
|
+
padding: 0.75rem;
|
|
6722
7074
|
cursor: pointer;
|
|
7075
|
+
border-radius: 0.5rem;
|
|
7076
|
+
margin-bottom: 0.375rem;
|
|
7077
|
+
transition: all 0.2s ease;
|
|
7078
|
+
border: 2px solid transparent;
|
|
7079
|
+
background: white;
|
|
7080
|
+
position: relative;
|
|
7081
|
+
overflow: hidden;
|
|
6723
7082
|
`;
|
|
6724
7083
|
|
|
6725
7084
|
const checkbox = document.createElement('input');
|
|
6726
7085
|
checkbox.type = 'checkbox';
|
|
7086
|
+
checkbox.className = 'custom-checkbox';
|
|
6727
7087
|
checkbox.value = opt.value;
|
|
6728
7088
|
checkbox.checked = this._selectedOptions.includes(opt.value);
|
|
6729
|
-
checkbox.style.marginRight = '
|
|
6730
|
-
checkbox.addEventListener('change', () => this._toggle(opt.value));
|
|
7089
|
+
checkbox.style.marginRight = '0.75rem';
|
|
6731
7090
|
|
|
6732
7091
|
const labelSpan = document.createElement('span');
|
|
6733
7092
|
labelSpan.innerHTML = this._highlight(opt.label, keyword);
|
|
7093
|
+
labelSpan.style.cssText = `
|
|
7094
|
+
flex: 1;
|
|
7095
|
+
font-size: 0.875rem;
|
|
7096
|
+
color: #374151;
|
|
7097
|
+
line-height: 1.4;
|
|
7098
|
+
font-weight: 500;
|
|
7099
|
+
`;
|
|
7100
|
+
|
|
7101
|
+
// 添加选中状态的视觉反馈
|
|
7102
|
+
if (checkbox.checked) {
|
|
7103
|
+
item.style.backgroundColor = '#f0f4ff';
|
|
7104
|
+
item.style.borderColor = '#667eea';
|
|
7105
|
+
}
|
|
7106
|
+
|
|
7107
|
+
checkbox.addEventListener('change', () => {
|
|
7108
|
+
this._toggle(opt.value);
|
|
7109
|
+
|
|
7110
|
+
// 更新项目样式
|
|
7111
|
+
if (checkbox.checked) {
|
|
7112
|
+
item.style.backgroundColor = '#f0f4ff';
|
|
7113
|
+
item.style.borderColor = '#667eea';
|
|
7114
|
+
} else {
|
|
7115
|
+
item.style.backgroundColor = 'white';
|
|
7116
|
+
item.style.borderColor = 'transparent';
|
|
7117
|
+
}
|
|
7118
|
+
|
|
7119
|
+
// 更新标题中的统计信息
|
|
7120
|
+
const subtitle = this._modal.querySelector('p');
|
|
7121
|
+
if (subtitle) {
|
|
7122
|
+
subtitle.textContent = `共 ${this._originalOptions.length} 个选项,已选择 ${this._selectedOptions.length} 个`;
|
|
7123
|
+
}
|
|
7124
|
+
});
|
|
6734
7125
|
|
|
6735
7126
|
item.appendChild(checkbox);
|
|
6736
7127
|
item.appendChild(labelSpan);
|
|
6737
7128
|
|
|
7129
|
+
// 添加进入动画
|
|
7130
|
+
item.style.opacity = '0';
|
|
7131
|
+
item.style.transform = 'translateY(10px)';
|
|
6738
7132
|
this._listBox.appendChild(item);
|
|
7133
|
+
|
|
7134
|
+
setTimeout(() => {
|
|
7135
|
+
item.style.transition = 'all 0.3s ease';
|
|
7136
|
+
item.style.opacity = '1';
|
|
7137
|
+
item.style.transform = 'translateY(0)';
|
|
7138
|
+
}, index * 30);
|
|
6739
7139
|
});
|
|
6740
7140
|
}
|
|
6741
7141
|
|
|
6742
|
-
/** 高亮关键词 */
|
|
6743
7142
|
_highlight(text, key) {
|
|
6744
7143
|
if (!key) return text;
|
|
6745
|
-
|
|
7144
|
+
const regex = new RegExp(`(${this._escapeRegExp(key)})`, 'gi');
|
|
7145
|
+
return text.replace(regex, '<mark style="background: linear-gradient(120deg, #fef3c7 0%, #fde68a 100%); padding: 0.125rem 0.25rem; border-radius: 0.25rem; font-weight: 600;">$1</mark>');
|
|
7146
|
+
}
|
|
7147
|
+
|
|
7148
|
+
_escapeRegExp(string) {
|
|
7149
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
6746
7150
|
}
|
|
6747
7151
|
|
|
6748
|
-
/** 选择切换 */
|
|
6749
7152
|
_toggle(value) {
|
|
6750
7153
|
const index = this._selectedOptions.indexOf(value);
|
|
6751
|
-
if (index >= 0)
|
|
6752
|
-
|
|
7154
|
+
if (index >= 0) {
|
|
7155
|
+
this._selectedOptions.splice(index, 1);
|
|
7156
|
+
} else {
|
|
7157
|
+
this._selectedOptions.push(value);
|
|
7158
|
+
}
|
|
6753
7159
|
}
|
|
6754
7160
|
|
|
6755
|
-
/** 点击确定 */
|
|
6756
7161
|
_confirm() {
|
|
6757
7162
|
this._onConfirm({
|
|
6758
7163
|
selectedOptions: this._selectedOptions,
|
|
@@ -6764,340 +7169,104 @@ class CustomOptionsControl {
|
|
|
6764
7169
|
this._closeModal();
|
|
6765
7170
|
}
|
|
6766
7171
|
|
|
6767
|
-
/** 销毁弹窗 */
|
|
6768
7172
|
_closeModal() {
|
|
6769
7173
|
if (this._overlay) {
|
|
6770
|
-
|
|
6771
|
-
this.
|
|
6772
|
-
this.
|
|
7174
|
+
// 添加退出动画
|
|
7175
|
+
this._modal.style.animation = 'modalSlideIn 0.2s ease-out reverse';
|
|
7176
|
+
this._overlay.style.animation = 'modalBackdropFadeIn 0.2s ease-out reverse';
|
|
7177
|
+
|
|
7178
|
+
setTimeout(() => {
|
|
7179
|
+
if (this._overlay && this._overlay.parentNode) {
|
|
7180
|
+
document.body.removeChild(this._overlay);
|
|
7181
|
+
}
|
|
7182
|
+
this._overlay = null;
|
|
7183
|
+
this._modal = null;
|
|
7184
|
+
}, 200);
|
|
7185
|
+
|
|
7186
|
+
document.removeEventListener('keydown', this._handleKeydown);
|
|
6773
7187
|
}
|
|
6774
7188
|
}
|
|
6775
7189
|
|
|
6776
7190
|
onRemove() {
|
|
6777
|
-
if (this._container)
|
|
7191
|
+
if (this._container) {
|
|
7192
|
+
this._container.remove();
|
|
7193
|
+
}
|
|
6778
7194
|
this._closeModal();
|
|
6779
7195
|
}
|
|
6780
7196
|
}
|
|
6781
7197
|
|
|
6782
|
-
// 自定义控件类:ToggleControl
|
|
7198
|
+
// 自定义控件类:ToggleControl
|
|
6783
7199
|
class CustomToggleControl {
|
|
6784
7200
|
/**
|
|
6785
7201
|
* 构造函数
|
|
6786
7202
|
* @param {Object} options
|
|
6787
|
-
* @param {string} options.name -
|
|
6788
|
-
* @param {string} options.field -
|
|
6789
|
-
* @param {boolean} options.defaultValue -
|
|
6790
|
-
* @param {string} options.svgIcon - SVG
|
|
6791
|
-
* @param {Function} [options.onToggle] -
|
|
6792
|
-
* @param {Array} [options.options] - 可选项目数组 [{id, name, icon?}]
|
|
6793
|
-
* @param {Function} [options.onOptionSelect] - 选项选择回调
|
|
6794
|
-
* @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] - 可选的回调函数,状态切换后调用,参数为最新的布尔值
|
|
6795
7208
|
*/
|
|
6796
|
-
constructor({
|
|
6797
|
-
name,
|
|
6798
|
-
field,
|
|
6799
|
-
defaultValue = false,
|
|
6800
|
-
svgIcon,
|
|
6801
|
-
onToggle,
|
|
6802
|
-
options = [],
|
|
6803
|
-
onOptionSelect,
|
|
6804
|
-
showSearch = true
|
|
6805
|
-
}) {
|
|
7209
|
+
constructor({ name, field, defaultValue = false, svgIcon, onToggle }) {
|
|
6806
7210
|
this.name = name;
|
|
6807
7211
|
this.field = field;
|
|
6808
7212
|
this.defaultValue = defaultValue;
|
|
6809
7213
|
this.svgIcon = svgIcon;
|
|
6810
|
-
this.onToggle = onToggle;
|
|
6811
|
-
this.options = options; // 可选项目
|
|
6812
|
-
this.onOptionSelect = onOptionSelect; // 选项选择回调
|
|
6813
|
-
this.showSearch = showSearch; // 是否显示搜索框
|
|
7214
|
+
this.onToggle = onToggle; // ✅ 新增:回调函数
|
|
6814
7215
|
|
|
6815
|
-
//
|
|
7216
|
+
// 控件容器
|
|
6816
7217
|
this._container = null;
|
|
6817
7218
|
this._button = null;
|
|
6818
|
-
this.
|
|
6819
|
-
this._searchInput = null;
|
|
6820
|
-
this._optionsList = null;
|
|
6821
|
-
this.isActive = false;
|
|
6822
|
-
this.isDropdownOpen = false;
|
|
6823
|
-
this.filteredOptions = [...options]; // 过滤后的选项
|
|
6824
|
-
|
|
6825
|
-
// 绑定事件处理函数
|
|
6826
|
-
this._boundHandleClickOutside = this._handleClickOutside.bind(this);
|
|
7219
|
+
this.isActive = false; // 当前是否为激活状态(高亮/true)
|
|
6827
7220
|
}
|
|
6828
7221
|
|
|
6829
7222
|
// Mapbox 要求的 onAdd 方法
|
|
6830
7223
|
onAdd(map) {
|
|
6831
7224
|
this.map = map;
|
|
6832
7225
|
|
|
6833
|
-
// 创建外层容器
|
|
7226
|
+
// 创建外层容器 div
|
|
6834
7227
|
this._container = document.createElement('div');
|
|
6835
|
-
this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group
|
|
7228
|
+
this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group';
|
|
6836
7229
|
|
|
6837
|
-
//
|
|
7230
|
+
// 创建 button 元素
|
|
6838
7231
|
this._button = document.createElement('button');
|
|
6839
7232
|
this._button.type = 'button';
|
|
6840
7233
|
this._button.innerHTML = this.svgIcon;
|
|
6841
|
-
this._button.title = this.name;
|
|
6842
7234
|
|
|
6843
7235
|
// 设置按钮样式
|
|
6844
|
-
this.
|
|
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';
|
|
6845
7243
|
|
|
6846
7244
|
// 初始化状态
|
|
6847
7245
|
this.updateStatus();
|
|
6848
7246
|
|
|
6849
|
-
//
|
|
6850
|
-
this._button.addEventListener('click', (
|
|
6851
|
-
e.stopPropagation();
|
|
7247
|
+
// 绑定点击事件
|
|
7248
|
+
this._button.addEventListener('click', () => {
|
|
6852
7249
|
this.toggle();
|
|
6853
7250
|
});
|
|
6854
7251
|
|
|
6855
7252
|
this._container.appendChild(this._button);
|
|
6856
7253
|
|
|
6857
|
-
// 创建下拉菜单(如果有选项)
|
|
6858
|
-
if (this.options.length > 0) {
|
|
6859
|
-
this._createDropdown();
|
|
6860
|
-
}
|
|
6861
|
-
|
|
6862
7254
|
return this._container;
|
|
6863
7255
|
}
|
|
6864
7256
|
|
|
6865
|
-
//
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
border: 'none',
|
|
6870
|
-
background: 'none',
|
|
6871
|
-
padding: '8px',
|
|
6872
|
-
display: 'flex',
|
|
6873
|
-
alignItems: 'center',
|
|
6874
|
-
justifyContent: 'center',
|
|
6875
|
-
borderRadius: '4px',
|
|
6876
|
-
transition: 'all 0.2s ease'
|
|
6877
|
-
});
|
|
6878
|
-
}
|
|
6879
|
-
|
|
6880
|
-
// 创建下拉菜单
|
|
6881
|
-
_createDropdown() {
|
|
6882
|
-
// 创建下拉容器
|
|
6883
|
-
this._dropdown = document.createElement('div');
|
|
6884
|
-
this._dropdown.className = 'custom-toggle-dropdown';
|
|
6885
|
-
Object.assign(this._dropdown.style, {
|
|
6886
|
-
position: 'absolute',
|
|
6887
|
-
top: '100%',
|
|
6888
|
-
right: '0',
|
|
6889
|
-
backgroundColor: 'white',
|
|
6890
|
-
border: '1px solid #ccc',
|
|
6891
|
-
borderRadius: '4px',
|
|
6892
|
-
boxShadow: '0 2px 10px rgba(0,0,0,0.1)',
|
|
6893
|
-
zIndex: '1000',
|
|
6894
|
-
minWidth: '200px',
|
|
6895
|
-
maxWidth: '300px',
|
|
6896
|
-
display: 'none',
|
|
6897
|
-
marginTop: '4px'
|
|
6898
|
-
});
|
|
6899
|
-
|
|
6900
|
-
// 创建搜索框(如果需要)
|
|
6901
|
-
if (this.showSearch && this.options.length > 5) {
|
|
6902
|
-
this._createSearchBox();
|
|
6903
|
-
}
|
|
6904
|
-
|
|
6905
|
-
// 创建选项列表
|
|
6906
|
-
this._createOptionsList();
|
|
6907
|
-
|
|
6908
|
-
this._container.appendChild(this._dropdown);
|
|
6909
|
-
}
|
|
6910
|
-
|
|
6911
|
-
// 创建搜索框
|
|
6912
|
-
_createSearchBox() {
|
|
6913
|
-
const searchContainer = document.createElement('div');
|
|
6914
|
-
Object.assign(searchContainer.style, {
|
|
6915
|
-
padding: '8px',
|
|
6916
|
-
borderBottom: '1px solid #eee'
|
|
6917
|
-
});
|
|
6918
|
-
|
|
6919
|
-
this._searchInput = document.createElement('input');
|
|
6920
|
-
this._searchInput.type = 'text';
|
|
6921
|
-
this._searchInput.placeholder = '搜索...';
|
|
6922
|
-
this._searchInput.style.cssText = `
|
|
6923
|
-
width: 100%;
|
|
6924
|
-
padding: 6px 8px;
|
|
6925
|
-
border: 1px solid #ddd;
|
|
6926
|
-
border-radius: 4px;
|
|
6927
|
-
fontSize: 12px;
|
|
6928
|
-
outline: none;
|
|
6929
|
-
box-sizing: border-box;
|
|
6930
|
-
`;
|
|
6931
|
-
|
|
6932
|
-
// 绑定搜索事件
|
|
6933
|
-
this._searchInput.addEventListener('input', (e) => {
|
|
6934
|
-
this._filterOptions(e.target.value);
|
|
6935
|
-
});
|
|
6936
|
-
|
|
6937
|
-
// 阻止下拉菜单关闭
|
|
6938
|
-
this._searchInput.addEventListener('click', (e) => {
|
|
6939
|
-
e.stopPropagation();
|
|
6940
|
-
});
|
|
6941
|
-
|
|
6942
|
-
searchContainer.appendChild(this._searchInput);
|
|
6943
|
-
this._dropdown.appendChild(searchContainer);
|
|
6944
|
-
}
|
|
6945
|
-
|
|
6946
|
-
// 创建选项列表
|
|
6947
|
-
_createOptionsList() {
|
|
6948
|
-
this._optionsList = document.createElement('div');
|
|
6949
|
-
Object.assign(this._optionsList.style, {
|
|
6950
|
-
maxHeight: '200px',
|
|
6951
|
-
overflowY: 'auto',
|
|
6952
|
-
padding: '4px 0'
|
|
6953
|
-
});
|
|
6954
|
-
|
|
6955
|
-
this._renderOptionsList();
|
|
6956
|
-
this._dropdown.appendChild(this._optionsList);
|
|
6957
|
-
}
|
|
6958
|
-
|
|
6959
|
-
// 渲染选项列表
|
|
6960
|
-
_renderOptionsList() {
|
|
6961
|
-
if (!this._optionsList) return;
|
|
6962
|
-
|
|
6963
|
-
this._optionsList.innerHTML = '';
|
|
6964
|
-
|
|
6965
|
-
this.filteredOptions.forEach(option => {
|
|
6966
|
-
const optionItem = document.createElement('div');
|
|
6967
|
-
optionItem.className = 'custom-toggle-option';
|
|
6968
|
-
optionItem.dataset.id = option.id;
|
|
6969
|
-
|
|
6970
|
-
Object.assign(optionItem.style, {
|
|
6971
|
-
padding: '8px 12px',
|
|
6972
|
-
cursor: 'pointer',
|
|
6973
|
-
display: 'flex',
|
|
6974
|
-
alignItems: 'center',
|
|
6975
|
-
gap: '8px',
|
|
6976
|
-
fontSize: '13px',
|
|
6977
|
-
transition: 'background-color 0.2s'
|
|
6978
|
-
});
|
|
6979
|
-
|
|
6980
|
-
// 添加图标(如果有)
|
|
6981
|
-
if (option.icon) {
|
|
6982
|
-
const icon = document.createElement('span');
|
|
6983
|
-
icon.innerHTML = option.icon;
|
|
6984
|
-
icon.style.fontSize = '14px';
|
|
6985
|
-
optionItem.appendChild(icon);
|
|
6986
|
-
}
|
|
6987
|
-
|
|
6988
|
-
// 添加文本
|
|
6989
|
-
const text = document.createElement('span');
|
|
6990
|
-
text.textContent = option.name;
|
|
6991
|
-
optionItem.appendChild(text);
|
|
6992
|
-
|
|
6993
|
-
// 绑定点击事件
|
|
6994
|
-
optionItem.addEventListener('click', (e) => {
|
|
6995
|
-
e.stopPropagation();
|
|
6996
|
-
this._selectOption(option);
|
|
6997
|
-
});
|
|
6998
|
-
|
|
6999
|
-
// 鼠标悬停效果
|
|
7000
|
-
optionItem.addEventListener('mouseenter', () => {
|
|
7001
|
-
optionItem.style.backgroundColor = '#f5f5f5';
|
|
7002
|
-
});
|
|
7003
|
-
|
|
7004
|
-
optionItem.addEventListener('mouseleave', () => {
|
|
7005
|
-
optionItem.style.backgroundColor = 'transparent';
|
|
7006
|
-
});
|
|
7007
|
-
|
|
7008
|
-
this._optionsList.appendChild(optionItem);
|
|
7009
|
-
});
|
|
7010
|
-
|
|
7011
|
-
// 如果没有匹配的选项
|
|
7012
|
-
if (this.filteredOptions.length === 0) {
|
|
7013
|
-
const noResults = document.createElement('div');
|
|
7014
|
-
noResults.textContent = '无匹配项';
|
|
7015
|
-
Object.assign(noResults.style, {
|
|
7016
|
-
padding: '12px',
|
|
7017
|
-
textAlign: 'center',
|
|
7018
|
-
color: '#999',
|
|
7019
|
-
fontSize: '12px'
|
|
7020
|
-
});
|
|
7021
|
-
this._optionsList.appendChild(noResults);
|
|
7022
|
-
}
|
|
7023
|
-
}
|
|
7024
|
-
|
|
7025
|
-
// 过滤选项
|
|
7026
|
-
_filterOptions(searchTerm) {
|
|
7027
|
-
const term = searchTerm.toLowerCase().trim();
|
|
7028
|
-
|
|
7029
|
-
if (!term) {
|
|
7030
|
-
this.filteredOptions = [...this.options];
|
|
7031
|
-
} else {
|
|
7032
|
-
this.filteredOptions = this.options.filter(option =>
|
|
7033
|
-
option.name.toLowerCase().includes(term) ||
|
|
7034
|
-
(option.id && option.id.toString().toLowerCase().includes(term))
|
|
7035
|
-
);
|
|
7036
|
-
}
|
|
7037
|
-
|
|
7038
|
-
this._renderOptionsList();
|
|
7039
|
-
}
|
|
7040
|
-
|
|
7041
|
-
// 选择选项
|
|
7042
|
-
_selectOption(option) {
|
|
7043
|
-
// 调用选项选择回调
|
|
7044
|
-
if (this.onOptionSelect) {
|
|
7045
|
-
this.onOptionSelect(option);
|
|
7046
|
-
}
|
|
7047
|
-
|
|
7048
|
-
// 关闭下拉菜单
|
|
7049
|
-
this.closeDropdown();
|
|
7050
|
-
}
|
|
7051
|
-
|
|
7052
|
-
// 切换下拉菜单显示状态
|
|
7053
|
-
toggle() {
|
|
7054
|
-
if (this.isDropdownOpen) {
|
|
7055
|
-
this.closeDropdown();
|
|
7056
|
-
} else {
|
|
7057
|
-
this.openDropdown();
|
|
7058
|
-
}
|
|
7059
|
-
}
|
|
7060
|
-
|
|
7061
|
-
// 打开下拉菜单
|
|
7062
|
-
openDropdown() {
|
|
7063
|
-
if (!this._dropdown || this.options.length === 0) return;
|
|
7064
|
-
|
|
7065
|
-
this.isDropdownOpen = true;
|
|
7066
|
-
this._dropdown.style.display = 'block';
|
|
7067
|
-
|
|
7068
|
-
// 添加全局点击监听
|
|
7069
|
-
document.addEventListener('click', this._boundHandleClickOutside);
|
|
7070
|
-
|
|
7071
|
-
// 聚焦搜索框
|
|
7072
|
-
if (this._searchInput) {
|
|
7073
|
-
setTimeout(() => {
|
|
7074
|
-
this._searchInput.focus();
|
|
7075
|
-
this._searchInput.value = '';
|
|
7076
|
-
this._filterOptions('');
|
|
7077
|
-
}, 100);
|
|
7078
|
-
}
|
|
7079
|
-
}
|
|
7080
|
-
|
|
7081
|
-
// 关闭下拉菜单
|
|
7082
|
-
closeDropdown() {
|
|
7083
|
-
if (!this._dropdown) return;
|
|
7084
|
-
|
|
7085
|
-
this.isDropdownOpen = false;
|
|
7086
|
-
this._dropdown.style.display = 'none';
|
|
7087
|
-
|
|
7088
|
-
// 移除全局点击监听
|
|
7089
|
-
document.removeEventListener('click', this._boundHandleClickOutside);
|
|
7090
|
-
}
|
|
7091
|
-
|
|
7092
|
-
// 处理外部点击
|
|
7093
|
-
_handleClickOutside(event) {
|
|
7094
|
-
if (!this._container.contains(event.target)) {
|
|
7095
|
-
this.closeDropdown();
|
|
7257
|
+
// Mapbox 要求的 onRemove 方法
|
|
7258
|
+
onRemove() {
|
|
7259
|
+
if (this._container && this._container.parentNode) {
|
|
7260
|
+
this._container.parentNode.removeChild(this._container);
|
|
7096
7261
|
}
|
|
7262
|
+
this.map = null;
|
|
7263
|
+
this._container = null;
|
|
7264
|
+
this._button = null;
|
|
7097
7265
|
}
|
|
7098
7266
|
|
|
7099
|
-
//
|
|
7267
|
+
// 更新控件状态(根据当前 field 值)
|
|
7100
7268
|
updateStatus() {
|
|
7269
|
+
// 从 map.SourceMap 中获取当前 field 的值,如果不存在则使用 defaultValue
|
|
7101
7270
|
let currentValue = this.defaultValue;
|
|
7102
7271
|
|
|
7103
7272
|
if (
|
|
@@ -7108,22 +7277,21 @@ class CustomToggleControl {
|
|
|
7108
7277
|
currentValue = this.map.SourceMap[this.field];
|
|
7109
7278
|
}
|
|
7110
7279
|
|
|
7111
|
-
this.isActive = currentValue;
|
|
7280
|
+
this.isActive = currentValue; // true 表示激活,false 表示未激活
|
|
7112
7281
|
|
|
7113
7282
|
// 更新按钮样式
|
|
7114
7283
|
if (this.isActive) {
|
|
7115
7284
|
this._button.style.opacity = '1';
|
|
7116
7285
|
this._button.style.filter = 'none';
|
|
7117
|
-
this._button.style.backgroundColor = '#e6f3ff';
|
|
7118
7286
|
} else {
|
|
7119
|
-
this._button.style.opacity = '0.
|
|
7287
|
+
this._button.style.opacity = '0.4';
|
|
7120
7288
|
this._button.style.filter = 'grayscale(100%)';
|
|
7121
|
-
this._button.style.backgroundColor = 'transparent';
|
|
7122
7289
|
}
|
|
7123
7290
|
}
|
|
7124
7291
|
|
|
7125
|
-
//
|
|
7126
|
-
|
|
7292
|
+
// 切换状态
|
|
7293
|
+
toggle() {
|
|
7294
|
+
// 获取当前值
|
|
7127
7295
|
let currentValue = this.defaultValue;
|
|
7128
7296
|
|
|
7129
7297
|
if (
|
|
@@ -7134,34 +7302,22 @@ class CustomToggleControl {
|
|
|
7134
7302
|
currentValue = this.map.SourceMap[this.field];
|
|
7135
7303
|
}
|
|
7136
7304
|
|
|
7305
|
+
// 切换值
|
|
7137
7306
|
const newValue = !currentValue;
|
|
7138
7307
|
|
|
7308
|
+
// 更新到 map.SourceMap 中
|
|
7139
7309
|
if (this.map && this.map.SourceMap) {
|
|
7140
7310
|
this.map.SourceMap[this.field] = newValue;
|
|
7141
7311
|
}
|
|
7142
7312
|
|
|
7313
|
+
// 更新内部状态
|
|
7143
7314
|
this.isActive = newValue;
|
|
7144
|
-
this.updateStatus();
|
|
7145
|
-
|
|
7146
|
-
if (this.onToggle) {
|
|
7147
|
-
this.onToggle(newValue);
|
|
7148
|
-
}
|
|
7149
|
-
}
|
|
7150
|
-
|
|
7151
|
-
// Mapbox 要求的 onRemove 方法
|
|
7152
|
-
onRemove() {
|
|
7153
|
-
this.closeDropdown();
|
|
7154
7315
|
|
|
7155
|
-
|
|
7156
|
-
|
|
7157
|
-
}
|
|
7316
|
+
// 更新 UI 样式
|
|
7317
|
+
this.updateStatus();
|
|
7158
7318
|
|
|
7159
|
-
|
|
7160
|
-
this.
|
|
7161
|
-
this._button = null;
|
|
7162
|
-
this._dropdown = null;
|
|
7163
|
-
this._searchInput = null;
|
|
7164
|
-
this._optionsList = null;
|
|
7319
|
+
// ✅ 调用回调函数(如果传入了 onToggle),并传入最新的值
|
|
7320
|
+
this.onToggle?.(newValue); // 安全调用,仅当函数存在时才执行
|
|
7165
7321
|
}
|
|
7166
7322
|
}
|
|
7167
7323
|
|