raintee-maputils 1.0.44 → 1.0.46

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
@@ -6738,6 +6738,582 @@ class RulerControl {
6738
6738
  }
6739
6739
  }
6740
6740
 
6741
+ // /**
6742
+ // * CustomSearchSelectControl - 紧凑型 Mapbox 控件
6743
+ // * 优化UI布局,提高空间利用率
6744
+ // */
6745
+ // class CustomSearchSelectControl {
6746
+ // /**
6747
+ // * 构造函数
6748
+ // * @param {Object} options 配置选项
6749
+ // * @param {Array} options.list 选项列表
6750
+ // * @param {Function} options.onSelect 选中回调函数
6751
+ // * @param {string} options.placeholder 搜索框占位符
6752
+ // * @param {string} options.title 弹窗标题
6753
+ // * @param {boolean} options.showSearch 是否显示搜索框
6754
+ // * @param {boolean} options.compactMode 是否启用紧凑模式
6755
+ // */
6756
+ // constructor(options = {}) {
6757
+ // this.options = {
6758
+ // list: [],
6759
+ // onSelect: () => { },
6760
+ // onCancel: () => { },
6761
+ // placeholder: '搜索...',
6762
+ // title: '选择',
6763
+ // showSearch: true,
6764
+ // compactMode: true, // 新增:紧凑模式
6765
+ // maxHeight: '60vh', // 新增:最大高度
6766
+ // width: '60vw', // 新增:弹窗宽度
6767
+ // ...options
6768
+ // };
6769
+
6770
+ // this._map = null;
6771
+ // this._container = null;
6772
+ // this._modal = null;
6773
+ // this._overlay = null;
6774
+ // this._searchInput = null;
6775
+ // this._optionsList = null;
6776
+ // this._filteredList = [...this.options.list];
6777
+ // }
6778
+
6779
+ // /**
6780
+ // * 添加到地图
6781
+ // * @param {Object} map Mapbox 地图实例
6782
+ // * @returns {HTMLElement} 控件容器
6783
+ // */
6784
+ // onAdd(map) {
6785
+ // this._map = map;
6786
+
6787
+ // // 创建控件按钮
6788
+ // this._container = document.createElement('div');
6789
+ // this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group vector-layer-ctrl';
6790
+ // this._container.style.cssText = `
6791
+ // position: relative;
6792
+ // `;
6793
+ // this._container.innerHTML = `
6794
+ // <button class="vector-layer-btn" title="${this.options.title}">
6795
+ // <svg viewBox="0 0 24 24" width="18" height="18">
6796
+ // <path d="M9,2V7.5L12,10.5L15,7.5V2H9ZM2,9H7.5L10.5,12L7.5,15H2V9ZM22,9H16.5L13.5,12L16.5,15H22V9ZM9,22V16.5L12,13.5L15,16.5V22H9Z"
6797
+ // fill="currentColor"/>
6798
+ // </svg>
6799
+ // </button>
6800
+ // `;
6801
+
6802
+ // // 添加点击事件
6803
+ // const button = this._container.querySelector('.vector-layer-btn');
6804
+ // button.addEventListener('click', () => this.openModal());
6805
+
6806
+ // return this._container;
6807
+ // }
6808
+
6809
+ // /**
6810
+ // * 从地图移除
6811
+ // */
6812
+ // onRemove() {
6813
+ // this.closeModal();
6814
+ // if (this._container) {
6815
+ // this._container.parentNode.removeChild(this._container);
6816
+ // }
6817
+ // this._map = undefined;
6818
+ // }
6819
+
6820
+ // /**
6821
+ // * 打开弹窗
6822
+ // */
6823
+ // openModal() {
6824
+ // if (this._modal) return;
6825
+
6826
+ // // 创建遮罩层
6827
+ // this._overlay = document.createElement('div');
6828
+ // this._overlay.className = 'vector-layer-overlay';
6829
+ // this._overlay.style.cssText = `
6830
+ // position: fixed;
6831
+ // top: 0;
6832
+ // left: 0;
6833
+ // width: 100%;
6834
+ // height: 100%;
6835
+ // background: rgba(0, 0, 0, 0.5);
6836
+ // z-index: 9999;
6837
+ // display: flex;
6838
+ // justify-content: center;
6839
+ // backdrop-filter: blur(2px);
6840
+ // `;
6841
+ // this._overlay.addEventListener('click', (e) => {
6842
+ // if (e.target === this._overlay) this.closeModal();
6843
+ // });
6844
+
6845
+ // // 创建弹窗
6846
+ // this._modal = document.createElement('div');
6847
+ // this._modal.className = 'vector-layer-modal';
6848
+ // this._modal.style.cssText = `
6849
+ // background: white;
6850
+ // border-radius: 8px;
6851
+ // padding: ${this.options.compactMode ? '16px' : '20px'};
6852
+ // width: ${this.options.width};
6853
+ // max-width: 90vw;
6854
+ // max-height: ${this.options.maxHeight};
6855
+ // display: flex;
6856
+ // flex-direction: column;
6857
+ // box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
6858
+ // animation: vector-layer-modal-appear 0.2s ease-out;
6859
+ // border: 1px solid #e0e0e0;
6860
+ // `;
6861
+
6862
+ // // 弹窗标题
6863
+ // const title = document.createElement('h3');
6864
+ // title.className = 'vector-layer-title';
6865
+ // title.textContent = this.options.title;
6866
+ // title.style.cssText = `
6867
+ // margin: 0 0 ${this.options.compactMode ? '12px' : '16px'} 0;
6868
+ // font-size: ${this.options.compactMode ? '15px' : '16px'};
6869
+ // font-weight: 600;
6870
+ // color: #2c3e50;
6871
+ // line-height: 1.3;
6872
+ // `;
6873
+ // this._modal.appendChild(title);
6874
+
6875
+ // // 搜索框
6876
+ // if (this.options.showSearch) {
6877
+ // const searchContainer = document.createElement('div');
6878
+ // searchContainer.className = 'vector-layer-search';
6879
+ // searchContainer.style.cssText = `
6880
+ // margin-bottom: ${this.options.compactMode ? '12px' : '16px'};
6881
+ // position: relative;
6882
+ // `;
6883
+
6884
+ // this._searchInput = document.createElement('input');
6885
+ // this._searchInput.type = 'text';
6886
+ // this._searchInput.placeholder = this.options.placeholder;
6887
+ // this._searchInput.className = 'vector-layer-search-input';
6888
+ // this._searchInput.style.cssText = `
6889
+ // width: 100%;
6890
+ // padding: ${this.options.compactMode ? '8px 12px 8px 36px' : '10px 16px 10px 40px'};
6891
+ // border: 1px solid #dcdfe6;
6892
+ // border-radius: 6px;
6893
+ // font-size: 13px;
6894
+ // outline: none;
6895
+ // transition: all 0.2s;
6896
+ // box-sizing: border-box;
6897
+ // background-color: #f8f9fa;
6898
+ // `;
6899
+ // this._searchInput.addEventListener('input', () => this.filterOptions());
6900
+ // this._searchInput.addEventListener('keydown', (e) => {
6901
+ // if (e.key === 'Escape') this.closeModal();
6902
+ // });
6903
+
6904
+ // // 搜索图标
6905
+ // const searchIcon = document.createElement('div');
6906
+ // searchIcon.innerHTML = `
6907
+ // <svg viewBox="0 0 24 24" width="16" height="16"
6908
+ // style="position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: #888;">
6909
+ // <path d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"
6910
+ // fill="currentColor"/>
6911
+ // </svg>
6912
+ // `;
6913
+
6914
+ // searchContainer.appendChild(searchIcon);
6915
+ // searchContainer.appendChild(this._searchInput);
6916
+ // this._modal.appendChild(searchContainer);
6917
+ // }
6918
+
6919
+ // // 选项列表容器
6920
+ // const listContainer = document.createElement('div');
6921
+ // listContainer.className = 'vector-layer-list-container';
6922
+ // listContainer.style.cssText = `
6923
+ // flex: 1;
6924
+ // overflow: hidden;
6925
+ // min-height: ${this.options.compactMode ? '120px' : '160px'};
6926
+ // border-radius: 6px;
6927
+ // border: 1px solid #e0e0e0;
6928
+ // `;
6929
+
6930
+ // this._optionsList = document.createElement('div');
6931
+ // this._optionsList.className = 'vector-layer-options';
6932
+ // this._optionsList.style.cssText = `
6933
+ // max-height: calc(${this.options.maxHeight} - ${this.options.compactMode ? '140px' : '180px'});
6934
+ // overflow-y: auto;
6935
+ // scroll-behavior: smooth;
6936
+ // `;
6937
+
6938
+ // // 填充选项
6939
+ // this.renderOptions();
6940
+
6941
+ // listContainer.appendChild(this._optionsList);
6942
+ // this._modal.appendChild(listContainer);
6943
+
6944
+ // // 操作按钮
6945
+ // const buttonContainer = document.createElement('div');
6946
+ // buttonContainer.className = 'vector-layer-actions';
6947
+ // buttonContainer.style.cssText = `
6948
+ // display: flex;
6949
+ // justify-content: flex-end;
6950
+ // gap: 8px;
6951
+ // margin-top: ${this.options.compactMode ? '12px' : '16px'};
6952
+ // padding-top: ${this.options.compactMode ? '12px' : '16px'};
6953
+ // border-top: 1px solid #f0f0f0;
6954
+ // `;
6955
+
6956
+ // const cancelBtn = document.createElement('button');
6957
+ // cancelBtn.textContent = '取消';
6958
+ // cancelBtn.className = 'vector-layer-cancel';
6959
+ // cancelBtn.style.cssText = `
6960
+ // padding: 6px 16px;
6961
+ // border: 1px solid #dcdfe6;
6962
+ // border-radius: 4px;
6963
+ // background: white;
6964
+ // color: #606266;
6965
+ // cursor: pointer;
6966
+ // font-size: 13px;
6967
+ // transition: all 0.2s;
6968
+ // font-weight: 500;
6969
+ // `;
6970
+ // cancelBtn.addEventListener('click', () => {
6971
+ // this.closeModal();
6972
+ // this.options.onCancel(this._map, null)
6973
+ // });
6974
+ // cancelBtn.addEventListener('mouseenter', () => {
6975
+ // cancelBtn.style.backgroundColor = '#f5f7fa';
6976
+ // cancelBtn.style.borderColor = '#c0c4cc';
6977
+ // });
6978
+ // cancelBtn.addEventListener('mouseleave', () => {
6979
+ // cancelBtn.style.backgroundColor = 'white';
6980
+ // cancelBtn.style.borderColor = '#dcdfe6';
6981
+ // });
6982
+
6983
+ // buttonContainer.appendChild(cancelBtn);
6984
+ // this._modal.appendChild(buttonContainer);
6985
+
6986
+ // this._overlay.appendChild(this._modal);
6987
+ // document.body.appendChild(this._overlay);
6988
+
6989
+ // // 阻止地图事件冒泡
6990
+ // this._modal.addEventListener('click', (e) => e.stopPropagation());
6991
+ // this._modal.addEventListener('mousedown', (e) => e.stopPropagation());
6992
+ // this._modal.addEventListener('mouseup', (e) => e.stopPropagation());
6993
+
6994
+ // // 聚焦搜索框
6995
+ // if (this._searchInput) {
6996
+ // setTimeout(() => this._searchInput.focus(), 50);
6997
+ // }
6998
+
6999
+ // // 添加动画样式
7000
+ // this.addStyles();
7001
+ // }
7002
+
7003
+ // /**
7004
+ // * 渲染选项列表
7005
+ // */
7006
+ // renderOptions() {
7007
+ // this._optionsList.innerHTML = '';
7008
+
7009
+ // if (this._filteredList.length === 0) {
7010
+ // const emptyItem = document.createElement('div');
7011
+ // emptyItem.className = 'vector-layer-option empty';
7012
+ // emptyItem.textContent = '无匹配结果';
7013
+ // emptyItem.style.cssText = `
7014
+ // padding: ${this.options.compactMode ? '20px 16px' : '24px 16px'};
7015
+ // text-align: center;
7016
+ // color: #999;
7017
+ // font-size: 13px;
7018
+ // font-style: italic;
7019
+ // `;
7020
+ // this._optionsList.appendChild(emptyItem);
7021
+ // return;
7022
+ // }
7023
+
7024
+ // this._filteredList.forEach((item, index) => {
7025
+ // const option = document.createElement('div');
7026
+ // option.className = 'vector-layer-option';
7027
+ // option.dataset.value = item.value || item.label;
7028
+ // option.dataset.index = index;
7029
+ // option.style.cssText = `
7030
+ // padding: ${this.options.compactMode ? '8px 12px' : '10px 16px'};
7031
+ // cursor: pointer;
7032
+ // border-bottom: 1px solid #f5f5f5;
7033
+ // font-size: 13px;
7034
+ // transition: all 0.15s;
7035
+ // display: flex;
7036
+ // align-items: center;
7037
+ // gap: 8px;
7038
+ // min-height: ${this.options.compactMode ? '36px' : '40px'};
7039
+ // box-sizing: border-box;
7040
+ // `;
7041
+
7042
+ // option.innerHTML = `
7043
+ // ${item.icon ? `<span class="option-icon" style="flex-shrink: 0; width: 16px; height: 16px;">${item.icon}</span>` : ''}
7044
+ // <span class="option-label" style="flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${item.label}</span>
7045
+ // ${item.description ? `<span class="option-desc" style="font-size: 12px; color: #888; flex-shrink: 0;">${item.description}</span>` : ''}
7046
+ // `;
7047
+
7048
+ // option.addEventListener('click', () => this.selectOption(item));
7049
+ // option.addEventListener('mouseenter', () => {
7050
+ // option.style.backgroundColor = '#f0f7ff';
7051
+ // option.style.borderLeftColor = '#1890ff';
7052
+ // });
7053
+ // option.addEventListener('mouseleave', () => {
7054
+ // option.style.backgroundColor = '';
7055
+ // option.style.borderLeftColor = '';
7056
+ // });
7057
+
7058
+ // this._optionsList.appendChild(option);
7059
+ // });
7060
+
7061
+ // // 移除最后一个选项的下边框
7062
+ // const lastOption = this._optionsList.lastChild;
7063
+ // if (lastOption && !lastOption.classList.contains('empty')) {
7064
+ // lastOption.style.borderBottom = 'none';
7065
+ // }
7066
+ // }
7067
+
7068
+ // /**
7069
+ // * 筛选选项
7070
+ // */
7071
+ // filterOptions() {
7072
+ // const searchText = this._searchInput ? this._searchInput.value.toLowerCase() : '';
7073
+
7074
+ // if (!searchText) {
7075
+ // this._filteredList = [...this.options.list];
7076
+ // } else {
7077
+ // this._filteredList = this.options.list.filter(item =>
7078
+ // item.label.toLowerCase().includes(searchText) ||
7079
+ // (item.value && item.value.toLowerCase().includes(searchText)) ||
7080
+ // (item.description && item.description.toLowerCase().includes(searchText))
7081
+ // );
7082
+ // }
7083
+
7084
+ // this.renderOptions();
7085
+ // }
7086
+
7087
+ // /**
7088
+ // * 选中选项
7089
+ // * @param {Object} item 选中的选项
7090
+ // */
7091
+ // selectOption(item) {
7092
+ // try {
7093
+ // // 执行回调
7094
+ // this.options.onSelect(this._map, item);
7095
+
7096
+ // // 添加选中动画
7097
+ // const option = this._optionsList.querySelector(`[data-value="${item.value || item.label}"]`);
7098
+ // if (option) {
7099
+ // const originalBg = option.style.backgroundColor;
7100
+ // const originalColor = option.style.color;
7101
+ // option.style.backgroundColor = '#1890ff';
7102
+ // option.style.color = 'white';
7103
+ // setTimeout(() => {
7104
+ // option.style.backgroundColor = originalBg;
7105
+ // option.style.color = originalColor;
7106
+ // }, 150);
7107
+ // setTimeout(() => {
7108
+ // this.closeModal();
7109
+ // }, 300);
7110
+ // } else {
7111
+ // this.closeModal();
7112
+ // }
7113
+ // } catch (error) {
7114
+ // console.error('选中回调执行失败:', error);
7115
+ // this.closeModal();
7116
+ // }
7117
+ // }
7118
+
7119
+ // /**
7120
+ // * 关闭弹窗
7121
+ // */
7122
+ // closeModal() {
7123
+ // if (this._overlay) {
7124
+ // this._overlay.style.opacity = '0';
7125
+ // this._overlay.style.transition = 'opacity 0.15s ease-out';
7126
+
7127
+ // setTimeout(() => {
7128
+ // if (this._overlay && this._overlay.parentNode) {
7129
+ // document.body.removeChild(this._overlay);
7130
+ // }
7131
+ // this._overlay = null;
7132
+ // this._modal = null;
7133
+ // this._searchInput = null;
7134
+ // this._optionsList = null;
7135
+ // }, 150);
7136
+ // }
7137
+ // }
7138
+
7139
+ // /**
7140
+ // * 更新选项列表
7141
+ // * @param {Array} newList 新的选项列表
7142
+ // */
7143
+ // updateList(newList) {
7144
+ // this.options.list = newList;
7145
+ // this._filteredList = [...newList];
7146
+ // if (this._modal) {
7147
+ // this.renderOptions();
7148
+ // }
7149
+ // }
7150
+
7151
+ // /**
7152
+ // * 添加CSS样式
7153
+ // */
7154
+ // addStyles() {
7155
+ // if (document.querySelector('#vector-layer-styles')) return;
7156
+
7157
+ // const style = document.createElement('style');
7158
+ // style.id = 'vector-layer-styles';
7159
+ // style.textContent = `
7160
+ // @keyframes vector-layer-modal-appear {
7161
+ // from {
7162
+ // opacity: 0;
7163
+ // transform: translateY(-8px) scale(0.98);
7164
+ // }
7165
+ // to {
7166
+ // opacity: 1;
7167
+ // transform: translateY(0) scale(1);
7168
+ // }
7169
+ // }
7170
+
7171
+ // .vector-layer-ctrl button {
7172
+ // background: white;
7173
+ // border: 1px solid #d9d9d9;
7174
+ // border-radius: 4px;
7175
+ // width: 28px;
7176
+ // height: 28px;
7177
+ // display: flex;
7178
+ // align-items: center;
7179
+ // justify-content: center;
7180
+ // cursor: pointer;
7181
+ // color: #555;
7182
+ // transition: all 0.2s;
7183
+ // padding: 0;
7184
+ // margin: 0;
7185
+ // }
7186
+
7187
+ // .vector-layer-ctrl button:hover {
7188
+ // background: #f5f5f5;
7189
+ // border-color: #40a9ff;
7190
+ // color: #40a9ff;
7191
+ // box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
7192
+ // }
7193
+
7194
+ // .vector-layer-search-input:focus {
7195
+ // border-color: #40a9ff;
7196
+ // box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
7197
+ // background-color: white;
7198
+ // }
7199
+
7200
+ // .vector-layer-option {
7201
+ // position: relative;
7202
+ // border-left: 3px solid transparent;
7203
+ // }
7204
+
7205
+ // .vector-layer-option:hover {
7206
+ // border-left-color: #1890ff;
7207
+ // }
7208
+
7209
+ // .vector-layer-option:active {
7210
+ // background-color: #e6f7ff !important;
7211
+ // }
7212
+
7213
+ // .vector-layer-options::-webkit-scrollbar {
7214
+ // width: 4px;
7215
+ // }
7216
+
7217
+ // .vector-layer-options::-webkit-scrollbar-track {
7218
+ // background: #f5f5f5;
7219
+ // border-radius: 2px;
7220
+ // }
7221
+
7222
+ // .vector-layer-options::-webkit-scrollbar-thumb {
7223
+ // background: #bfbfbf;
7224
+ // border-radius: 2px;
7225
+ // }
7226
+
7227
+ // .vector-layer-options::-webkit-scrollbar-thumb:hover {
7228
+ // background: #8c8c8c;
7229
+ // }
7230
+
7231
+ // .vector-layer-modal {
7232
+ // overflow: hidden;
7233
+ // }
7234
+
7235
+ // /* 紧凑模式下的额外样式 */
7236
+ // .vector-layer-modal.compact {
7237
+ // padding: 12px;
7238
+ // }
7239
+
7240
+ // .vector-layer-modal.compact .vector-layer-title {
7241
+ // font-size: 14px;
7242
+ // margin-bottom: 10px;
7243
+ // }
7244
+
7245
+ // .vector-layer-modal.compact .vector-layer-search-input {
7246
+ // padding: 6px 10px 6px 32px;
7247
+ // font-size: 12px;
7248
+ // }
7249
+
7250
+ // .vector-layer-modal.compact .vector-layer-option {
7251
+ // padding: 6px 10px;
7252
+ // font-size: 12px;
7253
+ // min-height: 32px;
7254
+ // }
7255
+
7256
+ // /* 暗色模式支持 */
7257
+ // @media (prefers-color-scheme: dark) {
7258
+ // .vector-layer-modal {
7259
+ // background: #2d2d2d;
7260
+ // border-color: #404040;
7261
+ // color: #e0e0e0;
7262
+ // }
7263
+
7264
+ // .vector-layer-title {
7265
+ // color: #e0e0e0;
7266
+ // }
7267
+
7268
+ // .vector-layer-search-input {
7269
+ // background-color: #3a3a3a;
7270
+ // border-color: #555;
7271
+ // color: #e0e0e0;
7272
+ // }
7273
+
7274
+ // .vector-layer-search-input:focus {
7275
+ // border-color: #1890ff;
7276
+ // }
7277
+
7278
+ // .vector-layer-list-container {
7279
+ // border-color: #404040;
7280
+ // }
7281
+
7282
+ // .vector-layer-option {
7283
+ // border-bottom-color: #404040;
7284
+ // }
7285
+
7286
+ // .vector-layer-option:hover {
7287
+ // background-color: #3a3a3a;
7288
+ // }
7289
+
7290
+ // .option-desc {
7291
+ // color: #aaa;
7292
+ // }
7293
+
7294
+ // .vector-layer-actions {
7295
+ // border-top-color: #404040;
7296
+ // }
7297
+
7298
+ // .vector-layer-cancel {
7299
+ // background: #3a3a3a;
7300
+ // border-color: #555;
7301
+ // color: #e0e0e0;
7302
+ // }
7303
+
7304
+ // .vector-layer-options::-webkit-scrollbar-track {
7305
+ // background: #3a3a3a;
7306
+ // }
7307
+
7308
+ // .vector-layer-options::-webkit-scrollbar-thumb {
7309
+ // background: #666;
7310
+ // }
7311
+ // }
7312
+ // `;
7313
+
7314
+ // document.head.appendChild(style);
7315
+ // }
7316
+ // }
6741
7317
  /**
6742
7318
  * CustomSearchSelectControl - 紧凑型 Mapbox 控件
6743
7319
  * 优化UI布局,提高空间利用率
@@ -6762,8 +7338,11 @@ class CustomSearchSelectControl {
6762
7338
  title: '选择',
6763
7339
  showSearch: true,
6764
7340
  compactMode: true, // 新增:紧凑模式
6765
- maxHeight: '60vh', // 新增:最大高度
7341
+ maxHeight: '100vh', // 新增:最大高度
6766
7342
  width: '60vw', // 新增:弹窗宽度
7343
+ mobileBreakpoint: 768, // 新增:移动端断点
7344
+ mobileMaxHeight: '50vh', // 新增:移动端最大高度
7345
+ mobileCompactMode: true, // 新增:移动端自动启用紧凑模式
6767
7346
  ...options
6768
7347
  };
6769
7348
 
@@ -6774,6 +7353,57 @@ class CustomSearchSelectControl {
6774
7353
  this._searchInput = null;
6775
7354
  this._optionsList = null;
6776
7355
  this._filteredList = [...this.options.list];
7356
+ this._isMobile = false;
7357
+ this._isLandscape = false;
7358
+ }
7359
+
7360
+ /**
7361
+ * 检测设备和屏幕方向
7362
+ */
7363
+ detectDeviceAndOrientation() {
7364
+ this._isMobile = window.innerWidth <= this.options.mobileBreakpoint;
7365
+ this._isLandscape = window.innerWidth > window.innerHeight;
7366
+
7367
+ // 横屏时特别处理
7368
+ if (this._isMobile && this._isLandscape) {
7369
+ this._isMobile = true;
7370
+ }
7371
+ }
7372
+
7373
+ /**
7374
+ * 获取弹窗高度设置
7375
+ */
7376
+ getModalHeightSettings() {
7377
+ this.detectDeviceAndOrientation();
7378
+
7379
+ if (this._isMobile) {
7380
+ // 移动端处理
7381
+ if (this._isLandscape) {
7382
+ // 横屏状态
7383
+ return {
7384
+ maxHeight: '100vh', // 横屏时稍微大一些
7385
+ modalHeight: 'calc(100vh - 20px)', // 横屏时几乎全屏
7386
+ listMaxHeight: 'calc(70vh - 100px)', // 为按钮留出空间
7387
+ compact: this.options.mobileCompactMode
7388
+ };
7389
+ } else {
7390
+ // 竖屏状态
7391
+ return {
7392
+ maxHeight: this.options.mobileMaxHeight,
7393
+ modalHeight: 'auto',
7394
+ listMaxHeight: `calc(${this.options.mobileMaxHeight} - 100px)`,
7395
+ compact: this.options.mobileCompactMode
7396
+ };
7397
+ }
7398
+ } else {
7399
+ // 桌面端
7400
+ return {
7401
+ maxHeight: this.options.maxHeight,
7402
+ modalHeight: 'auto',
7403
+ listMaxHeight: `calc(${this.options.maxHeight} - ${this.options.compactMode ? '140px' : '180px'})`,
7404
+ compact: this.options.compactMode
7405
+ };
7406
+ }
6777
7407
  }
6778
7408
 
6779
7409
  /**
@@ -6792,10 +7422,7 @@ class CustomSearchSelectControl {
6792
7422
  `;
6793
7423
  this._container.innerHTML = `
6794
7424
  <button class="vector-layer-btn" title="${this.options.title}">
6795
- <svg viewBox="0 0 24 24" width="18" height="18">
6796
- <path d="M9,2V7.5L12,10.5L15,7.5V2H9ZM2,9H7.5L10.5,12L7.5,15H2V9ZM22,9H16.5L13.5,12L16.5,15H22V9ZM9,22V16.5L12,13.5L15,16.5V22H9Z"
6797
- fill="currentColor"/>
6798
- </svg>
7425
+ <svg t="1765250004086" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2929" width="16" height="16"><path d="M1002.666667 768L512 1002.666667 21.333333 768l267.733334-128L512 746.666667l222.933333-106.666667L1002.666667 768z" fill="#00A6FF" p-id="2930"></path><path d="M734.933333 640L512 746.666667l-222.933333-106.666667L512 533.333333l222.933333 106.666667z" fill="#00C7B1" p-id="2931"></path><path d="M735.146667 384L512 490.666667l-222.933333-106.666667L21.333333 512l267.733334 128L512 533.333333l222.933333 106.666667L1002.666667 512l-267.52-128z" fill="#24F2DC" p-id="2932"></path><path d="M735.146667 384L512 490.666667l-222.933333-106.666667L512 277.333333l223.146667 106.666667z" fill="#FFC247" p-id="2933"></path><path d="M1002.666667 256l-267.52 128L512 277.333333l-222.933333 106.666667L21.333333 256 512 21.333333l490.666667 234.666667z" fill="#FFD747" p-id="2934"></path><path d="M815.082667 189.930667l18.410666-38.506667 50.432 24.106667-18.410666 38.528zM37.333333 752l-5.952-12.437333-19.2 9.194666a21.333333 21.333333 0 0 0 0 38.4l19.2 9.194667 5.952-12.437333 12.458667-5.952L44.970667 768l4.821333-10.048zM72.490667 719.893333l41.109333-19.669333 18.410667 38.506667-41.109334 19.669333zM401.322667 562.581333l41.109333-19.648 18.410667 38.506667-41.109334 19.648zM154.688 680.576l41.109333-19.669333 18.432 38.506666-41.109333 19.669334zM522.048 561.792l18.410667-38.4-19.2-9.194667a21.461333 21.461333 0 0 0-18.432 0l-19.2 9.194667 18.410666 38.4 9.962667-4.821333zM809.813333 699.392l18.389334-38.506667 41.109333 19.648-18.410667 38.506667zM563.157333 581.461333l18.410667-38.506666 41.109333 19.648-18.410666 38.506666zM891.989333 738.730667l18.410667-38.506667 41.109333 19.648-18.410666 38.528zM1011.882667 748.8l-19.2-9.194667-5.952 12.437334-12.458667 5.952 4.821333 10.048-4.821333 10.048 12.458667 5.952 5.952 12.437333 19.2-9.194667a21.333333 21.333333 0 0 0 0-38.4zM809.813333 836.608l41.088-19.648 18.432 38.506667-41.109333 19.669333zM645.354667 915.242667l41.109333-19.669334 18.432 38.506667-41.109333 19.669333zM727.552 875.925333l41.109333-19.669333 18.410667 38.485333-41.088 19.669334zM891.989333 797.248l41.109334-19.669333 18.432 38.506666-41.109334 19.669334zM563.157333 954.56l41.109334-19.669333 18.410666 38.506666-41.109333 19.669334zM512 979.029333l-10.048-4.821333-18.410667 38.4 19.2 9.194667a21.333333 21.333333 0 0 0 18.432 0l19.2-9.194667-18.410666-38.4zM72.490667 816.128l18.410666-38.528 41.109334 19.669333-18.410667 38.506667zM154.666667 855.424l18.432-38.506667 41.109333 19.648-18.410667 38.506667zM236.906667 894.72l18.410666-38.485333 41.109334 19.669333-18.410667 38.485333zM401.322667 973.397333l18.432-38.506666 41.109333 19.648-18.432 38.528zM319.146667 934.058667l18.410666-38.506667 41.109334 19.648-18.410667 38.528zM510.72 300.373333l18.410667-38.528 38.485333 18.410667-18.432 38.506667zM356.714667 327.936l38.528-18.410667 18.410666 38.485334-38.528 18.432zM433.706667 291.114667l38.506666-18.410667 18.410667 38.528-38.485333 18.389333zM587.690667 337.173333L606.122667 298.666667l38.485333 18.410666-18.432 38.485334z" p-id="2935"></path><path d="M1011.882667 492.8L784.490667 384l227.392-108.8a21.333333 21.333333 0 0 0 0-38.4l-85.333334-40.810667-18.432 38.4L953.237333 256l-239.68 114.624 8-16.725333-38.4-18.389334-18.432 38.4 20.928 10.005334L512 467.029333l-176.384-84.352-17.365333-36.266666-29.290667 13.994666L70.762667 256 512 44.970667 770.496 168.533333l18.410667-38.4-267.690667-128a21.461333 21.461333 0 0 0-18.432 0l-490.666667 234.666667a21.333333 21.333333 0 0 0 0 38.4L239.509333 384l-48.96 23.466667 18.517334 38.4 80-38.250667L502.784 509.866667a21.333333 21.333333 0 0 0 18.432 0l213.824-102.250667L953.237333 512 686.933333 639.338667l17.898667-37.418667-41.109333-19.648-18.410667 38.4 40.213333 19.2L512 723.029333 338.432 640l40.213333-19.2-18.410666-38.4-41.109334 19.648 17.898667 37.418667L70.762667 512l93.610666-44.8-18.410666-38.4-133.845334 64a21.333333 21.333333 0 0 0 0 38.4l227.413334 108.8-2.624 1.258667 18.432 38.4 33.621333-16.085334L502.784 765.866667a21.333333 21.333333 0 0 0 18.432 0l213.824-102.272 33.642667 16.106666 18.432-38.4-2.645334-1.301333 227.413334-108.8a21.333333 21.333333 0 0 0 0-38.4z" p-id="2936"></path></svg>
6799
7426
  </button>
6800
7427
  `;
6801
7428
 
@@ -6823,6 +7450,9 @@ class CustomSearchSelectControl {
6823
7450
  openModal() {
6824
7451
  if (this._modal) return;
6825
7452
 
7453
+ // 获取高度设置
7454
+ const heightSettings = this.getModalHeightSettings();
7455
+
6826
7456
  // 创建遮罩层
6827
7457
  this._overlay = document.createElement('div');
6828
7458
  this._overlay.className = 'vector-layer-overlay';
@@ -6836,6 +7466,9 @@ class CustomSearchSelectControl {
6836
7466
  z-index: 9999;
6837
7467
  display: flex;
6838
7468
  justify-content: center;
7469
+ align-items: center;
7470
+ padding: 10px;
7471
+ box-sizing: border-box;
6839
7472
  backdrop-filter: blur(2px);
6840
7473
  `;
6841
7474
  this._overlay.addEventListener('click', (e) => {
@@ -6845,30 +7478,75 @@ class CustomSearchSelectControl {
6845
7478
  // 创建弹窗
6846
7479
  this._modal = document.createElement('div');
6847
7480
  this._modal.className = 'vector-layer-modal';
6848
- this._modal.style.cssText = `
6849
- background: white;
6850
- border-radius: 8px;
6851
- padding: ${this.options.compactMode ? '16px' : '20px'};
6852
- width: ${this.options.width};
6853
- max-width: 90vw;
6854
- max-height: ${this.options.maxHeight};
6855
- display: flex;
6856
- flex-direction: column;
6857
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
6858
- animation: vector-layer-modal-appear 0.2s ease-out;
6859
- border: 1px solid #e0e0e0;
6860
- `;
7481
+
7482
+ // 根据设备设置不同样式
7483
+ if (this._isMobile) {
7484
+ if (this._isLandscape) {
7485
+ // 横屏状态
7486
+ this._modal.style.cssText = `
7487
+ background: white;
7488
+ border-radius: 8px;
7489
+ padding: ${heightSettings.compact ? '12px' : '16px'};
7490
+ width: ${this._isLandscape ? '80vw' : '90vw'};
7491
+ max-width: ${this._isLandscape ? '600px' : '90vw'};
7492
+ max-height: ${heightSettings.maxHeight};
7493
+ height: ${heightSettings.modalHeight};
7494
+ display: flex;
7495
+ flex-direction: column;
7496
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
7497
+ animation: vector-layer-modal-appear 0.2s ease-out;
7498
+ border: 1px solid #e0e0e0;
7499
+ box-sizing: border-box;
7500
+ overflow: hidden;
7501
+ `;
7502
+ } else {
7503
+ // 竖屏状态
7504
+ this._modal.style.cssText = `
7505
+ background: white;
7506
+ border-radius: 8px;
7507
+ padding: ${heightSettings.compact ? '12px' : '16px'};
7508
+ width: 90vw;
7509
+ max-width: 500px;
7510
+ max-height: ${heightSettings.maxHeight};
7511
+ display: flex;
7512
+ flex-direction: column;
7513
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
7514
+ animation: vector-layer-modal-appear 0.2s ease-out;
7515
+ border: 1px solid #e0e0e0;
7516
+ box-sizing: border-box;
7517
+ overflow: hidden;
7518
+ `;
7519
+ }
7520
+ } else {
7521
+ // 桌面端
7522
+ this._modal.style.cssText = `
7523
+ background: white;
7524
+ border-radius: 8px;
7525
+ padding: ${heightSettings.compact ? '16px' : '20px'};
7526
+ width: ${this.options.width};
7527
+ max-width: 90vw;
7528
+ max-height: ${heightSettings.maxHeight};
7529
+ display: flex;
7530
+ flex-direction: column;
7531
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
7532
+ animation: vector-layer-modal-appear 0.2s ease-out;
7533
+ border: 1px solid #e0e0e0;
7534
+ box-sizing: border-box;
7535
+ overflow: hidden;
7536
+ `;
7537
+ }
6861
7538
 
6862
7539
  // 弹窗标题
6863
7540
  const title = document.createElement('h3');
6864
7541
  title.className = 'vector-layer-title';
6865
7542
  title.textContent = this.options.title;
6866
7543
  title.style.cssText = `
6867
- margin: 0 0 ${this.options.compactMode ? '12px' : '16px'} 0;
6868
- font-size: ${this.options.compactMode ? '15px' : '16px'};
7544
+ margin: 0 0 ${heightSettings.compact ? '12px' : '16px'} 0;
7545
+ font-size: ${heightSettings.compact ? '15px' : '16px'};
6869
7546
  font-weight: 600;
6870
7547
  color: #2c3e50;
6871
7548
  line-height: 1.3;
7549
+ flex-shrink: 0;
6872
7550
  `;
6873
7551
  this._modal.appendChild(title);
6874
7552
 
@@ -6877,8 +7555,9 @@ class CustomSearchSelectControl {
6877
7555
  const searchContainer = document.createElement('div');
6878
7556
  searchContainer.className = 'vector-layer-search';
6879
7557
  searchContainer.style.cssText = `
6880
- margin-bottom: ${this.options.compactMode ? '12px' : '16px'};
7558
+ margin-bottom: ${heightSettings.compact ? '12px' : '16px'};
6881
7559
  position: relative;
7560
+ flex-shrink: 0;
6882
7561
  `;
6883
7562
 
6884
7563
  this._searchInput = document.createElement('input');
@@ -6887,10 +7566,10 @@ class CustomSearchSelectControl {
6887
7566
  this._searchInput.className = 'vector-layer-search-input';
6888
7567
  this._searchInput.style.cssText = `
6889
7568
  width: 100%;
6890
- padding: ${this.options.compactMode ? '8px 12px 8px 36px' : '10px 16px 10px 40px'};
7569
+ padding: ${heightSettings.compact ? '8px 12px 8px 36px' : '10px 16px 10px 40px'};
6891
7570
  border: 1px solid #dcdfe6;
6892
7571
  border-radius: 6px;
6893
- font-size: 13px;
7572
+ font-size: ${heightSettings.compact ? '13px' : '14px'};
6894
7573
  outline: none;
6895
7574
  transition: all 0.2s;
6896
7575
  box-sizing: border-box;
@@ -6922,17 +7601,21 @@ class CustomSearchSelectControl {
6922
7601
  listContainer.style.cssText = `
6923
7602
  flex: 1;
6924
7603
  overflow: hidden;
6925
- min-height: ${this.options.compactMode ? '120px' : '160px'};
7604
+ min-height: ${heightSettings.compact ? '100px' : '120px'};
6926
7605
  border-radius: 6px;
6927
7606
  border: 1px solid #e0e0e0;
7607
+ display: flex;
7608
+ flex-direction: column;
6928
7609
  `;
6929
7610
 
6930
7611
  this._optionsList = document.createElement('div');
6931
7612
  this._optionsList.className = 'vector-layer-options';
6932
7613
  this._optionsList.style.cssText = `
6933
- max-height: calc(${this.options.maxHeight} - ${this.options.compactMode ? '140px' : '180px'});
7614
+ flex: 1;
6934
7615
  overflow-y: auto;
6935
7616
  scroll-behavior: smooth;
7617
+ max-height: ${heightSettings.listMaxHeight};
7618
+ min-height: ${heightSettings.compact ? '80px' : '100px'};
6936
7619
  `;
6937
7620
 
6938
7621
  // 填充选项
@@ -6948,24 +7631,27 @@ class CustomSearchSelectControl {
6948
7631
  display: flex;
6949
7632
  justify-content: flex-end;
6950
7633
  gap: 8px;
6951
- margin-top: ${this.options.compactMode ? '12px' : '16px'};
6952
- padding-top: ${this.options.compactMode ? '12px' : '16px'};
7634
+ margin-top: ${heightSettings.compact ? '12px' : '16px'};
7635
+ padding-top: ${heightSettings.compact ? '12px' : '16px'};
6953
7636
  border-top: 1px solid #f0f0f0;
7637
+ flex-shrink: 0;
6954
7638
  `;
6955
7639
 
6956
7640
  const cancelBtn = document.createElement('button');
6957
7641
  cancelBtn.textContent = '取消';
6958
7642
  cancelBtn.className = 'vector-layer-cancel';
6959
7643
  cancelBtn.style.cssText = `
6960
- padding: 6px 16px;
7644
+ padding: ${this._isMobile ? '6px 12px' : '6px 16px'};
6961
7645
  border: 1px solid #dcdfe6;
6962
7646
  border-radius: 4px;
6963
7647
  background: white;
6964
7648
  color: #606266;
6965
7649
  cursor: pointer;
6966
- font-size: 13px;
7650
+ font-size: ${this._isMobile ? '12px' : '13px'};
6967
7651
  transition: all 0.2s;
6968
7652
  font-weight: 500;
7653
+ min-width: 60px;
7654
+ box-sizing: border-box;
6969
7655
  `;
6970
7656
  cancelBtn.addEventListener('click', () => {
6971
7657
  this.closeModal();
@@ -6979,6 +7665,12 @@ class CustomSearchSelectControl {
6979
7665
  cancelBtn.style.backgroundColor = 'white';
6980
7666
  cancelBtn.style.borderColor = '#dcdfe6';
6981
7667
  });
7668
+ cancelBtn.addEventListener('touchstart', () => {
7669
+ cancelBtn.style.backgroundColor = '#f5f7fa';
7670
+ });
7671
+ cancelBtn.addEventListener('touchend', () => {
7672
+ cancelBtn.style.backgroundColor = 'white';
7673
+ });
6982
7674
 
6983
7675
  buttonContainer.appendChild(cancelBtn);
6984
7676
  this._modal.appendChild(buttonContainer);
@@ -6990,6 +7682,30 @@ class CustomSearchSelectControl {
6990
7682
  this._modal.addEventListener('click', (e) => e.stopPropagation());
6991
7683
  this._modal.addEventListener('mousedown', (e) => e.stopPropagation());
6992
7684
  this._modal.addEventListener('mouseup', (e) => e.stopPropagation());
7685
+ this._modal.addEventListener('touchstart', (e) => e.stopPropagation());
7686
+ this._modal.addEventListener('touchend', (e) => e.stopPropagation());
7687
+
7688
+ // 处理窗口大小变化
7689
+ this._handleResize = () => {
7690
+ const newHeightSettings = this.getModalHeightSettings();
7691
+ if (this._modal) {
7692
+ if (this._isMobile && this._isLandscape) {
7693
+ this._modal.style.maxHeight = newHeightSettings.maxHeight;
7694
+ this._modal.style.height = newHeightSettings.modalHeight;
7695
+ this._optionsList.style.maxHeight = newHeightSettings.listMaxHeight;
7696
+ } else if (this._isMobile) {
7697
+ this._modal.style.maxHeight = newHeightSettings.maxHeight;
7698
+ this._modal.style.height = 'auto';
7699
+ this._optionsList.style.maxHeight = newHeightSettings.listMaxHeight;
7700
+ }
7701
+ }
7702
+ };
7703
+
7704
+ window.addEventListener('resize', this._handleResize);
7705
+ window.addEventListener('orientationchange', this._handleResize);
7706
+
7707
+ // 添加触摸事件支持
7708
+ this.addTouchSupport();
6993
7709
 
6994
7710
  // 聚焦搜索框
6995
7711
  if (this._searchInput) {
@@ -7000,6 +7716,18 @@ class CustomSearchSelectControl {
7000
7716
  this.addStyles();
7001
7717
  }
7002
7718
 
7719
+ /**
7720
+ * 添加触摸支持
7721
+ */
7722
+ addTouchSupport() {
7723
+ if (this._modal) {
7724
+ // 防止弹窗内滚动传播到body
7725
+ this._modal.addEventListener('touchmove', (e) => {
7726
+ e.stopPropagation();
7727
+ }, { passive: false });
7728
+ }
7729
+ }
7730
+
7003
7731
  /**
7004
7732
  * 渲染选项列表
7005
7733
  */
@@ -7016,6 +7744,10 @@ class CustomSearchSelectControl {
7016
7744
  color: #999;
7017
7745
  font-size: 13px;
7018
7746
  font-style: italic;
7747
+ display: flex;
7748
+ align-items: center;
7749
+ justify-content: center;
7750
+ height: 100px;
7019
7751
  `;
7020
7752
  this._optionsList.appendChild(emptyItem);
7021
7753
  return;
@@ -7027,29 +7759,44 @@ class CustomSearchSelectControl {
7027
7759
  option.dataset.value = item.value || item.label;
7028
7760
  option.dataset.index = index;
7029
7761
  option.style.cssText = `
7030
- padding: ${this.options.compactMode ? '8px 12px' : '10px 16px'};
7762
+ padding: ${this._isMobile ? '8px 10px' : '8px 12px'};
7031
7763
  cursor: pointer;
7032
7764
  border-bottom: 1px solid #f5f5f5;
7033
- font-size: 13px;
7765
+ font-size: ${this._isMobile ? '12px' : '13px'};
7034
7766
  transition: all 0.15s;
7035
7767
  display: flex;
7036
7768
  align-items: center;
7037
7769
  gap: 8px;
7038
- min-height: ${this.options.compactMode ? '36px' : '40px'};
7770
+ min-height: ${this._isMobile ? '40px' : '36px'};
7039
7771
  box-sizing: border-box;
7772
+ -webkit-tap-highlight-color: transparent;
7040
7773
  `;
7041
7774
 
7042
7775
  option.innerHTML = `
7043
7776
  ${item.icon ? `<span class="option-icon" style="flex-shrink: 0; width: 16px; height: 16px;">${item.icon}</span>` : ''}
7044
7777
  <span class="option-label" style="flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${item.label}</span>
7045
- ${item.description ? `<span class="option-desc" style="font-size: 12px; color: #888; flex-shrink: 0;">${item.description}</span>` : ''}
7778
+ ${item.description ? `<span class="option-desc" style="font-size: 11px; color: #888; flex-shrink: 0; display: ${this._isMobile && this._isLandscape ? 'none' : 'block'}">${item.description}</span>` : ''}
7046
7779
  `;
7047
7780
 
7781
+ // 点击事件
7048
7782
  option.addEventListener('click', () => this.selectOption(item));
7783
+
7784
+ // 触摸事件
7785
+ option.addEventListener('touchstart', () => {
7786
+ option.style.backgroundColor = '#f0f7ff';
7787
+ option.style.borderLeftColor = '#1890ff';
7788
+ });
7789
+
7790
+ option.addEventListener('touchend', () => {
7791
+ option.style.backgroundColor = '';
7792
+ option.style.borderLeftColor = '';
7793
+ });
7794
+
7049
7795
  option.addEventListener('mouseenter', () => {
7050
7796
  option.style.backgroundColor = '#f0f7ff';
7051
7797
  option.style.borderLeftColor = '#1890ff';
7052
7798
  });
7799
+
7053
7800
  option.addEventListener('mouseleave', () => {
7054
7801
  option.style.backgroundColor = '';
7055
7802
  option.style.borderLeftColor = '';
@@ -7120,6 +7867,12 @@ class CustomSearchSelectControl {
7120
7867
  * 关闭弹窗
7121
7868
  */
7122
7869
  closeModal() {
7870
+ // 移除事件监听
7871
+ if (this._handleResize) {
7872
+ window.removeEventListener('resize', this._handleResize);
7873
+ window.removeEventListener('orientationchange', this._handleResize);
7874
+ }
7875
+
7123
7876
  if (this._overlay) {
7124
7877
  this._overlay.style.opacity = '0';
7125
7878
  this._overlay.style.transition = 'opacity 0.15s ease-out';
@@ -7132,6 +7885,7 @@ class CustomSearchSelectControl {
7132
7885
  this._modal = null;
7133
7886
  this._searchInput = null;
7134
7887
  this._optionsList = null;
7888
+ this._handleResize = null;
7135
7889
  }, 150);
7136
7890
  }
7137
7891
  }
@@ -7172,8 +7926,8 @@ class CustomSearchSelectControl {
7172
7926
  background: white;
7173
7927
  border: 1px solid #d9d9d9;
7174
7928
  border-radius: 4px;
7175
- width: 28px;
7176
- height: 28px;
7929
+ width: 29px;
7930
+ height: 29px;
7177
7931
  display: flex;
7178
7932
  align-items: center;
7179
7933
  justify-content: center;
@@ -7232,25 +7986,65 @@ class CustomSearchSelectControl {
7232
7986
  overflow: hidden;
7233
7987
  }
7234
7988
 
7235
- /* 紧凑模式下的额外样式 */
7236
- .vector-layer-modal.compact {
7237
- padding: 12px;
7238
- }
7239
-
7240
- .vector-layer-modal.compact .vector-layer-title {
7241
- font-size: 14px;
7242
- margin-bottom: 10px;
7989
+ /* 移动端优化 */
7990
+ @media (max-width: 768px) {
7991
+ .vector-layer-modal {
7992
+ width: 90vw !important;
7993
+ max-width: 500px !important;
7994
+ }
7995
+
7996
+ .vector-layer-option {
7997
+ padding: 10px 12px;
7998
+ min-height: 44px;
7999
+ }
8000
+
8001
+ .vector-layer-actions {
8002
+ padding: 12px 0 0 0;
8003
+ }
8004
+
8005
+ .vector-layer-cancel {
8006
+ padding: 8px 16px;
8007
+ font-size: 14px;
8008
+ }
7243
8009
  }
7244
8010
 
7245
- .vector-layer-modal.compact .vector-layer-search-input {
7246
- padding: 6px 10px 6px 32px;
7247
- font-size: 12px;
8011
+ /* 横屏优化 */
8012
+ @media (max-width: 768px) and (orientation: landscape) {
8013
+ .vector-layer-modal {
8014
+ width: 80vw !important;
8015
+ max-height: 70vh !important;
8016
+ height: calc(100vh - 20px) !important;
8017
+ }
8018
+
8019
+ .vector-layer-list-container {
8020
+ min-height: 40vh !important;
8021
+ }
8022
+
8023
+ .vector-layer-options {
8024
+ max-height: calc(70vh - 120px) !important;
8025
+ }
8026
+
8027
+ .option-desc {
8028
+ display: none !important;
8029
+ }
7248
8030
  }
7249
8031
 
7250
- .vector-layer-modal.compact .vector-layer-option {
7251
- padding: 6px 10px;
7252
- font-size: 12px;
7253
- min-height: 32px;
8032
+ /* 小屏幕手机 */
8033
+ @media (max-width: 480px) {
8034
+ .vector-layer-modal {
8035
+ width: 95vw !important;
8036
+ padding: 12px !important;
8037
+ }
8038
+
8039
+ .vector-layer-title {
8040
+ font-size: 14px !important;
8041
+ margin-bottom: 10px !important;
8042
+ }
8043
+
8044
+ .vector-layer-search-input {
8045
+ padding: 6px 10px 6px 32px !important;
8046
+ font-size: 12px !important;
8047
+ }
7254
8048
  }
7255
8049
 
7256
8050
  /* 暗色模式支持 */
@@ -7309,12 +8103,661 @@ class CustomSearchSelectControl {
7309
8103
  background: #666;
7310
8104
  }
7311
8105
  }
8106
+
8107
+ /* 防止iOS上的回弹效果 */
8108
+ .vector-layer-overlay {
8109
+ overscroll-behavior: contain;
8110
+ }
8111
+
8112
+ /* 触摸优化 */
8113
+ .vector-layer-option {
8114
+ -webkit-tap-highlight-color: transparent;
8115
+ }
8116
+
8117
+ .vector-layer-cancel {
8118
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0.1);
8119
+ }
7312
8120
  `;
7313
8121
 
7314
8122
  document.head.appendChild(style);
7315
8123
  }
7316
8124
  }
7317
8125
 
8126
+ // class CustomOptionsControl {
8127
+ // constructor(args) {
8128
+ // const { title, options, onConfirm, icon } = args;
8129
+
8130
+ // this._map = null;
8131
+ // this._container = null;
8132
+
8133
+ // this._title = title || '';
8134
+ // this._options = options || [];
8135
+ // this._icon = icon || null;
8136
+ // this._onConfirm = onConfirm || (() => { });
8137
+ // this._originalOptions = [...this._options];
8138
+ // this._selectedOptions = [];
8139
+ // }
8140
+
8141
+ // onAdd(map) {
8142
+ // this._map = map;
8143
+
8144
+ // this._container = document.createElement('div');
8145
+ // this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group custom-options-control';
8146
+
8147
+ // const mainButton = document.createElement('button');
8148
+ // mainButton.style.cssText = `
8149
+ // padding: 0;
8150
+ // background: white;
8151
+ // border: 0.0625rem solid #ccc;
8152
+ // cursor: pointer;
8153
+ // display: flex;
8154
+ // align-items: center;
8155
+ // justify-content: center;
8156
+ // gap: 0.375rem;
8157
+ // `;
8158
+
8159
+ // if (this._icon) {
8160
+ // const iconWrapper = document.createElement('span');
8161
+ // iconWrapper.style.cssText = `
8162
+ // width: 1rem;
8163
+ // height: 1rem;
8164
+ // display: inline-flex;
8165
+ // align-items: center;
8166
+ // justify-content: center;
8167
+ // `;
8168
+
8169
+ // if (this._icon.trim().startsWith('<svg')) {
8170
+ // iconWrapper.innerHTML = this._icon;
8171
+ // } else {
8172
+ // const img = document.createElement('img');
8173
+ // img.src = this._icon;
8174
+ // img.style.cssText = `width: 1rem; height: 1rem; object-fit: contain;`;
8175
+ // iconWrapper.appendChild(img);
8176
+ // }
8177
+
8178
+ // mainButton.appendChild(iconWrapper);
8179
+ // }
8180
+
8181
+ // mainButton.addEventListener('click', () => {
8182
+ // this._showModal();
8183
+ // });
8184
+
8185
+ // this._container.appendChild(mainButton);
8186
+
8187
+ // // 添加全局样式
8188
+ // this._addGlobalStyles();
8189
+
8190
+ // return this._container;
8191
+ // }
8192
+
8193
+ // _addGlobalStyles() {
8194
+ // if (document.querySelector('#custom-options-styles')) return;
8195
+
8196
+ // const styles = document.createElement('style');
8197
+ // styles.id = 'custom-options-styles';
8198
+ // styles.textContent = `
8199
+ // @keyframes modalSlideIn {
8200
+ // from {
8201
+ // opacity: 0;
8202
+ // transform: scale(0.95) translateY(-20px);
8203
+ // }
8204
+ // to {
8205
+ // opacity: 1;
8206
+ // transform: scale(1) translateY(0);
8207
+ // }
8208
+ // }
8209
+
8210
+ // @keyframes modalBackdropFadeIn {
8211
+ // from { opacity: 0; }
8212
+ // to { opacity: 1; }
8213
+ // }
8214
+
8215
+ // @keyframes fadeInUp {
8216
+ // from {
8217
+ // opacity: 0;
8218
+ // transform: translateY(20px);
8219
+ // }
8220
+ // to {
8221
+ // opacity: 1;
8222
+ // transform: translateY(0);
8223
+ // }
8224
+ // }
8225
+
8226
+ // .custom-modal-overlay {
8227
+ // animation: modalBackdropFadeIn 0.2s ease-out;
8228
+ // }
8229
+
8230
+ // .custom-modal {
8231
+ // animation: modalSlideIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
8232
+ // }
8233
+
8234
+ // .custom-search-input:focus {
8235
+ // border-color: #667eea !important;
8236
+ // box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
8237
+ // }
8238
+
8239
+ // .custom-checkbox {
8240
+ // position: relative;
8241
+ // appearance: none;
8242
+ // width: 1rem;
8243
+ // height: 1rem;
8244
+ // border: 2px solid #d1d5db;
8245
+ // border-radius: 0.25rem;
8246
+ // background: white;
8247
+ // cursor: pointer;
8248
+ // transition: all 0.2s ease;
8249
+ // margin-right: 0.75rem;
8250
+ // }
8251
+
8252
+ // .custom-checkbox:checked {
8253
+ // background: linear-gradient(135deg, #667eea, #764ba2);
8254
+ // border-color: #667eea;
8255
+ // }
8256
+
8257
+ // .custom-checkbox:checked::after {
8258
+ // content: '✓';
8259
+ // position: absolute;
8260
+ // top: 50%;
8261
+ // left: 50%;
8262
+ // transform: translate(-50%, -50%);
8263
+ // color: white;
8264
+ // font-size: 0.75rem;
8265
+ // font-weight: bold;
8266
+ // }
8267
+
8268
+ // .custom-checkbox:hover {
8269
+ // border-color: #667eea;
8270
+ // box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
8271
+ // }
8272
+
8273
+ // .custom-list-item {
8274
+ // transition: all 0.2s ease;
8275
+ // }
8276
+
8277
+ // .custom-list-item:hover {
8278
+ // background-color: #f8fafc !important;
8279
+ // border-color: #e2e8f0 !important;
8280
+ // transform: translateX(4px) !important;
8281
+ // }
8282
+
8283
+ // .custom-modal::-webkit-scrollbar {
8284
+ // width: 6px;
8285
+ // }
8286
+
8287
+ // .custom-modal::-webkit-scrollbar-track {
8288
+ // background: #f1f5f9;
8289
+ // border-radius: 3px;
8290
+ // }
8291
+
8292
+ // .custom-modal::-webkit-scrollbar-thumb {
8293
+ // background: linear-gradient(135deg, #667eea, #764ba2);
8294
+ // border-radius: 3px;
8295
+ // }
8296
+
8297
+ // .custom-modal::-webkit-scrollbar-thumb:hover {
8298
+ // background: linear-gradient(135deg, #5a67d8, #6b46c1);
8299
+ // }
8300
+ // `;
8301
+ // document.head.appendChild(styles);
8302
+ // }
8303
+
8304
+ // _showModal() {
8305
+ // this._overlay = document.createElement('div');
8306
+ // this._overlay.className = 'custom-modal-overlay';
8307
+ // this._overlay.style.cssText = `
8308
+ // position: fixed;
8309
+ // top: 0; left: 0; right: 0; bottom: 0;
8310
+ // background: rgba(0, 0, 0, 0.5);
8311
+ // backdrop-filter: blur(4px);
8312
+ // -webkit-backdrop-filter: blur(4px);
8313
+ // z-index: 10000;
8314
+ // display: flex;
8315
+ // justify-content: center;
8316
+ // align-items: center;
8317
+ // padding: 1rem;
8318
+ // font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
8319
+ // `;
8320
+
8321
+ // this._modal = document.createElement('div');
8322
+ // this._modal.className = 'custom-modal';
8323
+ // this._modal.style.cssText = `
8324
+ // width: 100%;
8325
+ // max-width: 26rem;
8326
+ // max-height: 80vh;
8327
+ // background: linear-gradient(145deg, #ffffff 0%, #f8fafc 100%);
8328
+ // border-radius: 0.75rem;
8329
+ // box-shadow:
8330
+ // 0 20px 25px -5px rgba(0, 0, 0, 0.1),
8331
+ // 0 10px 10px -5px rgba(0, 0, 0, 0.04);
8332
+ // border: 1px solid rgba(255, 255, 255, 0.8);
8333
+ // overflow: hidden;
8334
+ // display: flex;
8335
+ // flex-direction: column;
8336
+ // `;
8337
+
8338
+ // // 创建头部
8339
+ // const header = this._createHeader();
8340
+ // this._modal.appendChild(header);
8341
+
8342
+ // // 创建搜索区域
8343
+ // const searchSection = this._createSearchSection();
8344
+ // this._modal.appendChild(searchSection);
8345
+
8346
+ // // 创建选项列表
8347
+ // this._listBox = document.createElement('div');
8348
+ // this._listBox.style.cssText = `
8349
+ // flex: 1;
8350
+ // overflow-y: auto;
8351
+ // padding: 0 1.25rem 1.25rem 1.25rem;
8352
+ // min-height: 10rem;
8353
+ // `;
8354
+ // this._modal.appendChild(this._listBox);
8355
+
8356
+ // // 创建底部按钮
8357
+ // const footer = this._createFooter();
8358
+ // this._modal.appendChild(footer);
8359
+
8360
+ // this._overlay.appendChild(this._modal);
8361
+ // document.body.appendChild(this._overlay);
8362
+
8363
+ // // 聚焦搜索框
8364
+ // // setTimeout(() => {
8365
+ // // const searchInput = this._modal.querySelector('.custom-search-input');
8366
+ // // if (searchInput) {
8367
+ // // searchInput.focus();
8368
+ // // }
8369
+ // // }, 100);
8370
+
8371
+ // // 点击遮罩关闭
8372
+ // this._overlay.addEventListener('click', (e) => {
8373
+ // if (e.target === this._overlay) {
8374
+ // this._closeModal();
8375
+ // }
8376
+ // });
8377
+
8378
+ // // ESC 键关闭
8379
+ // this._handleKeydown = (e) => {
8380
+ // if (e.key === 'Escape') {
8381
+ // this._closeModal();
8382
+ // }
8383
+ // };
8384
+ // document.addEventListener('keydown', this._handleKeydown);
8385
+
8386
+ // this._renderList('');
8387
+ // }
8388
+
8389
+ // _createHeader() {
8390
+ // const header = document.createElement('div');
8391
+ // header.style.cssText = `
8392
+ // padding: 1.25rem 1.25rem 1rem 1.25rem;
8393
+ // border-bottom: 1px solid #e2e8f0;
8394
+ // background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
8395
+ // `;
8396
+
8397
+ // const title = document.createElement('h2');
8398
+ // title.textContent = this._title;
8399
+ // title.style.cssText = `
8400
+ // margin: 0 0 0.5rem 0;
8401
+ // font-size: 1.125rem;
8402
+ // font-weight: 600;
8403
+ // color: #1e293b;
8404
+ // display: flex;
8405
+ // align-items: center;
8406
+ // gap: 0.5rem;
8407
+ // `;
8408
+
8409
+ // // 添加图标
8410
+ // const icon = document.createElement('span');
8411
+ // icon.innerHTML = '📋';
8412
+ // icon.style.fontSize = '1.25rem';
8413
+ // title.insertBefore(icon, title.firstChild);
8414
+
8415
+ // const subtitle = document.createElement('p');
8416
+ // subtitle.textContent = `共 ${this._originalOptions.length} 个选项,已选择 ${this._selectedOptions.length} 个`;
8417
+ // subtitle.style.cssText = `
8418
+ // margin: 0;
8419
+ // font-size: 0.8125rem;
8420
+ // color: #64748b;
8421
+ // `;
8422
+
8423
+ // const closeBtn = document.createElement('button');
8424
+ // closeBtn.innerHTML = '✕';
8425
+ // closeBtn.style.cssText = `
8426
+ // position: absolute;
8427
+ // top: 1rem;
8428
+ // right: 1rem;
8429
+ // width: 1.75rem;
8430
+ // height: 1.75rem;
8431
+ // border: none;
8432
+ // background: #f1f5f9;
8433
+ // color: #64748b;
8434
+ // border-radius: 50%;
8435
+ // cursor: pointer;
8436
+ // display: flex;
8437
+ // align-items: center;
8438
+ // justify-content: center;
8439
+ // font-size: 0.875rem;
8440
+ // transition: all 0.2s ease;
8441
+ // font-weight: 500;
8442
+ // `;
8443
+ // closeBtn.addEventListener('mouseenter', () => {
8444
+ // closeBtn.style.background = '#ef4444';
8445
+ // closeBtn.style.color = 'white';
8446
+ // closeBtn.style.transform = 'rotate(90deg)';
8447
+ // });
8448
+ // closeBtn.addEventListener('mouseleave', () => {
8449
+ // closeBtn.style.background = '#f1f5f9';
8450
+ // closeBtn.style.color = '#64748b';
8451
+ // closeBtn.style.transform = 'rotate(0deg)';
8452
+ // });
8453
+ // closeBtn.addEventListener('click', () => this._closeModal());
8454
+
8455
+ // header.style.position = 'relative';
8456
+ // header.appendChild(title);
8457
+ // header.appendChild(subtitle);
8458
+ // header.appendChild(closeBtn);
8459
+
8460
+ // return header;
8461
+ // }
8462
+
8463
+ // _createSearchSection() {
8464
+ // const section = document.createElement('div');
8465
+ // section.style.cssText = `
8466
+ // padding: 1.25rem 1.25rem 1rem 1.25rem;
8467
+ // `;
8468
+
8469
+ // const searchContainer = document.createElement('div');
8470
+ // searchContainer.style.cssText = `
8471
+ // position: relative;
8472
+ // `;
8473
+
8474
+ // const searchIcon = document.createElement('div');
8475
+ // searchIcon.innerHTML = '🔍';
8476
+ // searchIcon.style.cssText = `
8477
+ // position: absolute;
8478
+ // left: 0.875rem;
8479
+ // top: 50%;
8480
+ // transform: translateY(-50%);
8481
+ // font-size: 0.875rem;
8482
+ // color: #94a3b8;
8483
+ // pointer-events: none;
8484
+ // `;
8485
+
8486
+ // const searchInput = document.createElement('input');
8487
+ // searchInput.placeholder = '搜索选项...';
8488
+ // searchInput.className = 'custom-search-input';
8489
+ // searchInput.style.cssText = `
8490
+ // width: 100%;
8491
+ // padding: 0.75rem 1rem 0.75rem 2.5rem;
8492
+ // border: 2px solid #e2e8f0;
8493
+ // border-radius: 0.5rem;
8494
+ // font-size: 0.875rem;
8495
+ // background: white;
8496
+ // transition: all 0.3s ease;
8497
+ // box-sizing: border-box;
8498
+ // font-family: inherit;
8499
+ // outline: none;
8500
+ // `;
8501
+
8502
+ // searchInput.addEventListener('focus', () => {
8503
+ // searchInput.style.borderColor = '#667eea';
8504
+ // searchInput.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
8505
+ // });
8506
+
8507
+ // searchInput.addEventListener('blur', () => {
8508
+ // searchInput.style.borderColor = '#e2e8f0';
8509
+ // searchInput.style.boxShadow = 'none';
8510
+ // });
8511
+
8512
+ // searchInput.addEventListener('input', (e) => {
8513
+ // this._renderList(e.target.value);
8514
+ // });
8515
+
8516
+ // searchContainer.appendChild(searchIcon);
8517
+ // searchContainer.appendChild(searchInput);
8518
+ // section.appendChild(searchContainer);
8519
+
8520
+ // return section;
8521
+ // }
8522
+
8523
+ // _createFooter() {
8524
+ // const footer = document.createElement('div');
8525
+ // footer.style.cssText = `
8526
+ // padding: 1rem 1.25rem;
8527
+ // background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
8528
+ // border-top: 1px solid #e2e8f0;
8529
+ // display: flex;
8530
+ // justify-content: flex-end;
8531
+ // gap: 0.75rem;
8532
+ // `;
8533
+
8534
+ // const cancelBtn = document.createElement('button');
8535
+ // cancelBtn.textContent = '取消';
8536
+ // cancelBtn.style.cssText = `
8537
+ // padding: 0.5rem 1rem;
8538
+ // background: white;
8539
+ // border: 1px solid #d1d5db;
8540
+ // border-radius: 0.375rem;
8541
+ // cursor: pointer;
8542
+ // font-size: 0.875rem;
8543
+ // font-weight: 500;
8544
+ // color: #374151;
8545
+ // transition: all 0.2s ease;
8546
+ // font-family: inherit;
8547
+ // `;
8548
+ // cancelBtn.addEventListener('mouseenter', () => {
8549
+ // cancelBtn.style.borderColor = '#ef4444';
8550
+ // cancelBtn.style.color = '#ef4444';
8551
+ // cancelBtn.style.transform = 'translateY(-1px)';
8552
+ // });
8553
+ // cancelBtn.addEventListener('mouseleave', () => {
8554
+ // cancelBtn.style.borderColor = '#d1d5db';
8555
+ // cancelBtn.style.color = '#374151';
8556
+ // cancelBtn.style.transform = 'translateY(0)';
8557
+ // });
8558
+ // cancelBtn.addEventListener('click', () => this._closeModal());
8559
+
8560
+ // const okBtn = document.createElement('button');
8561
+ // okBtn.textContent = '确定';
8562
+ // okBtn.style.cssText = `
8563
+ // padding: 0.5rem 1rem;
8564
+ // background: #007cba;
8565
+ // color: white;
8566
+ // border: none;
8567
+ // border-radius: 0.375rem;
8568
+ // cursor: pointer;
8569
+ // font-size: 0.875rem;
8570
+ // font-weight: 500;
8571
+ // transition: all 0.2s ease;
8572
+ // font-family: inherit;
8573
+ // box-shadow: 0 2px 4px rgba(0, 124, 186, 0.2);
8574
+ // `;
8575
+ // okBtn.addEventListener('mouseenter', () => {
8576
+ // okBtn.style.background = '#005a87';
8577
+ // okBtn.style.transform = 'translateY(-1px)';
8578
+ // okBtn.style.boxShadow = '0 4px 8px rgba(0, 124, 186, 0.3)';
8579
+ // });
8580
+ // okBtn.addEventListener('mouseleave', () => {
8581
+ // okBtn.style.background = '#007cba';
8582
+ // okBtn.style.transform = 'translateY(0)';
8583
+ // okBtn.style.boxShadow = '0 2px 4px rgba(0, 124, 186, 0.2)';
8584
+ // });
8585
+ // okBtn.addEventListener('click', () => this._confirm());
8586
+
8587
+ // footer.appendChild(cancelBtn);
8588
+ // footer.appendChild(okBtn);
8589
+ // return footer;
8590
+ // }
8591
+
8592
+ // _renderList(keyword) {
8593
+ // this._listBox.innerHTML = '';
8594
+
8595
+ // const list = keyword
8596
+ // ? this._originalOptions.filter(
8597
+ // (o) =>
8598
+ // o.label.toLowerCase().includes(keyword.toLowerCase()) ||
8599
+ // String(o.value).toLowerCase().includes(keyword.toLowerCase())
8600
+ // )
8601
+ // : this._originalOptions;
8602
+
8603
+ // if (list.length === 0) {
8604
+ // const empty = document.createElement('div');
8605
+ // empty.style.cssText = `
8606
+ // text-align: center;
8607
+ // padding: 2.5rem 1rem;
8608
+ // color: #94a3b8;
8609
+ // `;
8610
+ // empty.innerHTML = `
8611
+ // <div style="font-size: 2.5rem; margin-bottom: 0.75rem; opacity: 0.6;">🔍</div>
8612
+ // <div style="font-size: 1rem; font-weight: 500; margin-bottom: 0.25rem; color: #64748b;">未找到相关结果</div>
8613
+ // <div style="font-size: 0.8125rem;">尝试使用其他关键词搜索</div>
8614
+ // `;
8615
+ // this._listBox.appendChild(empty);
8616
+ // return;
8617
+ // }
8618
+
8619
+ // // 添加选项统计
8620
+ // const stats = document.createElement('div');
8621
+ // stats.style.cssText = `
8622
+ // padding: 0.5rem 0;
8623
+ // font-size: 0.8125rem;
8624
+ // color: #64748b;
8625
+ // border-bottom: 1px solid #f1f5f9;
8626
+ // margin-bottom: 0.5rem;
8627
+ // `;
8628
+ // stats.textContent = `找到 ${list.length} 个相关选项`;
8629
+ // this._listBox.appendChild(stats);
8630
+
8631
+ // list.forEach((opt, index) => {
8632
+ // const item = document.createElement('label');
8633
+ // item.className = 'custom-list-item';
8634
+ // item.style.cssText = `
8635
+ // display: flex;
8636
+ // align-items: center;
8637
+ // padding: 0.75rem;
8638
+ // cursor: pointer;
8639
+ // border-radius: 0.5rem;
8640
+ // margin-bottom: 0.375rem;
8641
+ // transition: all 0.2s ease;
8642
+ // border: 2px solid transparent;
8643
+ // background: white;
8644
+ // position: relative;
8645
+ // overflow: hidden;
8646
+ // `;
8647
+
8648
+ // const checkbox = document.createElement('input');
8649
+ // checkbox.type = 'checkbox';
8650
+ // checkbox.className = 'custom-checkbox';
8651
+ // checkbox.value = opt.value;
8652
+ // checkbox.checked = this._selectedOptions.includes(opt.value);
8653
+ // checkbox.style.marginRight = '0.75rem';
8654
+
8655
+ // const labelSpan = document.createElement('span');
8656
+ // labelSpan.innerHTML = this._highlight(opt.label, keyword);
8657
+ // labelSpan.style.cssText = `
8658
+ // flex: 1;
8659
+ // font-size: 0.875rem;
8660
+ // color: #374151;
8661
+ // line-height: 1.4;
8662
+ // font-weight: 500;
8663
+ // `;
8664
+
8665
+ // // 添加选中状态的视觉反馈
8666
+ // if (checkbox.checked) {
8667
+ // item.style.backgroundColor = '#f0f4ff';
8668
+ // item.style.borderColor = '#667eea';
8669
+ // }
8670
+
8671
+ // checkbox.addEventListener('change', () => {
8672
+ // this._toggle(opt.value);
8673
+
8674
+ // // 更新项目样式
8675
+ // if (checkbox.checked) {
8676
+ // item.style.backgroundColor = '#f0f4ff';
8677
+ // item.style.borderColor = '#667eea';
8678
+ // } else {
8679
+ // item.style.backgroundColor = 'white';
8680
+ // item.style.borderColor = 'transparent';
8681
+ // }
8682
+
8683
+ // // 更新标题中的统计信息
8684
+ // const subtitle = this._modal.querySelector('p');
8685
+ // if (subtitle) {
8686
+ // subtitle.textContent = `共 ${this._originalOptions.length} 个选项,已选择 ${this._selectedOptions.length} 个`;
8687
+ // }
8688
+ // });
8689
+
8690
+ // item.appendChild(checkbox);
8691
+ // item.appendChild(labelSpan);
8692
+
8693
+ // // 添加进入动画
8694
+ // item.style.opacity = '0';
8695
+ // item.style.transform = 'translateY(10px)';
8696
+ // this._listBox.appendChild(item);
8697
+
8698
+ // setTimeout(() => {
8699
+ // item.style.transition = 'all 0.3s ease';
8700
+ // item.style.opacity = '1';
8701
+ // item.style.transform = 'translateY(0)';
8702
+ // }, index * 30);
8703
+ // });
8704
+ // }
8705
+
8706
+ // _highlight(text, key) {
8707
+ // if (!key) return text;
8708
+ // const regex = new RegExp(`(${this._escapeRegExp(key)})`, 'gi');
8709
+ // 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>');
8710
+ // }
8711
+
8712
+ // _escapeRegExp(string) {
8713
+ // return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
8714
+ // }
8715
+
8716
+ // _toggle(value) {
8717
+ // const index = this._selectedOptions.indexOf(value);
8718
+ // if (index >= 0) {
8719
+ // this._selectedOptions.splice(index, 1);
8720
+ // } else {
8721
+ // this._selectedOptions.push(value);
8722
+ // }
8723
+ // }
8724
+
8725
+ // _confirm() {
8726
+ // this._onConfirm({
8727
+ // selectedOptions: this._selectedOptions,
8728
+ // unselectedOptions: this._originalOptions.filter(
8729
+ // (o) => !this._selectedOptions.includes(o.value)
8730
+ // ),
8731
+ // allOptions: this._originalOptions
8732
+ // });
8733
+ // this._closeModal();
8734
+ // }
8735
+
8736
+ // _closeModal() {
8737
+ // if (this._overlay) {
8738
+ // // 添加退出动画
8739
+ // this._modal.style.animation = 'modalSlideIn 0.2s ease-out reverse';
8740
+ // this._overlay.style.animation = 'modalBackdropFadeIn 0.2s ease-out reverse';
8741
+
8742
+ // setTimeout(() => {
8743
+ // if (this._overlay && this._overlay.parentNode) {
8744
+ // document.body.removeChild(this._overlay);
8745
+ // }
8746
+ // this._overlay = null;
8747
+ // this._modal = null;
8748
+ // }, 200);
8749
+
8750
+ // document.removeEventListener('keydown', this._handleKeydown);
8751
+ // }
8752
+ // }
8753
+
8754
+ // onRemove() {
8755
+ // if (this._container) {
8756
+ // this._container.remove();
8757
+ // }
8758
+ // this._closeModal();
8759
+ // }
8760
+ // }
7318
8761
  class CustomOptionsControl {
7319
8762
  constructor(args) {
7320
8763
  const { title, options, onConfirm, icon } = args;
@@ -7338,21 +8781,22 @@ class CustomOptionsControl {
7338
8781
 
7339
8782
  const mainButton = document.createElement('button');
7340
8783
  mainButton.style.cssText = `
7341
- padding: 0;
8784
+ padding: 4px;
7342
8785
  background: white;
7343
- border: 0.0625rem solid #ccc;
8786
+ border: 1px solid #ccc;
7344
8787
  cursor: pointer;
7345
8788
  display: flex;
7346
8789
  align-items: center;
7347
8790
  justify-content: center;
7348
- gap: 0.375rem;
8791
+ width: 28px;
8792
+ height: 28px;
7349
8793
  `;
7350
8794
 
7351
8795
  if (this._icon) {
7352
8796
  const iconWrapper = document.createElement('span');
7353
8797
  iconWrapper.style.cssText = `
7354
- width: 1rem;
7355
- height: 1rem;
8798
+ width: 16px;
8799
+ height: 16px;
7356
8800
  display: inline-flex;
7357
8801
  align-items: center;
7358
8802
  justify-content: center;
@@ -7363,7 +8807,7 @@ class CustomOptionsControl {
7363
8807
  } else {
7364
8808
  const img = document.createElement('img');
7365
8809
  img.src = this._icon;
7366
- img.style.cssText = `width: 1rem; height: 1rem; object-fit: contain;`;
8810
+ img.style.cssText = `width: 16px; height: 16px; object-fit: contain;`;
7367
8811
  iconWrapper.appendChild(img);
7368
8812
  }
7369
8813
 
@@ -7404,17 +8848,6 @@ class CustomOptionsControl {
7404
8848
  to { opacity: 1; }
7405
8849
  }
7406
8850
 
7407
- @keyframes fadeInUp {
7408
- from {
7409
- opacity: 0;
7410
- transform: translateY(20px);
7411
- }
7412
- to {
7413
- opacity: 1;
7414
- transform: translateY(0);
7415
- }
7416
- }
7417
-
7418
8851
  .custom-modal-overlay {
7419
8852
  animation: modalBackdropFadeIn 0.2s ease-out;
7420
8853
  }
@@ -7425,20 +8858,21 @@ class CustomOptionsControl {
7425
8858
 
7426
8859
  .custom-search-input:focus {
7427
8860
  border-color: #667eea !important;
7428
- box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
8861
+ box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.1) !important;
7429
8862
  }
7430
8863
 
7431
8864
  .custom-checkbox {
7432
8865
  position: relative;
7433
8866
  appearance: none;
7434
- width: 1rem;
7435
- height: 1rem;
8867
+ width: 16px;
8868
+ height: 16px;
7436
8869
  border: 2px solid #d1d5db;
7437
- border-radius: 0.25rem;
8870
+ border-radius: 3px;
7438
8871
  background: white;
7439
8872
  cursor: pointer;
7440
8873
  transition: all 0.2s ease;
7441
- margin-right: 0.75rem;
8874
+ margin-right: 8px;
8875
+ flex-shrink: 0;
7442
8876
  }
7443
8877
 
7444
8878
  .custom-checkbox:checked {
@@ -7453,13 +8887,12 @@ class CustomOptionsControl {
7453
8887
  left: 50%;
7454
8888
  transform: translate(-50%, -50%);
7455
8889
  color: white;
7456
- font-size: 0.75rem;
8890
+ font-size: 12px;
7457
8891
  font-weight: bold;
7458
8892
  }
7459
8893
 
7460
8894
  .custom-checkbox:hover {
7461
8895
  border-color: #667eea;
7462
- box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
7463
8896
  }
7464
8897
 
7465
8898
  .custom-list-item {
@@ -7469,11 +8902,10 @@ class CustomOptionsControl {
7469
8902
  .custom-list-item:hover {
7470
8903
  background-color: #f8fafc !important;
7471
8904
  border-color: #e2e8f0 !important;
7472
- transform: translateX(4px) !important;
7473
8905
  }
7474
8906
 
7475
8907
  .custom-modal::-webkit-scrollbar {
7476
- width: 6px;
8908
+ width: 5px;
7477
8909
  }
7478
8910
 
7479
8911
  .custom-modal::-webkit-scrollbar-track {
@@ -7486,8 +8918,73 @@ class CustomOptionsControl {
7486
8918
  border-radius: 3px;
7487
8919
  }
7488
8920
 
7489
- .custom-modal::-webkit-scrollbar-thumb:hover {
7490
- background: linear-gradient(135deg, #5a67d8, #6b46c1);
8921
+ /* 移动端优化样式 */
8922
+ @media (max-height: 500px) and (orientation: landscape) {
8923
+ .custom-modal {
8924
+ max-height: 90vh !important;
8925
+ max-width: 90vw !important;
8926
+ width: 90vw !important;
8927
+ margin: 5vh auto !important;
8928
+ }
8929
+
8930
+ .custom-modal .modal-header {
8931
+ padding: 8px 12px !important;
8932
+ }
8933
+
8934
+ .custom-modal .modal-title {
8935
+ font-size: 13px !important;
8936
+ margin-bottom: 2px !important;
8937
+ }
8938
+
8939
+ .custom-modal .modal-subtitle {
8940
+ font-size: 11px !important;
8941
+ }
8942
+
8943
+ .custom-modal .modal-content {
8944
+ max-height: 60vh !important;
8945
+ min-height: 40vh !important;
8946
+ }
8947
+
8948
+ .custom-modal .list-item {
8949
+ padding: 6px 8px !important;
8950
+ font-size: 12px !important;
8951
+ }
8952
+
8953
+ .custom-modal .modal-footer {
8954
+ padding: 8px 12px !important;
8955
+ position: sticky;
8956
+ bottom: 0;
8957
+ background: #f8fafc;
8958
+ z-index: 10;
8959
+ }
8960
+
8961
+ .custom-modal .modal-footer button {
8962
+ padding: 5px 10px !important;
8963
+ font-size: 12px !important;
8964
+ }
8965
+
8966
+ .custom-modal .search-container {
8967
+ padding: 8px 12px 4px 12px !important;
8968
+ }
8969
+
8970
+ .custom-modal .search-input {
8971
+ padding: 6px 8px 6px 24px !important;
8972
+ font-size: 12px !important;
8973
+ }
8974
+
8975
+ .custom-modal .stats-text {
8976
+ font-size: 11px !important;
8977
+ padding: 2px 0 !important;
8978
+ }
8979
+ }
8980
+
8981
+ /* 小屏幕通用优化 */
8982
+ @media (max-width: 480px) {
8983
+ .custom-modal {
8984
+ width: 95vw !important;
8985
+ max-width: 95vw !important;
8986
+ margin: 2.5vh auto !important;
8987
+ }
7491
8988
  }
7492
8989
  `;
7493
8990
  document.head.appendChild(styles);
@@ -7500,31 +8997,31 @@ class CustomOptionsControl {
7500
8997
  position: fixed;
7501
8998
  top: 0; left: 0; right: 0; bottom: 0;
7502
8999
  background: rgba(0, 0, 0, 0.5);
7503
- backdrop-filter: blur(4px);
7504
- -webkit-backdrop-filter: blur(4px);
9000
+ backdrop-filter: blur(2px);
9001
+ -webkit-backdrop-filter: blur(2px);
7505
9002
  z-index: 10000;
7506
9003
  display: flex;
7507
9004
  justify-content: center;
7508
9005
  align-items: center;
7509
- padding: 1rem;
9006
+ padding: 12px;
7510
9007
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
9008
+ overflow-y: auto;
7511
9009
  `;
7512
9010
 
7513
9011
  this._modal = document.createElement('div');
7514
9012
  this._modal.className = 'custom-modal';
7515
9013
  this._modal.style.cssText = `
7516
9014
  width: 100%;
7517
- max-width: 26rem;
7518
- max-height: 80vh;
7519
- background: linear-gradient(145deg, #ffffff 0%, #f8fafc 100%);
7520
- border-radius: 0.75rem;
7521
- box-shadow:
7522
- 0 20px 25px -5px rgba(0, 0, 0, 0.1),
7523
- 0 10px 10px -5px rgba(0, 0, 0, 0.04);
7524
- border: 1px solid rgba(255, 255, 255, 0.8);
9015
+ max-width: 400px;
9016
+ max-height: 85vh;
9017
+ background: white;
9018
+ border-radius: 8px;
9019
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
9020
+ border: 1px solid #e2e8f0;
7525
9021
  overflow: hidden;
7526
9022
  display: flex;
7527
9023
  flex-direction: column;
9024
+ margin: auto;
7528
9025
  `;
7529
9026
 
7530
9027
  // 创建头部
@@ -7535,13 +9032,15 @@ class CustomOptionsControl {
7535
9032
  const searchSection = this._createSearchSection();
7536
9033
  this._modal.appendChild(searchSection);
7537
9034
 
7538
- // 创建选项列表
9035
+ // 创建选项列表容器
7539
9036
  this._listBox = document.createElement('div');
9037
+ this._listBox.className = 'modal-content';
7540
9038
  this._listBox.style.cssText = `
7541
9039
  flex: 1;
7542
9040
  overflow-y: auto;
7543
- padding: 0 1.25rem 1.25rem 1.25rem;
7544
- min-height: 10rem;
9041
+ padding: 0 16px 12px 16px;
9042
+ min-height: 200px;
9043
+ max-height: 50vh;
7545
9044
  `;
7546
9045
  this._modal.appendChild(this._listBox);
7547
9046
 
@@ -7552,13 +9051,12 @@ class CustomOptionsControl {
7552
9051
  this._overlay.appendChild(this._modal);
7553
9052
  document.body.appendChild(this._overlay);
7554
9053
 
7555
- // 聚焦搜索框
7556
- // setTimeout(() => {
7557
- // const searchInput = this._modal.querySelector('.custom-search-input');
7558
- // if (searchInput) {
7559
- // searchInput.focus();
7560
- // }
7561
- // }, 100);
9054
+ // 检查是否是横屏且高度不足
9055
+ this._checkViewportAndAdjust();
9056
+
9057
+ // 添加窗口调整事件监听
9058
+ this._handleResize = () => this._checkViewportAndAdjust();
9059
+ window.addEventListener('resize', this._handleResize);
7562
9060
 
7563
9061
  // 点击遮罩关闭
7564
9062
  this._overlay.addEventListener('click', (e) => {
@@ -7578,37 +9076,85 @@ class CustomOptionsControl {
7578
9076
  this._renderList('');
7579
9077
  }
7580
9078
 
9079
+ _checkViewportAndAdjust() {
9080
+ if (!this._modal) return;
9081
+
9082
+ const viewportHeight = window.innerHeight;
9083
+ const viewportWidth = window.innerWidth;
9084
+ const isLandscape = viewportWidth > viewportHeight;
9085
+
9086
+ // 如果是横屏且高度较小
9087
+ if (isLandscape && viewportHeight < 500) {
9088
+ this._modal.style.maxHeight = '90vh';
9089
+ this._modal.style.maxWidth = '90vw';
9090
+ this._modal.style.width = '90vw';
9091
+
9092
+ // 调整列表区域高度
9093
+ const listBox = this._modal.querySelector('.modal-content');
9094
+ if (listBox) {
9095
+ listBox.style.maxHeight = '60vh';
9096
+ listBox.style.minHeight = '30vh';
9097
+ }
9098
+
9099
+ // 确保底部按钮可见
9100
+ const footer = this._modal.querySelector('.modal-footer');
9101
+ if (footer) {
9102
+ footer.style.position = 'sticky';
9103
+ footer.style.bottom = '0';
9104
+ footer.style.background = '#f8fafc';
9105
+ footer.style.zIndex = '10';
9106
+ }
9107
+ } else {
9108
+ // 恢复正常样式
9109
+ this._modal.style.maxHeight = '85vh';
9110
+ this._modal.style.maxWidth = '400px';
9111
+ this._modal.style.width = '100%';
9112
+
9113
+ const listBox = this._modal.querySelector('.modal-content');
9114
+ if (listBox) {
9115
+ listBox.style.maxHeight = '50vh';
9116
+ listBox.style.minHeight = '200px';
9117
+ }
9118
+
9119
+ const footer = this._modal.querySelector('.modal-footer');
9120
+ if (footer) {
9121
+ footer.style.position = '';
9122
+ footer.style.bottom = '';
9123
+ footer.style.background = '';
9124
+ footer.style.zIndex = '';
9125
+ }
9126
+ }
9127
+ }
9128
+
7581
9129
  _createHeader() {
7582
9130
  const header = document.createElement('div');
9131
+ header.className = 'modal-header';
7583
9132
  header.style.cssText = `
7584
- padding: 1.25rem 1.25rem 1rem 1.25rem;
9133
+ padding: 16px 16px 12px 16px;
7585
9134
  border-bottom: 1px solid #e2e8f0;
7586
- background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
9135
+ background: #f8fafc;
9136
+ flex-shrink: 0;
7587
9137
  `;
7588
9138
 
7589
9139
  const title = document.createElement('h2');
9140
+ title.className = 'modal-title';
7590
9141
  title.textContent = this._title;
7591
9142
  title.style.cssText = `
7592
- margin: 0 0 0.5rem 0;
7593
- font-size: 1.125rem;
9143
+ margin: 0 0 4px 0;
9144
+ font-size: 15px;
7594
9145
  font-weight: 600;
7595
9146
  color: #1e293b;
7596
9147
  display: flex;
7597
9148
  align-items: center;
7598
- gap: 0.5rem;
9149
+ gap: 6px;
7599
9150
  `;
7600
9151
 
7601
- // 添加图标
7602
- const icon = document.createElement('span');
7603
- icon.innerHTML = '📋';
7604
- icon.style.fontSize = '1.25rem';
7605
- title.insertBefore(icon, title.firstChild);
7606
-
7607
9152
  const subtitle = document.createElement('p');
9153
+ subtitle.className = 'modal-subtitle';
7608
9154
  subtitle.textContent = `共 ${this._originalOptions.length} 个选项,已选择 ${this._selectedOptions.length} 个`;
7609
9155
  subtitle.style.cssText = `
7610
9156
  margin: 0;
7611
- font-size: 0.8125rem;
9157
+ font-size: 12px;
7612
9158
  color: #64748b;
7613
9159
  `;
7614
9160
 
@@ -7616,31 +9162,30 @@ class CustomOptionsControl {
7616
9162
  closeBtn.innerHTML = '✕';
7617
9163
  closeBtn.style.cssText = `
7618
9164
  position: absolute;
7619
- top: 1rem;
7620
- right: 1rem;
7621
- width: 1.75rem;
7622
- height: 1.75rem;
9165
+ top: 12px;
9166
+ right: 12px;
9167
+ width: 24px;
9168
+ height: 24px;
7623
9169
  border: none;
7624
9170
  background: #f1f5f9;
7625
9171
  color: #64748b;
7626
- border-radius: 50%;
9172
+ border-radius: 4px;
7627
9173
  cursor: pointer;
7628
9174
  display: flex;
7629
9175
  align-items: center;
7630
9176
  justify-content: center;
7631
- font-size: 0.875rem;
9177
+ font-size: 12px;
7632
9178
  transition: all 0.2s ease;
7633
9179
  font-weight: 500;
9180
+ flex-shrink: 0;
7634
9181
  `;
7635
9182
  closeBtn.addEventListener('mouseenter', () => {
7636
9183
  closeBtn.style.background = '#ef4444';
7637
9184
  closeBtn.style.color = 'white';
7638
- closeBtn.style.transform = 'rotate(90deg)';
7639
9185
  });
7640
9186
  closeBtn.addEventListener('mouseleave', () => {
7641
9187
  closeBtn.style.background = '#f1f5f9';
7642
9188
  closeBtn.style.color = '#64748b';
7643
- closeBtn.style.transform = 'rotate(0deg)';
7644
9189
  });
7645
9190
  closeBtn.addEventListener('click', () => this._closeModal());
7646
9191
 
@@ -7654,8 +9199,10 @@ class CustomOptionsControl {
7654
9199
 
7655
9200
  _createSearchSection() {
7656
9201
  const section = document.createElement('div');
9202
+ section.className = 'search-container';
7657
9203
  section.style.cssText = `
7658
- padding: 1.25rem 1.25rem 1rem 1.25rem;
9204
+ padding: 12px 16px 8px 16px;
9205
+ flex-shrink: 0;
7659
9206
  `;
7660
9207
 
7661
9208
  const searchContainer = document.createElement('div');
@@ -7667,25 +9214,25 @@ class CustomOptionsControl {
7667
9214
  searchIcon.innerHTML = '🔍';
7668
9215
  searchIcon.style.cssText = `
7669
9216
  position: absolute;
7670
- left: 0.875rem;
9217
+ left: 10px;
7671
9218
  top: 50%;
7672
9219
  transform: translateY(-50%);
7673
- font-size: 0.875rem;
9220
+ font-size: 12px;
7674
9221
  color: #94a3b8;
7675
9222
  pointer-events: none;
7676
9223
  `;
7677
9224
 
7678
9225
  const searchInput = document.createElement('input');
7679
9226
  searchInput.placeholder = '搜索选项...';
7680
- searchInput.className = 'custom-search-input';
9227
+ searchInput.className = 'custom-search-input search-input';
7681
9228
  searchInput.style.cssText = `
7682
9229
  width: 100%;
7683
- padding: 0.75rem 1rem 0.75rem 2.5rem;
7684
- border: 2px solid #e2e8f0;
7685
- border-radius: 0.5rem;
7686
- font-size: 0.875rem;
9230
+ padding: 8px 10px 8px 28px;
9231
+ border: 1px solid #e2e8f0;
9232
+ border-radius: 4px;
9233
+ font-size: 13px;
7687
9234
  background: white;
7688
- transition: all 0.3s ease;
9235
+ transition: all 0.2s ease;
7689
9236
  box-sizing: border-box;
7690
9237
  font-family: inherit;
7691
9238
  outline: none;
@@ -7693,7 +9240,7 @@ class CustomOptionsControl {
7693
9240
 
7694
9241
  searchInput.addEventListener('focus', () => {
7695
9242
  searchInput.style.borderColor = '#667eea';
7696
- searchInput.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
9243
+ searchInput.style.boxShadow = '0 0 0 2px rgba(102, 126, 234, 0.1)';
7697
9244
  });
7698
9245
 
7699
9246
  searchInput.addEventListener('blur', () => {
@@ -7714,65 +9261,62 @@ class CustomOptionsControl {
7714
9261
 
7715
9262
  _createFooter() {
7716
9263
  const footer = document.createElement('div');
9264
+ footer.className = 'modal-footer';
7717
9265
  footer.style.cssText = `
7718
- padding: 1rem 1.25rem;
7719
- background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
9266
+ padding: 12px 16px;
9267
+ background: #f8fafc;
7720
9268
  border-top: 1px solid #e2e8f0;
7721
9269
  display: flex;
7722
9270
  justify-content: flex-end;
7723
- gap: 0.75rem;
9271
+ gap: 8px;
9272
+ flex-shrink: 0;
7724
9273
  `;
7725
9274
 
7726
9275
  const cancelBtn = document.createElement('button');
7727
9276
  cancelBtn.textContent = '取消';
7728
9277
  cancelBtn.style.cssText = `
7729
- padding: 0.5rem 1rem;
9278
+ padding: 6px 12px;
7730
9279
  background: white;
7731
9280
  border: 1px solid #d1d5db;
7732
- border-radius: 0.375rem;
9281
+ border-radius: 4px;
7733
9282
  cursor: pointer;
7734
- font-size: 0.875rem;
9283
+ font-size: 13px;
7735
9284
  font-weight: 500;
7736
9285
  color: #374151;
7737
9286
  transition: all 0.2s ease;
7738
9287
  font-family: inherit;
9288
+ min-height: 32px;
7739
9289
  `;
7740
9290
  cancelBtn.addEventListener('mouseenter', () => {
7741
9291
  cancelBtn.style.borderColor = '#ef4444';
7742
9292
  cancelBtn.style.color = '#ef4444';
7743
- cancelBtn.style.transform = 'translateY(-1px)';
7744
9293
  });
7745
9294
  cancelBtn.addEventListener('mouseleave', () => {
7746
9295
  cancelBtn.style.borderColor = '#d1d5db';
7747
9296
  cancelBtn.style.color = '#374151';
7748
- cancelBtn.style.transform = 'translateY(0)';
7749
9297
  });
7750
9298
  cancelBtn.addEventListener('click', () => this._closeModal());
7751
9299
 
7752
9300
  const okBtn = document.createElement('button');
7753
9301
  okBtn.textContent = '确定';
7754
9302
  okBtn.style.cssText = `
7755
- padding: 0.5rem 1rem;
9303
+ padding: 6px 12px;
7756
9304
  background: #007cba;
7757
9305
  color: white;
7758
9306
  border: none;
7759
- border-radius: 0.375rem;
9307
+ border-radius: 4px;
7760
9308
  cursor: pointer;
7761
- font-size: 0.875rem;
9309
+ font-size: 13px;
7762
9310
  font-weight: 500;
7763
9311
  transition: all 0.2s ease;
7764
9312
  font-family: inherit;
7765
- box-shadow: 0 2px 4px rgba(0, 124, 186, 0.2);
9313
+ min-height: 32px;
7766
9314
  `;
7767
9315
  okBtn.addEventListener('mouseenter', () => {
7768
9316
  okBtn.style.background = '#005a87';
7769
- okBtn.style.transform = 'translateY(-1px)';
7770
- okBtn.style.boxShadow = '0 4px 8px rgba(0, 124, 186, 0.3)';
7771
9317
  });
7772
9318
  okBtn.addEventListener('mouseleave', () => {
7773
9319
  okBtn.style.background = '#007cba';
7774
- okBtn.style.transform = 'translateY(0)';
7775
- okBtn.style.boxShadow = '0 2px 4px rgba(0, 124, 186, 0.2)';
7776
9320
  });
7777
9321
  okBtn.addEventListener('click', () => this._confirm());
7778
9322
 
@@ -7796,13 +9340,13 @@ class CustomOptionsControl {
7796
9340
  const empty = document.createElement('div');
7797
9341
  empty.style.cssText = `
7798
9342
  text-align: center;
7799
- padding: 2.5rem 1rem;
9343
+ padding: 40px 16px;
7800
9344
  color: #94a3b8;
7801
9345
  `;
7802
9346
  empty.innerHTML = `
7803
- <div style="font-size: 2.5rem; margin-bottom: 0.75rem; opacity: 0.6;">🔍</div>
7804
- <div style="font-size: 1rem; font-weight: 500; margin-bottom: 0.25rem; color: #64748b;">未找到相关结果</div>
7805
- <div style="font-size: 0.8125rem;">尝试使用其他关键词搜索</div>
9347
+ <div style="font-size: 20px; margin-bottom: 8px; opacity: 0.6;">🔍</div>
9348
+ <div style="font-size: 13px; font-weight: 500; margin-bottom: 4px; color: #64748b;">未找到相关结果</div>
9349
+ <div style="font-size: 12px;">尝试使用其他关键词搜索</div>
7806
9350
  `;
7807
9351
  this._listBox.appendChild(empty);
7808
9352
  return;
@@ -7810,28 +9354,29 @@ class CustomOptionsControl {
7810
9354
 
7811
9355
  // 添加选项统计
7812
9356
  const stats = document.createElement('div');
9357
+ stats.className = 'stats-text';
7813
9358
  stats.style.cssText = `
7814
- padding: 0.5rem 0;
7815
- font-size: 0.8125rem;
9359
+ padding: 4px 0;
9360
+ font-size: 12px;
7816
9361
  color: #64748b;
7817
9362
  border-bottom: 1px solid #f1f5f9;
7818
- margin-bottom: 0.5rem;
9363
+ margin-bottom: 8px;
7819
9364
  `;
7820
9365
  stats.textContent = `找到 ${list.length} 个相关选项`;
7821
9366
  this._listBox.appendChild(stats);
7822
9367
 
7823
9368
  list.forEach((opt, index) => {
7824
9369
  const item = document.createElement('label');
7825
- item.className = 'custom-list-item';
9370
+ item.className = 'custom-list-item list-item';
7826
9371
  item.style.cssText = `
7827
9372
  display: flex;
7828
9373
  align-items: center;
7829
- padding: 0.75rem;
9374
+ padding: 8px;
7830
9375
  cursor: pointer;
7831
- border-radius: 0.5rem;
7832
- margin-bottom: 0.375rem;
7833
- transition: all 0.2s ease;
7834
- border: 2px solid transparent;
9376
+ border-radius: 4px;
9377
+ margin-bottom: 4px;
9378
+ transition: all 0.1s ease;
9379
+ border: 1px solid transparent;
7835
9380
  background: white;
7836
9381
  position: relative;
7837
9382
  overflow: hidden;
@@ -7842,16 +9387,17 @@ class CustomOptionsControl {
7842
9387
  checkbox.className = 'custom-checkbox';
7843
9388
  checkbox.value = opt.value;
7844
9389
  checkbox.checked = this._selectedOptions.includes(opt.value);
7845
- checkbox.style.marginRight = '0.75rem';
9390
+ checkbox.style.marginRight = '8px';
7846
9391
 
7847
9392
  const labelSpan = document.createElement('span');
7848
9393
  labelSpan.innerHTML = this._highlight(opt.label, keyword);
7849
9394
  labelSpan.style.cssText = `
7850
9395
  flex: 1;
7851
- font-size: 0.875rem;
9396
+ font-size: 13px;
7852
9397
  color: #374151;
7853
9398
  line-height: 1.4;
7854
9399
  font-weight: 500;
9400
+ word-break: break-word;
7855
9401
  `;
7856
9402
 
7857
9403
  // 添加选中状态的视觉反馈
@@ -7873,7 +9419,7 @@ class CustomOptionsControl {
7873
9419
  }
7874
9420
 
7875
9421
  // 更新标题中的统计信息
7876
- const subtitle = this._modal.querySelector('p');
9422
+ const subtitle = this._modal.querySelector('.modal-subtitle');
7877
9423
  if (subtitle) {
7878
9424
  subtitle.textContent = `共 ${this._originalOptions.length} 个选项,已选择 ${this._selectedOptions.length} 个`;
7879
9425
  }
@@ -7882,23 +9428,14 @@ class CustomOptionsControl {
7882
9428
  item.appendChild(checkbox);
7883
9429
  item.appendChild(labelSpan);
7884
9430
 
7885
- // 添加进入动画
7886
- item.style.opacity = '0';
7887
- item.style.transform = 'translateY(10px)';
7888
9431
  this._listBox.appendChild(item);
7889
-
7890
- setTimeout(() => {
7891
- item.style.transition = 'all 0.3s ease';
7892
- item.style.opacity = '1';
7893
- item.style.transform = 'translateY(0)';
7894
- }, index * 30);
7895
9432
  });
7896
9433
  }
7897
9434
 
7898
9435
  _highlight(text, key) {
7899
9436
  if (!key) return text;
7900
9437
  const regex = new RegExp(`(${this._escapeRegExp(key)})`, 'gi');
7901
- 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>');
9438
+ return text.replace(regex, '<mark style="background: #fef3c7; padding: 1px 3px; border-radius: 2px; font-weight: 600;">$1</mark>');
7902
9439
  }
7903
9440
 
7904
9441
  _escapeRegExp(string) {
@@ -7927,6 +9464,9 @@ class CustomOptionsControl {
7927
9464
 
7928
9465
  _closeModal() {
7929
9466
  if (this._overlay) {
9467
+ // 移除事件监听
9468
+ window.removeEventListener('resize', this._handleResize);
9469
+
7930
9470
  // 添加退出动画
7931
9471
  this._modal.style.animation = 'modalSlideIn 0.2s ease-out reverse';
7932
9472
  this._overlay.style.animation = 'modalBackdropFadeIn 0.2s ease-out reverse';