@momo-kits/native-kits 0.157.5-debug → 0.158.1-beta.1-debug
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +11 -0
- package/.claude/skills/design-system/SKILL.md +88 -0
- package/.claude/skills/design-system/references/components/avatar.md +134 -0
- package/.claude/skills/design-system/references/components/badge.md +127 -0
- package/.claude/skills/design-system/references/components/bottom-tab.md +177 -0
- package/.claude/skills/design-system/references/components/bottomsheet.md +170 -0
- package/.claude/skills/design-system/references/components/button.md +206 -0
- package/.claude/skills/design-system/references/components/carousel.md +117 -0
- package/.claude/skills/design-system/references/components/checkbox.md +98 -0
- package/.claude/skills/design-system/references/components/chip.md +146 -0
- package/.claude/skills/design-system/references/components/collapse.md +120 -0
- package/.claude/skills/design-system/references/components/date-picker.md +119 -0
- package/.claude/skills/design-system/references/components/divider.md +84 -0
- package/.claude/skills/design-system/references/components/icon.md +130 -0
- package/.claude/skills/design-system/references/components/image.md +81 -0
- package/.claude/skills/design-system/references/components/information.md +107 -0
- package/.claude/skills/design-system/references/components/input-dropdown.md +138 -0
- package/.claude/skills/design-system/references/components/input-money.md +157 -0
- package/.claude/skills/design-system/references/components/input-otp.md +132 -0
- package/.claude/skills/design-system/references/components/input-phone-number.md +140 -0
- package/.claude/skills/design-system/references/components/input-search.md +124 -0
- package/.claude/skills/design-system/references/components/input-text-area.md +133 -0
- package/.claude/skills/design-system/references/components/input.md +152 -0
- package/.claude/skills/design-system/references/components/loader.md +87 -0
- package/.claude/skills/design-system/references/components/pagination.md +105 -0
- package/.claude/skills/design-system/references/components/popup-notify.md +128 -0
- package/.claude/skills/design-system/references/components/progress-info.md +114 -0
- package/.claude/skills/design-system/references/components/radio.md +86 -0
- package/.claude/skills/design-system/references/components/rating.md +126 -0
- package/.claude/skills/design-system/references/components/skeleton.md +120 -0
- package/.claude/skills/design-system/references/components/slider.md +141 -0
- package/.claude/skills/design-system/references/components/snackbar.md +97 -0
- package/.claude/skills/design-system/references/components/stepper.md +100 -0
- package/.claude/skills/design-system/references/components/steps.md +91 -0
- package/.claude/skills/design-system/references/components/suggest-action.md +95 -0
- package/.claude/skills/design-system/references/components/swipe.md +121 -0
- package/.claude/skills/design-system/references/components/switch.md +98 -0
- package/.claude/skills/design-system/references/components/tab-view.md +120 -0
- package/.claude/skills/design-system/references/components/tag.md +118 -0
- package/.claude/skills/design-system/references/components/text.md +151 -0
- package/.claude/skills/design-system/references/components/toast.md +99 -0
- package/.claude/skills/design-system/references/components/tooltip.md +138 -0
- package/.claude/skills/design-system/references/components/top-nav-miniapp.md +94 -0
- package/.claude/skills/design-system/references/components/top-nav.md +226 -0
- package/.claude/skills/design-system/references/components/uploader.md +115 -0
- package/.claude/skills/design-system/references/navigation/bottom-tab.md +131 -0
- package/.claude/skills/design-system/references/navigation/bottomsheet.md +161 -0
- package/.claude/skills/design-system/references/navigation/modal.md +133 -0
- package/.claude/skills/design-system/references/navigation/navigation-options.md +225 -0
- package/.claude/skills/design-system/references/navigation/navigator.md +111 -0
- package/.claude/skills/design-system/references/navigation/setup.md +134 -0
- package/.claude/skills/design-system/references/navigation/stack.md +128 -0
- package/.claude/skills/design-system/references/spec-convention.md +80 -0
- package/.claude/skills/design-system/references/tokens/colors.md +131 -0
- package/.claude/skills/design-system/references/tokens/spacing-radius.md +144 -0
- package/.claude/skills/design-system/references/tokens/theme.md +125 -0
- package/.claude/skills/design-system/references/tokens/typography.md +135 -0
- package/.claude/skills/design-system-kits/SKILL.md +102 -0
- package/.claude/skills/design-system-kits/references/code-convention.md +118 -0
- package/.claude/skills/design-system-kits/references/components/avatar.md +45 -0
- package/.claude/skills/design-system-kits/references/components/badge.md +27 -0
- package/.claude/skills/design-system-kits/references/components/button.md +65 -0
- package/.claude/skills/design-system-kits/references/components/carousel.md +51 -0
- package/.claude/skills/design-system-kits/references/components/checkbox.md +39 -0
- package/.claude/skills/design-system-kits/references/components/chip.md +54 -0
- package/.claude/skills/design-system-kits/references/components/collapse.md +63 -0
- package/.claude/skills/design-system-kits/references/components/date-picker.md +36 -0
- package/.claude/skills/design-system-kits/references/components/divider.md +21 -0
- package/.claude/skills/design-system-kits/references/components/icon.md +382 -0
- package/.claude/skills/design-system-kits/references/components/image.md +62 -0
- package/.claude/skills/design-system-kits/references/components/information.md +61 -0
- package/.claude/skills/design-system-kits/references/components/input-dropdown.md +92 -0
- package/.claude/skills/design-system-kits/references/components/input-money.md +128 -0
- package/.claude/skills/design-system-kits/references/components/input-otp.md +85 -0
- package/.claude/skills/design-system-kits/references/components/input-phone-number.md +96 -0
- package/.claude/skills/design-system-kits/references/components/input-search.md +127 -0
- package/.claude/skills/design-system-kits/references/components/input-text-area.md +100 -0
- package/.claude/skills/design-system-kits/references/components/input.md +126 -0
- package/.claude/skills/design-system-kits/references/components/loader.md +41 -0
- package/.claude/skills/design-system-kits/references/components/pagination.md +47 -0
- package/.claude/skills/design-system-kits/references/components/popup-notify.md +69 -0
- package/.claude/skills/design-system-kits/references/components/popup-promotion.md +35 -0
- package/.claude/skills/design-system-kits/references/components/progress-info.md +55 -0
- package/.claude/skills/design-system-kits/references/components/radio.md +42 -0
- package/.claude/skills/design-system-kits/references/components/rating.md +36 -0
- package/.claude/skills/design-system-kits/references/components/skeleton.md +25 -0
- package/.claude/skills/design-system-kits/references/components/slider.md +53 -0
- package/.claude/skills/design-system-kits/references/components/snackbar.md +52 -0
- package/.claude/skills/design-system-kits/references/components/stepper.md +46 -0
- package/.claude/skills/design-system-kits/references/components/steps.md +57 -0
- package/.claude/skills/design-system-kits/references/components/suggest-action.md +44 -0
- package/.claude/skills/design-system-kits/references/components/swipe.md +44 -0
- package/.claude/skills/design-system-kits/references/components/switch.md +43 -0
- package/.claude/skills/design-system-kits/references/components/tab-view.md +56 -0
- package/.claude/skills/design-system-kits/references/components/tag.md +50 -0
- package/.claude/skills/design-system-kits/references/components/text.md +56 -0
- package/.claude/skills/design-system-kits/references/components/toast.md +51 -0
- package/.claude/skills/design-system-kits/references/components/tooltip.md +95 -0
- package/.claude/skills/design-system-kits/references/components/uploader.md +48 -0
- package/.claude/skills/design-system-kits/references/design-spec-structure.md +356 -0
- package/.claude/skills/design-system-kits/references/design-spec-to-code.md +596 -0
- package/.claude/skills/design-system-kits/references/navigation/bottom-tab.md +155 -0
- package/.claude/skills/design-system-kits/references/navigation/bottomsheet.md +94 -0
- package/.claude/skills/design-system-kits/references/navigation/modal.md +125 -0
- package/.claude/skills/design-system-kits/references/navigation/navigation-options.md +430 -0
- package/.claude/skills/design-system-kits/references/navigation/navigator.md +177 -0
- package/.claude/skills/design-system-kits/references/navigation/setup.md +94 -0
- package/.claude/skills/design-system-kits/references/navigation/stack.md +152 -0
- package/.claude/skills/design-system-kits/references/screen-layout-rule.md +125 -0
- package/.claude/skills/design-system-kits/references/tokens/colors.md +183 -0
- package/.claude/skills/design-system-kits/references/tokens/spacing-radius.md +45 -0
- package/.claude/skills/design-system-kits/references/tokens/theme.md +97 -0
- package/.claude/skills/design-system-kits/references/tokens/typography.md +105 -0
- package/.claude/skills/vibe-design/SKILL.md +306 -0
- package/compose/build.gradle.kts +1 -1
- package/compose/src/androidMain/kotlin/vn/momo/kits/platform/Platform.android.kt +7 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Avatar.kt +157 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Carousel.kt +123 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Collapse.kt +224 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Loader.kt +108 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/PopupPromotion.kt +2 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/ProgressInfo.kt +338 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Rating.kt +87 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Slider.kt +348 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Stepper.kt +256 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Steps.kt +494 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/SuggestAction.kt +131 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Swipe.kt +215 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/TabView.kt +531 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/components/Uploader.kt +192 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Spacing.kt +3 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/const/Theme.kt +5 -2
- package/compose/src/commonMain/kotlin/vn/momo/kits/modifier/AutomationId.kt +2 -11
- package/compose/src/commonMain/kotlin/vn/momo/kits/platform/Platform.kt +5 -1
- package/compose/src/iosMain/kotlin/vn/momo/kits/platform/Platform.ios.kt +12 -0
- package/gradle.properties +1 -1
- package/ios/Popup/PopupPromotion.swift +2 -2
- package/local.properties +8 -0
- package/package.json +1 -1
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Tooltip
|
|
2
|
+
|
|
3
|
+
> Contextual help popup attached to a trigger element, used for feature discovery, field help, and first-time guidance.
|
|
4
|
+
|
|
5
|
+
**Package:** `@momo-kits/animated-tooltip`
|
|
6
|
+
**Platform support:** RN ✅ (AnimatedTooltip) | Compose ✅
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Anatomy
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
┌──────────────────────────┐
|
|
14
|
+
│ Title (optional) │
|
|
15
|
+
│ Description text here │
|
|
16
|
+
│ [Action Button]│
|
|
17
|
+
└────────────┬─────────────┘
|
|
18
|
+
▼
|
|
19
|
+
(arrow pointer)
|
|
20
|
+
┌──────────┐
|
|
21
|
+
│ Trigger │
|
|
22
|
+
└──────────┘
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Part | Description | Required |
|
|
26
|
+
|---------------|------------------------------------------------------|----------|
|
|
27
|
+
| Container | Rounded rectangle holding tooltip content | Yes |
|
|
28
|
+
| Title | Bold heading line within the tooltip | No |
|
|
29
|
+
| Description | Explanatory text | Yes |
|
|
30
|
+
| Action button | Optional text button for a follow-up action | No |
|
|
31
|
+
| Arrow | Triangular pointer connecting tooltip to trigger | Yes |
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Placement
|
|
36
|
+
|
|
37
|
+
The tooltip can be positioned relative to the trigger element:
|
|
38
|
+
|
|
39
|
+
| Placement | Arrow direction |
|
|
40
|
+
|------------|-------------------------|
|
|
41
|
+
| **TOP** | Arrow points down |
|
|
42
|
+
| **BOTTOM** | Arrow points up |
|
|
43
|
+
| **LEFT** | Arrow points right |
|
|
44
|
+
| **RIGHT** | Arrow points left |
|
|
45
|
+
|
|
46
|
+
### Alignment
|
|
47
|
+
|
|
48
|
+
Within each placement, the tooltip can be aligned along the trigger:
|
|
49
|
+
|
|
50
|
+
| Alignment | Description |
|
|
51
|
+
|------------|----------------------------------------------|
|
|
52
|
+
| **START** | Tooltip aligns to the start edge of trigger |
|
|
53
|
+
| **CENTER** | Tooltip is centered on the trigger |
|
|
54
|
+
| **END** | Tooltip aligns to the end edge of trigger |
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Visual Specs
|
|
59
|
+
|
|
60
|
+
### Dark Theme (Default)
|
|
61
|
+
|
|
62
|
+
| Property | Token / Value |
|
|
63
|
+
|------------------|----------------------------|
|
|
64
|
+
| Background | `Colors.black_17` |
|
|
65
|
+
| Title color | `Colors.white` |
|
|
66
|
+
| Description color| `Colors.white` |
|
|
67
|
+
| Title typography | `body_default_semibold` |
|
|
68
|
+
| Desc. typography | `body_s_regular` |
|
|
69
|
+
| Corner radius | `Radius.S` |
|
|
70
|
+
| Padding | `Spacing.M` (12) all sides |
|
|
71
|
+
| Max width | 240 dp |
|
|
72
|
+
|
|
73
|
+
### Light Theme
|
|
74
|
+
|
|
75
|
+
| Property | Token / Value |
|
|
76
|
+
|------------------|----------------------------------------|
|
|
77
|
+
| Background | `Colors.surface` (theme surface color) |
|
|
78
|
+
| Title color | Default text color |
|
|
79
|
+
| Description color| Default text color |
|
|
80
|
+
| All other specs | Same as dark theme |
|
|
81
|
+
|
|
82
|
+
### Arrow
|
|
83
|
+
|
|
84
|
+
| Property | Value |
|
|
85
|
+
|-----------|------------------------------------------------|
|
|
86
|
+
| Size | 8 dp triangle |
|
|
87
|
+
| Color | Matches container background |
|
|
88
|
+
| Position | Points toward the trigger element center |
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Animation
|
|
93
|
+
|
|
94
|
+
| Property | Value |
|
|
95
|
+
|------------|----------------------|
|
|
96
|
+
| Enter | Fade in |
|
|
97
|
+
| Exit | Fade out |
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Interaction
|
|
102
|
+
|
|
103
|
+
| Trigger action | Behavior |
|
|
104
|
+
|----------------------|-----------------------------------|
|
|
105
|
+
| Tap trigger | Show, hide, or toggle tooltip |
|
|
106
|
+
| Tap outside tooltip | Dismiss tooltip |
|
|
107
|
+
| Tap action button | Execute action and dismiss |
|
|
108
|
+
|
|
109
|
+
The tooltip visibility is managed via state: **show**, **hide**, or **toggle**.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Accessibility
|
|
114
|
+
|
|
115
|
+
- Tooltip content must be announced to screen readers when displayed.
|
|
116
|
+
- Tooltip must be dismissible by tapping outside — do not trap focus.
|
|
117
|
+
- If the tooltip contains an action button, that button must be reachable by assistive technology.
|
|
118
|
+
- On screen readers, the trigger element should indicate that additional information is available.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Usage Guidelines
|
|
123
|
+
|
|
124
|
+
### Do's
|
|
125
|
+
|
|
126
|
+
- Use for feature discovery and onboarding highlights.
|
|
127
|
+
- Use to provide brief explanations for form fields or icons.
|
|
128
|
+
- Use for first-time user guidance to draw attention to new features.
|
|
129
|
+
- Keep description text short and scannable (1-2 sentences).
|
|
130
|
+
- Position the tooltip so it does not overflow the screen bounds.
|
|
131
|
+
|
|
132
|
+
### Don'ts
|
|
133
|
+
|
|
134
|
+
- Don't use for error messages — use the Input component's error state instead.
|
|
135
|
+
- Don't use for lengthy or complex content — use a Modal or BottomSheet instead.
|
|
136
|
+
- Don't display multiple tooltips simultaneously.
|
|
137
|
+
- Don't rely on tooltip content for critical information that the user must see — tooltips are supplementary.
|
|
138
|
+
- Don't use tooltips for menus or interactive lists — use a Popover or BottomSheet instead.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# TopNavMiniApp
|
|
2
|
+
|
|
3
|
+
> Header cho mini-app — pill combo với "more" + "quit" buttons bắt buộc. Khác hoàn toàn TopNav native.
|
|
4
|
+
|
|
5
|
+
**Package:** `@momo-kits/foundation` [VERIFY]
|
|
6
|
+
**Platform:** RN ✅ | Compose ❌ [VERIFY]
|
|
7
|
+
**Completeness:** need_update — thiếu Figma (không tìm thấy trong library), thiếu Dev Zip reference riêng
|
|
8
|
+
**Figma node:** không tìm thấy trong `ZP6qAaBcmkB8j2XmR2uXCv` — có thể ở file khác [VERIFY]
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Props
|
|
13
|
+
|
|
14
|
+
| Prop | Type | Values | Default | Description |
|
|
15
|
+
|------|------|--------|---------|-------------|
|
|
16
|
+
| `title` | string | — | required | Mini-app name |
|
|
17
|
+
| `showMoreButton` | boolean | `true` \| `false` | `true` | "More" button trong pill. BẮT BUỘC [VERIFY] |
|
|
18
|
+
| `showQuitButton` | boolean | `true` \| `false` | `true` | "Quit" (X) button trong pill. BẮT BUỘC [VERIFY] |
|
|
19
|
+
| `rightPillActions` | array | — | `["more", "quit"]` | Pill combo actions [VERIFY] |
|
|
20
|
+
| `onMorePress` | function | — | — | Callback khi tap More |
|
|
21
|
+
| `onQuitPress` | function | — | — | Callback khi tap Quit (X). `"onQuitPress": "action://closeMiniApp"` |
|
|
22
|
+
| `onBackPress` | function | — | — | Callback khi tap Back (nếu có) |
|
|
23
|
+
|
|
24
|
+
> **CRITICAL:** Mini-app TopNav PHẢI có pill combo (more + quit). Đây là platform requirement — không thể remove.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## States
|
|
29
|
+
|
|
30
|
+
| State | Title Color | Pill Style | Behavior |
|
|
31
|
+
|-------|------------|-----------|----------|
|
|
32
|
+
| **Default** | `Colors.black_17` | Outlined pill | Static |
|
|
33
|
+
| **Scrolled** | `Colors.black_17` | Outlined pill | Shadow/border appear |
|
|
34
|
+
|
|
35
|
+
> Mini-app TopNav đơn giản hơn native TopNav — ít background variations.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Variant-to-Context Map
|
|
40
|
+
|
|
41
|
+
| Context | Khi nào dùng | Tránh khi | Ví dụ trong MoMo |
|
|
42
|
+
|---------|-------------|-----------|-------------------|
|
|
43
|
+
| **Third-party mini-app** | App bên thứ 3 chạy trong MoMo container | Native MoMo feature → dùng **TopNav** | Game, dịch vụ partner (Grab, Tiki trong MoMo) |
|
|
44
|
+
| **Internal mini-app** | Feature MoMo build dưới dạng mini-app | Full native screen → dùng **TopNav** | Campaign pages, event pages |
|
|
45
|
+
|
|
46
|
+
> **Phân biệt:** Nếu là native MoMo feature → dùng **TopNav** (compact). Nếu là mini-app → dùng **TopNavMiniApp**. Chọn sai = toàn bộ navigation pattern sai.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## SSR Pattern
|
|
51
|
+
|
|
52
|
+
### Mini-app Screen
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"navigation": {
|
|
56
|
+
"headerType": "miniapp",
|
|
57
|
+
"headerTitle": { "type": "text", "title": "{{data.miniAppName}}" },
|
|
58
|
+
"rightPill": ["more", "quit"]
|
|
59
|
+
},
|
|
60
|
+
"layout": [
|
|
61
|
+
{
|
|
62
|
+
"id": "miniapp_content",
|
|
63
|
+
"type": "section",
|
|
64
|
+
"children": []
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"actions": {
|
|
68
|
+
"quit": { "type": "action", "handler": "closeMiniApp" },
|
|
69
|
+
"more": { "type": "action", "handler": "openMiniAppMenu" }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Accessibility
|
|
77
|
+
|
|
78
|
+
- Quit button: accessible label "Đóng mini-app" hoặc "Thoát".
|
|
79
|
+
- More button: accessible label "Tùy chọn" hoặc "Menu".
|
|
80
|
+
- Title: announce mini-app name.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Usage Guidelines
|
|
85
|
+
|
|
86
|
+
### Do
|
|
87
|
+
- LUÔN có pill combo (more + quit) — platform requirement.
|
|
88
|
+
- Title hiển thị tên mini-app rõ ràng.
|
|
89
|
+
- Quit button close mini-app hoàn toàn, return về MoMo.
|
|
90
|
+
|
|
91
|
+
### Don't
|
|
92
|
+
- KHÔNG remove quit button — user phải luôn có exit path.
|
|
93
|
+
- KHÔNG dùng cho native MoMo features — dùng **TopNav**.
|
|
94
|
+
- KHÔNG custom pill layout — giữ nguyên more + quit order.
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# Top Navigation
|
|
2
|
+
|
|
3
|
+
> Screen header cho native features — cung cấp navigation context, title, và actions. Mọi screen PHẢI có TopNav.
|
|
4
|
+
|
|
5
|
+
**Package:** `@momo-kits/foundation` [VERIFY]
|
|
6
|
+
**Platform:** RN ✅ | Compose ✅ [VERIFY]
|
|
7
|
+
**Completeness:** need_update — đã có Figma data, thiếu GitBook PDF riêng cho TopNav
|
|
8
|
+
**Figma node:** `13028:10861` — Component Set, 29 variants
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Variant Axes
|
|
13
|
+
|
|
14
|
+
| Property | Type | Values | Description |
|
|
15
|
+
|----------|------|--------|-------------|
|
|
16
|
+
| `Header type` | variant | `title` · `user name` · `location` · `journey` · `full page search` · `onboarding` · `forWL` | Loại nội dung hiển thị trong header |
|
|
17
|
+
| `Background` | variant | `compact` · `expand` · `dark banner` · `light banner` · `none` | Kiểu nền của header |
|
|
18
|
+
| `hasSearch` | variant (boolean) | `true` · `false` | Có hiển thị search bar trong header không |
|
|
19
|
+
| `isScrolled` | variant (boolean) | `true` · `false` | Trạng thái đã scroll — tự động chuyển Background → none |
|
|
20
|
+
| `hasExtension` | boolean | `true` · `false` | Hiển thị extended area bên dưới header |
|
|
21
|
+
| `extendedNavigation` | instance swap | — | Component đặt vào extended area (TabView, SegmentControl, etc.) |
|
|
22
|
+
|
|
23
|
+
> `isScrolled` do hệ thống tự quản lý, không cần set trong Design Spec. `none` background CHỈ cho scrolled state.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Props
|
|
28
|
+
|
|
29
|
+
| Prop | Type | Values | Default | Description |
|
|
30
|
+
|------|------|--------|---------|-------------|
|
|
31
|
+
| `headerType` | string | `"title"` \| `"user name"` \| `"location"` \| `"journey"` \| `"full page search"` \| `"onboarding"` \| `"forWL"` | `"title"` | Loại header. Xem Variants section cho chi tiết |
|
|
32
|
+
| `headerTitle` | object | `{ type, title }` \| `{ type, avatar, name, description }` \| `{ type, location, description }` | required | Title configuration — structure phụ thuộc headerType (xem bảng dưới) |
|
|
33
|
+
| `backgroundType` | string | `"compact"` \| `"expand"` \| `"dark banner"` \| `"light banner"` \| `"none"` | `"compact"` | Kiểu nền header |
|
|
34
|
+
| `hasSearch` | boolean | `true` \| `false` | `false` | Hiển thị search bar trong header |
|
|
35
|
+
| `showBackButton` | boolean | `true` \| `false` | `true` | Hiển thị nút back (chevron left) |
|
|
36
|
+
| `rightActions` | array | icon names | `[]` | Right-side action icons. Max 2-3. VD: `["search", "more"]` |
|
|
37
|
+
| `hasNotice` | boolean | `true` \| `false` | `false` | Notice indicator dot trên action icon |
|
|
38
|
+
| `bannerImage` | string | URL | — | Banner image URL. Dùng với `dark banner` / `light banner` |
|
|
39
|
+
| `hasExtension` | boolean | `true` \| `false` | `false` | Extended area bên dưới header |
|
|
40
|
+
| `extendedNavigation` | object | component config | — | Component trong extended area. VD: TabView, SegmentControl |
|
|
41
|
+
| `enableKeyboardAvoidingView` | boolean | `true` \| `false` | `false` | Screen có input → auto-avoid keyboard [VERIFY] |
|
|
42
|
+
|
|
43
|
+
### headerTitle Object — theo headerType
|
|
44
|
+
|
|
45
|
+
| headerType | headerTitle structure | Ví dụ |
|
|
46
|
+
|-----------|---------------------|-------|
|
|
47
|
+
| `title` | `{ "type": "text", "title": "Screen Name" }` | `{ "type": "text", "title": "Chuyển tiền" }` |
|
|
48
|
+
| `user name` | `{ "type": "user", "avatar": "url", "name": "Name", "description": "Status" }` | `{ "type": "user", "avatar": "{{data.avatar}}", "name": "{{data.name}}", "description": "Online" }` |
|
|
49
|
+
| `location` | `{ "type": "location", "location": "Address", "description": "Detail" }` | `{ "type": "location", "location": "Q.7, HCM", "description": "Gần bạn" }` |
|
|
50
|
+
| `journey` | `{ "type": "journey", "title": "Step Name" }` [VERIFY] | `{ "type": "journey", "title": "Xác thực danh tính" }` |
|
|
51
|
+
| `full page search` | `{ "type": "search" }` [VERIFY] | `{ "type": "search" }` |
|
|
52
|
+
| `onboarding` | `{ "type": "onboarding", "title": "Step" }` [VERIFY] | `{ "type": "onboarding", "title": "Chào mừng" }` |
|
|
53
|
+
| `forWL` | `{ "type": "whitelabel", "title": "App Name" }` [VERIFY] | RESTRICTED — không dùng khi chưa có confirm |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Variants
|
|
58
|
+
|
|
59
|
+
### Header Types
|
|
60
|
+
|
|
61
|
+
| Header Type | Mô tả | Props riêng |
|
|
62
|
+
|------------|-------|-------------|
|
|
63
|
+
| **title** | Standard screen title. DEFAULT choice | `title` (text) |
|
|
64
|
+
| **user name** | User/contact header với avatar | `name`, `description`, `avatar`, `showDescription`, `showStatusUser` [VERIFY] |
|
|
65
|
+
| **location** | Location context header | `location`, `description`, `showDescription` |
|
|
66
|
+
| **journey** | Multi-step flow với progress context | [VERIFY — cần xác nhận props riêng] |
|
|
67
|
+
| **full page search** | Dedicated search screen — search bar chiếm toàn bộ header | [VERIFY — cần xác nhận props riêng] |
|
|
68
|
+
| **onboarding** | Onboarding flow — skip-able, minimal navigation | [VERIFY — cần xác nhận props riêng] |
|
|
69
|
+
| **forWL** | White label. ⚠️ RESTRICTED — chưa có confirm từ system | [VERIFY] |
|
|
70
|
+
|
|
71
|
+
### Background Types
|
|
72
|
+
|
|
73
|
+
| Background | Visual | Khi nào dùng | Tránh khi |
|
|
74
|
+
|-----------|--------|-------------|-----------|
|
|
75
|
+
| **compact** | Pink nhạt. Text/icons đen | DEFAULT cho native features | Screen có hero image |
|
|
76
|
+
| **expand** | Pink nhạt. Mở rộng area | Cần search + extended area trong header | Simple detail screen |
|
|
77
|
+
| **dark banner** | Transparent trên dark image. Text/icons trắng | Hero image/banner tối phía sau header | Image quá sáng — không đủ contrast |
|
|
78
|
+
| **light banner** | Transparent trên light image. Text/icons đen | Hero image/banner sáng phía sau header | Image quá tối — không đủ contrast |
|
|
79
|
+
| **none** | White/transparent. Text/icons đen | CHỈ scrolled state — KHÔNG dùng làm default | Làm background mặc định |
|
|
80
|
+
|
|
81
|
+
**Rules:** `compact` là default. `dark banner` vs `light banner` phụ thuộc tone ảnh bên dưới. `none` tự switch khi scroll — không bao giờ là trạng thái ban đầu.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## States
|
|
86
|
+
|
|
87
|
+
| State | Background | Text/Icon Color | Search Bar | Extension | Behavior |
|
|
88
|
+
|-------|-----------|----------------|-----------|-----------|----------|
|
|
89
|
+
| **Default (compact)** | Pink nhạt | Đen | optional | optional | Static |
|
|
90
|
+
| **Scrolled** | Chuyển sang `none` (white) | Đen | ẩn nếu có | giữ nguyên | Auto-transition khi user scroll |
|
|
91
|
+
| **Dark banner** | Transparent trên dark image | Trắng | optional | optional | Floating trên image |
|
|
92
|
+
| **Light banner** | Transparent trên light image | Đen | optional | optional | Floating trên image |
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Variant-to-Context Map
|
|
97
|
+
|
|
98
|
+
| Header Type | Background | hasSearch | Khi nào dùng | Ví dụ trong MoMo |
|
|
99
|
+
|-------------|-----------|----------|-------------|-------------------|
|
|
100
|
+
| `title` | `compact` | `false` | Standard screen. DEFAULT choice | Chuyển tiền, Lịch sử GD, Cài đặt |
|
|
101
|
+
| `title` | `compact` | `true` | Screen cần search trong header | Danh bạ, Tìm dịch vụ |
|
|
102
|
+
| `title` | `expand` | `true` | Screen cần search + extended area | Home screen với search bar |
|
|
103
|
+
| `title` | `expand` | `false` | Header mở rộng không có search | Screen cần subtitle/filter trong header |
|
|
104
|
+
| `title` | `dark banner` | `false` | Screen có hero image tối | Campaign detail, Merchant page (ảnh tối) |
|
|
105
|
+
| `title` | `light banner` | `false` | Screen có hero image sáng | Profile với banner sáng |
|
|
106
|
+
| `user name` | `compact` | `false` | Chat/contact screen | Chat với người nhận chuyển tiền |
|
|
107
|
+
| `user name` | `expand` | `false` | Profile view mở rộng | Xem profile user |
|
|
108
|
+
| `user name` | `dark banner` | `false` | Profile với banner tối | Profile page với cover photo |
|
|
109
|
+
| `location` | `compact` | `false` | Screen có location context | ATM/PGD gần đây |
|
|
110
|
+
| `location` | `expand` | `false` | Location + extended info | Map view với filter |
|
|
111
|
+
| `journey` | `compact` | `false` | Multi-step flow | KYC flow, Mở tài khoản |
|
|
112
|
+
| `full page search` | `compact` | `false` | Dedicated search screen | Trang tìm kiếm chính |
|
|
113
|
+
| `onboarding` | `compact` | `false` | Onboarding flow | First-time intro |
|
|
114
|
+
|
|
115
|
+
> **Không phải tất cả 7×5 combinations đều tồn tại.** Chỉ 29 variants có trong Figma. ui-composer chỉ dùng những combinations listed ở trên.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## SSR Pattern
|
|
120
|
+
|
|
121
|
+
### Standard Screen (title + compact)
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"navigation": {
|
|
125
|
+
"headerType": "title",
|
|
126
|
+
"headerTitle": { "type": "text", "title": "Chuyển tiền" },
|
|
127
|
+
"backgroundType": "compact",
|
|
128
|
+
"hasSearch": false,
|
|
129
|
+
"showBackButton": true,
|
|
130
|
+
"rightActions": ["search"],
|
|
131
|
+
"enableKeyboardAvoidingView": true
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### User Header (chat screen)
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"navigation": {
|
|
140
|
+
"headerType": "user name",
|
|
141
|
+
"headerTitle": {
|
|
142
|
+
"type": "user",
|
|
143
|
+
"avatar": "{{data.userAvatar}}",
|
|
144
|
+
"name": "{{data.userName}}",
|
|
145
|
+
"description": "{{data.userStatus}}"
|
|
146
|
+
},
|
|
147
|
+
"backgroundType": "compact",
|
|
148
|
+
"showBackButton": true,
|
|
149
|
+
"rightActions": ["more"]
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Banner Screen (merchant/campaign)
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"navigation": {
|
|
158
|
+
"headerType": "title",
|
|
159
|
+
"headerTitle": { "type": "text", "title": "{{data.merchantName}}" },
|
|
160
|
+
"backgroundType": "dark banner",
|
|
161
|
+
"bannerImage": "{{data.bannerUrl}}",
|
|
162
|
+
"showBackButton": true
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Search Screen
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"navigation": {
|
|
171
|
+
"headerType": "title",
|
|
172
|
+
"headerTitle": { "type": "text", "title": "Tìm kiếm" },
|
|
173
|
+
"backgroundType": "compact",
|
|
174
|
+
"hasSearch": true,
|
|
175
|
+
"showBackButton": true
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Screen with Extended Navigation (tabs)
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"navigation": {
|
|
184
|
+
"headerType": "title",
|
|
185
|
+
"headerTitle": { "type": "text", "title": "Khám phá" },
|
|
186
|
+
"backgroundType": "expand",
|
|
187
|
+
"hasSearch": true,
|
|
188
|
+
"hasExtension": true,
|
|
189
|
+
"extendedNavigation": {
|
|
190
|
+
"component": "TabView",
|
|
191
|
+
"props": {
|
|
192
|
+
"tabs": ["Tất cả", "Ưu đãi", "Dịch vụ"]
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
"showBackButton": false
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Accessibility
|
|
203
|
+
|
|
204
|
+
- Back button: accessible label "Quay lại".
|
|
205
|
+
- Title: announce screen name cho screen readers.
|
|
206
|
+
- Toolkit icons: PHẢI có accessible labels ("Tìm kiếm", "Menu").
|
|
207
|
+
- Banner mode: đảm bảo đủ contrast text trên image (dark banner → text trắng, light banner → text đen).
|
|
208
|
+
- Search: announce "Tìm kiếm, text field" khi focus.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Usage Guidelines
|
|
213
|
+
|
|
214
|
+
### Do
|
|
215
|
+
- MỌI screen phải có TopNav — không exception trừ full-screen media.
|
|
216
|
+
- Default: `title` + `compact`. Khi không chắc → dùng cái này.
|
|
217
|
+
- Phân biệt rõ `dark banner` vs `light banner` dựa trên tone ảnh.
|
|
218
|
+
- Max 2-3 right action icons trong `rightActions`.
|
|
219
|
+
- Dùng `hasExtension` khi cần tab/segment ngay dưới header.
|
|
220
|
+
|
|
221
|
+
### Don't
|
|
222
|
+
- KHÔNG dùng `none` làm background mặc định — chỉ cho scrolled state.
|
|
223
|
+
- KHÔNG dùng `forWL` khi chưa có confirm từ system.
|
|
224
|
+
- KHÔNG dùng cho mini-app — dùng **TopNavMiniApp** (file riêng).
|
|
225
|
+
- KHÔNG custom header type ngoài 7 types đã định nghĩa.
|
|
226
|
+
- KHÔNG đặt quá 3 icons trong `rightActions`.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Uploader
|
|
2
|
+
|
|
3
|
+
> File/image upload interface — trigger area + thumbnails + progress. Single or multi-file upload.
|
|
4
|
+
|
|
5
|
+
**Package:** `@momo-kits/uploader`
|
|
6
|
+
**Platform:** RN ✅ | Compose ❌ (use platform file picker)
|
|
7
|
+
**Completeness:** need_update — thiếu Figma
|
|
8
|
+
**Figma node:** [VERIFY]
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Props
|
|
13
|
+
|
|
14
|
+
| Prop | Type | Values | Default | Description |
|
|
15
|
+
|------|------|--------|---------|-------------|
|
|
16
|
+
| `files` | array | `[{ uri, name, status }]` | `[]` | Current uploaded files list |
|
|
17
|
+
| `maxFiles` | number | — | `5` | Maximum files allowed. Trigger hidden khi reached |
|
|
18
|
+
| `acceptTypes` | string | MIME pattern | `"image/*"` | Allowed file types (e.g., `"image/*"`, `"application/pdf"`) [VERIFY] |
|
|
19
|
+
| `maxFileSize` | number | bytes | — | Maximum size per file [VERIFY] |
|
|
20
|
+
| `thumbnailSize` | number | dp | `80` | Preview thumbnail dimensions (square) [VERIFY] |
|
|
21
|
+
| `disabled` | boolean | `true` \| `false` | `false` | Non-interactive state |
|
|
22
|
+
| `onAdd` | function | — | — | Callback khi file selected. `"onAdd": "action://uploadFile"` |
|
|
23
|
+
| `onRemove` | function | — | — | Callback khi remove file. `"onRemove": "action://removeFile={{item.id}}"` |
|
|
24
|
+
|
|
25
|
+
### File Object
|
|
26
|
+
|
|
27
|
+
| Field | Type | Description |
|
|
28
|
+
|-------|------|-------------|
|
|
29
|
+
| `uri` | string | File URI for thumbnail preview |
|
|
30
|
+
| `name` | string | File name |
|
|
31
|
+
| `status` | string | `"uploading"` \| `"complete"` \| `"error"` |
|
|
32
|
+
| `progress` | number | Upload progress 0-100 (when status=uploading) [VERIFY] |
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## States
|
|
37
|
+
|
|
38
|
+
| State | Appearance | Interactive |
|
|
39
|
+
|-------|-----------|-------------|
|
|
40
|
+
| **Empty** | Only trigger area visible (dashed border + add icon) | true |
|
|
41
|
+
| **Uploading** | Thumbnail with semi-transparent overlay + progress indicator | partial |
|
|
42
|
+
| **Complete** | Thumbnail with image preview + remove (X) button | true |
|
|
43
|
+
| **Error** | Thumbnail border `Colors.red_03`, error icon overlay | true (retry) |
|
|
44
|
+
| **Max reached** | Trigger area hidden, only thumbnails visible | remove only |
|
|
45
|
+
| **Disabled** | Trigger border + icon `Colors.black_08`, non-interactive | false |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Variant-to-Context Map
|
|
50
|
+
|
|
51
|
+
| Context | Khi nào dùng | Tránh khi | Ví dụ trong MoMo |
|
|
52
|
+
|---------|-------------|-----------|-------------------|
|
|
53
|
+
| **Photo upload** | Attach photos to forms/reviews | Camera capture → dùng Camera | Upload CMND/CCCD, ảnh review merchant |
|
|
54
|
+
| **Document upload** | Attach PDF/docs | Structured data entry → dùng Input | Upload hợp đồng, biên lai |
|
|
55
|
+
| **Profile photo** | Single image selection | Multi-photo → set maxFiles=1 | Thay đổi ảnh đại diện |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## SSR Pattern
|
|
60
|
+
|
|
61
|
+
### ID Photo Upload
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"id": "id_upload",
|
|
65
|
+
"type": "section",
|
|
66
|
+
"children": [
|
|
67
|
+
{
|
|
68
|
+
"component": "Text",
|
|
69
|
+
"props": {
|
|
70
|
+
"content": "Tải ảnh CMND/CCCD",
|
|
71
|
+
"typography": "body_default_bold"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"component": "Uploader",
|
|
76
|
+
"props": {
|
|
77
|
+
"files": "{{state.idPhotos}}",
|
|
78
|
+
"maxFiles": 2,
|
|
79
|
+
"acceptTypes": "image/*"
|
|
80
|
+
},
|
|
81
|
+
"onAdd": "action://uploadIdPhoto",
|
|
82
|
+
"onRemove": "action://removeIdPhoto"
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Accessibility
|
|
91
|
+
|
|
92
|
+
- Trigger: accessible label "Thêm ảnh" hoặc "Tải tệp lên".
|
|
93
|
+
- Each thumbnail: announce file name + status + remove action.
|
|
94
|
+
- Remove button: "Xóa ảnh 1".
|
|
95
|
+
- Upload progress announced as live region: "Đang tải, 50%".
|
|
96
|
+
- Error state communicated: "Tải lên thất bại cho ảnh 2".
|
|
97
|
+
- All interactive elements meet 44dp touch target.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Usage Guidelines
|
|
102
|
+
|
|
103
|
+
### Do
|
|
104
|
+
- Dùng cho document/photo uploads trong forms.
|
|
105
|
+
- Show clear progress during upload.
|
|
106
|
+
- Allow easy removal with X button.
|
|
107
|
+
- Set appropriate file type + size restrictions — communicate limits to user.
|
|
108
|
+
- Thumbnail preview cho uploaded images.
|
|
109
|
+
|
|
110
|
+
### Don't
|
|
111
|
+
- Không dùng cho camera capture → dùng dedicated Camera component.
|
|
112
|
+
- Không allow unlimited uploads — always set reasonable maxFiles.
|
|
113
|
+
- Không silently reject oversized/wrong-type files → show error message.
|
|
114
|
+
- Không hide trigger until maxFiles reached.
|
|
115
|
+
- Không dùng tiny thumbnails — user cần verify uploaded content.
|