diff --git a/src/assets/styles/header.scss b/src/assets/styles/header.scss index d432742..98f3eac 100644 --- a/src/assets/styles/header.scss +++ b/src/assets/styles/header.scss @@ -58,97 +58,148 @@ height: 20px; } - .search-box { - height: 36px; - margin-right: 2px; - background: #fff; - border-radius: 34px; - display: flex; - overflow: hidden; - align-items: center; - justify-content: space-between; - user-select: none; - input { - flex: 1; - outline: none; - border: none; - margin-left: 15px; - width: 210px; - } - .icon { - margin: 0 8px; - // animation: icon-turn 0.3s linear; - } - } + } +} - @keyframes fade-animation { - 0% { - display: none; - } +/* ===== Header 搜索命令面板(2026-10-08 定稿 B 方案)===== + ⚠️ 必须放在顶层(不可嵌进 .default-header 内):面板由 渲染到 body 下, + 若嵌在 .default-header 内会生成 `.default-header .app-cmdk-layer`,匹配不到 body 下的元素。 + 类名统一 app-cmdk- 前缀(本文件是全局样式,非 scoped)。 */ +.app-cmdk-layer { + position: fixed; + inset: 0; + z-index: 2000; + opacity: 0; + pointer-events: none; + transition: opacity 0.3s linear; - 75% { - display: none; - } - 100% { - display: flex; - } - } - .fade1-enter-active, - .fade1-enter-to { - animation: fade-animation 0.5s; - } + &.is-open { + opacity: 1; + pointer-events: auto; + } +} +.app-cmdk-mask { + position: absolute; + inset: 0; + background: rgba(18, 26, 40, 0.34); + backdrop-filter: blur(10px) saturate(125%); + -webkit-backdrop-filter: blur(10px) saturate(125%); +} +.app-cmdk-panel { + position: absolute; + left: 50%; + top: 78px; + width: min(620px, calc(100% - 48px)); + background: #fff; + border-radius: 16px; + overflow: hidden; + box-shadow: 0 26px 68px rgba(18, 30, 54, 0.3), 0 2px 8px rgba(18, 30, 54, 0.1); + opacity: 0; + transform: translate(-50%, -14px) scale(0.965); + transition: opacity 0.26s linear, transform 0.48s cubic-bezier(0.2, 0.9, 0.24, 1); - .fade1-leave-from, - .fade1-leave-active { - display: none !important; - } + .app-cmdk-layer.is-open & { + opacity: 1; + transform: translate(-50%, 0) scale(1); + } +} +.app-cmdk-hd { + display: flex; + align-items: center; + gap: 12px; + padding: 0 18px; + height: 56px; + border-bottom: 1px solid #f0f3f8; + color: #98a2b0; - @keyframes search-animation { - 0% { - display: none; - width: 0; - } - 20% { - display: none; - width: 0; - } - 21% { - width: 0; - display: block; - } - 100% { - width: 210px; - } - } - - @keyframes icon-animation { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } - } - - .search-enter-active { - & input { - animation: search-animation 0.3s ease-in-out; - } - & .icon { - animation: icon-animation 0.4s; - } - } - - .search-leave-active { - & input { - animation: search-animation 0.35s ease-out reverse; - } - & .icon { - animation: icon-animation 0.4s reverse; - } + input { + flex: 1; + min-width: 0; + outline: none; + border: 0; + color: #252b35; + font-size: 15px; + background: none; + &::placeholder { + color: #aab3c0; } } } +.app-cmdk-kbd { + font-size: 11px; + color: #8b95a3; + background: #f2f5fa; + border: 1px solid #e4e9f2; + border-radius: 5px; + padding: 2px 6px; + font-family: ui-monospace, Menlo, monospace; +} +.app-cmdk-list { + padding: 8px; + max-height: min(58vh, 440px); + overflow: auto; +} +.app-cmdk-item { + display: flex; + align-items: center; + gap: 12px; + padding: 9px 12px; + border-radius: 10px; + cursor: pointer; + opacity: 0; + transform: translateY(9px); + transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1), + transform 0.42s cubic-bezier(0.4, 0, 0.2, 1), background 0.16s; + + .app-cmdk-layer.is-open & { + opacity: 1; + transform: none; + transition-delay: calc(0.14s + var(--i) * 0.035s), calc(0.14s + var(--i) * 0.035s), 0s; + } + &.is-hl, + &:hover { + background: #f3f6fc; + } +} +.app-cmdk-list.is-instant .app-cmdk-item { + transition-duration: 0.15s; + transition-delay: 0s; +} +.app-cmdk-img { + width: 34px; + height: 34px; + border-radius: 9px; + flex-shrink: 0; +} +.app-cmdk-name { + flex: 1; + min-width: 0; + font-size: 13.5px; + color: #252b35; + font-weight: 600; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.app-cmdk-empty { + display: none; + padding: 28px 18px 32px; + text-align: center; + color: #a8b1be; + font-size: 13px; + &.is-show { + display: block; + } +} +.app-cmdk-ft { + display: flex; + gap: 16px; + padding: 10px 18px; + border-top: 1px solid #f0f3f8; + font-size: 11.5px; + color: #98a2b0; + background: #fbfcfe; +} .role-info { height: 22px; diff --git a/src/components/Header.vue b/src/components/Header.vue index 46156db..a95c48e 100644 --- a/src/components/Header.vue +++ b/src/components/Header.vue @@ -8,17 +8,9 @@
  • - -
    - -
    -
    - - - +
    + +
  • + +
    +
    +
    +
    + + + Esc +
    +
    +
    + + + {{ item.name }} +
    +
    +
    + {{ store.appListLoading ? "正在加载应用…" : "未找到匹配的应用" }} +
    +
    + ↑↓ 选择↵ 打开Esc 关闭 +
    +
    +
    +