@momo-kits/native-kits 0.158.1-beta.1-debug → 0.158.1-beta.2-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/compose/build.gradle.kts +1 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/BottomSheet.kt +15 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/ModalScreen.kt +15 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigation.kt +1 -0
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/NavigationContainer.kt +4 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/Navigator.kt +11 -9
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/StackScreen.kt +56 -1
- package/compose/src/commonMain/kotlin/vn/momo/kits/navigation/tracking/ScreenTracker.kt +167 -0
- package/example/ios/Example.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/Example.xcscheme +32 -0
- package/example/ios/Example.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
- package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/WorkspaceSettings.xcsettings +16 -0
- package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +6 -0
- package/example/ios/Example.xcworkspace/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +5 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/MoMoUIKits.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/Pods-Example.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SDWebImage.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SDWebImageSwiftUI.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/SkeletonUI.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/lottie-ios-LottiePrivacyInfo.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/lottie-ios.xcscheme +58 -0
- package/example/ios/Pods/Pods.xcodeproj/xcuserdata/sonnguyen.xcuserdatad/xcschemes/xcschememanagement.plist +60 -0
- package/gradle.properties +1 -1
- package/local.properties +2 -2
- package/package.json +1 -1
- package/.claude/settings.local.json +0 -11
- package/.claude/skills/design-system/SKILL.md +0 -88
- package/.claude/skills/design-system/references/components/avatar.md +0 -134
- package/.claude/skills/design-system/references/components/badge.md +0 -127
- package/.claude/skills/design-system/references/components/bottom-tab.md +0 -177
- package/.claude/skills/design-system/references/components/bottomsheet.md +0 -170
- package/.claude/skills/design-system/references/components/button.md +0 -206
- package/.claude/skills/design-system/references/components/carousel.md +0 -117
- package/.claude/skills/design-system/references/components/checkbox.md +0 -98
- package/.claude/skills/design-system/references/components/chip.md +0 -146
- package/.claude/skills/design-system/references/components/collapse.md +0 -120
- package/.claude/skills/design-system/references/components/date-picker.md +0 -119
- package/.claude/skills/design-system/references/components/divider.md +0 -84
- package/.claude/skills/design-system/references/components/icon.md +0 -130
- package/.claude/skills/design-system/references/components/image.md +0 -81
- package/.claude/skills/design-system/references/components/information.md +0 -107
- package/.claude/skills/design-system/references/components/input-dropdown.md +0 -138
- package/.claude/skills/design-system/references/components/input-money.md +0 -157
- package/.claude/skills/design-system/references/components/input-otp.md +0 -132
- package/.claude/skills/design-system/references/components/input-phone-number.md +0 -140
- package/.claude/skills/design-system/references/components/input-search.md +0 -124
- package/.claude/skills/design-system/references/components/input-text-area.md +0 -133
- package/.claude/skills/design-system/references/components/input.md +0 -152
- package/.claude/skills/design-system/references/components/loader.md +0 -87
- package/.claude/skills/design-system/references/components/pagination.md +0 -105
- package/.claude/skills/design-system/references/components/popup-notify.md +0 -128
- package/.claude/skills/design-system/references/components/progress-info.md +0 -114
- package/.claude/skills/design-system/references/components/radio.md +0 -86
- package/.claude/skills/design-system/references/components/rating.md +0 -126
- package/.claude/skills/design-system/references/components/skeleton.md +0 -120
- package/.claude/skills/design-system/references/components/slider.md +0 -141
- package/.claude/skills/design-system/references/components/snackbar.md +0 -97
- package/.claude/skills/design-system/references/components/stepper.md +0 -100
- package/.claude/skills/design-system/references/components/steps.md +0 -91
- package/.claude/skills/design-system/references/components/suggest-action.md +0 -95
- package/.claude/skills/design-system/references/components/swipe.md +0 -121
- package/.claude/skills/design-system/references/components/switch.md +0 -98
- package/.claude/skills/design-system/references/components/tab-view.md +0 -120
- package/.claude/skills/design-system/references/components/tag.md +0 -118
- package/.claude/skills/design-system/references/components/text.md +0 -151
- package/.claude/skills/design-system/references/components/toast.md +0 -99
- package/.claude/skills/design-system/references/components/tooltip.md +0 -138
- package/.claude/skills/design-system/references/components/top-nav-miniapp.md +0 -94
- package/.claude/skills/design-system/references/components/top-nav.md +0 -226
- package/.claude/skills/design-system/references/components/uploader.md +0 -115
- package/.claude/skills/design-system/references/navigation/bottom-tab.md +0 -131
- package/.claude/skills/design-system/references/navigation/bottomsheet.md +0 -161
- package/.claude/skills/design-system/references/navigation/modal.md +0 -133
- package/.claude/skills/design-system/references/navigation/navigation-options.md +0 -225
- package/.claude/skills/design-system/references/navigation/navigator.md +0 -111
- package/.claude/skills/design-system/references/navigation/setup.md +0 -134
- package/.claude/skills/design-system/references/navigation/stack.md +0 -128
- package/.claude/skills/design-system/references/spec-convention.md +0 -80
- package/.claude/skills/design-system/references/tokens/colors.md +0 -131
- package/.claude/skills/design-system/references/tokens/spacing-radius.md +0 -144
- package/.claude/skills/design-system/references/tokens/theme.md +0 -125
- package/.claude/skills/design-system/references/tokens/typography.md +0 -135
- package/.claude/skills/design-system-kits/SKILL.md +0 -102
- package/.claude/skills/design-system-kits/references/code-convention.md +0 -118
- package/.claude/skills/design-system-kits/references/components/avatar.md +0 -45
- package/.claude/skills/design-system-kits/references/components/badge.md +0 -27
- package/.claude/skills/design-system-kits/references/components/button.md +0 -65
- package/.claude/skills/design-system-kits/references/components/carousel.md +0 -51
- package/.claude/skills/design-system-kits/references/components/checkbox.md +0 -39
- package/.claude/skills/design-system-kits/references/components/chip.md +0 -54
- package/.claude/skills/design-system-kits/references/components/collapse.md +0 -63
- package/.claude/skills/design-system-kits/references/components/date-picker.md +0 -36
- package/.claude/skills/design-system-kits/references/components/divider.md +0 -21
- package/.claude/skills/design-system-kits/references/components/icon.md +0 -382
- package/.claude/skills/design-system-kits/references/components/image.md +0 -62
- package/.claude/skills/design-system-kits/references/components/information.md +0 -61
- package/.claude/skills/design-system-kits/references/components/input-dropdown.md +0 -92
- package/.claude/skills/design-system-kits/references/components/input-money.md +0 -128
- package/.claude/skills/design-system-kits/references/components/input-otp.md +0 -85
- package/.claude/skills/design-system-kits/references/components/input-phone-number.md +0 -96
- package/.claude/skills/design-system-kits/references/components/input-search.md +0 -127
- package/.claude/skills/design-system-kits/references/components/input-text-area.md +0 -100
- package/.claude/skills/design-system-kits/references/components/input.md +0 -126
- package/.claude/skills/design-system-kits/references/components/loader.md +0 -41
- package/.claude/skills/design-system-kits/references/components/pagination.md +0 -47
- package/.claude/skills/design-system-kits/references/components/popup-notify.md +0 -69
- package/.claude/skills/design-system-kits/references/components/popup-promotion.md +0 -35
- package/.claude/skills/design-system-kits/references/components/progress-info.md +0 -55
- package/.claude/skills/design-system-kits/references/components/radio.md +0 -42
- package/.claude/skills/design-system-kits/references/components/rating.md +0 -36
- package/.claude/skills/design-system-kits/references/components/skeleton.md +0 -25
- package/.claude/skills/design-system-kits/references/components/slider.md +0 -53
- package/.claude/skills/design-system-kits/references/components/snackbar.md +0 -52
- package/.claude/skills/design-system-kits/references/components/stepper.md +0 -46
- package/.claude/skills/design-system-kits/references/components/steps.md +0 -57
- package/.claude/skills/design-system-kits/references/components/suggest-action.md +0 -44
- package/.claude/skills/design-system-kits/references/components/swipe.md +0 -44
- package/.claude/skills/design-system-kits/references/components/switch.md +0 -43
- package/.claude/skills/design-system-kits/references/components/tab-view.md +0 -56
- package/.claude/skills/design-system-kits/references/components/tag.md +0 -50
- package/.claude/skills/design-system-kits/references/components/text.md +0 -56
- package/.claude/skills/design-system-kits/references/components/toast.md +0 -51
- package/.claude/skills/design-system-kits/references/components/tooltip.md +0 -95
- package/.claude/skills/design-system-kits/references/components/uploader.md +0 -48
- package/.claude/skills/design-system-kits/references/design-spec-structure.md +0 -356
- package/.claude/skills/design-system-kits/references/design-spec-to-code.md +0 -596
- package/.claude/skills/design-system-kits/references/navigation/bottom-tab.md +0 -155
- package/.claude/skills/design-system-kits/references/navigation/bottomsheet.md +0 -94
- package/.claude/skills/design-system-kits/references/navigation/modal.md +0 -125
- package/.claude/skills/design-system-kits/references/navigation/navigation-options.md +0 -430
- package/.claude/skills/design-system-kits/references/navigation/navigator.md +0 -177
- package/.claude/skills/design-system-kits/references/navigation/setup.md +0 -94
- package/.claude/skills/design-system-kits/references/navigation/stack.md +0 -152
- package/.claude/skills/design-system-kits/references/screen-layout-rule.md +0 -125
- package/.claude/skills/design-system-kits/references/tokens/colors.md +0 -183
- package/.claude/skills/design-system-kits/references/tokens/spacing-radius.md +0 -45
- package/.claude/skills/design-system-kits/references/tokens/theme.md +0 -97
- package/.claude/skills/design-system-kits/references/tokens/typography.md +0 -105
- package/.claude/skills/vibe-design/SKILL.md +0 -306
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
# InputOTP
|
|
2
|
-
|
|
3
|
-
> Code entry với individual character cells — dùng cho xác thực OTP, mã PIN hiển thị trong MoMo.
|
|
4
|
-
|
|
5
|
-
**Package:** `@momo-kits/foundation`
|
|
6
|
-
**Platform:** RN ✅ | Compose ✅
|
|
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
|
-
| `length` | number | `4` \| `5` \| `6` | `6` | Số ô nhập (cells) [VERIFY] |
|
|
17
|
-
| `value` | string | — | `""` | Current OTP value |
|
|
18
|
-
| `errorMessage` | string | — | — | Error text bên dưới cells |
|
|
19
|
-
| `disabled` | boolean | `true` \| `false` | `false` | Non-interactive state |
|
|
20
|
-
| `autoFocus` | boolean | `true` \| `false` | `true` | Auto focus cell đầu tiên khi mount [VERIFY] |
|
|
21
|
-
| `onComplete` | function | — | — | Callback khi nhập đủ digits. `"onComplete": "action://verifyOTP"` [VERIFY] |
|
|
22
|
-
| `onChange` | function | — | — | Callback mỗi digit thay đổi. `"onChange": "setState://otpValue"` |
|
|
23
|
-
|
|
24
|
-
> **Khác biệt lớn:** InputOTP KHÔNG dùng floating label, prefix, suffix, hintText, size prop. Anatomy hoàn toàn khác các Input variants khác.
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## States
|
|
29
|
-
|
|
30
|
-
| State | Cell Border | Cell Background | Digit Color | Error Color | Interactive |
|
|
31
|
-
|-------|------------|----------------|------------|-------------|-------------|
|
|
32
|
-
| **Empty** | `Colors.black_04` | `Colors.white` | — | — | true |
|
|
33
|
-
| **Focused** | `Colors.blue_03` | `Colors.white` | `Colors.black_17` | — | true |
|
|
34
|
-
| **Filled** | `Colors.black_04` | `Colors.white` | `Colors.black_17` | — | true |
|
|
35
|
-
| **Error** | `Colors.red_03` | `Colors.white` | `Colors.black_17` | `Colors.red_03` | true |
|
|
36
|
-
| **Disabled** | `Colors.black_03` | `Colors.white` | `Colors.black_08` | — | false |
|
|
37
|
-
|
|
38
|
-
- Error state: TẤT CẢ cells chuyển border sang `Colors.red_03`, không chỉ cell sai.
|
|
39
|
-
- Focused cell: chỉ 1 cell có `Colors.blue_03` border tại mỗi thời điểm.
|
|
40
|
-
- Auto-advance: nhập 1 digit → focus tự chuyển sang cell tiếp theo.
|
|
41
|
-
- Auto-paste: paste SMS OTP → fill tất cả cells cùng lúc.
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## Variant-to-Context Map
|
|
46
|
-
|
|
47
|
-
| Context | Khi nào dùng | Tránh khi | Ví dụ trong MoMo |
|
|
48
|
-
|---------|-------------|-----------|-------------------|
|
|
49
|
-
| **OTP verification** | Xác thực giao dịch qua SMS/email code | Code dài >6 digits — dùng Input standard | OTP xác nhận chuyển tiền, OTP đăng nhập |
|
|
50
|
-
| **Confirmation code** | Nhập mã xác nhận từ email/app | Code có chữ cái — InputOTP chỉ numeric | Mã xác nhận từ email MoMo |
|
|
51
|
-
| **PIN display** | Nhập PIN hiển thị (không mask) | Cần mask dots → dùng Input standard + secureTextEntry | — |
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## SSR Pattern
|
|
56
|
-
|
|
57
|
-
### OTP Verification Screen
|
|
58
|
-
```json
|
|
59
|
-
{
|
|
60
|
-
"id": "otp_section",
|
|
61
|
-
"type": "section",
|
|
62
|
-
"children": [
|
|
63
|
-
{
|
|
64
|
-
"component": "Text",
|
|
65
|
-
"props": {
|
|
66
|
-
"content": "Nhập mã xác thực",
|
|
67
|
-
"typography": "heading_default_bold"
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
"component": "Text",
|
|
72
|
-
"props": {
|
|
73
|
-
"content": "Mã OTP đã gửi đến {{data.maskedPhone}}",
|
|
74
|
-
"typography": "body_default_regular"
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
"component": "InputOTP",
|
|
79
|
-
"props": {
|
|
80
|
-
"length": 6,
|
|
81
|
-
"errorMessage": "{{state.otpError}}",
|
|
82
|
-
"autoFocus": true
|
|
83
|
-
},
|
|
84
|
-
"onComplete": "action://verifyOTP",
|
|
85
|
-
"onChange": "setState://otpValue"
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
"component": "Text",
|
|
89
|
-
"props": {
|
|
90
|
-
"content": "Gửi lại sau {{state.countdown}}s",
|
|
91
|
-
"typography": "caption_default_regular"
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
"component": "Button",
|
|
96
|
-
"props": {
|
|
97
|
-
"title": "Gửi lại mã",
|
|
98
|
-
"type": "textlink",
|
|
99
|
-
"disabled": "{{state.countdown > 0}}"
|
|
100
|
-
},
|
|
101
|
-
"onPress": "action://resendOTP"
|
|
102
|
-
}
|
|
103
|
-
]
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## Accessibility
|
|
110
|
-
|
|
111
|
-
- Each cell phải có accessible label: "Digit 1 of 6", "Digit 2 of 6", etc.
|
|
112
|
-
- Auto-advance phải announce: "Moving to next digit".
|
|
113
|
-
- Error announcement: screen reader phải announce error message khi validation fails.
|
|
114
|
-
- Keyboard: numeric only.
|
|
115
|
-
- Auto-paste: support clipboard paste cho toàn bộ OTP.
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## Usage Guidelines
|
|
120
|
-
|
|
121
|
-
### Do
|
|
122
|
-
- Dùng `autoFocus` để focus cell đầu tiên ngay khi screen mount.
|
|
123
|
-
- Support auto-paste từ SMS — user không cần nhập từng digit.
|
|
124
|
-
- Show countdown timer cho resend OTP.
|
|
125
|
-
- Clear error state khi user bắt đầu nhập lại.
|
|
126
|
-
- Dùng `length=6` cho OTP standard, `length=4` cho short codes.
|
|
127
|
-
|
|
128
|
-
### Don't
|
|
129
|
-
- Không dùng InputOTP cho password — dùng **Input** standard + secureTextEntry.
|
|
130
|
-
- Không dùng cho text codes có chữ cái — InputOTP chỉ numeric.
|
|
131
|
-
- Không disable auto-paste — đây là UX critical cho OTP flow.
|
|
132
|
-
- Không show timer quá 5 phút — user sẽ bỏ flow.
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# InputPhoneNumber
|
|
2
|
-
|
|
3
|
-
> Phone number input với country code prefix — dùng cho nhập số điện thoại trong MoMo.
|
|
4
|
-
|
|
5
|
-
**Package:** `@momo-kits/foundation`
|
|
6
|
-
**Platform:** RN ✅ | Compose ✅
|
|
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
|
-
| `value` | string | — | `""` | Phone number value (without country code) |
|
|
17
|
-
| `floatingValue` | string | — | required | Floating label text |
|
|
18
|
-
| `placeholder` | string | — | — | Hint text ("0912 345 678") |
|
|
19
|
-
| `hintText` | string | — | — | Helper text bên dưới |
|
|
20
|
-
| `errorMessage` | string | — | — | Error text. "Số điện thoại không hợp lệ" |
|
|
21
|
-
| `size` | string | `"large"` \| `"medium"` | `"medium"` | Input size |
|
|
22
|
-
| `disabled` | boolean | `true` \| `false` | `false` | Non-interactive |
|
|
23
|
-
| `required` | boolean | `true` \| `false` | `false` | Required indicator |
|
|
24
|
-
| `countryCode` | string | `"+84"` \| `"+1"` \| ... | `"+84"` | Country code prefix [VERIFY] |
|
|
25
|
-
| `showClearButton` | boolean | `true` \| `false` | `true` | Clear button [VERIFY] |
|
|
26
|
-
| `onChange` | function | — | — | Callback khi value thay đổi |
|
|
27
|
-
| `onFocus` | function | — | — | Callback khi focus |
|
|
28
|
-
| `onBlur` | function | — | — | Callback khi blur |
|
|
29
|
-
| `onClear` | function | — | — | Callback khi clear [VERIFY] |
|
|
30
|
-
|
|
31
|
-
> **Keyboard:** phone-pad. Country code prefix hiển thị built-in, user chỉ nhập số phone.
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## States
|
|
36
|
-
|
|
37
|
-
| State | Border | Text Color | Label Color | Error Color | Cursor | Clear Btn | Interactive |
|
|
38
|
-
|-------|--------|-----------|------------|-------------|--------|-----------|-------------|
|
|
39
|
-
| **Default** | `Colors.black_04` | `Colors.black_17` | `Colors.black_17` | — | hidden | hidden | true |
|
|
40
|
-
| **Focused** | `Colors.blue_03` | `Colors.black_17` | `Colors.black_17` | — | visible | hidden | true |
|
|
41
|
-
| **Typing** | `Colors.blue_03` | `Colors.black_17` | `Colors.black_17` | — | visible | visible | true |
|
|
42
|
-
| **Filled** | `Colors.black_04` | `Colors.black_17` | `Colors.black_17` | — | hidden | visible | true |
|
|
43
|
-
| **Error** | `Colors.red_03` | `Colors.black_17` | `Colors.black_17` | `Colors.red_03` | hidden | visible | true |
|
|
44
|
-
| **Disabled** | `Colors.black_03` | `Colors.black_08` | `Colors.black_08` | — | hidden | hidden | false |
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## Variant-to-Context Map
|
|
49
|
-
|
|
50
|
-
| Context | Khi nào dùng | Tránh khi | Ví dụ trong MoMo |
|
|
51
|
-
|---------|-------------|-----------|-------------------|
|
|
52
|
-
| **Receiver phone** | Nhập SĐT người nhận | Nhập từ contacts → auto-fill, không cần manual input | Form chuyển tiền — SĐT người nhận |
|
|
53
|
-
| **Registration** | Nhập SĐT đăng ký | Đã có SĐT từ SIM → auto-detect [VERIFY] | Đăng ký tài khoản MoMo |
|
|
54
|
-
| **Verification** | Nhập SĐT để verify | — | Xác thực số điện thoại, KYC |
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## SSR Pattern
|
|
59
|
-
|
|
60
|
-
### Transfer to Phone
|
|
61
|
-
```json
|
|
62
|
-
{
|
|
63
|
-
"id": "transfer_form",
|
|
64
|
-
"type": "section",
|
|
65
|
-
"children": [
|
|
66
|
-
{
|
|
67
|
-
"component": "InputPhoneNumber",
|
|
68
|
-
"props": {
|
|
69
|
-
"floatingValue": "Số điện thoại người nhận",
|
|
70
|
-
"placeholder": "0912 345 678",
|
|
71
|
-
"countryCode": "+84",
|
|
72
|
-
"size": "medium",
|
|
73
|
-
"required": true,
|
|
74
|
-
"errorMessage": "{{state.phoneError}}"
|
|
75
|
-
},
|
|
76
|
-
"onChange": "setState://receiverPhone"
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
"component": "InputMoney",
|
|
80
|
-
"props": {
|
|
81
|
-
"floatingValue": "Số tiền",
|
|
82
|
-
"size": "large",
|
|
83
|
-
"required": true
|
|
84
|
-
},
|
|
85
|
-
"onChange": "setState://amount"
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
"component": "Button",
|
|
89
|
-
"props": {
|
|
90
|
-
"title": "Chuyển tiền",
|
|
91
|
-
"type": "primary",
|
|
92
|
-
"size": "large",
|
|
93
|
-
"full": true
|
|
94
|
-
},
|
|
95
|
-
"onPress": "action://transfer"
|
|
96
|
-
}
|
|
97
|
-
]
|
|
98
|
-
}
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### Registration Form
|
|
102
|
-
```json
|
|
103
|
-
{
|
|
104
|
-
"component": "InputPhoneNumber",
|
|
105
|
-
"props": {
|
|
106
|
-
"floatingValue": "Số điện thoại",
|
|
107
|
-
"placeholder": "Nhập số điện thoại",
|
|
108
|
-
"countryCode": "+84",
|
|
109
|
-
"size": "large",
|
|
110
|
-
"required": true,
|
|
111
|
-
"errorMessage": "{{state.phoneError}}"
|
|
112
|
-
},
|
|
113
|
-
"onChange": "setState://phoneNumber"
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## Accessibility
|
|
120
|
-
|
|
121
|
-
- Floating label required.
|
|
122
|
-
- Country code announce: "+84, Vietnam".
|
|
123
|
-
- Phone number format announce digits, không announce spaces.
|
|
124
|
-
- Error linked.
|
|
125
|
-
- Keyboard: phone-pad.
|
|
126
|
-
|
|
127
|
-
---
|
|
128
|
-
|
|
129
|
-
## Usage Guidelines
|
|
130
|
-
|
|
131
|
-
### Do
|
|
132
|
-
- Default country code `+84` cho Vietnam market.
|
|
133
|
-
- Cho phép chọn country code khác nếu app support international.
|
|
134
|
-
- Validate phone format trên blur.
|
|
135
|
-
- Auto-format phone number với spaces (0912 345 678).
|
|
136
|
-
|
|
137
|
-
### Don't
|
|
138
|
-
- Không dùng cho nhập số tài khoản ngân hàng — dùng **Input** standard.
|
|
139
|
-
- Không dùng cho nhập OTP — dùng **InputOTP**.
|
|
140
|
-
- Không require user nhập country code manually — phải có picker.
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
# InputSearch
|
|
2
|
-
|
|
3
|
-
> Search bar với search icon prefix và cancel action — dùng cho mọi search flow trong MoMo.
|
|
4
|
-
|
|
5
|
-
**Package:** `@momo-kits/foundation`
|
|
6
|
-
**Platform:** RN ✅ | Compose ✅
|
|
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
|
-
| `value` | string | — | `""` | Current search query |
|
|
17
|
-
| `placeholder` | string | — | `"Tìm kiếm"` | Hint text. Không dùng floating label [VERIFY] |
|
|
18
|
-
| `hintText` | string | — | — | Helper text bên dưới (hiếm dùng cho search) |
|
|
19
|
-
| `errorMessage` | string | — | — | Error text (hiếm dùng cho search) |
|
|
20
|
-
| `size` | string | `"large"` \| `"medium"` | `"medium"` | Search bar size |
|
|
21
|
-
| `disabled` | boolean | `true` \| `false` | `false` | Non-interactive |
|
|
22
|
-
| `showClearButton` | boolean | `true` \| `false` | `true` | Clear button khi có value [VERIFY] |
|
|
23
|
-
| `onChange` | function | — | — | Callback mỗi keystroke. `"onChange": "setState://searchQuery"` |
|
|
24
|
-
| `onFocus` | function | — | — | Callback khi focus — thường trigger search UI |
|
|
25
|
-
| `onBlur` | function | — | — | Callback khi blur |
|
|
26
|
-
| `onClear` | function | — | — | Callback khi clear [VERIFY] |
|
|
27
|
-
| `onCancel` | function | — | — | Callback khi tap Cancel button. Clear value + dismiss focus [VERIFY] |
|
|
28
|
-
|
|
29
|
-
> **Khác biệt:** InputSearch có search icon prefix built-in và Cancel button appears on focus. Có thể KHÔNG dùng `floatingValue` mà dùng `placeholder` trực tiếp [VERIFY].
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## States
|
|
34
|
-
|
|
35
|
-
| State | Border | Text Color | Icon Color | Cancel Btn | Clear Btn | Interactive |
|
|
36
|
-
|-------|--------|-----------|-----------|------------|-----------|-------------|
|
|
37
|
-
| **Default** | `Colors.black_04` | `Colors.black_17` | `Colors.black_12` | hidden | hidden | true |
|
|
38
|
-
| **Focused** | `Colors.blue_03` | `Colors.black_17` | `Colors.black_12` | visible | hidden | true |
|
|
39
|
-
| **Typing** | `Colors.blue_03` | `Colors.black_17` | `Colors.black_12` | visible | visible | true |
|
|
40
|
-
| **Filled** | `Colors.black_04` | `Colors.black_17` | `Colors.black_12` | hidden | visible | true |
|
|
41
|
-
| **Disabled** | `Colors.black_03` | `Colors.black_08` | `Colors.black_08` | hidden | hidden | false |
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## Variant-to-Context Map
|
|
46
|
-
|
|
47
|
-
| Context | Khi nào dùng | Tránh khi | Ví dụ trong MoMo |
|
|
48
|
-
|---------|-------------|-----------|-------------------|
|
|
49
|
-
| **List search** | Tìm kiếm trong danh sách dài | Chỉ filter đơn giản 3-5 options — dùng Chip group | Search giao dịch lịch sử, search contacts |
|
|
50
|
-
| **Service search** | Tìm dịch vụ/merchant | Danh mục cố định — dùng tabs/chips | Search dịch vụ trên Home, search merchant |
|
|
51
|
-
| **Global search** | Search bar chính của app | — | Search bar trên Home screen MoMo |
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## SSR Pattern
|
|
56
|
-
|
|
57
|
-
### Search with Results List
|
|
58
|
-
```json
|
|
59
|
-
{
|
|
60
|
-
"id": "search_section",
|
|
61
|
-
"type": "section",
|
|
62
|
-
"children": [
|
|
63
|
-
{
|
|
64
|
-
"component": "InputSearch",
|
|
65
|
-
"props": {
|
|
66
|
-
"placeholder": "Tìm kiếm giao dịch",
|
|
67
|
-
"size": "medium"
|
|
68
|
-
},
|
|
69
|
-
"onChange": "setState://searchQuery"
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
"id": "search_results",
|
|
73
|
-
"type": "section",
|
|
74
|
-
"forEach": "{{data.searchResults}}",
|
|
75
|
-
"render": {
|
|
76
|
-
"component": "ListItem",
|
|
77
|
-
"props": {
|
|
78
|
-
"title": "{{item.title}}",
|
|
79
|
-
"subtitle": "{{item.date}}",
|
|
80
|
-
"rightText": "{{item.amount}}"
|
|
81
|
-
},
|
|
82
|
-
"onPress": "navigate://TransactionDetail?id={{item.id}}"
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
]
|
|
86
|
-
}
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Global Search Bar
|
|
90
|
-
```json
|
|
91
|
-
{
|
|
92
|
-
"component": "InputSearch",
|
|
93
|
-
"props": {
|
|
94
|
-
"placeholder": "Tìm dịch vụ, bạn bè...",
|
|
95
|
-
"size": "large"
|
|
96
|
-
},
|
|
97
|
-
"onFocus": "navigate://SearchScreen",
|
|
98
|
-
"onChange": "setState://globalSearch"
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
---
|
|
103
|
-
|
|
104
|
-
## Accessibility
|
|
105
|
-
|
|
106
|
-
- Search icon phải accessible — role "search".
|
|
107
|
-
- Placeholder announce: "Tìm kiếm giao dịch, search field".
|
|
108
|
-
- Cancel button: announce "Cancel search".
|
|
109
|
-
- Results count announce khi results change: "5 results found".
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
## Usage Guidelines
|
|
114
|
-
|
|
115
|
-
### Do
|
|
116
|
-
- Dùng full width cho search bar.
|
|
117
|
-
- Show Cancel button khi focused — cho phép user dismiss nhanh.
|
|
118
|
-
- Implement live search (debounced) hoặc search on submit.
|
|
119
|
-
- Clear results khi query cleared.
|
|
120
|
-
|
|
121
|
-
### Don't
|
|
122
|
-
- Không dùng cho simple filter — dùng **Chip** group.
|
|
123
|
-
- Không hide search icon — user cần visual cue đây là search.
|
|
124
|
-
- Không disable Cancel khi focused — luôn cho phép dismiss.
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
# InputTextArea
|
|
2
|
-
|
|
3
|
-
> Multiline text input — container grows vertically theo content cho đến max height.
|
|
4
|
-
|
|
5
|
-
**Package:** `@momo-kits/foundation`
|
|
6
|
-
**Platform:** RN ✅ | Compose ✅
|
|
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
|
-
| `value` | string | — | `""` | Current input value (multiline) |
|
|
17
|
-
| `floatingValue` | string | — | required | Floating label text |
|
|
18
|
-
| `placeholder` | string | — | — | Hint text khi chưa có value |
|
|
19
|
-
| `hintText` | string | — | — | Helper text bên dưới container |
|
|
20
|
-
| `errorMessage` | string | — | — | Error text. Replaces hintText |
|
|
21
|
-
| `size` | string | `"large"` \| `"medium"` | `"medium"` | Initial input size |
|
|
22
|
-
| `disabled` | boolean | `true` \| `false` | `false` | Non-interactive state |
|
|
23
|
-
| `editable` | boolean | `true` \| `false` | `true` | `false` = read-only [VERIFY] |
|
|
24
|
-
| `required` | boolean | `true` \| `false` | `false` | Required indicator |
|
|
25
|
-
| `maxLines` | number | — | — | Max dòng trước khi scroll [VERIFY] |
|
|
26
|
-
| `maxHeight` | number | — | — | Max chiều cao container [VERIFY] |
|
|
27
|
-
| `showClearButton` | boolean | `true` \| `false` | `true` | Clear button [VERIFY] |
|
|
28
|
-
| `onChange` | function | — | — | Callback khi value thay đổi |
|
|
29
|
-
| `onFocus` | function | — | — | Callback khi focus |
|
|
30
|
-
| `onBlur` | function | — | — | Callback khi blur |
|
|
31
|
-
| `onClear` | function | — | — | Callback khi clear [VERIFY] |
|
|
32
|
-
|
|
33
|
-
> **Khác biệt so với Input:** Container height KHÔNG cố định — grows vertically theo content. Keyboard default (multiline enter).
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## States
|
|
38
|
-
|
|
39
|
-
| State | Border | Text Color | Label Color | Error Color | Cursor | Clear Btn | Interactive |
|
|
40
|
-
|-------|--------|-----------|------------|-------------|--------|-----------|-------------|
|
|
41
|
-
| **Default** | `Colors.black_04` | `Colors.black_17` | `Colors.black_17` | — | hidden | hidden | true |
|
|
42
|
-
| **Focused** | `Colors.blue_03` | `Colors.black_17` | `Colors.black_17` | — | visible | hidden | true |
|
|
43
|
-
| **Typing** | `Colors.blue_03` | `Colors.black_17` | `Colors.black_17` | — | visible | visible | true |
|
|
44
|
-
| **Filled** | `Colors.black_04` | `Colors.black_17` | `Colors.black_17` | — | hidden | visible | true |
|
|
45
|
-
| **Error** | `Colors.red_03` | `Colors.black_17` | `Colors.black_17` | `Colors.red_03` | hidden | visible | true |
|
|
46
|
-
| **Disabled** | `Colors.black_03` | `Colors.black_08` | `Colors.black_08` | — | hidden | hidden | false |
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## Variant-to-Context Map
|
|
51
|
-
|
|
52
|
-
| Context | Khi nào dùng | Tránh khi | Ví dụ trong MoMo |
|
|
53
|
-
|---------|-------------|-----------|-------------------|
|
|
54
|
-
| **Long note** | Nhập text dài nhiều dòng | Text ngắn 1 dòng — dùng Input standard | Ghi chú chuyển tiền dài, lý do hoàn tiền |
|
|
55
|
-
| **Description** | Mô tả chi tiết | Chỉ cần 1 field ngắn | Mô tả yêu cầu hỗ trợ, feedback |
|
|
56
|
-
| **Message** | Tin nhắn dạng freeform | Structured input — dùng form fields riêng | Nhắn tin cho merchant, comment |
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## SSR Pattern
|
|
61
|
-
|
|
62
|
-
### Feedback Form
|
|
63
|
-
```json
|
|
64
|
-
{
|
|
65
|
-
"id": "feedback_section",
|
|
66
|
-
"type": "section",
|
|
67
|
-
"children": [
|
|
68
|
-
{
|
|
69
|
-
"component": "Rating",
|
|
70
|
-
"props": {
|
|
71
|
-
"value": "{{state.rating}}"
|
|
72
|
-
},
|
|
73
|
-
"onChange": "setState://rating"
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
"component": "InputTextArea",
|
|
77
|
-
"props": {
|
|
78
|
-
"floatingValue": "Nhận xét của bạn",
|
|
79
|
-
"placeholder": "Chia sẻ trải nghiệm...",
|
|
80
|
-
"size": "medium",
|
|
81
|
-
"maxLines": 5
|
|
82
|
-
},
|
|
83
|
-
"onChange": "setState://feedback"
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
"component": "Button",
|
|
87
|
-
"props": {
|
|
88
|
-
"title": "Gửi đánh giá",
|
|
89
|
-
"type": "primary",
|
|
90
|
-
"size": "large",
|
|
91
|
-
"full": true
|
|
92
|
-
},
|
|
93
|
-
"onPress": "action://submitFeedback"
|
|
94
|
-
}
|
|
95
|
-
]
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Transfer Note
|
|
100
|
-
```json
|
|
101
|
-
{
|
|
102
|
-
"component": "InputTextArea",
|
|
103
|
-
"props": {
|
|
104
|
-
"floatingValue": "Lời nhắn",
|
|
105
|
-
"placeholder": "Nhập ghi chú cho người nhận",
|
|
106
|
-
"size": "medium",
|
|
107
|
-
"maxLines": 3
|
|
108
|
-
},
|
|
109
|
-
"onChange": "setState://transferNote"
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
---
|
|
114
|
-
|
|
115
|
-
## Accessibility
|
|
116
|
-
|
|
117
|
-
- Floating label required cho screen readers.
|
|
118
|
-
- Announce multiline capability — "text area, 3 of 5 lines".
|
|
119
|
-
- Error message linked.
|
|
120
|
-
- Touch target: full container tappable.
|
|
121
|
-
|
|
122
|
-
---
|
|
123
|
-
|
|
124
|
-
## Usage Guidelines
|
|
125
|
-
|
|
126
|
-
### Do
|
|
127
|
-
- Set `maxLines` hoặc `maxHeight` để tránh content chiếm toàn bộ screen.
|
|
128
|
-
- Dùng `placeholder` để guide content ("Chia sẻ trải nghiệm...").
|
|
129
|
-
- Show character count nếu có limit [VERIFY — cần check prop].
|
|
130
|
-
|
|
131
|
-
### Don't
|
|
132
|
-
- Không dùng cho text ngắn 1 dòng — dùng **Input** standard.
|
|
133
|
-
- Không set maxLines quá nhỏ (1-2) — vô nghĩa, dùng Input standard.
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
# Input
|
|
2
|
-
|
|
3
|
-
> Single-line text input với floating label — form control cơ bản cho mọi dạng nhập text trong MoMo.
|
|
4
|
-
|
|
5
|
-
**Package:** `@momo-kits/foundation`
|
|
6
|
-
**Platform:** RN ✅ | Compose ✅
|
|
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
|
-
| `value` | string | — | `""` | Current input value |
|
|
17
|
-
| `floatingValue` | string | — | required | Floating label text. Animates từ placeholder position lên trên khi focus/filled |
|
|
18
|
-
| `placeholder` | string | — | — | Hint text khi chưa có value |
|
|
19
|
-
| `hintText` | string | — | — | Helper text hiển thị bên dưới container |
|
|
20
|
-
| `errorMessage` | string | — | — | Error text bên dưới container. Khi có, replaces hintText |
|
|
21
|
-
| `size` | string | `"large"` \| `"medium"` | `"medium"` | Input size. Maps to `InputSize.Large` / `InputSize.Medium` |
|
|
22
|
-
| `disabled` | boolean | `true` \| `false` | `false` | Non-interactive state |
|
|
23
|
-
| `editable` | boolean | `true` \| `false` | `true` | `false` = read-only state [VERIFY] |
|
|
24
|
-
| `required` | boolean | `true` \| `false` | `false` | Hiển thị required indicator bên cạnh label |
|
|
25
|
-
| `prefix` | node | icon \| text | — | Element ở đầu input |
|
|
26
|
-
| `trailingIcon` | node | icon | — | Icon ở cuối input |
|
|
27
|
-
| `showClearButton` | boolean | `true` \| `false` | `true` | Clear button xuất hiện ở typing/filled/error states [VERIFY] |
|
|
28
|
-
| `showInformationIcon` | boolean | `true` \| `false` | `false` | Optional info icon [VERIFY] |
|
|
29
|
-
| `image` | node | — | — | Optional image inside input [VERIFY] |
|
|
30
|
-
| `onChange` | function | — | — | Callback khi value thay đổi. `"onChange": "setState://fieldName"` |
|
|
31
|
-
| `onFocus` | function | — | — | Callback khi input nhận focus |
|
|
32
|
-
| `onBlur` | function | — | — | Callback khi input mất focus |
|
|
33
|
-
| `onClear` | function | — | — | Callback khi tap clear button [VERIFY] |
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## States
|
|
38
|
-
|
|
39
|
-
| State | Border | Text Color | Label Color | Error Color | Cursor | Clear Btn | Interactive |
|
|
40
|
-
|-------|--------|-----------|------------|-------------|--------|-----------|-------------|
|
|
41
|
-
| **Default** | `Colors.black_04` | `Colors.black_17` | `Colors.black_17` | — | hidden | hidden | true |
|
|
42
|
-
| **Focused** | `Colors.blue_03` | `Colors.black_17` | `Colors.black_17` | — | visible | hidden | true |
|
|
43
|
-
| **Typing** | `Colors.blue_03` | `Colors.black_17` | `Colors.black_17` | — | visible | visible | true |
|
|
44
|
-
| **Filled** | `Colors.black_04` | `Colors.black_17` | `Colors.black_17` | — | hidden | visible | true |
|
|
45
|
-
| **Error** | `Colors.red_03` | `Colors.black_17` | `Colors.black_17` | `Colors.red_03` | hidden | visible | true |
|
|
46
|
-
| **Disabled** | `Colors.black_03` | `Colors.black_08` | `Colors.black_08` | — | hidden | hidden | false |
|
|
47
|
-
| **Read-only** | `Colors.black_04` | `Colors.black_17` | `Colors.black_17` | — | hidden | hidden | false |
|
|
48
|
-
|
|
49
|
-
**Floating label behavior:**
|
|
50
|
-
- Default (no value): label inside at placeholder position
|
|
51
|
-
- Focus hoặc có value: label animates upward, reduces in size
|
|
52
|
-
|
|
53
|
-
**Support text priority:** Error > Read-only ("Không thể chỉnh sửa") > Hint
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
## Variant-to-Context Map
|
|
58
|
-
|
|
59
|
-
| Context | Khi nào dùng | Tránh khi | Ví dụ trong MoMo |
|
|
60
|
-
|---------|-------------|-----------|-------------------|
|
|
61
|
-
| **Text entry** | Nhập text ngắn 1 dòng trong form | Cần nhập số tiền → `InputMoney`, SĐT → `InputPhoneNumber` | Họ tên form KYC, địa chỉ giao hàng |
|
|
62
|
-
| **With prefix** | Field có icon/label prefix | Icon không mang ý nghĩa → bỏ prefix | Email field với @ icon |
|
|
63
|
-
| **Read-only display** | Show value không cho edit | Cần interactive display → dùng Text component | Thông tin tài khoản đã xác thực |
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
## SSR Pattern
|
|
68
|
-
|
|
69
|
-
### Standard Form
|
|
70
|
-
```json
|
|
71
|
-
{
|
|
72
|
-
"id": "form_section",
|
|
73
|
-
"type": "section",
|
|
74
|
-
"children": [
|
|
75
|
-
{
|
|
76
|
-
"component": "Input",
|
|
77
|
-
"props": {
|
|
78
|
-
"floatingValue": "Họ và tên",
|
|
79
|
-
"placeholder": "Nhập họ và tên",
|
|
80
|
-
"size": "medium",
|
|
81
|
-
"required": true
|
|
82
|
-
},
|
|
83
|
-
"onChange": "setState://fullName"
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
"component": "Input",
|
|
87
|
-
"props": {
|
|
88
|
-
"floatingValue": "Email",
|
|
89
|
-
"placeholder": "example@email.com",
|
|
90
|
-
"size": "medium"
|
|
91
|
-
},
|
|
92
|
-
"onChange": "setState://email"
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
"component": "Button",
|
|
96
|
-
"props": {
|
|
97
|
-
"title": "Tiếp tục",
|
|
98
|
-
"type": "primary",
|
|
99
|
-
"size": "large",
|
|
100
|
-
"full": true,
|
|
101
|
-
"disabled": "{{state.fullName == ''}}"
|
|
102
|
-
},
|
|
103
|
-
"onPress": "action://submitForm"
|
|
104
|
-
}
|
|
105
|
-
]
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### Input with Validation Error
|
|
110
|
-
```json
|
|
111
|
-
{
|
|
112
|
-
"component": "Input",
|
|
113
|
-
"props": {
|
|
114
|
-
"floatingValue": "Email",
|
|
115
|
-
"placeholder": "example@email.com",
|
|
116
|
-
"size": "medium",
|
|
117
|
-
"required": true,
|
|
118
|
-
"errorMessage": "{{state.emailError}}",
|
|
119
|
-
"value": "{{state.email}}"
|
|
120
|
-
},
|
|
121
|
-
"onChange": "setState://email"
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
|
-
## Accessibility
|
|
128
|
-
|
|
129
|
-
- Every input phải có floating label cho screen readers. Không dùng placeholder thay label.
|
|
130
|
-
- Error message phải programmatically associated với input.
|
|
131
|
-
- Tap label hoặc container area = focus input.
|
|
132
|
-
- Read-only: screen reader phải announce non-editable status.
|
|
133
|
-
|
|
134
|
-
---
|
|
135
|
-
|
|
136
|
-
## Usage Guidelines
|
|
137
|
-
|
|
138
|
-
### Do
|
|
139
|
-
- Luôn cung cấp floating label — không dùng placeholder thay label.
|
|
140
|
-
- Error message inline bên dưới input, không dùng alert/toast.
|
|
141
|
-
- Dùng hint text để clarify format ("DD/MM/YYYY").
|
|
142
|
-
- Clear error state ngay khi user sửa input.
|
|
143
|
-
- Read-only PHẢI có support text.
|
|
144
|
-
|
|
145
|
-
### Don't
|
|
146
|
-
- Không dùng disabled input để hiển thị read-only info — dùng **Text**.
|
|
147
|
-
- Không stack nhiều error messages cho 1 input.
|
|
148
|
-
- Không ẩn floating label khi input có value.
|
|
149
|
-
- Hint text không quá 2 dòng.
|
|
150
|
-
- Cần nhập tiền → dùng **InputMoney**, không dùng Input standard.
|
|
151
|
-
- Cần nhập SĐT → dùng **InputPhoneNumber**.
|
|
152
|
-
- Cần nhập OTP → dùng **InputOTP**.
|