Nghiên Cứu: Cấu Trúc UI Hierarchy — Cross-Platform
Date: 2026-03-11 Sources: Apple HIG, Material Design 3, Figma SDK Foundation V2 Purpose: So sánh cấu trúc UI hierarchy giữa 3 hệ sinh thái để validate hệ thống tier của Prisma
1. So Sánh 3 Hệ Sinh Thái
Apple (iOS / SwiftUI / UIKit)
App
└ Scene (WindowGroup)
└ NavigationStack / TabView ← Navigation container
└ View (Screen) ← LEVEL 1: Screen
├ NavigationBar ← Fixed chrome
├ ScrollView / List ← LEVEL 2: Content area
│ ├ Section ← LEVEL 3: Content section
│ │ ├ VStack / HStack / LazyVGrid ← LEVEL 4: Layout container (Group)
│ │ │ ├ Cell / Row ← LEVEL 5: Component (reusable UI)
│ │ │ │ ├ Image ← LEVEL 6: Element
│ │ │ │ ├ Text ← LEVEL 6: Element
│ │ │ │ └ Toggle ← LEVEL 6: Element
│ │ │ └ ...
│ │ └ ...
│ └ ...
└ TabBar ← Fixed chrome
Apple hierarchy thực tế: 6 levels
| Level | SwiftUI | UIKit | Vai trò |
|---|---|---|---|
| 1 | View (root) |
UIViewController |
Toàn bộ screen |
| 2 | ScrollView / List |
UIScrollView / UITableView |
Content area (scrollable) |
| 3 | Section |
UITableViewSection |
Nhóm nội dung có header |
| 4 | VStack / HStack / LazyVGrid |
UIStackView |
Layout container |
| 5 | Custom View / Cell | UITableViewCell / UICollectionViewCell |
Reusable UI component |
| 6 | Text / Image / Toggle |
UILabel / UIImageView / UISwitch |
Atomic element |
Android / Material Design 3
Activity / Fragment
└ Scaffold ← LEVEL 1: Screen shell
├ TopAppBar ← Fixed chrome
├ Content (Body Region) ← LEVEL 2: Body region
│ ├ Pane (1-3 panes) ← LEVEL 2b: Pane (responsive)
│ │ ├ LazyColumn / LazyVerticalGrid ← LEVEL 3: Scrollable list
│ │ │ ├ Card / ListItem ← LEVEL 4: Component
│ │ │ │ ├ Icon ← LEVEL 5: Element
│ │ │ │ ├ Text ← LEVEL 5: Element
│ │ │ │ └ Switch ← LEVEL 5: Element
│ │ │ └ ...
│ │ └ ...
│ └ ...
├ BottomNavigation ← Fixed chrome
└ FAB ← Floating action
M3 layout concepts:
- Window → Navigation Region + Body Region
- Body Region → 1-3 Panes (fixed or flexible)
- Panes → Content organized in lists/grids
- Canonical Layouts: List-Detail, Supporting Pane, Feed
| Level | Compose | XML | M3 Concept | Vai trò |
|---|---|---|---|---|
| 1 | Scaffold |
CoordinatorLayout |
Window | Screen shell |
| 2 | Column / content lambda |
FrameLayout |
Body Region / Pane | Content area |
| 3 | LazyColumn / LazyVerticalGrid |
RecyclerView |
List / Grid | Scrollable container |
| 4 | Card / ListItem |
CardView / custom ViewHolder |
Component | Reusable UI |
| 5 | Text / Icon / Switch |
TextView / ImageView / MaterialSwitch |
Element | Atomic element |
Figma VNPAY (hiện tại)
| Level | Tên | Vai trò |
|---|---|---|
| 1 | Page | Toàn bộ màn hình |
| 2 | Section | Chia vùng nội dung lớn |
| 3 | Group | Nhóm layout |
| 4 | Component | UI có chức năng (reusable) |
| 5 | Element | Thành phần nhỏ nhất |
| 6 | Token | Style system (meta) |
2. Master Comparison Table
| # | Vai trò | Apple HIG | Android M3 | Figma VNPAY | Prisma (hiện tại) | Liên quan? |
|---|---|---|---|---|---|---|
| 1 | Screen shell | UIViewController / View | Scaffold / Activity | Page | page |
✅ Match |
| 2 | Content area | ScrollView / List | Body Region / Pane | Section | section |
✅ Match |
| 3 | Layout container | VStack / HStack / Section | LazyColumn / Grid | Group | group |
✅ Match |
| 4 | Reusable UI | Cell / Custom View | Card / ListItem | Component | comp |
✅ Match |
| 5 | Atomic element | Text / Image / Toggle | Text / Icon / Switch | Element | (chưa có) | 🔴 Gap |
| 6 | Style system | Dynamic Color / SF Font | Material Tokens / Theme | Token | primitives/shared | ✅ Meta |
3. Analysis: Prisma Cần Element Tier Không?
Tại sao Apple & Android KHÔNG có "Element" spacing tokens?
| Platform | Cách xử lý Element spacing |
|---|---|
| Apple | Dùng .padding() modifier trực tiếp, không có "element tier" riêng. Spacing giữa icon+text dùng HStack(spacing: 8) — giá trị inline. |
| Android M3 | Dùng Modifier.padding(), spacing nằm trong component spec (ListItem có built-in gap). Không có "element tier" tokens. |
Kết luận: Element KHÔNG CẦN tier-level tokens
Lý do:
- Apple & Android đều không có Element spacing tokens — element spacing nằm trong component spec
- Element quá nhỏ để cần density scaling — icon 20px không đổi giữa compact/default
- Element spacing đã được handle bởi comp tier —
--comp-stack-gap-small: 4pxđã cover gap giữa icon+text - Element sizing → nên là primitive — icon size, avatar size... là static, không scale theo density
Đề xuất: Thêm Element Sizing Token (KHÔNG phải spacing tier)
Thay vì tạo --elem-* tier giống page/section/group/comp, chỉ cần thêm sizing primitives:
/* Element sizing — trong primitives, KHÔNG trong density */
--icon-size-xs: 12px;
--icon-size-sm: 16px;
--icon-size-default: 20px;
--icon-size-md: 24px;
--icon-size-lg: 32px;
--icon-size-xl: 40px;
--avatar-size-xs: 20px;
--avatar-size-sm: 24px;
--avatar-size-default: 32px;
--avatar-size-md: 40px;
--avatar-size-lg: 48px;
--avatar-size-xl: 64px;
--indicator-size: 8px;
--indicator-size-sm: 6px;
4. Validation: Prisma 4-Tier = Industry Standard
| Apple (6 tiers*) | Android M3 (5 tiers) | Figma VNPAY (5+1) | Prisma (4 tiers) | |
|---|---|---|---|---|
| Screen | ✅ | ✅ | ✅ Page | ✅ page |
| Content Area | ✅ | ✅ | ✅ Section | ✅ section |
| Layout Group | ✅ | ✅ | ✅ Group | ✅ group |
| Component | ✅ | ✅ | ✅ Component | ✅ comp |
| Element | ✅ (no tokens) | ✅ (no tokens) | ✅ Element | ❌ (không cần tokens) |
| Token/Style | ✅ meta | ✅ meta | ✅ Token | ✅ meta |
Kết luận: Prisma 4-tier system (
page > section > group > comp) đã đúng và match industry standard. Element tier tồn tại trong design hierarchy nhưng KHÔNG cần spacing/density tokens riêng. Element sizing tokens (icon, avatar) nên là primitives, không phải density tier.
5. Triết Lý Thiết Kế (từ Figma)
| Platform | Triết lý |
|---|---|
| VNPAY | Design system oriented — token-first, mọi thứ quy về token |
| Apple | View hierarchy oriented — mọi thứ là View, compose bằng modifier |
| Android | Layout container oriented — Scaffold + slots, constraint-based |
Prisma đi theo hướng VNPAY = Design system oriented, đúng vì Prisma là design system. Token-first approach phù hợp khi:
- Serve nhiều platform (web, iOS, Android, React Native)
- Cần consistency across products
- Scale qua nhiều team và brand