用途
该技能为 CIA 平台定义设计系统,确保 Vaadin 组件使用一致、无障碍合规、响应式设计模式统一,并为政治数据可视化提供连贯的用户体验。它为 web-widgets 模块提供可复用的模式。
何时使用
适用场景:
- 创建新的 Vaadin 视图或组件
- 修改现有 UI 布局或导航
- 实现数据可视化仪表板
- 添加交互式政治数据图表
- 确保 WCAG 2.1 AA 无障碍合规
- 设计面向移动设备的响应式布局
- 审查 UI 拉取请求的一致性
不适用场景:
- 无 UI 影响的后端服务逻辑
- 数据库模式变更
- 构建或部署流水线变更
设计原则
- 政治中立:UI 不得通过颜色、位置或强调偏向任何党派
- 数据优先:优先保证政治数据的清晰性,而非装饰性元素
- 无障碍:所有组件符合 WCAG 2.1 AA
- 一致性:复用设计系统组件,避免一次性样式
- 性能:懒加载数据,减少 DOM 复杂度
- 响应式:支持桌面(主要)、平板和移动视口
组件库模式
布局组件
标准页面布局模式示例:
public class PoliticianOverviewView extends VerticalLayout {
public PoliticianOverviewView() {
setSizeFull();
setPadding(true);
setSpacing(true);
// Page header with breadcrumb
add(createPageHeader("Politician Overview"));
// Content area with responsive grid
HorizontalLayout content = new HorizontalLayout();
content.setSizeFull();
content.add(createFilterPanel(), createDataGrid());
content.setFlexGrow(1, createDataGrid());
add(content);
}
}
数据网格模式
一致的网格配置示例:
public Grid<PoliticianSummary> createPoliticianGrid() {
Grid<PoliticianSummary> grid = new Grid<>(PoliticianSummary.class, false);
// Column configuration with consistent ordering
grid.addColumn(PoliticianSummary::getFirstName)
.setHeader("First Name").setSortable(true).setAutoWidth(true);
grid.addColumn(PoliticianSummary::getLastName)
.setHeader("Last Name").setSortable(true).setAutoWidth(true);
grid.addColumn(PoliticianSummary::getParty)
.setHeader("Party").setSortable(true).setAutoWidth(true);
grid.addColumn(new NumberRenderer<>(PoliticianSummary::getAttendanceRate,
"%.1f%%")).setHeader("Attendance").setSortable(true);
// Lazy loading
grid.setPageSize(50);
grid.setMultiSort(true);
// Accessibility
grid.getElement().setAttribute("aria-label", "Politician data table");
return grid;
}
图表组件
政治中立党派配色方案示例:
public static final Map<String, String> PARTY_COLORS = Map.of(
"S", "#E8112d", // Socialdemokraterna
"M", "#52BDEC", // Moderaterna
"SD", "#DDDD00", // Sverigedemokraterna
"C", "#009933", // Centerpartiet
"V", "#DA291C", // Vänsterpartiet
"KD", "#000077", // Kristdemokraterna
"L", "#006AB3", // Liberalerna
"MP", "#83CF39" // Miljöpartiet
);
始终包含党派标签,切勿仅依赖颜色(无障碍要求)。
通知模式
一致的通知使用示例:
public class NotificationHelper {
public static void showSuccess(String message) {
Notification.show(message, 3000, Notification.Position.BOTTOM_START)
.addThemeVariants(NotificationVariant.LUMO_SUCCESS);
}
public static void showError(String message) {
Notification.show(message, 5000, Notification.Position.BOTTOM_START)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
}
public static void showInfo(String message) {
Notification.show(message, 3000, Notification.Position.BOTTOM_START)
.addThemeVariants(NotificationVariant.LUMO_PRIMARY);
}
}
响应式设计
断点
| 断点 | 宽度 | 布局适配 |
|---|---|---|
| 桌面 | ≥ 1024px | 完整侧边栏 + 内容网格 |
| 平板 | 768–1023px | 可折叠侧边栏,面板堆叠 |
| 移动 | < 768px | 底部导航,单列 |
响应式模式
使用 Vaadin 的 FormLayout 实现响应式布局示例:
FormLayout form = new FormLayout();
form.setResponsiveSteps(
new FormLayout.ResponsiveStep("0", 1), // Mobile: 1 column
new FormLayout.ResponsiveStep("768px", 2), // Tablet: 2 columns
new FormLayout.ResponsiveStep("1024px", 3) // Desktop: 3 columns
);
无障碍集成
WCAG 2.1 AA 要求
无障碍组件模式示例:
public class AccessibleDashboard extends VerticalLayout {
public AccessibleDashboard() {
// Landmark roles
getElement().setAttribute("role", "main");
getElement().setAttribute("aria-label", "Political Dashboard");
// Heading hierarchy
H1 title = new H1("Dashboard");
title.getElement().setAttribute("tabindex", "0");
add(title);
// Data tables with proper headers
Grid<Data> grid = createGrid();
grid.getElement().setAttribute("aria-label", "Voting records");
// Charts with text alternatives
Div chart = createChart();
chart.getElement().setAttribute("aria-label",
"Bar chart showing voting attendance by party");
chart.getElement().setAttribute("role", "img");
}
}
无障碍检查清单
- 正常文本颜色对比度 ≥ 4.5:1
- 大号文本颜色对比度 ≥ 3:1
- 所有交互元素可键盘导航
- 所有自定义组件带 ARIA 标签
- 表单字段有关联标签
- 焦点指示器可见(永不使用 outline: none)
- 为键盘用户提供跳转导航链接
- 所有图表和图像有文本替代
- 错误消息与表单字段关联
- 不单独依赖颜色传达信息
命名约定
CSS 类名
格式:.cia-[component]-[modifier]
示例:
.cia-dashboard-header.cia-politician-grid.cia-chart-container.cia-filter-panel--collapsed.cia-nav-item--active
视图类名
格式:[Entity][Action]View.java
示例:
PoliticianOverviewView.javaCommitteeDetailView.javaVotingHistoryView.javaPartyComparisonView.java
设计系统治理
添加新组件
- 检查现有 Vaadin 组件是否满足需求
- 检查是否存在 CIA 设计系统模式
- 如需自定义组件,在本技能中记录
- 从一开始就包含无障碍属性
- 添加响应式断点处理
- 为该组件编写 Playwright UI 测试
组件审查标准
- 遵循现有设计系统模式
- 使用标准 CIA 配色方案
- 符合 WCAG 2.1 AA 无障碍
- 在所有断点下响应式
- 政治中立呈现
- 对大数据集懒加载
- 具有适当的 ARIA 标签
参考
- Vaadin Design System
- WCAG 2.1 Guidelines
- Vaadin Accessibility Guide
- Swedish Riksdag Party Information