feat: 侧边栏两态重构(统一视图身份)+ 第四轮触控化走查

侧边栏(真机验证):
- 砍掉悬浮态,只留收起⇄固定展开;TerminalSidebar 单一视图身份,
  内容恒按 288pt 排版、收起=左侧裁切(clipped 宽度动画),
  图标列两态同尺寸同位置,明细淡入淡出,终端随宽度盖上/让开
- 开合入口收敛:Logo 位(收起态=»展开键/展开态=Logo)+ 头部«;
  删底部开合键与 Pin;LeadingHitShape 修 clipped 不裁触摸
- 修 GridBox 从不通知 UI:onGridChange→objectWillChange,
  标题胶囊格子数随开合实时刷新

触控化走查(上一轮,真机部署验证):
- 窗口按钮 13pt 色点→22pt 圆角方块常显字形;动作条改可点按钮
- TXTech 拼写/配色规范(SSH/mosh/tmux 官方写法+品牌色映射)
- 首页会话卡固定 3 列 4:3;去掉未实现的 ⌘K 提示

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
kid
2026-07-26 00:55:53 +08:00
parent 28e9cfc207
commit 5707d70dff
15 changed files with 1086 additions and 675 deletions

View File

@@ -1,4 +1,5 @@
import SwiftUI
import UIKit
import GhosttyTerminal
import GhosttyTheme
@@ -257,6 +258,9 @@ enum TX {
static let dialog: CGFloat = 15
/// chrome/
static let capsule: CGFloat = 11
/// pane ** app chrome **
/// `TerminalScreen.paneShape`
static let pane: CGFloat = 6
//
static let chip: CGFloat = 9
@@ -291,8 +295,94 @@ enum TX {
static let minTouch: CGFloat = 44
/// pane
static let capsuleInset: CGFloat = 86
/// ****线 y
/// **** / / 齿线
/// 线 y home indicator
/// chrome `TX.Layout.footBand`
static let footHeight: CGFloat = 34
/// = + ****
/// home indicator
static func footBand(_ safeBottom: CGFloat) -> CGFloat { footHeight + safeBottom }
/// ****
///
/// iPad 14/
/// 30
static func capsuleTop(_ safeTop: CGFloat) -> CGFloat {
safeTop > 30 ? safeTop - 12 : 14
}
}
/// 稿 200260ms `easeOut`
///
/// 线 URL
/// 退
enum Motion {
///
@MainActor static var standard: Animation {
.easeOut(duration: (reduceMotion ? 0.12 : 0.24) * slowFactor)
}
///
@MainActor static var quick: Animation {
.easeOut(duration: (reduceMotion ? 0.08 : 0.14) * slowFactor)
}
@MainActor static var reduceMotion: Bool { UIAccessibility.isReduceMotionEnabled }
/// `-txSlowMotion 1` ×12
///
/// `simctl io screenshot` 240ms
/// ""退 DEBUG
private static var slowFactor: Double {
#if DEBUG
UserDefaults.standard.bool(forKey: "txSlowMotion") ? 12 : 1
#else
1
#endif
}
///
@MainActor static func slide(_ edge: Edge) -> AnyTransition {
reduceMotion ? .opacity : .move(edge: edge)
}
/// + 96% 100%""
@MainActor static var pop: AnyTransition {
reduceMotion ? .opacity : .opacity.combined(with: .scale(scale: 0.96))
}
/// 97% ""
@MainActor static var pushBack: AnyTransition {
reduceMotion ? .opacity : .opacity.combined(with: .scale(scale: 1.02))
}
}
/// **稿** chrome
/// 稿 CSS 3080px / .55.7
/// 穿""
struct Shadow {
let opacity: Double
let radius: CGFloat
var x: CGFloat = 0
var y: CGFloat = 0
}
enum Elevation {
/// chrome /
static let floating = Shadow(opacity: 0.22, radius: 7, y: 2)
///
static let panel = Shadow(opacity: 0.28, radius: 16, x: 4)
/// /
static let dialog = Shadow(opacity: 0.34, radius: 16, y: 6)
///
static let card = Shadow(opacity: 0.16, radius: 4, y: 2)
static let cardFocused = Shadow(opacity: 0.24, radius: 8, y: 3)
}
///
enum Scrim {
static let color = Color(hex: 0x0A0B12)
/// ""
static let dialog: Double = 0.5
///
static let sidebar: Double = 0.42
}
enum Font {