ui-and-design
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePerformance & Rendering
性能与渲染
- Const-First: Every widget that can be MUST be
const.const - Lazy Rendering: Mandatory use of lazy-loading constructs (or
SliverList.builder) for any list exceeding 10 items.SliverGrid.builder - Repaint Boundaries: Wrap complex animations or heavy UI sections in to optimize Impeller frame budget.
RepaintBoundary - Isolate Parsing: Mandate or
compute()for JSON parsing exceeding 1MB to avoid main-thread jank.Isolate - Optimize image handling with
cached_network_image - Handle asynchronous operations cleanly with proper cancellation during widget disposal
- Minimize unnecessary rebuilds using memoization techniques
- Implement pagination for large data sets
- Flatten widget hierarchies where reasonable for better rendering performance
- BuildContext Safety: Check before using
mountedacross async gaps to preventcontextafter dispose.setState
- Const优先:所有可以声明为的widget必须声明为
const。const - 懒渲染:任何超过10项的列表必须使用懒加载构造(或
SliverList.builder)。SliverGrid.builder - 重绘边界:将复杂动画或重度UI区块包裹在中,以优化Impeller帧预算。
RepaintBoundary - 隔离解析:超过1MB的JSON解析必须使用或
compute(),避免主线程卡顿。Isolate - 使用优化图片处理
cached_network_image - 干净地处理异步操作,在widget销毁时正确取消异步任务
- 使用记忆化技术减少不必要的重建
- 针对大型数据集实现分页
- 在合理范围内扁平化widget层级,以提升渲染性能
- BuildContext安全:在异步间隙使用前检查
context状态,避免销毁后调用mounted。setState
Design System
设计系统
See design-system/SKILL.md for full token definitions (colors, spacing, radius, typography), reusable component rules, theming standards, and accessibility. Always use design tokens — never hardcode values.
完整的令牌定义(颜色、间距、圆角、排版)、可复用组件规则、主题标准和可访问性规范请查看design-system/SKILL.md。始终使用设计令牌,绝对不要硬编码数值。
Widget Patterns
Widget模式
- Widget Extraction: STRICTLY prohibit private methods that return widgets. Extract them into separate
_build*()orStatelessWidgetclasses (can be private withStatefulWidgetprefix). This ensures better testability, reusability, and composition._ - Sliver Preference: Prefer with
CustomScrollViewoverSliversfor any non-trivial scrollable layout to ensure lazy loading and avoid jank. UseSingleChildScrollVieworSliverList.builderandSliverList.separatedfor mixed content types.SliverGrid.builder - Prominently use Sliver widgets: ,
SliverAppBar,SliverList,SliverGrid,SliverToBoxAdapter,SliverPadding,SliverPersistentHeader,SliverFillRemaining,SliverFixedExtentList,SliverAnimatedList,SliverFillViewport,SliverOpacity,SliverIgnorePointer,SliverLayoutBuilder,SliverPrototypeExtentListSliverVisibility - No Unnecessary Containers: Reduce usage of . Use chained widgets like
Container,DecoratedBox,Padding, etc. PreferSizedBoxoverSizedBoxfor simple spacing.Container - Use inbuilt animated widgets where applicable (,
AnimatedContainer,AnimatedOpacity,AnimatedSwitcher, etc.) before resorting to explicitAnimatedPositioned.AnimationController - Keep widgets focused and composable with clear responsibilities
- Widget Keys: Assign to interactive widgets for test access. Use
Key('feature_action_id')(notValueKey(item.id)) for list items.ValueKey(index)
- Widget提取:严格禁止返回widget的私有方法。将它们提取为独立的
_build*()或StatelessWidget类(可以用StatefulWidget前缀声明为私有)。这能保证更好的可测试性、可复用性和组合性。_ - 优先使用Sliver:对于任何非简单可滚动布局,优先使用带的
Slivers而不是CustomScrollView,以保证懒加载、避免卡顿。混合内容类型请使用SingleChildScrollView、SliverList.builder和SliverList.separated。SliverGrid.builder - 优先使用Sliver组件:、
SliverAppBar、SliverList、SliverGrid、SliverToBoxAdapter、SliverPadding、SliverPersistentHeader、SliverFillRemaining、SliverFixedExtentList、SliverAnimatedList、SliverFillViewport、SliverOpacity、SliverIgnorePointer、SliverLayoutBuilder、SliverPrototypeExtentListSliverVisibility - 不要使用不必要的Container:减少的使用。使用链式组件如
Container、DecoratedBox、Padding等。简单间距优先使用SizedBox而不是SizedBox。Container - 适用场景下优先使用内置动画组件(、
AnimatedContainer、AnimatedOpacity、AnimatedSwitcher等),再考虑显式使用AnimatedPositioned。AnimationController - 保持widget专注、可组合,职责清晰
- Widget Key:为可交互组件分配以便测试访问。列表项使用
Key('feature_action_id')(不要用ValueKey(item.id))。ValueKey(index)
UI States
UI状态
- Use a loading indicator while fetching data
- Use an error indicator with appropriate messaging for error displays
- Handle empty states gracefully in UI with clear messaging
- 拉取数据时展示加载指示器
- 错误展示时使用带合适提示文案的错误指示器
- 优雅处理UI空状态,提供清晰的提示文案
Interaction Patterns
交互模式
- FAB Usage: Use Floating Action Buttons (FAB) for primary positive actions (Add, Create, Generate, Save) on a screen. Avoid inline primary buttons when a FAB is more appropriate for the screen context.
- Scroll Padding: ALWAYS add dynamic bottom padding to or
SliverList.builderwhen a FAB or Bottom Navigation Bar is present. UseSingleChildScrollView(orMediaQuery.of(context).padding.bottom + kFloatingActionButtonMargin + 56) to prevent content overlap.AppSpacing.xxl - Screen vs Sheet: Prefer full screens over
Scaffoldfor complex forms, especially those with text inputs, to ensure proper keyboard handling and deep linking capability.ModalBottomSheet - Deep Linking: Complex flows should be addressable via deep links (e.g., instead of just a bottom sheet).
/strategy/:id
- FAB使用规范:屏幕的主要正向操作(添加、创建、生成、保存)使用浮动操作按钮(FAB)。如果当前屏幕上下文更适合使用FAB,则避免使用行内主按钮。
- 滚动内边距:当页面存在FAB或底部导航栏时,必须为或
SliverList.builder添加动态底部内边距。使用SingleChildScrollView(或MediaQuery.of(context).padding.bottom + kFloatingActionButtonMargin + 56)避免内容被遮挡。AppSpacing.xxl - 页面vs底部弹窗:复杂表单优先使用完整的页面而不是
Scaffold,尤其是包含文本输入的表单,以保证正确的键盘处理和深度链接能力。ModalBottomSheet - 深度链接:复杂流程应该可以通过深度链接访问(例如,而不是仅通过底部弹窗打开)。
/strategy/:id
Adaptive & Responsive Design
自适应与响应式设计
- Design mobile first
- Use and
LayoutBuilderfor adaptive layoutsMediaQuery - Design for different screen sizes and orientations using responsive breakpoints
- 优先设计移动端版本
- 使用和
LayoutBuilder实现自适应布局MediaQuery - 使用响应式断点适配不同屏幕尺寸和方向
Adaptive Workflow (Abstract → Measure → Branch)
自适应工作流(抽象 → 测量 → 分支)
- Abstract: Identify widgets needing adaptability. Share common data (e.g., for both
DestinationandNavigationBar).NavigationRail - Measure: Use for app-level layout decisions;
MediaQuery.sizeOf(context)for widget-specific constraints.LayoutBuilder - Branch: Apply breakpoints — mobile,
< 600tablet,600–840desktop (Material guidelines).>= 840
- 抽象:识别需要适配的widget,共享通用数据(例如和
NavigationBar通用的NavigationRail数据)。Destination - 测量:应用层级的布局决策使用;widget特定的约束使用
MediaQuery.sizeOf(context)。LayoutBuilder - 分支:应用断点规则——为移动端,
< 600为平板,600–840为桌面端(Material设计规范)。>= 840
Adaptive Rules
自适应规则
- Never lock orientation; support both portrait and landscape
- Never use /
Platform.isIOSfor layout decisions; use window sizePlatform.isAndroid - Don't use for layout changes; use
OrientationBuilderorMediaQuery.sizeOfwith breakpointsLayoutBuilder - On large screens, avoid full-width content; constrain content width for readability
- Support keyboard navigation, mouse hover effects, and focus handling for custom widgets
- 永远不要锁定屏幕方向,同时支持竖屏和横屏
- 永远不要使用/
Platform.isIOS做布局决策,使用窗口尺寸判断Platform.isAndroid - 不要使用处理布局变化,使用
OrientationBuilder或带断点的MediaQuery.sizeOfLayoutBuilder - 大屏设备上避免内容占满全宽,限制内容宽度以提升可读性
- 自定义组件支持键盘导航、鼠标悬停效果和焦点处理