/* Kole UI Menu 族样式 — 由 tools/gen-family-impl.mjs 从族模板生成,勿手改。 * * @generated by tools/gen-family-impl.mjs * 族:nav-menu(基座 Menu + direction 参数)。 * 本文件服务:sidemenu / topmenu / mixednavigation。 * * 三个组件的 CSS 是同一份样式表 —— 差异全部由根元素的 data-direction / * data-collapsed 参数表达,不再各自手写一遍。改样式请改模板后重跑生成器: * node tools/gen-family-impl.mjs nav-menu */ /* ---------- 基础:方向无关 ---------- */ .kole-menu { font-family: var(--font-family, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif); color: var(--kole-color-text-body); background: var(--kole-color-card-bg); user-select: none; } .kole-menu-item { position: relative; display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; color: var(--kole-color-text-body); transition: background .15s, color .15s, border-color .15s; } .kole-menu-item:hover { background: var(--kole-color-page-bg); } .kole-menu-item.is-active { color: var(--kole-color-brand); font-weight: 500; } .kole-menu-item.is-disabled { color: var(--kole-color-text-disabled); cursor: not-allowed; } .kole-menu-item.is-disabled:hover { background: none; } .kole-menu-icon { width: 16px; text-align: center; flex-shrink: 0; font-size: 15px; } .kole-menu-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .kole-menu-badge { background: var(--kole-color-error); color: var(--kole-color-text-inverse); font-size: 11px; min-width: 16px; height: 16px; border-radius: var(--kole-radius-large); padding: 0 5px; display: inline-flex; align-items: center; justify-content: center; } .kole-menu-arrow { color: var(--kole-color-text-secondary); font-size: 12px; transition: transform .15s; } .kole-menu-item.is-open > .kole-menu-arrow { transform: rotate(90deg); } .kole-menu-children { background: var(--kole-color-table-header-bg); } .kole-menu-children .kole-menu-item { height: 40px; padding-inline-start: 40px; font-size: 13px; } /* 折叠态悬浮浮层(side 方向专用) */ .kole-menu-pop { position: absolute; inset-inline-start: 56px; top: 0; min-width: 180px; background: var(--kole-color-card-bg); border: 1px solid var(--kole-color-border); border-radius: var(--kole-radius-medium); box-shadow: var(--kole-shadow-medium, 0 4px 12px rgba(0, 0, 0, .12)); padding: 4px 0; z-index: 200; } .kole-menu-pop-title { padding: 6px 16px; font-size: 12px; color: var(--kole-color-text-secondary); } .kole-menu-pop .kole-menu-item { height: 40px; padding: 0 16px; } /* ---------- direction=top:水平导航,选中态底部指示条 ---------- */ .kole-menu[data-direction="top"] { display: flex; align-items: stretch; border-bottom: 1px solid var(--kole-color-border); padding: 0 8px; } .kole-menu[data-direction="top"] > .kole-menu-item { height: 48px; padding: 0 16px; } .kole-menu[data-direction="top"] > .kole-menu-item:hover { background: none; color: var(--kole-color-brand); } .kole-menu[data-direction="top"] > .kole-menu-item.is-active::after { content: ''; position: absolute; inset-inline: 12px; bottom: 0; height: 2px; background: var(--kole-color-brand); } /* top 方向的下拉:绝对定位面板,hover / focus-within 展开(键盘同样可达) */ .kole-menu[data-direction="top"] .kole-menu-children { position: absolute; top: 100%; inset-inline-start: 0; display: none; min-width: 160px; background: var(--kole-color-card-bg); border: 1px solid var(--kole-color-border); border-radius: var(--kole-radius-medium); box-shadow: var(--kole-shadow-medium, 0 4px 12px rgba(0, 0, 0, .08)); padding: 4px; z-index: 50; } .kole-menu[data-direction="top"] .kole-menu-item:hover > .kole-menu-children, .kole-menu[data-direction="top"] .kole-menu-item:focus-within > .kole-menu-children { display: block; } .kole-menu[data-direction="top"] .kole-menu-children .kole-menu-item { height: auto; padding: 8px 12px; font-size: 13px; border-radius: var(--kole-radius-small); } .kole-menu[data-direction="top"] .kole-menu-children .kole-menu-item:hover { background: var(--kole-color-brand-bg); color: var(--kole-color-brand); } .kole-menu[data-direction="top"] .kole-menu-children .kole-menu-item.is-active { background: var(--kole-color-brand-bg); } /* ---------- direction=side:侧边栏,选中态品牌底 + 侧指示条 ---------- */ .kole-menu[data-direction="side"] { width: 220px; border-inline-end: 1px solid var(--kole-color-border); } /* item 允许换行:二级菜单是 item 的子节点,而 item 是 flex 行 —— 不换行的话 子级会被当成横向 flex 子项挤在同一行里、溢出侧栏宽度;换行后子级独占一整行。 height 改 min-height:展开时 item 需要跟着长高。 */ .kole-menu[data-direction="side"] > .kole-menu-item { height: auto; min-height: 44px; padding: 0 16px; flex-wrap: wrap; row-gap: 0; } .kole-menu[data-direction="side"] > .kole-menu-item.is-active { background: var(--kole-color-brand-bg); } .kole-menu[data-direction="side"] > .kole-menu-item.is-active::before { content: ''; position: absolute; inset-inline-start: 0; top: 0; bottom: 0; width: 3px; background: var(--kole-color-brand); } /* side 方向的二级:默认收起,点开(.is-open)后在同列内换行展开、铺满侧栏宽。 100% + 32px 与 margin 的 -16px 是配套的:100% 是该行内容宽(侧栏宽减去 item 左右 各 16px 内边距),加回 32px 再抵消内边距,子级底色才与一级同宽 (折叠前的手写实现是把子级挂在菜单根下,这里用同样效果还原)。 */ .kole-menu[data-direction="side"] > .kole-menu-item > .kole-menu-children { flex: 0 0 calc(100% + 32px); display: none; margin: 0 -16px; } .kole-menu[data-direction="side"] > .kole-menu-item.is-open > .kole-menu-children { display: block; } /* ---------- direction=mixed:顶部一级 + 侧边二级 ---------- */ .kole-menu[data-direction="mixed"] { border: 1px solid var(--kole-color-border); border-radius: var(--kole-radius-large); overflow: hidden; } .kole-menu[data-direction="mixed"] > .kole-menu-top { display: flex; gap: 4px; border-bottom: 1px solid var(--kole-color-border); padding: 0 8px; } .kole-menu[data-direction="mixed"] > .kole-menu-top > .kole-menu-item { height: 48px; padding: 0 16px; } .kole-menu[data-direction="mixed"] > .kole-menu-top > .kole-menu-item:hover { background: none; } .kole-menu[data-direction="mixed"] > .kole-menu-top > .kole-menu-item.is-active::after { content: ''; position: absolute; inset-inline: 12px; bottom: 0; height: 2px; background: var(--kole-color-brand); } .kole-menu[data-direction="mixed"] > .kole-menu-side { width: 168px; min-height: 200px; background: var(--kole-color-table-header-bg); border-inline-end: 1px solid var(--kole-color-border); padding: 8px 0; } .kole-menu[data-direction="mixed"] > .kole-menu-side > .kole-menu-item { height: 40px; padding: 0 16px; } .kole-menu[data-direction="mixed"] > .kole-menu-side > .kole-menu-item.is-active { background: var(--kole-color-brand-bg); } .kole-menu[data-direction="mixed"] > .kole-menu-side > .kole-menu-item.is-active::before { content: ''; position: absolute; inset-inline-start: 0; top: 0; bottom: 0; width: 3px; background: var(--kole-color-brand); } /* ---------- 参数:collapsed(仅 side 方向生效) ---------- */ .kole-menu[data-direction="side"][data-collapsed="true"] { width: 56px; } .kole-menu[data-direction="side"][data-collapsed="true"] .kole-menu-label, .kole-menu[data-direction="side"][data-collapsed="true"] .kole-menu-badge, .kole-menu[data-direction="side"][data-collapsed="true"] .kole-menu-arrow { display: none; } .kole-menu[data-direction="side"][data-collapsed="true"] > .kole-menu-item { justify-content: center; padding: 0; } .kole-menu[data-direction="side"][data-collapsed="true"] > .kole-menu-item.is-active::before { display: none; } /* 折叠态只留图标,子级一律不展开(改由 .kole-menu-pop 悬浮浮层承载);选择器要与上面 的 .is-open 展开规则同权重,且在其之后,才能压住已点开的项 */ .kole-menu[data-direction="side"][data-collapsed="true"] > .kole-menu-item > .kole-menu-children { display: none; } /* 嵌套 children 的层级缩进(side 方向展开时) */ .kole-menu[data-direction="side"] > .kole-menu-item > .kole-menu-children .kole-menu-item.is-active::before { display: none; }