SuperAPI AI 工具集

ui-ux-design-system

设计与创作

查看项目

更新于 10-16 04:06

技能介绍

用途

该技能为 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.java
  • CommitteeDetailView.java
  • VotingHistoryView.java
  • PartyComparisonView.java

设计系统治理

添加新组件

  1. 检查现有 Vaadin 组件是否满足需求
  2. 检查是否存在 CIA 设计系统模式
  3. 如需自定义组件,在本技能中记录
  4. 从一开始就包含无障碍属性
  5. 添加响应式断点处理
  6. 为该组件编写 Playwright UI 测试

组件审查标准

  • 遵循现有设计系统模式
  • 使用标准 CIA 配色方案
  • 符合 WCAG 2.1 AA 无障碍
  • 在所有断点下响应式
  • 政治中立呈现
  • 对大数据集懒加载
  • 具有适当的 ARIA 标签

参考

  • Vaadin Design System
  • WCAG 2.1 Guidelines
  • Vaadin Accessibility Guide
  • Swedish Riksdag Party Information