feat(admin): 添加形状选择器的原生覆盖层并改进交互体验
为形状选择器添加原生覆盖层,提供更好的视觉预览和交互体验 重构相关JavaScript代码,将覆盖层初始化逻辑移至主函数中 调整样式以保持UI一致性
This commit is contained in:
parent
a64c19750f
commit
4698c4d793
|
|
@ -155,6 +155,57 @@
|
||||||
}
|
}
|
||||||
renderExistingShapeCardPreviews();
|
renderExistingShapeCardPreviews();
|
||||||
|
|
||||||
|
function initShapeNativeOverlay(){
|
||||||
|
if (!shapeNativeOverlay) { return; }
|
||||||
|
var nodes = shapeNativeOverlay.querySelectorAll('.yoone-snow-shape-native-item');
|
||||||
|
nodes.forEach(function(btn){
|
||||||
|
var key = btn.getAttribute('data-shape-key');
|
||||||
|
var host = btn.querySelector('.yoone-snow-shape-native-preview');
|
||||||
|
if (host && (!host.childNodes || host.childNodes.length === 0)){
|
||||||
|
var previewEl = createShapePreviewElement(key);
|
||||||
|
if (previewEl){
|
||||||
|
try { previewEl.style.backgroundColor = 'transparent'; } catch(e){}
|
||||||
|
try { previewEl.style.border = 'none'; } catch(e){}
|
||||||
|
try { previewEl.style.borderRadius = '0'; } catch(e){}
|
||||||
|
try { previewEl.style.marginRight = '0'; } catch(e){}
|
||||||
|
try { previewEl.style.margin = '0'; } catch(e){}
|
||||||
|
try { previewEl.style.width = '28px'; } catch(e){}
|
||||||
|
try { previewEl.style.height = '28px'; } catch(e){}
|
||||||
|
host.appendChild(previewEl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
btn.addEventListener('click', function(){
|
||||||
|
if (shapeLabelPreviewHost){
|
||||||
|
while (shapeLabelPreviewHost.firstChild){ shapeLabelPreviewHost.removeChild(shapeLabelPreviewHost.firstChild); }
|
||||||
|
var previewEl2 = createShapePreviewElement(key);
|
||||||
|
if (previewEl2){
|
||||||
|
try { previewEl2.style.backgroundColor = 'transparent'; } catch(e){}
|
||||||
|
try { previewEl2.style.border = 'none'; } catch(e){}
|
||||||
|
try { previewEl2.style.borderRadius = '0'; } catch(e){}
|
||||||
|
try { previewEl2.style.marginRight = '0'; } catch(e){}
|
||||||
|
try { previewEl2.style.margin = '0'; } catch(e){}
|
||||||
|
try { previewEl2.style.width = '28px'; } catch(e){}
|
||||||
|
try { previewEl2.style.height = '28px'; } catch(e){}
|
||||||
|
shapeLabelPreviewHost.style.display = 'flex';
|
||||||
|
shapeLabelPreviewHost.appendChild(previewEl2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addShapeBox(key);
|
||||||
|
if (shapeNativeOverlay){ shapeNativeOverlay.style.display = 'none'; }
|
||||||
|
if (shapeAddSelect){ shapeAddSelect.value = ''; }
|
||||||
|
if (shapeLabelPreviewHost){
|
||||||
|
while (shapeLabelPreviewHost.firstChild){ shapeLabelPreviewHost.removeChild(shapeLabelPreviewHost.firstChild); }
|
||||||
|
shapeLabelPreviewHost.style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
document.addEventListener('click', function(e){
|
||||||
|
var t = e.target;
|
||||||
|
var inside = (t === shapeNativeOverlay || (shapeNativeOverlay && shapeNativeOverlay.contains(t)) || (shapeAddSelect && (t === shapeAddSelect || shapeAddSelect.contains(t))));
|
||||||
|
if (!inside && shapeNativeOverlay){ shapeNativeOverlay.style.display = 'none'; }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 添加形状卡片 并插入预览与隐藏输入 用于保存选择
|
// 添加形状卡片 并插入预览与隐藏输入 用于保存选择
|
||||||
function addShapeBox(shapeKey){
|
function addShapeBox(shapeKey){
|
||||||
if (!shapeListContainer) { return; }
|
if (!shapeListContainer) { return; }
|
||||||
|
|
@ -561,6 +612,16 @@
|
||||||
// 僅使用原生下拉 不再彈出自定義覆蓋列表
|
// 僅使用原生下拉 不再彈出自定義覆蓋列表
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shapeAddSelect && shapeNativeOverlay){
|
||||||
|
initShapeNativeOverlay();
|
||||||
|
var openOverlay = function(){
|
||||||
|
try { shapeNativeOverlay.style.width = (shapeAddSelect.offsetWidth || 280) + 'px'; } catch(e){}
|
||||||
|
shapeNativeOverlay.style.display = 'block';
|
||||||
|
};
|
||||||
|
shapeAddSelect.addEventListener('mousedown', function(e){ e.preventDefault(); openOverlay(); });
|
||||||
|
shapeAddSelect.addEventListener('click', function(e){ e.preventDefault(); openOverlay(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 切换类型面板 显示对应控件 其他隐藏
|
// 切换类型面板 显示对应控件 其他隐藏
|
||||||
|
|
@ -666,52 +727,6 @@
|
||||||
} else {
|
} else {
|
||||||
initAdminMedia();
|
initAdminMedia();
|
||||||
}
|
}
|
||||||
})();
|
|
||||||
// 初始化內嵌下拉的預覽與點擊交互
|
|
||||||
(function(){
|
|
||||||
if (!shapeNativeOverlay) { return; }
|
|
||||||
var nodes = shapeNativeOverlay.querySelectorAll('.yoone-snow-shape-native-item');
|
|
||||||
nodes.forEach(function(btn){
|
|
||||||
var key = btn.getAttribute('data-shape-key');
|
|
||||||
var host = btn.querySelector('.yoone-snow-shape-native-preview');
|
|
||||||
if (host && host.childNodes && host.childNodes.length === 0){
|
|
||||||
var previewEl = createShapePreviewElement(key);
|
|
||||||
if (previewEl){
|
|
||||||
try { previewEl.style.backgroundColor = 'transparent'; } catch(e){}
|
|
||||||
try { previewEl.style.border = 'none'; } catch(e){}
|
|
||||||
try { previewEl.style.borderRadius = '0'; } catch(e){}
|
|
||||||
host.appendChild(previewEl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
btn.addEventListener('click', function(){
|
|
||||||
// 先更新左側預覽 再添加卡片 並關閉內嵌下拉
|
|
||||||
if (shapeLabelPreviewHost){
|
|
||||||
while (shapeLabelPreviewHost.firstChild){ shapeLabelPreviewHost.removeChild(shapeLabelPreviewHost.firstChild); }
|
|
||||||
var previewEl2 = createShapePreviewElement(key);
|
|
||||||
if (previewEl2){
|
|
||||||
try { previewEl2.style.backgroundColor = 'transparent'; } catch(e){}
|
|
||||||
try { previewEl2.style.border = 'none'; } catch(e){}
|
|
||||||
try { previewEl2.style.borderRadius = '0'; } catch(e){}
|
|
||||||
shapeLabelPreviewHost.style.display = 'flex';
|
|
||||||
shapeLabelPreviewHost.appendChild(previewEl2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addShapeBox(key);
|
|
||||||
if (shapeNativeOverlay){ shapeNativeOverlay.style.display = 'none'; }
|
|
||||||
// 重置原生下拉為未選中 清空左側預覽 保持簡潔
|
|
||||||
if (shapeAddSelect){ shapeAddSelect.value = ''; }
|
|
||||||
if (shapeLabelPreviewHost){
|
|
||||||
while (shapeLabelPreviewHost.firstChild){ shapeLabelPreviewHost.removeChild(shapeLabelPreviewHost.firstChild); }
|
|
||||||
shapeLabelPreviewHost.style.display = 'none';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// 外部點擊時關閉內嵌下拉
|
|
||||||
document.addEventListener('click', function(e){
|
|
||||||
var t = e.target;
|
|
||||||
var inside = (t === shapeNativeOverlay || shapeNativeOverlay.contains(t) || (shapeAddSelect && (t === shapeAddSelect || shapeAddSelect.contains(t))));
|
|
||||||
if (!inside){ shapeNativeOverlay.style.display = 'none'; }
|
|
||||||
});
|
|
||||||
})();
|
})();
|
||||||
function t(key, fallback){
|
function t(key, fallback){
|
||||||
var dict = (typeof window !== 'undefined' && window.YooneSnowAdmin && window.YooneSnowAdmin.i18n) ? window.YooneSnowAdmin.i18n : {};
|
var dict = (typeof window !== 'undefined' && window.YooneSnowAdmin && window.YooneSnowAdmin.i18n) ? window.YooneSnowAdmin.i18n : {};
|
||||||
|
|
|
||||||
|
|
@ -514,14 +514,20 @@ function yoone_snow_register_settings() {
|
||||||
echo '</select></label>';
|
echo '</select></label>';
|
||||||
echo '</div>';
|
echo '</div>';
|
||||||
echo '<div id="yooneSnowAddDefaultPane" style="display:flex;gap:8px;align-items:center;position:relative;">';
|
echo '<div id="yooneSnowAddDefaultPane" style="display:flex;gap:8px;align-items:center;position:relative;">';
|
||||||
echo '<div id="yooneSnowAddShapeLabelPreview" style="width:32px;height:32px;display:none;align-items:center;justify-content:center;"></div>';
|
echo '<div id="yooneSnowAddShapeLabelPreview" style="width:32px;height:32px;display:none;align-items:center;justify-content:center;background-color:#808080;border-radius:4px;"></div>';
|
||||||
echo '<select id="yooneSnowAddShapeSelect" style="min-width:240px;"><option value="">' . esc_html__('Select shape', 'yoone-snow') . '</option>';
|
echo '<select id="yooneSnowAddShapeSelect" style="min-width:240px;"><option value="">' . esc_html__('Select shape', 'yoone-snow') . '</option>';
|
||||||
foreach ($options as $key => $label) {
|
foreach ($options as $key => $label) {
|
||||||
echo '<option value="' . esc_attr($key) . '">' . esc_html($label) . '</option>';
|
echo '<option value="' . esc_attr($key) . '">' . esc_html($label) . '</option>';
|
||||||
}
|
}
|
||||||
echo '</select>';
|
echo '</select>';
|
||||||
|
echo '<div id="yooneSnowShapeNativeOverlay" style="display:none;position:absolute;top:100%;left:0;width:280px;max-height:240px;overflow:auto;background:#fff;border:1px solid #ddd;border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,0.08);padding:6px;z-index:9999;">';
|
||||||
|
foreach ($options as $key => $label) {
|
||||||
|
echo '<button type="button" class="yoone-snow-shape-native-item" data-shape-key="' . esc_attr($key) . '" style="display:flex;align-items:center;width:100%;padding:6px;margin:0;background:none;border:none;border-radius:4px;cursor:pointer;text-align:left;">';
|
||||||
|
echo '<div class="yoone-snow-shape-native-preview" style="font-size:28px;line-height:32px;width:32px;height:32px;margin-right:8px;display:flex;align-items:center;justify-content:center;background-color:#e6e6e6;border:1px solid #ddd;border-radius:4px;"></div>';
|
||||||
|
echo '<span>' . esc_html($label) . '</span>';
|
||||||
|
echo '</button>';
|
||||||
|
}
|
||||||
|
echo '</div>';
|
||||||
echo '</div>';
|
echo '</div>';
|
||||||
echo '<div id="yooneSnowAddEmojiPane" style="display:none;gap:8px;align-items:center;">';
|
echo '<div id="yooneSnowAddEmojiPane" style="display:none;gap:8px;align-items:center;">';
|
||||||
echo '<select id="yooneSnowEmojiSelect" style="min-width:240px;"><option value="">' . esc_html__('Select emoji', 'yoone-snow') . '</option></select>';
|
echo '<select id="yooneSnowEmojiSelect" style="min-width:240px;"><option value="">' . esc_html__('Select emoji', 'yoone-snow') . '</option></select>';
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue