raintee-maputils 1.0.43 → 1.0.45

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布局,提高空间利用率
@@ -6757,12 +7333,16 @@ class CustomSearchSelectControl {
6757
7333
  this.options = {
6758
7334
  list: [],
6759
7335
  onSelect: () => { },
7336
+ onCancel: () => { },
6760
7337
  placeholder: '搜索...',
6761
7338
  title: '选择',
6762
7339
  showSearch: true,
6763
7340
  compactMode: true, // 新增:紧凑模式
6764
- maxHeight: '60vh', // 新增:最大高度
7341
+ maxHeight: '100vh', // 新增:最大高度
6765
7342
  width: '60vw', // 新增:弹窗宽度
7343
+ mobileBreakpoint: 768, // 新增:移动端断点
7344
+ mobileMaxHeight: '50vh', // 新增:移动端最大高度
7345
+ mobileCompactMode: true, // 新增:移动端自动启用紧凑模式
6766
7346
  ...options
6767
7347
  };
6768
7348
 
@@ -6773,6 +7353,57 @@ class CustomSearchSelectControl {
6773
7353
  this._searchInput = null;
6774
7354
  this._optionsList = null;
6775
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
+ }
6776
7407
  }
6777
7408
 
6778
7409
  /**
@@ -6785,7 +7416,7 @@ class CustomSearchSelectControl {
6785
7416
 
6786
7417
  // 创建控件按钮
6787
7418
  this._container = document.createElement('div');
6788
- this._container.className = 'mapboxgl-ctrl vector-layer-ctrl';
7419
+ this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group vector-layer-ctrl';
6789
7420
  this._container.style.cssText = `
6790
7421
  position: relative;
6791
7422
  `;
@@ -6822,6 +7453,9 @@ class CustomSearchSelectControl {
6822
7453
  openModal() {
6823
7454
  if (this._modal) return;
6824
7455
 
7456
+ // 获取高度设置
7457
+ const heightSettings = this.getModalHeightSettings();
7458
+
6825
7459
  // 创建遮罩层
6826
7460
  this._overlay = document.createElement('div');
6827
7461
  this._overlay.className = 'vector-layer-overlay';
@@ -6835,6 +7469,9 @@ class CustomSearchSelectControl {
6835
7469
  z-index: 9999;
6836
7470
  display: flex;
6837
7471
  justify-content: center;
7472
+ align-items: center;
7473
+ padding: 10px;
7474
+ box-sizing: border-box;
6838
7475
  backdrop-filter: blur(2px);
6839
7476
  `;
6840
7477
  this._overlay.addEventListener('click', (e) => {
@@ -6844,30 +7481,75 @@ class CustomSearchSelectControl {
6844
7481
  // 创建弹窗
6845
7482
  this._modal = document.createElement('div');
6846
7483
  this._modal.className = 'vector-layer-modal';
6847
- this._modal.style.cssText = `
6848
- background: white;
6849
- border-radius: 8px;
6850
- padding: ${this.options.compactMode ? '16px' : '20px'};
6851
- width: ${this.options.width};
6852
- max-width: 90vw;
6853
- max-height: ${this.options.maxHeight};
6854
- display: flex;
6855
- flex-direction: column;
6856
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
6857
- animation: vector-layer-modal-appear 0.2s ease-out;
6858
- border: 1px solid #e0e0e0;
6859
- `;
7484
+
7485
+ // 根据设备设置不同样式
7486
+ if (this._isMobile) {
7487
+ if (this._isLandscape) {
7488
+ // 横屏状态
7489
+ this._modal.style.cssText = `
7490
+ background: white;
7491
+ border-radius: 8px;
7492
+ padding: ${heightSettings.compact ? '12px' : '16px'};
7493
+ width: ${this._isLandscape ? '80vw' : '90vw'};
7494
+ max-width: ${this._isLandscape ? '600px' : '90vw'};
7495
+ max-height: ${heightSettings.maxHeight};
7496
+ height: ${heightSettings.modalHeight};
7497
+ display: flex;
7498
+ flex-direction: column;
7499
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
7500
+ animation: vector-layer-modal-appear 0.2s ease-out;
7501
+ border: 1px solid #e0e0e0;
7502
+ box-sizing: border-box;
7503
+ overflow: hidden;
7504
+ `;
7505
+ } else {
7506
+ // 竖屏状态
7507
+ this._modal.style.cssText = `
7508
+ background: white;
7509
+ border-radius: 8px;
7510
+ padding: ${heightSettings.compact ? '12px' : '16px'};
7511
+ width: 90vw;
7512
+ max-width: 500px;
7513
+ max-height: ${heightSettings.maxHeight};
7514
+ display: flex;
7515
+ flex-direction: column;
7516
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
7517
+ animation: vector-layer-modal-appear 0.2s ease-out;
7518
+ border: 1px solid #e0e0e0;
7519
+ box-sizing: border-box;
7520
+ overflow: hidden;
7521
+ `;
7522
+ }
7523
+ } else {
7524
+ // 桌面端
7525
+ this._modal.style.cssText = `
7526
+ background: white;
7527
+ border-radius: 8px;
7528
+ padding: ${heightSettings.compact ? '16px' : '20px'};
7529
+ width: ${this.options.width};
7530
+ max-width: 90vw;
7531
+ max-height: ${heightSettings.maxHeight};
7532
+ display: flex;
7533
+ flex-direction: column;
7534
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
7535
+ animation: vector-layer-modal-appear 0.2s ease-out;
7536
+ border: 1px solid #e0e0e0;
7537
+ box-sizing: border-box;
7538
+ overflow: hidden;
7539
+ `;
7540
+ }
6860
7541
 
6861
7542
  // 弹窗标题
6862
7543
  const title = document.createElement('h3');
6863
7544
  title.className = 'vector-layer-title';
6864
7545
  title.textContent = this.options.title;
6865
7546
  title.style.cssText = `
6866
- margin: 0 0 ${this.options.compactMode ? '12px' : '16px'} 0;
6867
- font-size: ${this.options.compactMode ? '15px' : '16px'};
7547
+ margin: 0 0 ${heightSettings.compact ? '12px' : '16px'} 0;
7548
+ font-size: ${heightSettings.compact ? '15px' : '16px'};
6868
7549
  font-weight: 600;
6869
7550
  color: #2c3e50;
6870
7551
  line-height: 1.3;
7552
+ flex-shrink: 0;
6871
7553
  `;
6872
7554
  this._modal.appendChild(title);
6873
7555
 
@@ -6876,8 +7558,9 @@ class CustomSearchSelectControl {
6876
7558
  const searchContainer = document.createElement('div');
6877
7559
  searchContainer.className = 'vector-layer-search';
6878
7560
  searchContainer.style.cssText = `
6879
- margin-bottom: ${this.options.compactMode ? '12px' : '16px'};
7561
+ margin-bottom: ${heightSettings.compact ? '12px' : '16px'};
6880
7562
  position: relative;
7563
+ flex-shrink: 0;
6881
7564
  `;
6882
7565
 
6883
7566
  this._searchInput = document.createElement('input');
@@ -6886,10 +7569,10 @@ class CustomSearchSelectControl {
6886
7569
  this._searchInput.className = 'vector-layer-search-input';
6887
7570
  this._searchInput.style.cssText = `
6888
7571
  width: 100%;
6889
- padding: ${this.options.compactMode ? '8px 12px 8px 36px' : '10px 16px 10px 40px'};
7572
+ padding: ${heightSettings.compact ? '8px 12px 8px 36px' : '10px 16px 10px 40px'};
6890
7573
  border: 1px solid #dcdfe6;
6891
7574
  border-radius: 6px;
6892
- font-size: 13px;
7575
+ font-size: ${heightSettings.compact ? '13px' : '14px'};
6893
7576
  outline: none;
6894
7577
  transition: all 0.2s;
6895
7578
  box-sizing: border-box;
@@ -6921,17 +7604,21 @@ class CustomSearchSelectControl {
6921
7604
  listContainer.style.cssText = `
6922
7605
  flex: 1;
6923
7606
  overflow: hidden;
6924
- min-height: ${this.options.compactMode ? '120px' : '160px'};
7607
+ min-height: ${heightSettings.compact ? '100px' : '120px'};
6925
7608
  border-radius: 6px;
6926
7609
  border: 1px solid #e0e0e0;
7610
+ display: flex;
7611
+ flex-direction: column;
6927
7612
  `;
6928
7613
 
6929
7614
  this._optionsList = document.createElement('div');
6930
7615
  this._optionsList.className = 'vector-layer-options';
6931
7616
  this._optionsList.style.cssText = `
6932
- max-height: calc(${this.options.maxHeight} - ${this.options.compactMode ? '140px' : '180px'});
7617
+ flex: 1;
6933
7618
  overflow-y: auto;
6934
7619
  scroll-behavior: smooth;
7620
+ max-height: ${heightSettings.listMaxHeight};
7621
+ min-height: ${heightSettings.compact ? '80px' : '100px'};
6935
7622
  `;
6936
7623
 
6937
7624
  // 填充选项
@@ -6947,26 +7634,32 @@ class CustomSearchSelectControl {
6947
7634
  display: flex;
6948
7635
  justify-content: flex-end;
6949
7636
  gap: 8px;
6950
- margin-top: ${this.options.compactMode ? '12px' : '16px'};
6951
- padding-top: ${this.options.compactMode ? '12px' : '16px'};
7637
+ margin-top: ${heightSettings.compact ? '12px' : '16px'};
7638
+ padding-top: ${heightSettings.compact ? '12px' : '16px'};
6952
7639
  border-top: 1px solid #f0f0f0;
7640
+ flex-shrink: 0;
6953
7641
  `;
6954
7642
 
6955
7643
  const cancelBtn = document.createElement('button');
6956
7644
  cancelBtn.textContent = '取消';
6957
7645
  cancelBtn.className = 'vector-layer-cancel';
6958
7646
  cancelBtn.style.cssText = `
6959
- padding: 6px 16px;
7647
+ padding: ${this._isMobile ? '6px 12px' : '6px 16px'};
6960
7648
  border: 1px solid #dcdfe6;
6961
7649
  border-radius: 4px;
6962
7650
  background: white;
6963
7651
  color: #606266;
6964
7652
  cursor: pointer;
6965
- font-size: 13px;
7653
+ font-size: ${this._isMobile ? '12px' : '13px'};
6966
7654
  transition: all 0.2s;
6967
7655
  font-weight: 500;
7656
+ min-width: 60px;
7657
+ box-sizing: border-box;
6968
7658
  `;
6969
- cancelBtn.addEventListener('click', () => this.closeModal());
7659
+ cancelBtn.addEventListener('click', () => {
7660
+ this.closeModal();
7661
+ this.options.onCancel(this._map, null);
7662
+ });
6970
7663
  cancelBtn.addEventListener('mouseenter', () => {
6971
7664
  cancelBtn.style.backgroundColor = '#f5f7fa';
6972
7665
  cancelBtn.style.borderColor = '#c0c4cc';
@@ -6975,6 +7668,12 @@ class CustomSearchSelectControl {
6975
7668
  cancelBtn.style.backgroundColor = 'white';
6976
7669
  cancelBtn.style.borderColor = '#dcdfe6';
6977
7670
  });
7671
+ cancelBtn.addEventListener('touchstart', () => {
7672
+ cancelBtn.style.backgroundColor = '#f5f7fa';
7673
+ });
7674
+ cancelBtn.addEventListener('touchend', () => {
7675
+ cancelBtn.style.backgroundColor = 'white';
7676
+ });
6978
7677
 
6979
7678
  buttonContainer.appendChild(cancelBtn);
6980
7679
  this._modal.appendChild(buttonContainer);
@@ -6986,6 +7685,30 @@ class CustomSearchSelectControl {
6986
7685
  this._modal.addEventListener('click', (e) => e.stopPropagation());
6987
7686
  this._modal.addEventListener('mousedown', (e) => e.stopPropagation());
6988
7687
  this._modal.addEventListener('mouseup', (e) => e.stopPropagation());
7688
+ this._modal.addEventListener('touchstart', (e) => e.stopPropagation());
7689
+ this._modal.addEventListener('touchend', (e) => e.stopPropagation());
7690
+
7691
+ // 处理窗口大小变化
7692
+ this._handleResize = () => {
7693
+ const newHeightSettings = this.getModalHeightSettings();
7694
+ if (this._modal) {
7695
+ if (this._isMobile && this._isLandscape) {
7696
+ this._modal.style.maxHeight = newHeightSettings.maxHeight;
7697
+ this._modal.style.height = newHeightSettings.modalHeight;
7698
+ this._optionsList.style.maxHeight = newHeightSettings.listMaxHeight;
7699
+ } else if (this._isMobile) {
7700
+ this._modal.style.maxHeight = newHeightSettings.maxHeight;
7701
+ this._modal.style.height = 'auto';
7702
+ this._optionsList.style.maxHeight = newHeightSettings.listMaxHeight;
7703
+ }
7704
+ }
7705
+ };
7706
+
7707
+ window.addEventListener('resize', this._handleResize);
7708
+ window.addEventListener('orientationchange', this._handleResize);
7709
+
7710
+ // 添加触摸事件支持
7711
+ this.addTouchSupport();
6989
7712
 
6990
7713
  // 聚焦搜索框
6991
7714
  if (this._searchInput) {
@@ -6996,6 +7719,18 @@ class CustomSearchSelectControl {
6996
7719
  this.addStyles();
6997
7720
  }
6998
7721
 
7722
+ /**
7723
+ * 添加触摸支持
7724
+ */
7725
+ addTouchSupport() {
7726
+ if (this._modal) {
7727
+ // 防止弹窗内滚动传播到body
7728
+ this._modal.addEventListener('touchmove', (e) => {
7729
+ e.stopPropagation();
7730
+ }, { passive: false });
7731
+ }
7732
+ }
7733
+
6999
7734
  /**
7000
7735
  * 渲染选项列表
7001
7736
  */
@@ -7012,6 +7747,10 @@ class CustomSearchSelectControl {
7012
7747
  color: #999;
7013
7748
  font-size: 13px;
7014
7749
  font-style: italic;
7750
+ display: flex;
7751
+ align-items: center;
7752
+ justify-content: center;
7753
+ height: 100px;
7015
7754
  `;
7016
7755
  this._optionsList.appendChild(emptyItem);
7017
7756
  return;
@@ -7023,29 +7762,44 @@ class CustomSearchSelectControl {
7023
7762
  option.dataset.value = item.value || item.label;
7024
7763
  option.dataset.index = index;
7025
7764
  option.style.cssText = `
7026
- padding: ${this.options.compactMode ? '8px 12px' : '10px 16px'};
7765
+ padding: ${this._isMobile ? '8px 10px' : '8px 12px'};
7027
7766
  cursor: pointer;
7028
7767
  border-bottom: 1px solid #f5f5f5;
7029
- font-size: 13px;
7768
+ font-size: ${this._isMobile ? '12px' : '13px'};
7030
7769
  transition: all 0.15s;
7031
7770
  display: flex;
7032
7771
  align-items: center;
7033
7772
  gap: 8px;
7034
- min-height: ${this.options.compactMode ? '36px' : '40px'};
7773
+ min-height: ${this._isMobile ? '40px' : '36px'};
7035
7774
  box-sizing: border-box;
7775
+ -webkit-tap-highlight-color: transparent;
7036
7776
  `;
7037
7777
 
7038
7778
  option.innerHTML = `
7039
7779
  ${item.icon ? `<span class="option-icon" style="flex-shrink: 0; width: 16px; height: 16px;">${item.icon}</span>` : ''}
7040
7780
  <span class="option-label" style="flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">${item.label}</span>
7041
- ${item.description ? `<span class="option-desc" style="font-size: 12px; color: #888; flex-shrink: 0;">${item.description}</span>` : ''}
7781
+ ${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>` : ''}
7042
7782
  `;
7043
7783
 
7784
+ // 点击事件
7044
7785
  option.addEventListener('click', () => this.selectOption(item));
7786
+
7787
+ // 触摸事件
7788
+ option.addEventListener('touchstart', () => {
7789
+ option.style.backgroundColor = '#f0f7ff';
7790
+ option.style.borderLeftColor = '#1890ff';
7791
+ });
7792
+
7793
+ option.addEventListener('touchend', () => {
7794
+ option.style.backgroundColor = '';
7795
+ option.style.borderLeftColor = '';
7796
+ });
7797
+
7045
7798
  option.addEventListener('mouseenter', () => {
7046
7799
  option.style.backgroundColor = '#f0f7ff';
7047
7800
  option.style.borderLeftColor = '#1890ff';
7048
7801
  });
7802
+
7049
7803
  option.addEventListener('mouseleave', () => {
7050
7804
  option.style.backgroundColor = '';
7051
7805
  option.style.borderLeftColor = '';
@@ -7116,6 +7870,12 @@ class CustomSearchSelectControl {
7116
7870
  * 关闭弹窗
7117
7871
  */
7118
7872
  closeModal() {
7873
+ // 移除事件监听
7874
+ if (this._handleResize) {
7875
+ window.removeEventListener('resize', this._handleResize);
7876
+ window.removeEventListener('orientationchange', this._handleResize);
7877
+ }
7878
+
7119
7879
  if (this._overlay) {
7120
7880
  this._overlay.style.opacity = '0';
7121
7881
  this._overlay.style.transition = 'opacity 0.15s ease-out';
@@ -7128,6 +7888,7 @@ class CustomSearchSelectControl {
7128
7888
  this._modal = null;
7129
7889
  this._searchInput = null;
7130
7890
  this._optionsList = null;
7891
+ this._handleResize = null;
7131
7892
  }, 150);
7132
7893
  }
7133
7894
  }
@@ -7228,25 +7989,65 @@ class CustomSearchSelectControl {
7228
7989
  overflow: hidden;
7229
7990
  }
7230
7991
 
7231
- /* 紧凑模式下的额外样式 */
7232
- .vector-layer-modal.compact {
7233
- padding: 12px;
7234
- }
7235
-
7236
- .vector-layer-modal.compact .vector-layer-title {
7237
- font-size: 14px;
7238
- margin-bottom: 10px;
7992
+ /* 移动端优化 */
7993
+ @media (max-width: 768px) {
7994
+ .vector-layer-modal {
7995
+ width: 90vw !important;
7996
+ max-width: 500px !important;
7997
+ }
7998
+
7999
+ .vector-layer-option {
8000
+ padding: 10px 12px;
8001
+ min-height: 44px;
8002
+ }
8003
+
8004
+ .vector-layer-actions {
8005
+ padding: 12px 0 0 0;
8006
+ }
8007
+
8008
+ .vector-layer-cancel {
8009
+ padding: 8px 16px;
8010
+ font-size: 14px;
8011
+ }
7239
8012
  }
7240
8013
 
7241
- .vector-layer-modal.compact .vector-layer-search-input {
7242
- padding: 6px 10px 6px 32px;
7243
- font-size: 12px;
8014
+ /* 横屏优化 */
8015
+ @media (max-width: 768px) and (orientation: landscape) {
8016
+ .vector-layer-modal {
8017
+ width: 80vw !important;
8018
+ max-height: 70vh !important;
8019
+ height: calc(100vh - 20px) !important;
8020
+ }
8021
+
8022
+ .vector-layer-list-container {
8023
+ min-height: 40vh !important;
8024
+ }
8025
+
8026
+ .vector-layer-options {
8027
+ max-height: calc(70vh - 120px) !important;
8028
+ }
8029
+
8030
+ .option-desc {
8031
+ display: none !important;
8032
+ }
7244
8033
  }
7245
8034
 
7246
- .vector-layer-modal.compact .vector-layer-option {
7247
- padding: 6px 10px;
7248
- font-size: 12px;
7249
- min-height: 32px;
8035
+ /* 小屏幕手机 */
8036
+ @media (max-width: 480px) {
8037
+ .vector-layer-modal {
8038
+ width: 95vw !important;
8039
+ padding: 12px !important;
8040
+ }
8041
+
8042
+ .vector-layer-title {
8043
+ font-size: 14px !important;
8044
+ margin-bottom: 10px !important;
8045
+ }
8046
+
8047
+ .vector-layer-search-input {
8048
+ padding: 6px 10px 6px 32px !important;
8049
+ font-size: 12px !important;
8050
+ }
7250
8051
  }
7251
8052
 
7252
8053
  /* 暗色模式支持 */
@@ -7305,12 +8106,661 @@ class CustomSearchSelectControl {
7305
8106
  background: #666;
7306
8107
  }
7307
8108
  }
8109
+
8110
+ /* 防止iOS上的回弹效果 */
8111
+ .vector-layer-overlay {
8112
+ overscroll-behavior: contain;
8113
+ }
8114
+
8115
+ /* 触摸优化 */
8116
+ .vector-layer-option {
8117
+ -webkit-tap-highlight-color: transparent;
8118
+ }
8119
+
8120
+ .vector-layer-cancel {
8121
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0.1);
8122
+ }
7308
8123
  `;
7309
8124
 
7310
8125
  document.head.appendChild(style);
7311
8126
  }
7312
8127
  }
7313
8128
 
8129
+ // class CustomOptionsControl {
8130
+ // constructor(args) {
8131
+ // const { title, options, onConfirm, icon } = args;
8132
+
8133
+ // this._map = null;
8134
+ // this._container = null;
8135
+
8136
+ // this._title = title || '';
8137
+ // this._options = options || [];
8138
+ // this._icon = icon || null;
8139
+ // this._onConfirm = onConfirm || (() => { });
8140
+ // this._originalOptions = [...this._options];
8141
+ // this._selectedOptions = [];
8142
+ // }
8143
+
8144
+ // onAdd(map) {
8145
+ // this._map = map;
8146
+
8147
+ // this._container = document.createElement('div');
8148
+ // this._container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group custom-options-control';
8149
+
8150
+ // const mainButton = document.createElement('button');
8151
+ // mainButton.style.cssText = `
8152
+ // padding: 0;
8153
+ // background: white;
8154
+ // border: 0.0625rem solid #ccc;
8155
+ // cursor: pointer;
8156
+ // display: flex;
8157
+ // align-items: center;
8158
+ // justify-content: center;
8159
+ // gap: 0.375rem;
8160
+ // `;
8161
+
8162
+ // if (this._icon) {
8163
+ // const iconWrapper = document.createElement('span');
8164
+ // iconWrapper.style.cssText = `
8165
+ // width: 1rem;
8166
+ // height: 1rem;
8167
+ // display: inline-flex;
8168
+ // align-items: center;
8169
+ // justify-content: center;
8170
+ // `;
8171
+
8172
+ // if (this._icon.trim().startsWith('<svg')) {
8173
+ // iconWrapper.innerHTML = this._icon;
8174
+ // } else {
8175
+ // const img = document.createElement('img');
8176
+ // img.src = this._icon;
8177
+ // img.style.cssText = `width: 1rem; height: 1rem; object-fit: contain;`;
8178
+ // iconWrapper.appendChild(img);
8179
+ // }
8180
+
8181
+ // mainButton.appendChild(iconWrapper);
8182
+ // }
8183
+
8184
+ // mainButton.addEventListener('click', () => {
8185
+ // this._showModal();
8186
+ // });
8187
+
8188
+ // this._container.appendChild(mainButton);
8189
+
8190
+ // // 添加全局样式
8191
+ // this._addGlobalStyles();
8192
+
8193
+ // return this._container;
8194
+ // }
8195
+
8196
+ // _addGlobalStyles() {
8197
+ // if (document.querySelector('#custom-options-styles')) return;
8198
+
8199
+ // const styles = document.createElement('style');
8200
+ // styles.id = 'custom-options-styles';
8201
+ // styles.textContent = `
8202
+ // @keyframes modalSlideIn {
8203
+ // from {
8204
+ // opacity: 0;
8205
+ // transform: scale(0.95) translateY(-20px);
8206
+ // }
8207
+ // to {
8208
+ // opacity: 1;
8209
+ // transform: scale(1) translateY(0);
8210
+ // }
8211
+ // }
8212
+
8213
+ // @keyframes modalBackdropFadeIn {
8214
+ // from { opacity: 0; }
8215
+ // to { opacity: 1; }
8216
+ // }
8217
+
8218
+ // @keyframes fadeInUp {
8219
+ // from {
8220
+ // opacity: 0;
8221
+ // transform: translateY(20px);
8222
+ // }
8223
+ // to {
8224
+ // opacity: 1;
8225
+ // transform: translateY(0);
8226
+ // }
8227
+ // }
8228
+
8229
+ // .custom-modal-overlay {
8230
+ // animation: modalBackdropFadeIn 0.2s ease-out;
8231
+ // }
8232
+
8233
+ // .custom-modal {
8234
+ // animation: modalSlideIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
8235
+ // }
8236
+
8237
+ // .custom-search-input:focus {
8238
+ // border-color: #667eea !important;
8239
+ // box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
8240
+ // }
8241
+
8242
+ // .custom-checkbox {
8243
+ // position: relative;
8244
+ // appearance: none;
8245
+ // width: 1rem;
8246
+ // height: 1rem;
8247
+ // border: 2px solid #d1d5db;
8248
+ // border-radius: 0.25rem;
8249
+ // background: white;
8250
+ // cursor: pointer;
8251
+ // transition: all 0.2s ease;
8252
+ // margin-right: 0.75rem;
8253
+ // }
8254
+
8255
+ // .custom-checkbox:checked {
8256
+ // background: linear-gradient(135deg, #667eea, #764ba2);
8257
+ // border-color: #667eea;
8258
+ // }
8259
+
8260
+ // .custom-checkbox:checked::after {
8261
+ // content: '✓';
8262
+ // position: absolute;
8263
+ // top: 50%;
8264
+ // left: 50%;
8265
+ // transform: translate(-50%, -50%);
8266
+ // color: white;
8267
+ // font-size: 0.75rem;
8268
+ // font-weight: bold;
8269
+ // }
8270
+
8271
+ // .custom-checkbox:hover {
8272
+ // border-color: #667eea;
8273
+ // box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
8274
+ // }
8275
+
8276
+ // .custom-list-item {
8277
+ // transition: all 0.2s ease;
8278
+ // }
8279
+
8280
+ // .custom-list-item:hover {
8281
+ // background-color: #f8fafc !important;
8282
+ // border-color: #e2e8f0 !important;
8283
+ // transform: translateX(4px) !important;
8284
+ // }
8285
+
8286
+ // .custom-modal::-webkit-scrollbar {
8287
+ // width: 6px;
8288
+ // }
8289
+
8290
+ // .custom-modal::-webkit-scrollbar-track {
8291
+ // background: #f1f5f9;
8292
+ // border-radius: 3px;
8293
+ // }
8294
+
8295
+ // .custom-modal::-webkit-scrollbar-thumb {
8296
+ // background: linear-gradient(135deg, #667eea, #764ba2);
8297
+ // border-radius: 3px;
8298
+ // }
8299
+
8300
+ // .custom-modal::-webkit-scrollbar-thumb:hover {
8301
+ // background: linear-gradient(135deg, #5a67d8, #6b46c1);
8302
+ // }
8303
+ // `;
8304
+ // document.head.appendChild(styles);
8305
+ // }
8306
+
8307
+ // _showModal() {
8308
+ // this._overlay = document.createElement('div');
8309
+ // this._overlay.className = 'custom-modal-overlay';
8310
+ // this._overlay.style.cssText = `
8311
+ // position: fixed;
8312
+ // top: 0; left: 0; right: 0; bottom: 0;
8313
+ // background: rgba(0, 0, 0, 0.5);
8314
+ // backdrop-filter: blur(4px);
8315
+ // -webkit-backdrop-filter: blur(4px);
8316
+ // z-index: 10000;
8317
+ // display: flex;
8318
+ // justify-content: center;
8319
+ // align-items: center;
8320
+ // padding: 1rem;
8321
+ // font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
8322
+ // `;
8323
+
8324
+ // this._modal = document.createElement('div');
8325
+ // this._modal.className = 'custom-modal';
8326
+ // this._modal.style.cssText = `
8327
+ // width: 100%;
8328
+ // max-width: 26rem;
8329
+ // max-height: 80vh;
8330
+ // background: linear-gradient(145deg, #ffffff 0%, #f8fafc 100%);
8331
+ // border-radius: 0.75rem;
8332
+ // box-shadow:
8333
+ // 0 20px 25px -5px rgba(0, 0, 0, 0.1),
8334
+ // 0 10px 10px -5px rgba(0, 0, 0, 0.04);
8335
+ // border: 1px solid rgba(255, 255, 255, 0.8);
8336
+ // overflow: hidden;
8337
+ // display: flex;
8338
+ // flex-direction: column;
8339
+ // `;
8340
+
8341
+ // // 创建头部
8342
+ // const header = this._createHeader();
8343
+ // this._modal.appendChild(header);
8344
+
8345
+ // // 创建搜索区域
8346
+ // const searchSection = this._createSearchSection();
8347
+ // this._modal.appendChild(searchSection);
8348
+
8349
+ // // 创建选项列表
8350
+ // this._listBox = document.createElement('div');
8351
+ // this._listBox.style.cssText = `
8352
+ // flex: 1;
8353
+ // overflow-y: auto;
8354
+ // padding: 0 1.25rem 1.25rem 1.25rem;
8355
+ // min-height: 10rem;
8356
+ // `;
8357
+ // this._modal.appendChild(this._listBox);
8358
+
8359
+ // // 创建底部按钮
8360
+ // const footer = this._createFooter();
8361
+ // this._modal.appendChild(footer);
8362
+
8363
+ // this._overlay.appendChild(this._modal);
8364
+ // document.body.appendChild(this._overlay);
8365
+
8366
+ // // 聚焦搜索框
8367
+ // // setTimeout(() => {
8368
+ // // const searchInput = this._modal.querySelector('.custom-search-input');
8369
+ // // if (searchInput) {
8370
+ // // searchInput.focus();
8371
+ // // }
8372
+ // // }, 100);
8373
+
8374
+ // // 点击遮罩关闭
8375
+ // this._overlay.addEventListener('click', (e) => {
8376
+ // if (e.target === this._overlay) {
8377
+ // this._closeModal();
8378
+ // }
8379
+ // });
8380
+
8381
+ // // ESC 键关闭
8382
+ // this._handleKeydown = (e) => {
8383
+ // if (e.key === 'Escape') {
8384
+ // this._closeModal();
8385
+ // }
8386
+ // };
8387
+ // document.addEventListener('keydown', this._handleKeydown);
8388
+
8389
+ // this._renderList('');
8390
+ // }
8391
+
8392
+ // _createHeader() {
8393
+ // const header = document.createElement('div');
8394
+ // header.style.cssText = `
8395
+ // padding: 1.25rem 1.25rem 1rem 1.25rem;
8396
+ // border-bottom: 1px solid #e2e8f0;
8397
+ // background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
8398
+ // `;
8399
+
8400
+ // const title = document.createElement('h2');
8401
+ // title.textContent = this._title;
8402
+ // title.style.cssText = `
8403
+ // margin: 0 0 0.5rem 0;
8404
+ // font-size: 1.125rem;
8405
+ // font-weight: 600;
8406
+ // color: #1e293b;
8407
+ // display: flex;
8408
+ // align-items: center;
8409
+ // gap: 0.5rem;
8410
+ // `;
8411
+
8412
+ // // 添加图标
8413
+ // const icon = document.createElement('span');
8414
+ // icon.innerHTML = '📋';
8415
+ // icon.style.fontSize = '1.25rem';
8416
+ // title.insertBefore(icon, title.firstChild);
8417
+
8418
+ // const subtitle = document.createElement('p');
8419
+ // subtitle.textContent = `共 ${this._originalOptions.length} 个选项,已选择 ${this._selectedOptions.length} 个`;
8420
+ // subtitle.style.cssText = `
8421
+ // margin: 0;
8422
+ // font-size: 0.8125rem;
8423
+ // color: #64748b;
8424
+ // `;
8425
+
8426
+ // const closeBtn = document.createElement('button');
8427
+ // closeBtn.innerHTML = '✕';
8428
+ // closeBtn.style.cssText = `
8429
+ // position: absolute;
8430
+ // top: 1rem;
8431
+ // right: 1rem;
8432
+ // width: 1.75rem;
8433
+ // height: 1.75rem;
8434
+ // border: none;
8435
+ // background: #f1f5f9;
8436
+ // color: #64748b;
8437
+ // border-radius: 50%;
8438
+ // cursor: pointer;
8439
+ // display: flex;
8440
+ // align-items: center;
8441
+ // justify-content: center;
8442
+ // font-size: 0.875rem;
8443
+ // transition: all 0.2s ease;
8444
+ // font-weight: 500;
8445
+ // `;
8446
+ // closeBtn.addEventListener('mouseenter', () => {
8447
+ // closeBtn.style.background = '#ef4444';
8448
+ // closeBtn.style.color = 'white';
8449
+ // closeBtn.style.transform = 'rotate(90deg)';
8450
+ // });
8451
+ // closeBtn.addEventListener('mouseleave', () => {
8452
+ // closeBtn.style.background = '#f1f5f9';
8453
+ // closeBtn.style.color = '#64748b';
8454
+ // closeBtn.style.transform = 'rotate(0deg)';
8455
+ // });
8456
+ // closeBtn.addEventListener('click', () => this._closeModal());
8457
+
8458
+ // header.style.position = 'relative';
8459
+ // header.appendChild(title);
8460
+ // header.appendChild(subtitle);
8461
+ // header.appendChild(closeBtn);
8462
+
8463
+ // return header;
8464
+ // }
8465
+
8466
+ // _createSearchSection() {
8467
+ // const section = document.createElement('div');
8468
+ // section.style.cssText = `
8469
+ // padding: 1.25rem 1.25rem 1rem 1.25rem;
8470
+ // `;
8471
+
8472
+ // const searchContainer = document.createElement('div');
8473
+ // searchContainer.style.cssText = `
8474
+ // position: relative;
8475
+ // `;
8476
+
8477
+ // const searchIcon = document.createElement('div');
8478
+ // searchIcon.innerHTML = '🔍';
8479
+ // searchIcon.style.cssText = `
8480
+ // position: absolute;
8481
+ // left: 0.875rem;
8482
+ // top: 50%;
8483
+ // transform: translateY(-50%);
8484
+ // font-size: 0.875rem;
8485
+ // color: #94a3b8;
8486
+ // pointer-events: none;
8487
+ // `;
8488
+
8489
+ // const searchInput = document.createElement('input');
8490
+ // searchInput.placeholder = '搜索选项...';
8491
+ // searchInput.className = 'custom-search-input';
8492
+ // searchInput.style.cssText = `
8493
+ // width: 100%;
8494
+ // padding: 0.75rem 1rem 0.75rem 2.5rem;
8495
+ // border: 2px solid #e2e8f0;
8496
+ // border-radius: 0.5rem;
8497
+ // font-size: 0.875rem;
8498
+ // background: white;
8499
+ // transition: all 0.3s ease;
8500
+ // box-sizing: border-box;
8501
+ // font-family: inherit;
8502
+ // outline: none;
8503
+ // `;
8504
+
8505
+ // searchInput.addEventListener('focus', () => {
8506
+ // searchInput.style.borderColor = '#667eea';
8507
+ // searchInput.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
8508
+ // });
8509
+
8510
+ // searchInput.addEventListener('blur', () => {
8511
+ // searchInput.style.borderColor = '#e2e8f0';
8512
+ // searchInput.style.boxShadow = 'none';
8513
+ // });
8514
+
8515
+ // searchInput.addEventListener('input', (e) => {
8516
+ // this._renderList(e.target.value);
8517
+ // });
8518
+
8519
+ // searchContainer.appendChild(searchIcon);
8520
+ // searchContainer.appendChild(searchInput);
8521
+ // section.appendChild(searchContainer);
8522
+
8523
+ // return section;
8524
+ // }
8525
+
8526
+ // _createFooter() {
8527
+ // const footer = document.createElement('div');
8528
+ // footer.style.cssText = `
8529
+ // padding: 1rem 1.25rem;
8530
+ // background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
8531
+ // border-top: 1px solid #e2e8f0;
8532
+ // display: flex;
8533
+ // justify-content: flex-end;
8534
+ // gap: 0.75rem;
8535
+ // `;
8536
+
8537
+ // const cancelBtn = document.createElement('button');
8538
+ // cancelBtn.textContent = '取消';
8539
+ // cancelBtn.style.cssText = `
8540
+ // padding: 0.5rem 1rem;
8541
+ // background: white;
8542
+ // border: 1px solid #d1d5db;
8543
+ // border-radius: 0.375rem;
8544
+ // cursor: pointer;
8545
+ // font-size: 0.875rem;
8546
+ // font-weight: 500;
8547
+ // color: #374151;
8548
+ // transition: all 0.2s ease;
8549
+ // font-family: inherit;
8550
+ // `;
8551
+ // cancelBtn.addEventListener('mouseenter', () => {
8552
+ // cancelBtn.style.borderColor = '#ef4444';
8553
+ // cancelBtn.style.color = '#ef4444';
8554
+ // cancelBtn.style.transform = 'translateY(-1px)';
8555
+ // });
8556
+ // cancelBtn.addEventListener('mouseleave', () => {
8557
+ // cancelBtn.style.borderColor = '#d1d5db';
8558
+ // cancelBtn.style.color = '#374151';
8559
+ // cancelBtn.style.transform = 'translateY(0)';
8560
+ // });
8561
+ // cancelBtn.addEventListener('click', () => this._closeModal());
8562
+
8563
+ // const okBtn = document.createElement('button');
8564
+ // okBtn.textContent = '确定';
8565
+ // okBtn.style.cssText = `
8566
+ // padding: 0.5rem 1rem;
8567
+ // background: #007cba;
8568
+ // color: white;
8569
+ // border: none;
8570
+ // border-radius: 0.375rem;
8571
+ // cursor: pointer;
8572
+ // font-size: 0.875rem;
8573
+ // font-weight: 500;
8574
+ // transition: all 0.2s ease;
8575
+ // font-family: inherit;
8576
+ // box-shadow: 0 2px 4px rgba(0, 124, 186, 0.2);
8577
+ // `;
8578
+ // okBtn.addEventListener('mouseenter', () => {
8579
+ // okBtn.style.background = '#005a87';
8580
+ // okBtn.style.transform = 'translateY(-1px)';
8581
+ // okBtn.style.boxShadow = '0 4px 8px rgba(0, 124, 186, 0.3)';
8582
+ // });
8583
+ // okBtn.addEventListener('mouseleave', () => {
8584
+ // okBtn.style.background = '#007cba';
8585
+ // okBtn.style.transform = 'translateY(0)';
8586
+ // okBtn.style.boxShadow = '0 2px 4px rgba(0, 124, 186, 0.2)';
8587
+ // });
8588
+ // okBtn.addEventListener('click', () => this._confirm());
8589
+
8590
+ // footer.appendChild(cancelBtn);
8591
+ // footer.appendChild(okBtn);
8592
+ // return footer;
8593
+ // }
8594
+
8595
+ // _renderList(keyword) {
8596
+ // this._listBox.innerHTML = '';
8597
+
8598
+ // const list = keyword
8599
+ // ? this._originalOptions.filter(
8600
+ // (o) =>
8601
+ // o.label.toLowerCase().includes(keyword.toLowerCase()) ||
8602
+ // String(o.value).toLowerCase().includes(keyword.toLowerCase())
8603
+ // )
8604
+ // : this._originalOptions;
8605
+
8606
+ // if (list.length === 0) {
8607
+ // const empty = document.createElement('div');
8608
+ // empty.style.cssText = `
8609
+ // text-align: center;
8610
+ // padding: 2.5rem 1rem;
8611
+ // color: #94a3b8;
8612
+ // `;
8613
+ // empty.innerHTML = `
8614
+ // <div style="font-size: 2.5rem; margin-bottom: 0.75rem; opacity: 0.6;">🔍</div>
8615
+ // <div style="font-size: 1rem; font-weight: 500; margin-bottom: 0.25rem; color: #64748b;">未找到相关结果</div>
8616
+ // <div style="font-size: 0.8125rem;">尝试使用其他关键词搜索</div>
8617
+ // `;
8618
+ // this._listBox.appendChild(empty);
8619
+ // return;
8620
+ // }
8621
+
8622
+ // // 添加选项统计
8623
+ // const stats = document.createElement('div');
8624
+ // stats.style.cssText = `
8625
+ // padding: 0.5rem 0;
8626
+ // font-size: 0.8125rem;
8627
+ // color: #64748b;
8628
+ // border-bottom: 1px solid #f1f5f9;
8629
+ // margin-bottom: 0.5rem;
8630
+ // `;
8631
+ // stats.textContent = `找到 ${list.length} 个相关选项`;
8632
+ // this._listBox.appendChild(stats);
8633
+
8634
+ // list.forEach((opt, index) => {
8635
+ // const item = document.createElement('label');
8636
+ // item.className = 'custom-list-item';
8637
+ // item.style.cssText = `
8638
+ // display: flex;
8639
+ // align-items: center;
8640
+ // padding: 0.75rem;
8641
+ // cursor: pointer;
8642
+ // border-radius: 0.5rem;
8643
+ // margin-bottom: 0.375rem;
8644
+ // transition: all 0.2s ease;
8645
+ // border: 2px solid transparent;
8646
+ // background: white;
8647
+ // position: relative;
8648
+ // overflow: hidden;
8649
+ // `;
8650
+
8651
+ // const checkbox = document.createElement('input');
8652
+ // checkbox.type = 'checkbox';
8653
+ // checkbox.className = 'custom-checkbox';
8654
+ // checkbox.value = opt.value;
8655
+ // checkbox.checked = this._selectedOptions.includes(opt.value);
8656
+ // checkbox.style.marginRight = '0.75rem';
8657
+
8658
+ // const labelSpan = document.createElement('span');
8659
+ // labelSpan.innerHTML = this._highlight(opt.label, keyword);
8660
+ // labelSpan.style.cssText = `
8661
+ // flex: 1;
8662
+ // font-size: 0.875rem;
8663
+ // color: #374151;
8664
+ // line-height: 1.4;
8665
+ // font-weight: 500;
8666
+ // `;
8667
+
8668
+ // // 添加选中状态的视觉反馈
8669
+ // if (checkbox.checked) {
8670
+ // item.style.backgroundColor = '#f0f4ff';
8671
+ // item.style.borderColor = '#667eea';
8672
+ // }
8673
+
8674
+ // checkbox.addEventListener('change', () => {
8675
+ // this._toggle(opt.value);
8676
+
8677
+ // // 更新项目样式
8678
+ // if (checkbox.checked) {
8679
+ // item.style.backgroundColor = '#f0f4ff';
8680
+ // item.style.borderColor = '#667eea';
8681
+ // } else {
8682
+ // item.style.backgroundColor = 'white';
8683
+ // item.style.borderColor = 'transparent';
8684
+ // }
8685
+
8686
+ // // 更新标题中的统计信息
8687
+ // const subtitle = this._modal.querySelector('p');
8688
+ // if (subtitle) {
8689
+ // subtitle.textContent = `共 ${this._originalOptions.length} 个选项,已选择 ${this._selectedOptions.length} 个`;
8690
+ // }
8691
+ // });
8692
+
8693
+ // item.appendChild(checkbox);
8694
+ // item.appendChild(labelSpan);
8695
+
8696
+ // // 添加进入动画
8697
+ // item.style.opacity = '0';
8698
+ // item.style.transform = 'translateY(10px)';
8699
+ // this._listBox.appendChild(item);
8700
+
8701
+ // setTimeout(() => {
8702
+ // item.style.transition = 'all 0.3s ease';
8703
+ // item.style.opacity = '1';
8704
+ // item.style.transform = 'translateY(0)';
8705
+ // }, index * 30);
8706
+ // });
8707
+ // }
8708
+
8709
+ // _highlight(text, key) {
8710
+ // if (!key) return text;
8711
+ // const regex = new RegExp(`(${this._escapeRegExp(key)})`, 'gi');
8712
+ // 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>');
8713
+ // }
8714
+
8715
+ // _escapeRegExp(string) {
8716
+ // return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
8717
+ // }
8718
+
8719
+ // _toggle(value) {
8720
+ // const index = this._selectedOptions.indexOf(value);
8721
+ // if (index >= 0) {
8722
+ // this._selectedOptions.splice(index, 1);
8723
+ // } else {
8724
+ // this._selectedOptions.push(value);
8725
+ // }
8726
+ // }
8727
+
8728
+ // _confirm() {
8729
+ // this._onConfirm({
8730
+ // selectedOptions: this._selectedOptions,
8731
+ // unselectedOptions: this._originalOptions.filter(
8732
+ // (o) => !this._selectedOptions.includes(o.value)
8733
+ // ),
8734
+ // allOptions: this._originalOptions
8735
+ // });
8736
+ // this._closeModal();
8737
+ // }
8738
+
8739
+ // _closeModal() {
8740
+ // if (this._overlay) {
8741
+ // // 添加退出动画
8742
+ // this._modal.style.animation = 'modalSlideIn 0.2s ease-out reverse';
8743
+ // this._overlay.style.animation = 'modalBackdropFadeIn 0.2s ease-out reverse';
8744
+
8745
+ // setTimeout(() => {
8746
+ // if (this._overlay && this._overlay.parentNode) {
8747
+ // document.body.removeChild(this._overlay);
8748
+ // }
8749
+ // this._overlay = null;
8750
+ // this._modal = null;
8751
+ // }, 200);
8752
+
8753
+ // document.removeEventListener('keydown', this._handleKeydown);
8754
+ // }
8755
+ // }
8756
+
8757
+ // onRemove() {
8758
+ // if (this._container) {
8759
+ // this._container.remove();
8760
+ // }
8761
+ // this._closeModal();
8762
+ // }
8763
+ // }
7314
8764
  class CustomOptionsControl {
7315
8765
  constructor(args) {
7316
8766
  const { title, options, onConfirm, icon } = args;
@@ -7334,21 +8784,22 @@ class CustomOptionsControl {
7334
8784
 
7335
8785
  const mainButton = document.createElement('button');
7336
8786
  mainButton.style.cssText = `
7337
- padding: 0;
8787
+ padding: 4px;
7338
8788
  background: white;
7339
- border: 0.0625rem solid #ccc;
8789
+ border: 1px solid #ccc;
7340
8790
  cursor: pointer;
7341
8791
  display: flex;
7342
8792
  align-items: center;
7343
8793
  justify-content: center;
7344
- gap: 0.375rem;
8794
+ width: 28px;
8795
+ height: 28px;
7345
8796
  `;
7346
8797
 
7347
8798
  if (this._icon) {
7348
8799
  const iconWrapper = document.createElement('span');
7349
8800
  iconWrapper.style.cssText = `
7350
- width: 1rem;
7351
- height: 1rem;
8801
+ width: 16px;
8802
+ height: 16px;
7352
8803
  display: inline-flex;
7353
8804
  align-items: center;
7354
8805
  justify-content: center;
@@ -7359,7 +8810,7 @@ class CustomOptionsControl {
7359
8810
  } else {
7360
8811
  const img = document.createElement('img');
7361
8812
  img.src = this._icon;
7362
- img.style.cssText = `width: 1rem; height: 1rem; object-fit: contain;`;
8813
+ img.style.cssText = `width: 16px; height: 16px; object-fit: contain;`;
7363
8814
  iconWrapper.appendChild(img);
7364
8815
  }
7365
8816
 
@@ -7400,17 +8851,6 @@ class CustomOptionsControl {
7400
8851
  to { opacity: 1; }
7401
8852
  }
7402
8853
 
7403
- @keyframes fadeInUp {
7404
- from {
7405
- opacity: 0;
7406
- transform: translateY(20px);
7407
- }
7408
- to {
7409
- opacity: 1;
7410
- transform: translateY(0);
7411
- }
7412
- }
7413
-
7414
8854
  .custom-modal-overlay {
7415
8855
  animation: modalBackdropFadeIn 0.2s ease-out;
7416
8856
  }
@@ -7421,20 +8861,21 @@ class CustomOptionsControl {
7421
8861
 
7422
8862
  .custom-search-input:focus {
7423
8863
  border-color: #667eea !important;
7424
- box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
8864
+ box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.1) !important;
7425
8865
  }
7426
8866
 
7427
8867
  .custom-checkbox {
7428
8868
  position: relative;
7429
8869
  appearance: none;
7430
- width: 1rem;
7431
- height: 1rem;
8870
+ width: 16px;
8871
+ height: 16px;
7432
8872
  border: 2px solid #d1d5db;
7433
- border-radius: 0.25rem;
8873
+ border-radius: 3px;
7434
8874
  background: white;
7435
8875
  cursor: pointer;
7436
8876
  transition: all 0.2s ease;
7437
- margin-right: 0.75rem;
8877
+ margin-right: 8px;
8878
+ flex-shrink: 0;
7438
8879
  }
7439
8880
 
7440
8881
  .custom-checkbox:checked {
@@ -7449,13 +8890,12 @@ class CustomOptionsControl {
7449
8890
  left: 50%;
7450
8891
  transform: translate(-50%, -50%);
7451
8892
  color: white;
7452
- font-size: 0.75rem;
8893
+ font-size: 12px;
7453
8894
  font-weight: bold;
7454
8895
  }
7455
8896
 
7456
8897
  .custom-checkbox:hover {
7457
8898
  border-color: #667eea;
7458
- box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
7459
8899
  }
7460
8900
 
7461
8901
  .custom-list-item {
@@ -7465,11 +8905,10 @@ class CustomOptionsControl {
7465
8905
  .custom-list-item:hover {
7466
8906
  background-color: #f8fafc !important;
7467
8907
  border-color: #e2e8f0 !important;
7468
- transform: translateX(4px) !important;
7469
8908
  }
7470
8909
 
7471
8910
  .custom-modal::-webkit-scrollbar {
7472
- width: 6px;
8911
+ width: 5px;
7473
8912
  }
7474
8913
 
7475
8914
  .custom-modal::-webkit-scrollbar-track {
@@ -7482,8 +8921,73 @@ class CustomOptionsControl {
7482
8921
  border-radius: 3px;
7483
8922
  }
7484
8923
 
7485
- .custom-modal::-webkit-scrollbar-thumb:hover {
7486
- background: linear-gradient(135deg, #5a67d8, #6b46c1);
8924
+ /* 移动端优化样式 */
8925
+ @media (max-height: 500px) and (orientation: landscape) {
8926
+ .custom-modal {
8927
+ max-height: 90vh !important;
8928
+ max-width: 90vw !important;
8929
+ width: 90vw !important;
8930
+ margin: 5vh auto !important;
8931
+ }
8932
+
8933
+ .custom-modal .modal-header {
8934
+ padding: 8px 12px !important;
8935
+ }
8936
+
8937
+ .custom-modal .modal-title {
8938
+ font-size: 13px !important;
8939
+ margin-bottom: 2px !important;
8940
+ }
8941
+
8942
+ .custom-modal .modal-subtitle {
8943
+ font-size: 11px !important;
8944
+ }
8945
+
8946
+ .custom-modal .modal-content {
8947
+ max-height: 60vh !important;
8948
+ min-height: 40vh !important;
8949
+ }
8950
+
8951
+ .custom-modal .list-item {
8952
+ padding: 6px 8px !important;
8953
+ font-size: 12px !important;
8954
+ }
8955
+
8956
+ .custom-modal .modal-footer {
8957
+ padding: 8px 12px !important;
8958
+ position: sticky;
8959
+ bottom: 0;
8960
+ background: #f8fafc;
8961
+ z-index: 10;
8962
+ }
8963
+
8964
+ .custom-modal .modal-footer button {
8965
+ padding: 5px 10px !important;
8966
+ font-size: 12px !important;
8967
+ }
8968
+
8969
+ .custom-modal .search-container {
8970
+ padding: 8px 12px 4px 12px !important;
8971
+ }
8972
+
8973
+ .custom-modal .search-input {
8974
+ padding: 6px 8px 6px 24px !important;
8975
+ font-size: 12px !important;
8976
+ }
8977
+
8978
+ .custom-modal .stats-text {
8979
+ font-size: 11px !important;
8980
+ padding: 2px 0 !important;
8981
+ }
8982
+ }
8983
+
8984
+ /* 小屏幕通用优化 */
8985
+ @media (max-width: 480px) {
8986
+ .custom-modal {
8987
+ width: 95vw !important;
8988
+ max-width: 95vw !important;
8989
+ margin: 2.5vh auto !important;
8990
+ }
7487
8991
  }
7488
8992
  `;
7489
8993
  document.head.appendChild(styles);
@@ -7496,31 +9000,31 @@ class CustomOptionsControl {
7496
9000
  position: fixed;
7497
9001
  top: 0; left: 0; right: 0; bottom: 0;
7498
9002
  background: rgba(0, 0, 0, 0.5);
7499
- backdrop-filter: blur(4px);
7500
- -webkit-backdrop-filter: blur(4px);
9003
+ backdrop-filter: blur(2px);
9004
+ -webkit-backdrop-filter: blur(2px);
7501
9005
  z-index: 10000;
7502
9006
  display: flex;
7503
9007
  justify-content: center;
7504
9008
  align-items: center;
7505
- padding: 1rem;
9009
+ padding: 12px;
7506
9010
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
9011
+ overflow-y: auto;
7507
9012
  `;
7508
9013
 
7509
9014
  this._modal = document.createElement('div');
7510
9015
  this._modal.className = 'custom-modal';
7511
9016
  this._modal.style.cssText = `
7512
9017
  width: 100%;
7513
- max-width: 26rem;
7514
- max-height: 80vh;
7515
- background: linear-gradient(145deg, #ffffff 0%, #f8fafc 100%);
7516
- border-radius: 0.75rem;
7517
- box-shadow:
7518
- 0 20px 25px -5px rgba(0, 0, 0, 0.1),
7519
- 0 10px 10px -5px rgba(0, 0, 0, 0.04);
7520
- border: 1px solid rgba(255, 255, 255, 0.8);
9018
+ max-width: 400px;
9019
+ max-height: 85vh;
9020
+ background: white;
9021
+ border-radius: 8px;
9022
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
9023
+ border: 1px solid #e2e8f0;
7521
9024
  overflow: hidden;
7522
9025
  display: flex;
7523
9026
  flex-direction: column;
9027
+ margin: auto;
7524
9028
  `;
7525
9029
 
7526
9030
  // 创建头部
@@ -7531,13 +9035,15 @@ class CustomOptionsControl {
7531
9035
  const searchSection = this._createSearchSection();
7532
9036
  this._modal.appendChild(searchSection);
7533
9037
 
7534
- // 创建选项列表
9038
+ // 创建选项列表容器
7535
9039
  this._listBox = document.createElement('div');
9040
+ this._listBox.className = 'modal-content';
7536
9041
  this._listBox.style.cssText = `
7537
9042
  flex: 1;
7538
9043
  overflow-y: auto;
7539
- padding: 0 1.25rem 1.25rem 1.25rem;
7540
- min-height: 10rem;
9044
+ padding: 0 16px 12px 16px;
9045
+ min-height: 200px;
9046
+ max-height: 50vh;
7541
9047
  `;
7542
9048
  this._modal.appendChild(this._listBox);
7543
9049
 
@@ -7548,13 +9054,12 @@ class CustomOptionsControl {
7548
9054
  this._overlay.appendChild(this._modal);
7549
9055
  document.body.appendChild(this._overlay);
7550
9056
 
7551
- // 聚焦搜索框
7552
- // setTimeout(() => {
7553
- // const searchInput = this._modal.querySelector('.custom-search-input');
7554
- // if (searchInput) {
7555
- // searchInput.focus();
7556
- // }
7557
- // }, 100);
9057
+ // 检查是否是横屏且高度不足
9058
+ this._checkViewportAndAdjust();
9059
+
9060
+ // 添加窗口调整事件监听
9061
+ this._handleResize = () => this._checkViewportAndAdjust();
9062
+ window.addEventListener('resize', this._handleResize);
7558
9063
 
7559
9064
  // 点击遮罩关闭
7560
9065
  this._overlay.addEventListener('click', (e) => {
@@ -7574,37 +9079,85 @@ class CustomOptionsControl {
7574
9079
  this._renderList('');
7575
9080
  }
7576
9081
 
9082
+ _checkViewportAndAdjust() {
9083
+ if (!this._modal) return;
9084
+
9085
+ const viewportHeight = window.innerHeight;
9086
+ const viewportWidth = window.innerWidth;
9087
+ const isLandscape = viewportWidth > viewportHeight;
9088
+
9089
+ // 如果是横屏且高度较小
9090
+ if (isLandscape && viewportHeight < 500) {
9091
+ this._modal.style.maxHeight = '90vh';
9092
+ this._modal.style.maxWidth = '90vw';
9093
+ this._modal.style.width = '90vw';
9094
+
9095
+ // 调整列表区域高度
9096
+ const listBox = this._modal.querySelector('.modal-content');
9097
+ if (listBox) {
9098
+ listBox.style.maxHeight = '60vh';
9099
+ listBox.style.minHeight = '30vh';
9100
+ }
9101
+
9102
+ // 确保底部按钮可见
9103
+ const footer = this._modal.querySelector('.modal-footer');
9104
+ if (footer) {
9105
+ footer.style.position = 'sticky';
9106
+ footer.style.bottom = '0';
9107
+ footer.style.background = '#f8fafc';
9108
+ footer.style.zIndex = '10';
9109
+ }
9110
+ } else {
9111
+ // 恢复正常样式
9112
+ this._modal.style.maxHeight = '85vh';
9113
+ this._modal.style.maxWidth = '400px';
9114
+ this._modal.style.width = '100%';
9115
+
9116
+ const listBox = this._modal.querySelector('.modal-content');
9117
+ if (listBox) {
9118
+ listBox.style.maxHeight = '50vh';
9119
+ listBox.style.minHeight = '200px';
9120
+ }
9121
+
9122
+ const footer = this._modal.querySelector('.modal-footer');
9123
+ if (footer) {
9124
+ footer.style.position = '';
9125
+ footer.style.bottom = '';
9126
+ footer.style.background = '';
9127
+ footer.style.zIndex = '';
9128
+ }
9129
+ }
9130
+ }
9131
+
7577
9132
  _createHeader() {
7578
9133
  const header = document.createElement('div');
9134
+ header.className = 'modal-header';
7579
9135
  header.style.cssText = `
7580
- padding: 1.25rem 1.25rem 1rem 1.25rem;
9136
+ padding: 16px 16px 12px 16px;
7581
9137
  border-bottom: 1px solid #e2e8f0;
7582
- background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
9138
+ background: #f8fafc;
9139
+ flex-shrink: 0;
7583
9140
  `;
7584
9141
 
7585
9142
  const title = document.createElement('h2');
9143
+ title.className = 'modal-title';
7586
9144
  title.textContent = this._title;
7587
9145
  title.style.cssText = `
7588
- margin: 0 0 0.5rem 0;
7589
- font-size: 1.125rem;
9146
+ margin: 0 0 4px 0;
9147
+ font-size: 15px;
7590
9148
  font-weight: 600;
7591
9149
  color: #1e293b;
7592
9150
  display: flex;
7593
9151
  align-items: center;
7594
- gap: 0.5rem;
9152
+ gap: 6px;
7595
9153
  `;
7596
9154
 
7597
- // 添加图标
7598
- const icon = document.createElement('span');
7599
- icon.innerHTML = '📋';
7600
- icon.style.fontSize = '1.25rem';
7601
- title.insertBefore(icon, title.firstChild);
7602
-
7603
9155
  const subtitle = document.createElement('p');
9156
+ subtitle.className = 'modal-subtitle';
7604
9157
  subtitle.textContent = `共 ${this._originalOptions.length} 个选项,已选择 ${this._selectedOptions.length} 个`;
7605
9158
  subtitle.style.cssText = `
7606
9159
  margin: 0;
7607
- font-size: 0.8125rem;
9160
+ font-size: 12px;
7608
9161
  color: #64748b;
7609
9162
  `;
7610
9163
 
@@ -7612,31 +9165,30 @@ class CustomOptionsControl {
7612
9165
  closeBtn.innerHTML = '✕';
7613
9166
  closeBtn.style.cssText = `
7614
9167
  position: absolute;
7615
- top: 1rem;
7616
- right: 1rem;
7617
- width: 1.75rem;
7618
- height: 1.75rem;
9168
+ top: 12px;
9169
+ right: 12px;
9170
+ width: 24px;
9171
+ height: 24px;
7619
9172
  border: none;
7620
9173
  background: #f1f5f9;
7621
9174
  color: #64748b;
7622
- border-radius: 50%;
9175
+ border-radius: 4px;
7623
9176
  cursor: pointer;
7624
9177
  display: flex;
7625
9178
  align-items: center;
7626
9179
  justify-content: center;
7627
- font-size: 0.875rem;
9180
+ font-size: 12px;
7628
9181
  transition: all 0.2s ease;
7629
9182
  font-weight: 500;
9183
+ flex-shrink: 0;
7630
9184
  `;
7631
9185
  closeBtn.addEventListener('mouseenter', () => {
7632
9186
  closeBtn.style.background = '#ef4444';
7633
9187
  closeBtn.style.color = 'white';
7634
- closeBtn.style.transform = 'rotate(90deg)';
7635
9188
  });
7636
9189
  closeBtn.addEventListener('mouseleave', () => {
7637
9190
  closeBtn.style.background = '#f1f5f9';
7638
9191
  closeBtn.style.color = '#64748b';
7639
- closeBtn.style.transform = 'rotate(0deg)';
7640
9192
  });
7641
9193
  closeBtn.addEventListener('click', () => this._closeModal());
7642
9194
 
@@ -7650,8 +9202,10 @@ class CustomOptionsControl {
7650
9202
 
7651
9203
  _createSearchSection() {
7652
9204
  const section = document.createElement('div');
9205
+ section.className = 'search-container';
7653
9206
  section.style.cssText = `
7654
- padding: 1.25rem 1.25rem 1rem 1.25rem;
9207
+ padding: 12px 16px 8px 16px;
9208
+ flex-shrink: 0;
7655
9209
  `;
7656
9210
 
7657
9211
  const searchContainer = document.createElement('div');
@@ -7663,25 +9217,25 @@ class CustomOptionsControl {
7663
9217
  searchIcon.innerHTML = '🔍';
7664
9218
  searchIcon.style.cssText = `
7665
9219
  position: absolute;
7666
- left: 0.875rem;
9220
+ left: 10px;
7667
9221
  top: 50%;
7668
9222
  transform: translateY(-50%);
7669
- font-size: 0.875rem;
9223
+ font-size: 12px;
7670
9224
  color: #94a3b8;
7671
9225
  pointer-events: none;
7672
9226
  `;
7673
9227
 
7674
9228
  const searchInput = document.createElement('input');
7675
9229
  searchInput.placeholder = '搜索选项...';
7676
- searchInput.className = 'custom-search-input';
9230
+ searchInput.className = 'custom-search-input search-input';
7677
9231
  searchInput.style.cssText = `
7678
9232
  width: 100%;
7679
- padding: 0.75rem 1rem 0.75rem 2.5rem;
7680
- border: 2px solid #e2e8f0;
7681
- border-radius: 0.5rem;
7682
- font-size: 0.875rem;
9233
+ padding: 8px 10px 8px 28px;
9234
+ border: 1px solid #e2e8f0;
9235
+ border-radius: 4px;
9236
+ font-size: 13px;
7683
9237
  background: white;
7684
- transition: all 0.3s ease;
9238
+ transition: all 0.2s ease;
7685
9239
  box-sizing: border-box;
7686
9240
  font-family: inherit;
7687
9241
  outline: none;
@@ -7689,7 +9243,7 @@ class CustomOptionsControl {
7689
9243
 
7690
9244
  searchInput.addEventListener('focus', () => {
7691
9245
  searchInput.style.borderColor = '#667eea';
7692
- searchInput.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)';
9246
+ searchInput.style.boxShadow = '0 0 0 2px rgba(102, 126, 234, 0.1)';
7693
9247
  });
7694
9248
 
7695
9249
  searchInput.addEventListener('blur', () => {
@@ -7710,65 +9264,62 @@ class CustomOptionsControl {
7710
9264
 
7711
9265
  _createFooter() {
7712
9266
  const footer = document.createElement('div');
9267
+ footer.className = 'modal-footer';
7713
9268
  footer.style.cssText = `
7714
- padding: 1rem 1.25rem;
7715
- background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
9269
+ padding: 12px 16px;
9270
+ background: #f8fafc;
7716
9271
  border-top: 1px solid #e2e8f0;
7717
9272
  display: flex;
7718
9273
  justify-content: flex-end;
7719
- gap: 0.75rem;
9274
+ gap: 8px;
9275
+ flex-shrink: 0;
7720
9276
  `;
7721
9277
 
7722
9278
  const cancelBtn = document.createElement('button');
7723
9279
  cancelBtn.textContent = '取消';
7724
9280
  cancelBtn.style.cssText = `
7725
- padding: 0.5rem 1rem;
9281
+ padding: 6px 12px;
7726
9282
  background: white;
7727
9283
  border: 1px solid #d1d5db;
7728
- border-radius: 0.375rem;
9284
+ border-radius: 4px;
7729
9285
  cursor: pointer;
7730
- font-size: 0.875rem;
9286
+ font-size: 13px;
7731
9287
  font-weight: 500;
7732
9288
  color: #374151;
7733
9289
  transition: all 0.2s ease;
7734
9290
  font-family: inherit;
9291
+ min-height: 32px;
7735
9292
  `;
7736
9293
  cancelBtn.addEventListener('mouseenter', () => {
7737
9294
  cancelBtn.style.borderColor = '#ef4444';
7738
9295
  cancelBtn.style.color = '#ef4444';
7739
- cancelBtn.style.transform = 'translateY(-1px)';
7740
9296
  });
7741
9297
  cancelBtn.addEventListener('mouseleave', () => {
7742
9298
  cancelBtn.style.borderColor = '#d1d5db';
7743
9299
  cancelBtn.style.color = '#374151';
7744
- cancelBtn.style.transform = 'translateY(0)';
7745
9300
  });
7746
9301
  cancelBtn.addEventListener('click', () => this._closeModal());
7747
9302
 
7748
9303
  const okBtn = document.createElement('button');
7749
9304
  okBtn.textContent = '确定';
7750
9305
  okBtn.style.cssText = `
7751
- padding: 0.5rem 1rem;
9306
+ padding: 6px 12px;
7752
9307
  background: #007cba;
7753
9308
  color: white;
7754
9309
  border: none;
7755
- border-radius: 0.375rem;
9310
+ border-radius: 4px;
7756
9311
  cursor: pointer;
7757
- font-size: 0.875rem;
9312
+ font-size: 13px;
7758
9313
  font-weight: 500;
7759
9314
  transition: all 0.2s ease;
7760
9315
  font-family: inherit;
7761
- box-shadow: 0 2px 4px rgba(0, 124, 186, 0.2);
9316
+ min-height: 32px;
7762
9317
  `;
7763
9318
  okBtn.addEventListener('mouseenter', () => {
7764
9319
  okBtn.style.background = '#005a87';
7765
- okBtn.style.transform = 'translateY(-1px)';
7766
- okBtn.style.boxShadow = '0 4px 8px rgba(0, 124, 186, 0.3)';
7767
9320
  });
7768
9321
  okBtn.addEventListener('mouseleave', () => {
7769
9322
  okBtn.style.background = '#007cba';
7770
- okBtn.style.transform = 'translateY(0)';
7771
- okBtn.style.boxShadow = '0 2px 4px rgba(0, 124, 186, 0.2)';
7772
9323
  });
7773
9324
  okBtn.addEventListener('click', () => this._confirm());
7774
9325
 
@@ -7792,13 +9343,13 @@ class CustomOptionsControl {
7792
9343
  const empty = document.createElement('div');
7793
9344
  empty.style.cssText = `
7794
9345
  text-align: center;
7795
- padding: 2.5rem 1rem;
9346
+ padding: 40px 16px;
7796
9347
  color: #94a3b8;
7797
9348
  `;
7798
9349
  empty.innerHTML = `
7799
- <div style="font-size: 2.5rem; margin-bottom: 0.75rem; opacity: 0.6;">🔍</div>
7800
- <div style="font-size: 1rem; font-weight: 500; margin-bottom: 0.25rem; color: #64748b;">未找到相关结果</div>
7801
- <div style="font-size: 0.8125rem;">尝试使用其他关键词搜索</div>
9350
+ <div style="font-size: 20px; margin-bottom: 8px; opacity: 0.6;">🔍</div>
9351
+ <div style="font-size: 13px; font-weight: 500; margin-bottom: 4px; color: #64748b;">未找到相关结果</div>
9352
+ <div style="font-size: 12px;">尝试使用其他关键词搜索</div>
7802
9353
  `;
7803
9354
  this._listBox.appendChild(empty);
7804
9355
  return;
@@ -7806,28 +9357,29 @@ class CustomOptionsControl {
7806
9357
 
7807
9358
  // 添加选项统计
7808
9359
  const stats = document.createElement('div');
9360
+ stats.className = 'stats-text';
7809
9361
  stats.style.cssText = `
7810
- padding: 0.5rem 0;
7811
- font-size: 0.8125rem;
9362
+ padding: 4px 0;
9363
+ font-size: 12px;
7812
9364
  color: #64748b;
7813
9365
  border-bottom: 1px solid #f1f5f9;
7814
- margin-bottom: 0.5rem;
9366
+ margin-bottom: 8px;
7815
9367
  `;
7816
9368
  stats.textContent = `找到 ${list.length} 个相关选项`;
7817
9369
  this._listBox.appendChild(stats);
7818
9370
 
7819
9371
  list.forEach((opt, index) => {
7820
9372
  const item = document.createElement('label');
7821
- item.className = 'custom-list-item';
9373
+ item.className = 'custom-list-item list-item';
7822
9374
  item.style.cssText = `
7823
9375
  display: flex;
7824
9376
  align-items: center;
7825
- padding: 0.75rem;
9377
+ padding: 8px;
7826
9378
  cursor: pointer;
7827
- border-radius: 0.5rem;
7828
- margin-bottom: 0.375rem;
7829
- transition: all 0.2s ease;
7830
- border: 2px solid transparent;
9379
+ border-radius: 4px;
9380
+ margin-bottom: 4px;
9381
+ transition: all 0.1s ease;
9382
+ border: 1px solid transparent;
7831
9383
  background: white;
7832
9384
  position: relative;
7833
9385
  overflow: hidden;
@@ -7838,16 +9390,17 @@ class CustomOptionsControl {
7838
9390
  checkbox.className = 'custom-checkbox';
7839
9391
  checkbox.value = opt.value;
7840
9392
  checkbox.checked = this._selectedOptions.includes(opt.value);
7841
- checkbox.style.marginRight = '0.75rem';
9393
+ checkbox.style.marginRight = '8px';
7842
9394
 
7843
9395
  const labelSpan = document.createElement('span');
7844
9396
  labelSpan.innerHTML = this._highlight(opt.label, keyword);
7845
9397
  labelSpan.style.cssText = `
7846
9398
  flex: 1;
7847
- font-size: 0.875rem;
9399
+ font-size: 13px;
7848
9400
  color: #374151;
7849
9401
  line-height: 1.4;
7850
9402
  font-weight: 500;
9403
+ word-break: break-word;
7851
9404
  `;
7852
9405
 
7853
9406
  // 添加选中状态的视觉反馈
@@ -7869,7 +9422,7 @@ class CustomOptionsControl {
7869
9422
  }
7870
9423
 
7871
9424
  // 更新标题中的统计信息
7872
- const subtitle = this._modal.querySelector('p');
9425
+ const subtitle = this._modal.querySelector('.modal-subtitle');
7873
9426
  if (subtitle) {
7874
9427
  subtitle.textContent = `共 ${this._originalOptions.length} 个选项,已选择 ${this._selectedOptions.length} 个`;
7875
9428
  }
@@ -7878,23 +9431,14 @@ class CustomOptionsControl {
7878
9431
  item.appendChild(checkbox);
7879
9432
  item.appendChild(labelSpan);
7880
9433
 
7881
- // 添加进入动画
7882
- item.style.opacity = '0';
7883
- item.style.transform = 'translateY(10px)';
7884
9434
  this._listBox.appendChild(item);
7885
-
7886
- setTimeout(() => {
7887
- item.style.transition = 'all 0.3s ease';
7888
- item.style.opacity = '1';
7889
- item.style.transform = 'translateY(0)';
7890
- }, index * 30);
7891
9435
  });
7892
9436
  }
7893
9437
 
7894
9438
  _highlight(text, key) {
7895
9439
  if (!key) return text;
7896
9440
  const regex = new RegExp(`(${this._escapeRegExp(key)})`, 'gi');
7897
- 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>');
9441
+ return text.replace(regex, '<mark style="background: #fef3c7; padding: 1px 3px; border-radius: 2px; font-weight: 600;">$1</mark>');
7898
9442
  }
7899
9443
 
7900
9444
  _escapeRegExp(string) {
@@ -7923,6 +9467,9 @@ class CustomOptionsControl {
7923
9467
 
7924
9468
  _closeModal() {
7925
9469
  if (this._overlay) {
9470
+ // 移除事件监听
9471
+ window.removeEventListener('resize', this._handleResize);
9472
+
7926
9473
  // 添加退出动画
7927
9474
  this._modal.style.animation = 'modalSlideIn 0.2s ease-out reverse';
7928
9475
  this._overlay.style.animation = 'modalBackdropFadeIn 0.2s ease-out reverse';