diff --git a/assets/admin/src/schema/sections/page-display/index.js b/assets/admin/src/schema/sections/page-display/index.js index 1b40dcab..a9786a1b 100644 --- a/assets/admin/src/schema/sections/page-display/index.js +++ b/assets/admin/src/schema/sections/page-display/index.js @@ -36,7 +36,6 @@ export const pageDisplaySchemas = { header_fixed: true, header_search_enabled: true, header_user_menu: true, - header_publish_btn: true, header_mobile_drawer: true, header_nav_style: 'default', header_max_width: 1200, @@ -52,7 +51,7 @@ export const pageDisplaySchemas = { header_newposts_enabled: true, header_newposts_text: ' 发布', header_newposts_radius: true, - header_newposts_class: '', + header_newposts_class: 'jb-blue', header_theme_custom: false, header_theme_bg_custom: '', header_theme_bg: '', @@ -124,10 +123,17 @@ export const pageDisplaySchemas = { title: '发布按钮', icon: 'fas fa-pen', fields: [ - { key: 'header_newposts_enabled', label: '启用发布按钮', type: 'switch', default: true, help: '导航栏显示前台发布入口' }, + { key: 'header_newposts_enabled', label: '启用发布按钮', type: 'switch', default: true, help: '顶部导航显示发布入口(对齐 zibll nav_newposts)' }, { key: 'header_newposts_text', label: '按钮文案', type: 'input', default: ' 发布', dependsOn: { key: 'header_newposts_enabled', value: true } }, { key: 'header_newposts_radius', label: '按钮圆角(胶囊)', type: 'switch', default: true, dependsOn: { key: 'header_newposts_enabled', value: true }, help: '开启后两端大圆角,对齐 zibll nav_newposts_radius' }, - { key: 'header_newposts_class', label: '自定义 CSS 类', type: 'input', default: '', dependsOn: { key: 'header_newposts_enabled', value: true } }, + { key: 'header_newposts_class', label: '按钮颜色', type: 'select', default: 'jb-blue', options: [ + { label: '蓝色', value: 'jb-blue' }, + { label: '红色', value: 'jb-red' }, + { label: '绿色', value: 'jb-green' }, + { label: '黄色', value: 'jb-yellow' }, + { label: '紫色', value: 'jb-purple' }, + { label: '粉色', value: 'jb-pink' }, + ], dependsOn: { key: 'header_newposts_enabled', value: true } }, { key: 'header_newposts_types', label: '发布类型', type: 'select', multiple: true, default: ['post'], options: [ { label: '文章', value: 'post' }, { label: '帖子', value: 'topic' }, @@ -161,7 +167,6 @@ export const pageDisplaySchemas = { fields: [ { key: 'header_search_enabled', label: '搜索入口', type: 'switch', default: true }, { key: 'header_user_menu', label: '用户菜单', type: 'switch', default: true }, - { key: 'header_publish_btn', label: '发布按钮', type: 'switch', default: true, help: '管理员可见的前台发布入口' }, { key: 'header_mobile_drawer', label: '移动端抽屉导航', type: 'switch', default: true }, ], }, diff --git a/assets/css/frontend/nav.css b/assets/css/frontend/nav.css index 207f608b..97ddde74 100644 --- a/assets/css/frontend/nav.css +++ b/assets/css/frontend/nav.css @@ -3,6 +3,7 @@ @import url("nav/zib-mobile-navbar.css"); @import url("nav/zib-senior-submenu.css"); @import url("nav/zib-utilities.css"); +@import url("nav/zib-search-box.css"); @import url("nav/header-menu-buttons.css"); @import url("nav/header-userbox.css"); @import url("nav/dark-mode-submenu.css"); diff --git a/assets/css/frontend/nav/zib-search-box.css b/assets/css/frontend/nav/zib-search-box.css new file mode 100644 index 00000000..65d28747 --- /dev/null +++ b/assets/css/frontend/nav/zib-search-box.css @@ -0,0 +1,194 @@ +/* zibll search-box / menu_search panel parity */ + +/* Layout-2 focus dropdown */ +.navbar-collapse .form-group.relative.dropdown { + position: relative; +} + +.navbar-collapse .search-input ~ .dropdown-menu, +.navbar-collapse .form-group .dropdown-menu.hover-show-con { + display: none; + position: absolute; + left: 0; + top: 100%; + z-index: 1002; + min-width: 320px; + width: max(320px, 100%); + max-width: 460px; + margin-top: 10px; + padding: 10px; + background: var(--main-bg-color, #fff); + border-radius: var(--main-radius, 8px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1); + visibility: visible; + opacity: 1; +} + +.navbar-form.hover-show:hover .dropdown-menu.hover-show-con, +.navbar-form.hover-show:focus-within .dropdown-menu.hover-show-con, +.navbar-collapse .form-group:focus-within .dropdown-menu.hover-show-con, +.navbar-collapse .dropdown-menu.hover-show-con.is-open { + display: block; +} + +/* Search box body */ +.search-input .search-keywords { + padding: 6px 10px 2px; +} +.search-input .search-keywords > p { + margin: 0 0 6px; + font-size: 0.9em; +} +.search-input .search-keywords .but, +.search-input .search-keywords a.but { + display: inline-block; + margin: 0 6px 6px 0; + padding: 2px 10px; + font-size: 0.85em; + border-radius: 20px; + background: var(--main-shadow, rgba(0, 0, 0, 0.05)); + color: inherit; + text-decoration: none; +} +.search-input .search-keywords .but:hover { + color: var(--focus-color, #2997f7); +} + +.search-input .history-search .trash-history-search { + text-decoration: none; + opacity: 0.7; +} +.search-input .history-search .trash-history-search:hover { + opacity: 1; + color: var(--focus-color, #2997f7); +} + +/* Hot posts swiper row */ +.search-input .relates-thumb { + overflow: hidden; +} +.search-input .relates-thumb .swiper-container, +.search-input .relates-thumb .swiper-scroll { + overflow: hidden; + position: relative; +} +.search-input .relates-thumb .swiper-wrapper { + display: flex; + overflow-x: auto; + scroll-snap-type: x mandatory; + -webkit-overflow-scrolling: touch; + gap: 0; + scrollbar-width: none; +} +.search-input .relates-thumb .swiper-wrapper::-webkit-scrollbar { + display: none; +} +.search-input .relates-thumb .swiper-slide { + flex: 0 0 auto; + scroll-snap-align: start; +} +.search-input .relates-thumb .swiper-button-prev, +.search-input .relates-thumb .swiper-button-next { + display: none; +} + +/* Full navbar-search slide (layout 1/3) */ +.navbar-search { + position: fixed; + left: 0; + right: 0; + top: 0; + width: 100%; +} +.navbar-search .container { + max-width: var(--nav-max-width, 1200px); + margin: 0 auto; + position: relative; + padding: 10px 15px 20px; +} +.navbar-search .navbar-search-close, +.navbar-search > .container > .close { + position: absolute; + right: 12px; + top: 12px; + z-index: 2; + background: none; + border: 0; + font-size: 1.25rem; + color: inherit; + cursor: pointer; + opacity: 0.7; +} +.navbar-search .navbar-search-close:hover { + opacity: 1; +} + +/* Line form (full search box) */ +.search-input .line-form { + display: flex; + align-items: stretch; + border-bottom: 1px solid rgba(0, 0, 0, 0.08); + position: relative; +} +.search-input .search-input-text { + flex: 1; + position: relative; + min-width: 0; +} +.search-input .line-form-input { + width: 100%; + border: 0; + background: transparent; + padding: 12px 40px 12px 4px; + font-size: 1.05em; + outline: none; + color: inherit; +} +.search-input .scale-placeholder { + position: absolute; + left: 4px; + top: 50%; + transform: translateY(-50%); + pointer-events: none; + opacity: 0.45; + transition: 0.2s; +} +.search-input .scale-placeholder.is-focus, +.search-input .line-form-input:focus + .line-form-line + .scale-placeholder, +.search-input .line-form-input:not([value=""]) ~ .scale-placeholder { + opacity: 0; +} +.search-input .option-dropdown { + flex-shrink: 0; + display: flex; + align-items: center; + padding-right: 8px; +} +.search-input .search-type-but-average .but { + margin: 0 4px; +} +.search-input .search-type-but-average .but.active { + color: #fff; + background: var(--focus-color, #2997f7); +} + +/* Live suggest (extension) */ +.navbar-inline-search-suggest__item, +.aksrt-menu-search-suggest a { + display: flex; + justify-content: space-between; + gap: 10px; + padding: 6px 4px; + text-decoration: none; + color: inherit; +} +.navbar-inline-search-suggest__item:hover { + color: var(--focus-color, #2997f7); +} + +body.theme-dark .navbar-collapse .form-group .dropdown-menu.hover-show-con, +html.dark .navbar-collapse .form-group .dropdown-menu.hover-show-con, +body.dark-theme .navbar-collapse .form-group .dropdown-menu.hover-show-con { + background: var(--main-bg-color, #1e1e1e); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35); +} diff --git a/assets/js/core/search.js b/assets/js/core/search.js index ca26bd77..e6737e2f 100644 --- a/assets/js/core/search.js +++ b/assets/js/core/search.js @@ -291,19 +291,20 @@ document.querySelectorAll(".main-search-btn, .nav-search-toggle, [data-aksrt-open-search]").forEach(function (btn) { btn.addEventListener("click", function (e) { + // Top bar uses zibll .navbar-search slide — skip tabbar overlay. + var tgt = btn.getAttribute("data-target") || ""; + if (tgt.indexOf("navbar-search") !== -1 || tgt.indexOf("main-search") !== -1) { + return; + } e.preventDefault(); setOpen(true); }); }); - // Zibll-compatible data-toggle-class for .navbar-search - document.addEventListener("click", function (e) { - var toggle = e.target.closest('[data-toggle-class][data-target=".navbar-search"], [data-toggle-class][data-target=".main-search"]'); - if (!toggle) return; - e.preventDefault(); - var isOpen = mobileOverlay && !mobileOverlay.hasAttribute("hidden"); - setOpen(!isOpen); - }); + // Top-nav .navbar-search is toggled by aksrt-runtime (data-toggle-class="show"). + // Do NOT redirect those clicks into the footer tabbar overlay. + // Only open tabbar overlay for explicit main-search-btn without .navbar-search target + // (handled above via .main-search-btn listeners). if (historyClear) { historyClear.addEventListener("click", function () { diff --git a/assets/js/header-inline-search.js b/assets/js/header-inline-search.js index ef356dbd..d4604713 100644 --- a/assets/js/header-inline-search.js +++ b/assets/js/header-inline-search.js @@ -1,6 +1,7 @@ /** - * Layout-2 navbar search — zibll remote-box + live suggestions. - * Loads aksrt_menu_search panel (history/hot/posts), then suggests on input. + * Layout-2 navbar search — zibll remote-box + search-input panel. + * Loads menu_search panel (.dropdown-menu.hover-show-con > .search-input), + * fills guest history from localStorage, live suggestions optional. */ (function () { "use strict"; @@ -40,6 +41,24 @@ } catch (e) {} } + function keywordChips(list) { + return (list || []) + .map(function (kw) { + return ( + '' + + kw + + " " + ); + }) + .join(""); + } + function loadRemote(box) { if (!box || box.getAttribute("data-loaded") === "1") return; var url = box.getAttribute("remote-box") || box.getAttribute("data-url"); @@ -58,57 +77,51 @@ box.innerHTML = ""; return; } + var parent = box.parentNode; box.outerHTML = html; - var form = document.querySelector('form[data-aksrt-search-form="inline"]'); + var form = parent ? parent.closest("form") : document.querySelector('form[data-aksrt-search-form="inline"]'); if (form) enhancePanel(form); + initSwiperScroll(form || document); }) .catch(function () { box.removeAttribute("data-loaded"); }); } - function enhancePanel(form) { - var group = form.querySelector(".form-group"); - var panel = form.querySelector(".navbar-inline-search-panel"); - var input = form.querySelector(".search-input"); - if (!group || !input) return; + function initSwiperScroll(root) { + if (!root || typeof window.Swiper === "undefined") return; + root.querySelectorAll(".relates-thumb .swiper-container:not(.swiper-initialized)").forEach(function (el) { + try { + new window.Swiper(el, { + slidesPerView: "auto", + freeMode: true, + navigation: { + nextEl: el.querySelector(".swiper-button-next"), + prevEl: el.querySelector(".swiper-button-prev"), + }, + }); + } catch (e) {} + }); + } - // Merge guest local history into panel list. - var histList = form.querySelector(".aksrt-menu-search-history__list"); + function enhancePanel(form) { + if (!form || form._aksrtMenuSearchEnhanced) return; + form._aksrtMenuSearchEnhanced = 1; + + var input = form.querySelector(".search-input, input[name='s']"); + var histList = form.querySelector(".history-search-list, .history-search > div:last-child"); + + // Guest local history → panel. if (histList && !(window.aksrtData && aksrtData.isLoggedIn)) { var local = readLocalHistory(); if (local.length) { - histList.innerHTML = local - .map(function (kw) { - return ( - '' + - kw + - " " - ); - }) - .join(""); + histList.innerHTML = keywordChips(local); } } - - form.querySelectorAll("[data-aksrt-menu-search-type]").forEach(function (chip) { - chip.addEventListener("click", function (e) { - e.preventDefault(); - var v = chip.getAttribute("data-aksrt-menu-search-type") || "post"; - var tin = form.querySelector('input[name="aksrt_search_type"]'); - if (tin) tin.value = v; - form.querySelectorAll("[data-aksrt-menu-search-type]").forEach(function (c) { - c.classList.toggle("active", c === chip); - }); - }); - }); - -var clearBtn = form.querySelector("[data-aksrt-clear-menu-history]"); - if (clearBtn && !clearBtn._bound) { + // Clear history (zibll .trash-history-search). + form.querySelectorAll(".trash-history-search, [data-aksrt-clear-menu-history]").forEach(function (clearBtn) { + if (clearBtn._bound) return; clearBtn._bound = 1; clearBtn.addEventListener("click", function (e) { e.preventDefault(); @@ -118,14 +131,30 @@ var clearBtn = form.querySelector("[data-aksrt-clear-menu-history]"); '暂无历史'; } }); - } + }); + + // Type chips inside panel (if any). + form.querySelectorAll("[data-for='type'], [data-aksrt-menu-search-type]").forEach(function (chip) { + chip.addEventListener("click", function (e) { + e.preventDefault(); + var v = + chip.getAttribute("data-value") || + chip.getAttribute("data-aksrt-menu-search-type") || + "post"; + var tin = form.querySelector('input[name="aksrt_search_type"], input[name="type"]'); + if (tin) tin.value = v; + form.querySelectorAll("[data-for='type'], [data-aksrt-menu-search-type]").forEach(function (c) { + c.classList.toggle("active", c === chip); + }); + }); + }); var suggestMount = form.querySelector("[data-aksrt-menu-suggest]"); var timer = null; var searchConfig = (window.aksrtData && aksrtData.search) || {}; function typeValue() { - var t = form.querySelector('input[name="aksrt_search_type"]'); + var t = form.querySelector('input[name="aksrt_search_type"], input[name="type"]'); return (t && t.value) || searchConfig.defaultType || "post"; } @@ -153,14 +182,14 @@ var clearBtn = form.querySelector("[data-aksrt-clear-menu-history]"); var html = '
' + (searchConfig.suggestTitle || "搜索建议") + - "
"; + '