feat: 新增平台
This commit is contained in:
@@ -136,9 +136,130 @@ h1, h2, h3, h4, h5, h6 {
|
||||
box-shadow: 0 0 0 3px var(--primary-100);
|
||||
}
|
||||
|
||||
/* Select / Dropdown */
|
||||
/* Custom Select / Dropdown */
|
||||
.ui-select-wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui-select-trigger {
|
||||
width: 100%;
|
||||
padding: 0.625rem 2.5rem 0.625rem 1rem;
|
||||
border: 1px solid var(--secondary-200);
|
||||
border-radius: var(--radius-md);
|
||||
background-color: white;
|
||||
color: var(--text-main);
|
||||
font-size: 0.875rem;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.ui-select-trigger::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 0.75rem;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
border-top: 5px solid var(--secondary-500);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.ui-select-wrapper.open .ui-select-trigger::after {
|
||||
transform: translateY(-50%) rotate(180deg);
|
||||
}
|
||||
|
||||
.ui-select-trigger:hover {
|
||||
border-color: var(--secondary-300);
|
||||
}
|
||||
|
||||
.ui-select-wrapper.open .ui-select-trigger,
|
||||
.ui-select-trigger:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary-500);
|
||||
box-shadow: 0 0 0 3px var(--primary-100);
|
||||
}
|
||||
|
||||
.ui-select-trigger .placeholder {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.ui-select-dropdown {
|
||||
position: absolute;
|
||||
top: calc(100% + 4px);
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: white;
|
||||
border: 1px solid var(--secondary-200);
|
||||
border-radius: var(--radius-md);
|
||||
box-shadow: var(--shadow-lg);
|
||||
z-index: 1000;
|
||||
max-height: 240px;
|
||||
overflow-y: auto;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateY(-8px);
|
||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.ui-select-wrapper.open .ui-select-dropdown {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.ui-select-option {
|
||||
padding: 0.625rem 1rem;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.ui-select-option:hover {
|
||||
background: var(--secondary-50);
|
||||
}
|
||||
|
||||
.ui-select-option.selected {
|
||||
background: var(--primary-50);
|
||||
color: var(--primary-700);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.ui-select-option.selected::before {
|
||||
content: '✓';
|
||||
font-size: 0.75rem;
|
||||
color: var(--primary-600);
|
||||
}
|
||||
|
||||
.ui-select-option:first-child {
|
||||
border-radius: var(--radius-md) var(--radius-md) 0 0;
|
||||
}
|
||||
|
||||
.ui-select-option:last-child {
|
||||
border-radius: 0 0 var(--radius-md) var(--radius-md);
|
||||
}
|
||||
|
||||
/* 隐藏原生 select */
|
||||
.ui-select-wrapper select.ui-select-native {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 兼容旧的 select.ui-input 样式 */
|
||||
select.ui-input,
|
||||
.ui-select {
|
||||
select.ui-select {
|
||||
width: 100%;
|
||||
padding: 0.625rem 2.5rem 0.625rem 1rem;
|
||||
border: 1px solid var(--secondary-200);
|
||||
@@ -158,14 +279,14 @@ select.ui-input,
|
||||
}
|
||||
|
||||
select.ui-input:focus,
|
||||
.ui-select:focus {
|
||||
select.ui-select:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary-500);
|
||||
box-shadow: 0 0 0 3px var(--primary-100);
|
||||
}
|
||||
|
||||
select.ui-input:hover,
|
||||
.ui-select:hover {
|
||||
select.ui-select:hover {
|
||||
border-color: var(--secondary-300);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,107 @@
|
||||
// 现代化UI组件库
|
||||
const UI = {
|
||||
// 初始化所有自定义下拉框
|
||||
initSelects() {
|
||||
document.querySelectorAll('select.ui-input, select.ui-select').forEach(select => {
|
||||
if (select.dataset.uiInit) return; // 已初始化
|
||||
this.createCustomSelect(select);
|
||||
});
|
||||
},
|
||||
|
||||
// 创建自定义下拉框
|
||||
createCustomSelect(select) {
|
||||
select.dataset.uiInit = 'true';
|
||||
|
||||
// 创建包装器
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'ui-select-wrapper';
|
||||
select.parentNode.insertBefore(wrapper, select);
|
||||
|
||||
// 隐藏原生 select
|
||||
select.classList.add('ui-select-native');
|
||||
wrapper.appendChild(select);
|
||||
|
||||
// 创建触发器
|
||||
const trigger = document.createElement('div');
|
||||
trigger.className = 'ui-select-trigger';
|
||||
trigger.tabIndex = 0;
|
||||
wrapper.appendChild(trigger);
|
||||
|
||||
// 创建下拉菜单
|
||||
const dropdown = document.createElement('div');
|
||||
dropdown.className = 'ui-select-dropdown';
|
||||
wrapper.appendChild(dropdown);
|
||||
|
||||
// 更新选项
|
||||
const updateOptions = () => {
|
||||
dropdown.innerHTML = '';
|
||||
const selectedValue = select.value;
|
||||
let selectedText = '';
|
||||
|
||||
Array.from(select.options).forEach(option => {
|
||||
const optionEl = document.createElement('div');
|
||||
optionEl.className = 'ui-select-option';
|
||||
optionEl.dataset.value = option.value;
|
||||
optionEl.textContent = option.textContent;
|
||||
|
||||
if (option.value === selectedValue) {
|
||||
optionEl.classList.add('selected');
|
||||
selectedText = option.textContent;
|
||||
}
|
||||
|
||||
optionEl.addEventListener('click', () => {
|
||||
select.value = option.value;
|
||||
select.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
wrapper.classList.remove('open');
|
||||
updateTrigger();
|
||||
});
|
||||
|
||||
dropdown.appendChild(optionEl);
|
||||
});
|
||||
|
||||
return selectedText;
|
||||
};
|
||||
|
||||
// 更新触发器显示
|
||||
const updateTrigger = () => {
|
||||
const selectedText = updateOptions();
|
||||
if (selectedText) {
|
||||
trigger.innerHTML = `<span>${selectedText}</span>`;
|
||||
} else {
|
||||
trigger.innerHTML = `<span class="placeholder">${select.options[0]?.textContent || '请选择'}</span>`;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化
|
||||
updateTrigger();
|
||||
|
||||
// 点击触发器
|
||||
trigger.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
// 关闭其他下拉框
|
||||
document.querySelectorAll('.ui-select-wrapper.open').forEach(w => {
|
||||
if (w !== wrapper) w.classList.remove('open');
|
||||
});
|
||||
wrapper.classList.toggle('open');
|
||||
});
|
||||
|
||||
// 键盘支持
|
||||
trigger.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
wrapper.classList.toggle('open');
|
||||
} else if (e.key === 'Escape') {
|
||||
wrapper.classList.remove('open');
|
||||
}
|
||||
});
|
||||
|
||||
// 监听原生 select 变化
|
||||
select.addEventListener('change', updateTrigger);
|
||||
|
||||
// 监听选项变化(用于动态更新)
|
||||
const observer = new MutationObserver(updateTrigger);
|
||||
observer.observe(select, { childList: true, subtree: true });
|
||||
},
|
||||
// 显示通知消息
|
||||
notify(message, type = 'info', duration = 3000) {
|
||||
const container = document.getElementById('notification-container') || this.createNotificationContainer();
|
||||
@@ -118,3 +220,20 @@ const UI = {
|
||||
return icons[type] || icons.info;
|
||||
}
|
||||
};
|
||||
|
||||
// 点击外部关闭下拉框
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!e.target.closest('.ui-select-wrapper')) {
|
||||
document.querySelectorAll('.ui-select-wrapper.open').forEach(w => {
|
||||
w.classList.remove('open');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 页面加载完成后自动初始化下拉框
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
UI.initSelects();
|
||||
});
|
||||
|
||||
// 提供手动刷新方法(用于动态加载的内容)
|
||||
UI.refreshSelects = UI.initSelects;
|
||||
|
||||
Reference in New Issue
Block a user