feat(design): 加 unlucky-design 令牌 crate(M3 色彩/排版/形状/动效/图标)
D26 把视觉基线锁到 Material 3 Expressive,本 crate 是「UI 整体性」的地基: 令牌唯一真源,后续 iced 页面只消费不新增。零第三方依赖、零 UI 框架依赖 (cargo tree -p unlucky-design --edges normal 只有它自己一行)。 - 色彩:49 个 M3 语义角色 × light/dark,种子色派生 6 条 tone 调色板; tone 轴严格用 CIELAB L*(偏差 ≤1),色相/彩度用 OKLCh 近似 CAM16 并在 模块文档里写明口径与已知偏差(不宣称是标准 HCT 动态取色) - 对比度:26 组文字对 × 6 组种子 × 2 模式全部 ≥4.5:1;3 条例外显式登记 (Outline 非文字 3:1、OutlineVariant 装饰、SurfaceVariant 是容器色) - 排版:M3 type scale 15 档 + 三平台字体族回退栈(只写族名,不内嵌受限字体) - 形状/高程/动效:Expressive 形状刻度 + shape morph 数据、elevation 级别与 surface container 映射、时长/缓动/弹簧(纯函数可采样) - 图标:24 个从 Slint 版迁移的 SVG path + 4 个新增,IconKind 冻结只可末尾追加; 写明 Slint 的 stroke-width 是绝对像素、SVG 是 viewBox 用户单位的语义差异, 换算封装成 Icon::stroke_width - 组件档位表:20 个组件的形状/高程/字体/动效一次取全 TODO(M63):elevation shadow 的 blur/offset/alpha 与四组弹簧参数是占位值, 接口先定、数值待玻璃视觉规格表(tower 已通告边界)。
This commit is contained in:
1 parent
fef0922073
commit
65ca0ed29a
25 files changed
+4622
-1
No files matched your search
@@ -0,0 +1,256 @@
|
||||
//! 组件档位数据表(**下标必须等于 `Component as usize`**,由测试钉死)。
|
||||
//!
|
||||
//! 一行一个组件。改值就是在改全站观感——同步协作文档再改。
|
||||
|
||||
use super::{Component, ComponentSpec};
|
||||
use crate::elevation::Elevation;
|
||||
use crate::motion::{DurationToken, Easing, SPRING_SPATIAL_DEFAULT, SPRING_SPATIAL_FAST};
|
||||
use crate::shape::{ShapeMorph, ShapeScale};
|
||||
use crate::typography::TypeRole;
|
||||
|
||||
/// 一个组件的档位行(`const fn` 便捷构造,字段名在 [`ComponentSpec`] 里)。
|
||||
const fn spec(
|
||||
component: Component,
|
||||
shape: ShapeScale,
|
||||
elevation: Elevation,
|
||||
text: TypeRole,
|
||||
support: Option<TypeRole>,
|
||||
motion: Easing,
|
||||
duration: DurationToken,
|
||||
morph: Option<ShapeMorph>,
|
||||
) -> ComponentSpec {
|
||||
ComponentSpec {
|
||||
component,
|
||||
shape,
|
||||
elevation,
|
||||
text,
|
||||
support,
|
||||
motion,
|
||||
duration,
|
||||
morph,
|
||||
}
|
||||
}
|
||||
|
||||
/// 20 个组件的档位表。
|
||||
pub(super) const SPECS: [ComponentSpec; 20] = [
|
||||
spec(
|
||||
Component::TopAppBar,
|
||||
ShapeScale::None,
|
||||
Elevation::Level0,
|
||||
TypeRole::TitleLarge,
|
||||
Some(TypeRole::BodySmall),
|
||||
Easing::Standard,
|
||||
DurationToken::Medium2,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::NavigationItem,
|
||||
ShapeScale::Full,
|
||||
Elevation::Level0,
|
||||
TypeRole::LabelLarge,
|
||||
None,
|
||||
Easing::Emphasized,
|
||||
DurationToken::Medium2,
|
||||
Some(ShapeMorph::new(
|
||||
ShapeScale::Large,
|
||||
ShapeScale::Full,
|
||||
SPRING_SPATIAL_FAST,
|
||||
)),
|
||||
),
|
||||
spec(
|
||||
Component::PrimaryButton,
|
||||
ShapeScale::Full,
|
||||
Elevation::Level0,
|
||||
TypeRole::LabelLarge,
|
||||
None,
|
||||
Easing::Emphasized,
|
||||
DurationToken::Short4,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::SecondaryButton,
|
||||
ShapeScale::Full,
|
||||
Elevation::Level0,
|
||||
TypeRole::LabelLarge,
|
||||
None,
|
||||
Easing::Standard,
|
||||
DurationToken::Short4,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::TextButton,
|
||||
ShapeScale::Full,
|
||||
Elevation::Level0,
|
||||
TypeRole::LabelLarge,
|
||||
None,
|
||||
Easing::Standard,
|
||||
DurationToken::Short4,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::IconButton,
|
||||
ShapeScale::Full,
|
||||
Elevation::Level0,
|
||||
TypeRole::LabelMedium,
|
||||
None,
|
||||
Easing::Standard,
|
||||
DurationToken::Short3,
|
||||
Some(ShapeMorph::new(
|
||||
ShapeScale::Medium,
|
||||
ShapeScale::Full,
|
||||
SPRING_SPATIAL_FAST,
|
||||
)),
|
||||
),
|
||||
spec(
|
||||
Component::OutlinedCard,
|
||||
ShapeScale::Medium,
|
||||
Elevation::Level1,
|
||||
TypeRole::TitleMedium,
|
||||
Some(TypeRole::BodySmall),
|
||||
Easing::Standard,
|
||||
DurationToken::Medium1,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::FilledCard,
|
||||
ShapeScale::Medium,
|
||||
Elevation::Level2,
|
||||
TypeRole::TitleMedium,
|
||||
Some(TypeRole::BodySmall),
|
||||
Easing::Standard,
|
||||
DurationToken::Medium1,
|
||||
Some(ShapeMorph::new(
|
||||
ShapeScale::Medium,
|
||||
ShapeScale::Large,
|
||||
SPRING_SPATIAL_DEFAULT,
|
||||
)),
|
||||
),
|
||||
spec(
|
||||
Component::ListItem,
|
||||
ShapeScale::Small,
|
||||
Elevation::Level0,
|
||||
TypeRole::BodyLarge,
|
||||
Some(TypeRole::BodySmall),
|
||||
Easing::Standard,
|
||||
DurationToken::Short4,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::TextField,
|
||||
ShapeScale::ExtraSmall,
|
||||
Elevation::Level0,
|
||||
TypeRole::BodyLarge,
|
||||
Some(TypeRole::BodySmall),
|
||||
Easing::Standard,
|
||||
DurationToken::Short4,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::SegmentedButton,
|
||||
ShapeScale::Full,
|
||||
Elevation::Level0,
|
||||
TypeRole::LabelLarge,
|
||||
None,
|
||||
Easing::Emphasized,
|
||||
DurationToken::Medium2,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::Chip,
|
||||
ShapeScale::Small,
|
||||
Elevation::Level0,
|
||||
TypeRole::LabelMedium,
|
||||
None,
|
||||
Easing::Standard,
|
||||
DurationToken::Short3,
|
||||
Some(ShapeMorph::new(
|
||||
ShapeScale::ExtraSmall,
|
||||
ShapeScale::Small,
|
||||
SPRING_SPATIAL_FAST,
|
||||
)),
|
||||
),
|
||||
spec(
|
||||
Component::Switch,
|
||||
ShapeScale::Full,
|
||||
Elevation::Level0,
|
||||
TypeRole::BodyMedium,
|
||||
Some(TypeRole::BodySmall),
|
||||
Easing::Emphasized,
|
||||
DurationToken::Medium2,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::Slider,
|
||||
ShapeScale::Full,
|
||||
Elevation::Level0,
|
||||
TypeRole::BodyMedium,
|
||||
Some(TypeRole::BodySmall),
|
||||
Easing::Standard,
|
||||
DurationToken::Short2,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::ProgressIndicator,
|
||||
ShapeScale::Full,
|
||||
Elevation::Level0,
|
||||
TypeRole::LabelMedium,
|
||||
None,
|
||||
Easing::Linear,
|
||||
DurationToken::Long2,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::Dialog,
|
||||
ShapeScale::ExtraLarge,
|
||||
Elevation::Level5,
|
||||
TypeRole::HeadlineSmall,
|
||||
Some(TypeRole::BodyMedium),
|
||||
Easing::EmphasizedDecelerate,
|
||||
DurationToken::Long4,
|
||||
Some(ShapeMorph::new(
|
||||
ShapeScale::Large,
|
||||
ShapeScale::ExtraLarge,
|
||||
SPRING_SPATIAL_DEFAULT,
|
||||
)),
|
||||
),
|
||||
spec(
|
||||
Component::Menu,
|
||||
ShapeScale::Small,
|
||||
Elevation::Level4,
|
||||
TypeRole::BodyMedium,
|
||||
None,
|
||||
Easing::StandardDecelerate,
|
||||
DurationToken::Short4,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::Snackbar,
|
||||
ShapeScale::ExtraSmall,
|
||||
Elevation::Level3,
|
||||
TypeRole::BodyMedium,
|
||||
None,
|
||||
Easing::EmphasizedDecelerate,
|
||||
DurationToken::Medium2,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::Tooltip,
|
||||
ShapeScale::ExtraSmall,
|
||||
Elevation::Level2,
|
||||
TypeRole::BodySmall,
|
||||
None,
|
||||
Easing::StandardDecelerate,
|
||||
DurationToken::Short2,
|
||||
None,
|
||||
),
|
||||
spec(
|
||||
Component::EmptyState,
|
||||
ShapeScale::Large,
|
||||
Elevation::Level0,
|
||||
TypeRole::HeadlineSmall,
|
||||
Some(TypeRole::BodySmall),
|
||||
Easing::Standard,
|
||||
DurationToken::Medium2,
|
||||
None,
|
||||
),
|
||||
];
|
||||
Reference in new issue
Block a user