lv před 1 měsícem
rodič
revize
653d472617
100 změnil soubory, kde provedl 19876 přidání a 1144 odebrání
  1. 2 2
      .gitignore
  2. 3 0
      .npmrc
  3. 1 0
      .watchmanconfig
  4. 101 0
      AGENTS.md
  5. 16 0
      android/.gitignore
  6. 182 0
      android/app/build.gradle
  7. binární
      android/app/debug.keystore
  8. 14 0
      android/app/proguard-rules.pro
  9. 7 0
      android/app/src/debug/AndroidManifest.xml
  10. 7 0
      android/app/src/debugOptimized/AndroidManifest.xml
  11. 36 0
      android/app/src/main/AndroidManifest.xml
  12. 65 0
      android/app/src/main/java/com/cdloan/assistant/MainActivity.kt
  13. 45 0
      android/app/src/main/java/com/cdloan/assistant/MainApplication.kt
  14. binární
      android/app/src/main/res/drawable-hdpi/splashscreen_logo.png
  15. binární
      android/app/src/main/res/drawable-mdpi/splashscreen_logo.png
  16. binární
      android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png
  17. binární
      android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png
  18. binární
      android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png
  19. 6 0
      android/app/src/main/res/drawable/ic_launcher_background.xml
  20. 37 0
      android/app/src/main/res/drawable/rn_edit_text_material.xml
  21. 6 0
      android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  22. 6 0
      android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  23. binární
      android/app/src/main/res/mipmap-hdpi/ic_launcher.webp
  24. binární
      android/app/src/main/res/mipmap-hdpi/ic_launcher_background.webp
  25. binární
      android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
  26. binární
      android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.webp
  27. binární
      android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
  28. binární
      android/app/src/main/res/mipmap-mdpi/ic_launcher.webp
  29. binární
      android/app/src/main/res/mipmap-mdpi/ic_launcher_background.webp
  30. binární
      android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
  31. binární
      android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.webp
  32. binární
      android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
  33. binární
      android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
  34. binární
      android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.webp
  35. binární
      android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
  36. binární
      android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.webp
  37. binární
      android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
  38. binární
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
  39. binární
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.webp
  40. binární
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
  41. binární
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.webp
  42. binární
      android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
  43. binární
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
  44. binární
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.webp
  45. binární
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
  46. binární
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.webp
  47. binární
      android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
  48. 1 0
      android/app/src/main/res/values-night/colors.xml
  49. 5 0
      android/app/src/main/res/values/colors.xml
  50. 6 0
      android/app/src/main/res/values/strings.xml
  51. 14 0
      android/app/src/main/res/values/styles.xml
  52. 24 0
      android/build.gradle
  53. 61 0
      android/gradle.properties
  54. binární
      android/gradle/wrapper/gradle-wrapper.jar
  55. 7 0
      android/gradle/wrapper/gradle-wrapper.properties
  56. 251 0
      android/gradlew
  57. 94 0
      android/gradlew.bat
  58. 39 0
      android/settings.gradle
  59. 6 6
      app.json
  60. 3 0
      babel.config.js
  61. 7922 0
      docs/antd/llms-full.txt
  62. 5019 0
      docs/antd/llms-semantic.md
  63. 202 0
      docs/antd/llms.txt
  64. 10 0
      eslint.config.js
  65. 30 0
      ios/.gitignore
  66. 11 0
      ios/.xcode.env
  67. 556 0
      ios/LoanAssistant.xcodeproj/project.pbxproj
  68. 88 0
      ios/LoanAssistant.xcodeproj/xcshareddata/xcschemes/LoanAssistant.xcscheme
  69. 10 0
      ios/LoanAssistant.xcworkspace/contents.xcworkspacedata
  70. 69 0
      ios/LoanAssistant/AppDelegate.swift
  71. 13 0
      ios/LoanAssistant/Images.xcassets/AppIcon.appiconset/Contents.json
  72. 6 0
      ios/LoanAssistant/Images.xcassets/Contents.json
  73. 20 0
      ios/LoanAssistant/Images.xcassets/SplashScreenBackground.colorset/Contents.json
  74. 78 0
      ios/LoanAssistant/Info.plist
  75. 3 0
      ios/LoanAssistant/LoanAssistant-Bridging-Header.h
  76. 5 0
      ios/LoanAssistant/LoanAssistant.entitlements
  77. 48 0
      ios/LoanAssistant/PrivacyInfo.xcprivacy
  78. 39 0
      ios/LoanAssistant/SplashScreen.storyboard
  79. 16 0
      ios/LoanAssistant/Supporting/Expo.plist
  80. 3 0
      ios/LoanAssistant/expo.icon/Assets/expo-symbol 2.svg
  81. binární
      ios/LoanAssistant/expo.icon/Assets/grid.png
  82. 40 0
      ios/LoanAssistant/expo.icon/icon.json
  83. 65 0
      ios/Podfile
  84. 2689 0
      ios/Podfile.lock
  85. 4 0
      ios/Podfile.properties.json
  86. 8 1
      metro.config.js
  87. 11 1
      package.json
  88. 666 7
      pnpm-lock.yaml
  89. 8 64
      src/app/(tabs)/_layout.tsx
  90. 118 122
      src/app/(tabs)/analytics.tsx
  91. 166 131
      src/app/(tabs)/customer.tsx
  92. 212 93
      src/app/(tabs)/index.tsx
  93. 55 55
      src/app/(tabs)/profile.tsx
  94. 189 181
      src/app/(tabs)/reports.tsx
  95. 79 0
      src/app/+html.tsx
  96. 43 14
      src/app/_layout.tsx
  97. 271 172
      src/app/sign-in.tsx
  98. 24 0
      src/components/app-tabs.tsx
  99. 35 29
      src/components/app-tabs.web.tsx
  100. 0 266
      src/components/ui/hud.tsx

+ 2 - 2
.gitignore

@@ -39,5 +39,5 @@ yarn-error.*
 app-example
 
 # generated native folders
-/ios
-/android
+# /ios
+# /android

+ 3 - 0
.npmrc

@@ -0,0 +1,3 @@
+public-hoist-pattern[]=*react-native-css-interop*
+public-hoist-pattern[]=*nativewind*
+shamefully-hoist=true

+ 1 - 0
.watchmanconfig

@@ -0,0 +1 @@
+{}

+ 101 - 0
AGENTS.md

@@ -0,0 +1,101 @@
+# AGENTS.md
+
+本文件用于约束在 `Loan/client` 仓库内工作的 AI agent / 协作者,目标是让改动更稳、更贴近当前项目结构,并减少无关返工。仓库信息变化后,请同步更新此文件。
+
+## 项目概览
+
+- 项目名称:`Loan Assistant` / `借贷助手` 客户端
+- 技术栈:`Expo 55`、`React Native 0.83`、`React 19`、`TypeScript`、`expo-router`、`NativeWind 4`、`@ant-design/react-native 5`
+- 目标平台:`iOS`、`Android`、`Web`
+- 包管理器:仓库包含 `pnpm-lock.yaml`,默认优先使用 `pnpm`
+- 当前 UI 基调:浅色主题,根布局与全局 Provider 在 `src/app/_layout.tsx`
+
+## 常用命令
+
+- 安装依赖:`pnpm install`
+- 启动开发环境:`pnpm start`
+- 启动 Android:`pnpm android`
+- 启动 iOS:`pnpm ios`
+- 启动 Web:`pnpm web`
+- 代码检查:`pnpm lint`
+
+如果必须使用 `npm`,请确保不要混乱提交锁文件;默认仍以 `pnpm-lock.yaml` 为准。
+
+## 目录约定
+
+- `src/app`:`expo-router` 路由入口、`layout`、页面级 screen 文件
+- `src/app/(tabs)`:底部标签页相关路由
+- `src/components`:跨页面复用组件
+- `src/components/ui`:更基础的 UI 组件与页面积木
+- `src/hooks`:自定义 hooks
+- `src/utils`:基础能力与业务支撑工具,例如 `api`、`auth`、`storage`
+- `src/constants`:主题和常量
+- `src/global.css`:`NativeWind` 全局样式入口
+- `assets`:运行时资源
+- `design`:设计参考稿或静态参考资料,默认不作为运行时代码来源
+- `docs/antd`:本地 Ant Design RN 参考文档,新增或调整组件时优先查阅
+- `android`、`ios`:原生工程,除非是原生能力、权限、构建配置相关改动,否则不要随意修改
+- `dist`:构建产物目录,不要手工编辑
+
+## 代码组织规则
+
+- 路由文件尽量保持轻量,复杂 UI 和业务逻辑优先下沉到 `src/components`、`src/hooks`、`src/utils`
+- 本项目已配置路径别名:
+  - `@/*` -> `src/*`
+  - `@/assets/*` -> `assets/*`
+- 新页面优先放在 `src/app` 下对应路由位置,不要回退到旧式集中路由表
+- 涉及标签页结构时,同时检查 `src/app/(tabs)/_layout.tsx`
+- 平台差异优先通过 `*.web.tsx` 等平台文件处理,避免在单文件里堆过多平台分支
+- 尽量复用已有基础组件,不要在页面里重复造按钮、输入框、弹窗、状态标签
+
+## UI 与样式约定
+
+- 样式方案以 `NativeWind + global.css + tailwind.config.js` 为主
+- 组件型交互优先复用 `@ant-design/react-native`
+- 根节点已经包裹 `@ant-design/react-native` 的 `Provider`,全局 Provider 变更集中放在 `src/app/_layout.tsx`
+- 项目已有一套 Tailwind 扩展颜色和圆角 token,新增样式优先复用,不要到处散落魔法值
+- 如果引入新的 Ant Design RN 组件,先查 `docs/antd/llms-semantic.md` 或 `docs/antd/llms-full.txt`
+- Web 与 Native 表现如果需要分流,优先延续现有 `component.tsx` / `component.web.tsx` 结构
+
+## 数据、认证与存储
+
+- 网络请求优先复用 `src/utils/api.ts` 中的统一请求封装,不要重复创建新的 axios client
+- 接口地址与版本信息优先从现有配置读取,不要在页面或组件中硬编码 base URL
+- 鉴权上下文在 `src/utils/auth.tsx`,修改登录态逻辑时同步检查 Provider、hook、请求头注入
+- 本地持久化与缓存使用 `src/utils/storage.ts` 中的 `MMKV` 封装,避免绕过统一入口
+
+## 工程约定
+
+- TypeScript 处于 `strict` 模式,新增代码不要用 `any` 糊过去,必要时补充明确类型
+- `expo-router` 已启用 `typedRoutes`,新增路由时保持类型友好
+- 项目开启了 `reactCompiler`,默认不要为了“优化”到处添加 `useMemo` / `useCallback`
+- JS 层改动默认不要动 `android/`、`ios/`
+- 配置类文件如 `app.json`、`babel.config.js`、`metro.config.js`、`tailwind.config.js` 修改前先确认影响范围
+- 不要引入重量级新依赖,除非现有方案明显无法满足需求
+
+## Agent 工作方式
+
+- 开始前先看 `git status --short`,确认工作区是否已有用户未提交改动
+- 不要回滚与当前任务无关的变更
+- 先阅读相关文件,再改代码;避免“按印象重写”
+- 优先做最小必要改动,保持与现有风格一致
+- 修改公共能力时,检查调用方是否需要同步更新
+- 如果改动影响路由、鉴权、全局 Provider、主题或构建配置,在说明中明确指出
+
+## 验证要求
+
+- 最低要求:执行 `pnpm lint`
+- 如果改动影响页面交互、路由、平台差异或构建配置,尽量补充对应平台验证
+- 如果因为环境限制无法完成验证,需要在最终说明中明确写出“未验证项”
+
+## 提交说明建议
+
+最终汇报建议至少包含以下信息:
+
+- 改了什么
+- 为什么这么改
+- 怎么验证
+- 还有哪些风险或待补充项
+
+## 待项目负责人补充
+

+ 16 - 0
android/.gitignore

@@ -0,0 +1,16 @@
+# OSX
+#
+.DS_Store
+
+# Android/IntelliJ
+#
+build/
+.idea
+.gradle
+local.properties
+*.iml
+*.hprof
+.cxx/
+
+# Bundle artifacts
+*.jsbundle

+ 182 - 0
android/app/build.gradle

@@ -0,0 +1,182 @@
+apply plugin: "com.android.application"
+apply plugin: "org.jetbrains.kotlin.android"
+apply plugin: "com.facebook.react"
+
+def projectRoot = rootDir.getAbsoluteFile().getParentFile().getAbsolutePath()
+
+/**
+ * This is the configuration block to customize your React Native Android app.
+ * By default you don't need to apply any configuration, just uncomment the lines you need.
+ */
+react {
+    entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", projectRoot, "android", "absolute"].execute(null, rootDir).text.trim())
+    reactNativeDir = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile()
+    hermesCommand = new File(["node", "--print", "require.resolve('hermes-compiler/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/hermesc/%OS-BIN%/hermesc"
+    codegenDir = new File(["node", "--print", "require.resolve('@react-native/codegen/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile()
+
+    enableBundleCompression = (findProperty('android.enableBundleCompression') ?: false).toBoolean()
+    // Use Expo CLI to bundle the app, this ensures the Metro config
+    // works correctly with Expo projects.
+    cliFile = new File(["node", "--print", "require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })"].execute(null, rootDir).text.trim())
+    bundleCommand = "export:embed"
+
+    /* Folders */
+     //   The root of your project, i.e. where "package.json" lives. Default is '../..'
+    // root = file("../../")
+    //   The folder where the react-native NPM package is. Default is ../../node_modules/react-native
+    // reactNativeDir = file("../../node_modules/react-native")
+    //   The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen
+    // codegenDir = file("../../node_modules/@react-native/codegen")
+
+    /* Variants */
+    //   The list of variants to that are debuggable. For those we're going to
+    //   skip the bundling of the JS bundle and the assets. By default is just 'debug'.
+    //   If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
+    // debuggableVariants = ["liteDebug", "prodDebug"]
+
+    /* Bundling */
+    //   A list containing the node command and its flags. Default is just 'node'.
+    // nodeExecutableAndArgs = ["node"]
+
+    //
+    //   The path to the CLI configuration file. Default is empty.
+    // bundleConfig = file(../rn-cli.config.js)
+    //
+    //   The name of the generated asset file containing your JS bundle
+    // bundleAssetName = "MyApplication.android.bundle"
+    //
+    //   The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
+    // entryFile = file("../js/MyApplication.android.js")
+    //
+    //   A list of extra flags to pass to the 'bundle' commands.
+    //   See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
+    // extraPackagerArgs = []
+
+    /* Hermes Commands */
+    //   The hermes compiler command to run. By default it is 'hermesc'
+    // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
+    //
+    //   The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
+    // hermesFlags = ["-O", "-output-source-map"]
+
+    /* Autolinking */
+    autolinkLibrariesWithApp()
+}
+
+/**
+ * Set this to true in release builds to optimize the app using [R8](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization).
+ */
+def enableMinifyInReleaseBuilds = (findProperty('android.enableMinifyInReleaseBuilds') ?: false).toBoolean()
+
+/**
+ * The preferred build flavor of JavaScriptCore (JSC)
+ *
+ * For example, to use the international variant, you can use:
+ * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
+ *
+ * The international variant includes ICU i18n library and necessary data
+ * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
+ * give correct results when using with locales other than en-US. Note that
+ * this variant is about 6MiB larger per architecture than default.
+ */
+def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+'
+
+android {
+    ndkVersion rootProject.ext.ndkVersion
+
+    buildToolsVersion rootProject.ext.buildToolsVersion
+    compileSdk rootProject.ext.compileSdkVersion
+
+    namespace 'com.cdloan.assistant'
+    defaultConfig {
+        applicationId 'com.cdloan.assistant'
+        minSdkVersion rootProject.ext.minSdkVersion
+        targetSdkVersion rootProject.ext.targetSdkVersion
+        versionCode 1
+        versionName "1.0.0"
+
+        buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\""
+    }
+    signingConfigs {
+        debug {
+            storeFile file('debug.keystore')
+            storePassword 'android'
+            keyAlias 'androiddebugkey'
+            keyPassword 'android'
+        }
+    }
+    buildTypes {
+        debug {
+            signingConfig signingConfigs.debug
+        }
+        release {
+            // Caution! In production, you need to generate your own keystore file.
+            // see https://reactnative.dev/docs/signed-apk-android.
+            signingConfig signingConfigs.debug
+            def enableShrinkResources = findProperty('android.enableShrinkResourcesInReleaseBuilds') ?: 'false'
+            shrinkResources enableShrinkResources.toBoolean()
+            minifyEnabled enableMinifyInReleaseBuilds
+            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
+            def enablePngCrunchInRelease = findProperty('android.enablePngCrunchInReleaseBuilds') ?: 'true'
+            crunchPngs enablePngCrunchInRelease.toBoolean()
+        }
+    }
+    packagingOptions {
+        jniLibs {
+            def enableLegacyPackaging = findProperty('expo.useLegacyPackaging') ?: 'false'
+            useLegacyPackaging enableLegacyPackaging.toBoolean()
+        }
+    }
+    androidResources {
+        ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~'
+    }
+}
+
+// Apply static values from `gradle.properties` to the `android.packagingOptions`
+// Accepts values in comma delimited lists, example:
+// android.packagingOptions.pickFirsts=/LICENSE,**/picasa.ini
+["pickFirsts", "excludes", "merges", "doNotStrip"].each { prop ->
+    // Split option: 'foo,bar' -> ['foo', 'bar']
+    def options = (findProperty("android.packagingOptions.$prop") ?: "").split(",");
+    // Trim all elements in place.
+    for (i in 0..<options.size()) options[i] = options[i].trim();
+    // `[] - ""` is essentially `[""].filter(Boolean)` removing all empty strings.
+    options -= ""
+
+    if (options.length > 0) {
+        println "android.packagingOptions.$prop += $options ($options.length)"
+        // Ex: android.packagingOptions.pickFirsts += '**/SCCS/**'
+        options.each {
+            android.packagingOptions[prop] += it
+        }
+    }
+}
+
+dependencies {
+    // The version of react-native is set by the React Native Gradle Plugin
+    implementation("com.facebook.react:react-android")
+
+    def isGifEnabled = (findProperty('expo.gif.enabled') ?: "") == "true";
+    def isWebpEnabled = (findProperty('expo.webp.enabled') ?: "") == "true";
+    def isWebpAnimatedEnabled = (findProperty('expo.webp.animated') ?: "") == "true";
+
+    if (isGifEnabled) {
+        // For animated gif support
+        implementation("com.facebook.fresco:animated-gif:${expoLibs.versions.fresco.get()}")
+    }
+
+    if (isWebpEnabled) {
+        // For webp support
+        implementation("com.facebook.fresco:webpsupport:${expoLibs.versions.fresco.get()}")
+        if (isWebpAnimatedEnabled) {
+            // Animated webp support
+            implementation("com.facebook.fresco:animated-webp:${expoLibs.versions.fresco.get()}")
+        }
+    }
+
+    if (hermesEnabled.toBoolean()) {
+        implementation("com.facebook.react:hermes-android")
+    } else {
+        implementation jscFlavor
+    }
+}

binární
android/app/debug.keystore


+ 14 - 0
android/app/proguard-rules.pro

@@ -0,0 +1,14 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# react-native-reanimated
+-keep class com.swmansion.reanimated.** { *; }
+-keep class com.facebook.react.turbomodule.** { *; }
+
+# Add any project specific keep options here:

+ 7 - 0
android/app/src/debug/AndroidManifest.xml

@@ -0,0 +1,7 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
+
+    <application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" tools:replace="android:usesCleartextTraffic" />
+</manifest>

+ 7 - 0
android/app/src/debugOptimized/AndroidManifest.xml

@@ -0,0 +1,7 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
+
+    <application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" tools:replace="android:usesCleartextTraffic" />
+</manifest>

+ 36 - 0
android/app/src/main/AndroidManifest.xml

@@ -0,0 +1,36 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
+  <uses-permission android:name="android.permission.CAMERA"/>
+  <uses-permission android:name="android.permission.INTERNET"/>
+  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" tools:replace="android:maxSdkVersion"/>
+  <uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
+  <uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
+  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
+  <uses-permission android:name="android.permission.VIBRATE"/>
+  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" tools:replace="android:maxSdkVersion"/>
+  <queries>
+    <intent>
+      <action android:name="android.intent.action.VIEW"/>
+      <category android:name="android.intent.category.BROWSABLE"/>
+      <data android:scheme="https"/>
+    </intent>
+  </queries>
+  <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="true" android:theme="@style/AppTheme" android:supportsRtl="true" android:enableOnBackInvokedCallback="false">
+    <meta-data android:name="expo.modules.updates.ENABLED" android:value="true"/>
+    <meta-data android:name="expo.modules.updates.EXPO_RUNTIME_VERSION" android:value="@string/expo_runtime_version"/>
+    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
+    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="30000"/>
+    <meta-data android:name="expo.modules.updates.EXPO_UPDATE_URL" android:value="https://loan.ewaga.com/airpatch/manifest"/>
+    <activity android:name=".MainActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode|smallestScreenSize" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN"/>
+        <category android:name="android.intent.category.LAUNCHER"/>
+      </intent-filter>
+      <intent-filter>
+        <action android:name="android.intent.action.VIEW"/>
+        <category android:name="android.intent.category.DEFAULT"/>
+        <category android:name="android.intent.category.BROWSABLE"/>
+        <data android:scheme="loanassistant"/>
+      </intent-filter>
+    </activity>
+  </application>
+</manifest>

+ 65 - 0
android/app/src/main/java/com/cdloan/assistant/MainActivity.kt

@@ -0,0 +1,65 @@
+package com.cdloan.assistant
+import expo.modules.splashscreen.SplashScreenManager
+
+import android.os.Build
+import android.os.Bundle
+
+import com.facebook.react.ReactActivity
+import com.facebook.react.ReactActivityDelegate
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
+import com.facebook.react.defaults.DefaultReactActivityDelegate
+
+import expo.modules.ReactActivityDelegateWrapper
+
+class MainActivity : ReactActivity() {
+  override fun onCreate(savedInstanceState: Bundle?) {
+    // Set the theme to AppTheme BEFORE onCreate to support
+    // coloring the background, status bar, and navigation bar.
+    // This is required for expo-splash-screen.
+    // setTheme(R.style.AppTheme);
+    // @generated begin expo-splashscreen - expo prebuild (DO NOT MODIFY) sync-f3ff59a738c56c9a6119210cb55f0b613eb8b6af
+    SplashScreenManager.registerOnActivity(this)
+    // @generated end expo-splashscreen
+    super.onCreate(null)
+  }
+
+  /**
+   * Returns the name of the main component registered from JavaScript. This is used to schedule
+   * rendering of the component.
+   */
+  override fun getMainComponentName(): String = "main"
+
+  /**
+   * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
+   * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
+   */
+  override fun createReactActivityDelegate(): ReactActivityDelegate {
+    return ReactActivityDelegateWrapper(
+          this,
+          BuildConfig.IS_NEW_ARCHITECTURE_ENABLED,
+          object : DefaultReactActivityDelegate(
+              this,
+              mainComponentName,
+              fabricEnabled
+          ){})
+  }
+
+  /**
+    * Align the back button behavior with Android S
+    * where moving root activities to background instead of finishing activities.
+    * @see <a href="https://developer.android.com/reference/android/app/Activity#onBackPressed()">onBackPressed</a>
+    */
+  override fun invokeDefaultOnBackPressed() {
+      if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
+          if (!moveTaskToBack(false)) {
+              // For non-root activities, use the default implementation to finish them.
+              super.invokeDefaultOnBackPressed()
+          }
+          return
+      }
+
+      // Use the default back button implementation on Android S
+      // because it's doing more than [Activity.moveTaskToBack] in fact.
+      super.invokeDefaultOnBackPressed()
+  }
+}

+ 45 - 0
android/app/src/main/java/com/cdloan/assistant/MainApplication.kt

@@ -0,0 +1,45 @@
+package com.cdloan.assistant
+
+import android.app.Application
+import android.content.res.Configuration
+
+import com.facebook.react.PackageList
+import com.facebook.react.ReactApplication
+import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
+import com.facebook.react.ReactPackage
+import com.facebook.react.ReactHost
+import com.facebook.react.common.ReleaseLevel
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint
+
+import expo.modules.ApplicationLifecycleDispatcher
+import expo.modules.ExpoReactHostFactory
+
+class MainApplication : Application(), ReactApplication {
+
+  override val reactHost: ReactHost by lazy {
+    ExpoReactHostFactory.getDefaultReactHost(
+      context = applicationContext,
+      packageList =
+        PackageList(this).packages.apply {
+          // Packages that cannot be autolinked yet can be added manually here, for example:
+          // add(MyReactNativePackage())
+        }
+    )
+  }
+
+  override fun onCreate() {
+    super.onCreate()
+    DefaultNewArchitectureEntryPoint.releaseLevel = try {
+      ReleaseLevel.valueOf(BuildConfig.REACT_NATIVE_RELEASE_LEVEL.uppercase())
+    } catch (e: IllegalArgumentException) {
+      ReleaseLevel.STABLE
+    }
+    loadReactNative(this)
+    ApplicationLifecycleDispatcher.onApplicationCreate(this)
+  }
+
+  override fun onConfigurationChanged(newConfig: Configuration) {
+    super.onConfigurationChanged(newConfig)
+    ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
+  }
+}

binární
android/app/src/main/res/drawable-hdpi/splashscreen_logo.png


binární
android/app/src/main/res/drawable-mdpi/splashscreen_logo.png


binární
android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png


binární
android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png


binární
android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png


+ 6 - 0
android/app/src/main/res/drawable/ic_launcher_background.xml

@@ -0,0 +1,6 @@
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:drawable="@color/splashscreen_background"/>
+  <item>
+    <bitmap android:gravity="center" android:src="@drawable/splashscreen_logo"/>
+  </item>
+</layer-list>

+ 37 - 0
android/app/src/main/res/drawable/rn_edit_text_material.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+       android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material"
+       android:insetRight="@dimen/abc_edit_text_inset_horizontal_material"
+       android:insetTop="@dimen/abc_edit_text_inset_top_material"
+       android:insetBottom="@dimen/abc_edit_text_inset_bottom_material"
+       >
+
+    <selector>
+        <!--
+          This file is a copy of abc_edit_text_material (https://bit.ly/3k8fX7I).
+          The item below with state_pressed="false" and state_focused="false" causes a NullPointerException.
+          NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)'
+
+          <item android:state_pressed="false" android:state_focused="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
+
+          For more info, see https://bit.ly/3CdLStv (react-native/pull/29452) and https://bit.ly/3nxOMoR.
+        -->
+        <item android:state_enabled="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
+        <item android:drawable="@drawable/abc_textfield_activated_mtrl_alpha"/>
+    </selector>
+
+</inset>

+ 6 - 0
android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@mipmap/ic_launcher_background"/>
+    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
+    <monochrome android:drawable="@mipmap/ic_launcher_monochrome"/>
+</adaptive-icon>

+ 6 - 0
android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@mipmap/ic_launcher_background"/>
+    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
+    <monochrome android:drawable="@mipmap/ic_launcher_monochrome"/>
+</adaptive-icon>

binární
android/app/src/main/res/mipmap-hdpi/ic_launcher.webp


binární
android/app/src/main/res/mipmap-hdpi/ic_launcher_background.webp


binární
android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp


binární
android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.webp


binární
android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp


binární
android/app/src/main/res/mipmap-mdpi/ic_launcher.webp


binární
android/app/src/main/res/mipmap-mdpi/ic_launcher_background.webp


binární
android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp


binární
android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.webp


binární
android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp


binární
android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp


binární
android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.webp


binární
android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp


binární
android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.webp


binární
android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp


binární
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp


binární
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.webp


binární
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp


binární
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.webp


binární
android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp


binární
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp


binární
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.webp


binární
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp


binární
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.webp


binární
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp


+ 1 - 0
android/app/src/main/res/values-night/colors.xml

@@ -0,0 +1 @@
+<resources/>

+ 5 - 0
android/app/src/main/res/values/colors.xml

@@ -0,0 +1,5 @@
+<resources>
+  <color name="splashscreen_background">#208AEF</color>
+  <color name="iconBackground">#E6F4FE</color>
+  <color name="colorPrimary">#023c69</color>
+</resources>

+ 6 - 0
android/app/src/main/res/values/strings.xml

@@ -0,0 +1,6 @@
+<resources>
+  <string name="app_name">Loan Assistant</string>
+  <string name="expo_system_ui_user_interface_style" translatable="false">light</string>
+  <string name="expo_runtime_version">1.0.0</string>
+  <string name="expo_splash_screen_resize_mode" translatable="false">contain</string>
+</resources>

+ 14 - 0
android/app/src/main/res/values/styles.xml

@@ -0,0 +1,14 @@
+<resources xmlns:tools="http://schemas.android.com/tools">
+  <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
+    <item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
+    <item name="colorPrimary">@color/colorPrimary</item>
+    <item name="android:statusBarColor">@android:color/transparent</item>
+    <item name="android:navigationBarColor">@android:color/transparent</item>
+  </style>
+  <style name="Theme.App.SplashScreen" parent="Theme.SplashScreen">
+    <item name="windowSplashScreenBackground">@color/splashscreen_background</item>
+    <item name="windowSplashScreenAnimatedIcon">@drawable/splashscreen_logo</item>
+    <item name="postSplashScreenTheme">@style/AppTheme</item>
+    <item name="android:windowSplashScreenBehavior">icon_preferred</item>
+  </style>
+</resources>

+ 24 - 0
android/build.gradle

@@ -0,0 +1,24 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+  repositories {
+    google()
+    mavenCentral()
+  }
+  dependencies {
+    classpath('com.android.tools.build:gradle')
+    classpath('com.facebook.react:react-native-gradle-plugin')
+    classpath('org.jetbrains.kotlin:kotlin-gradle-plugin')
+  }
+}
+
+allprojects {
+  repositories {
+    google()
+    mavenCentral()
+    maven { url 'https://www.jitpack.io' }
+  }
+}
+
+apply plugin: "expo-root-project"
+apply plugin: "com.facebook.react.rootproject"

+ 61 - 0
android/gradle.properties

@@ -0,0 +1,61 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
+org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+org.gradle.parallel=true
+
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+
+# Enable AAPT2 PNG crunching
+android.enablePngCrunchInReleaseBuilds=true
+
+# Use this property to specify which architecture you want to build.
+# You can also override it from the CLI using
+# ./gradlew <task> -PreactNativeArchitectures=x86_64
+reactNativeArchitectures=arm64-v8a
+
+# Use this property to enable support to the new architecture.
+# This will allow you to use TurboModules and the Fabric render in
+# your application. You should enable this flag either if you want
+# to write custom TurboModules/Fabric components OR use libraries that
+# are providing them.
+newArchEnabled=true
+
+# Use this property to enable or disable the Hermes JS engine.
+# If set to false, you will be using JSC instead.
+hermesEnabled=true
+
+# Use this property to enable edge-to-edge display support.
+# This allows your app to draw behind system bars for an immersive UI.
+# Note: Only works with ReactActivity and should not be used with custom Activity.
+edgeToEdgeEnabled=true
+
+# Enable GIF support in React Native images (~200 B increase)
+expo.gif.enabled=true
+# Enable webp support in React Native images (~85 KB increase)
+expo.webp.enabled=true
+# Enable animated webp support (~3.4 MB increase)
+# Disabled by default because iOS doesn't support animated webp
+expo.webp.animated=false
+
+# Enable network inspector
+EX_DEV_CLIENT_NETWORK_INSPECTOR=true
+
+# Use legacy packaging to compress native libraries in the resulting APK.
+expo.useLegacyPackaging=false

binární
android/gradle/wrapper/gradle-wrapper.jar


+ 7 - 0
android/gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists

+ 251 - 0
android/gradlew

@@ -0,0 +1,251 @@
+#!/bin/sh
+
+#
+# Copyright © 2015 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH="\\\"\\\""
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD=$JAVA_HOME/jre/sh/java
+    else
+        JAVACMD=$JAVA_HOME/bin/java
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    if ! command -v java >/dev/null 2>&1
+    then
+        die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+#     and any embedded shellness will be escaped.
+#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+#     treated as '${Hostname}' itself on the command line.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
+        "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+    die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"

+ 94 - 0
android/gradlew.bat

@@ -0,0 +1,94 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 39 - 0
android/settings.gradle

@@ -0,0 +1,39 @@
+pluginManagement {
+  def reactNativeGradlePlugin = new File(
+    providers.exec {
+      workingDir(rootDir)
+      commandLine("node", "--print", "require.resolve('@react-native/gradle-plugin/package.json', { paths: [require.resolve('react-native/package.json')] })")
+    }.standardOutput.asText.get().trim()
+  ).getParentFile().absolutePath
+  includeBuild(reactNativeGradlePlugin)
+  
+  def expoPluginsPath = new File(
+    providers.exec {
+      workingDir(rootDir)
+      commandLine("node", "--print", "require.resolve('expo-modules-autolinking/package.json', { paths: [require.resolve('expo/package.json')] })")
+    }.standardOutput.asText.get().trim(),
+    "../android/expo-gradle-plugin"
+  ).absolutePath
+  includeBuild(expoPluginsPath)
+}
+
+plugins {
+  id("com.facebook.react.settings")
+  id("expo-autolinking-settings")
+}
+
+extensions.configure(com.facebook.react.ReactSettingsExtension) { ex ->
+  if (System.getenv('EXPO_USE_COMMUNITY_AUTOLINKING') == '1') {
+    ex.autolinkLibrariesFromCommand()
+  } else {
+    ex.autolinkLibrariesFromCommand(expoAutolinking.rnConfigCommand)
+  }
+}
+expoAutolinking.useExpoModules()
+
+rootProject.name = 'Loan Assistant'
+
+expoAutolinking.useExpoVersionCatalog()
+
+include ':app'
+includeBuild(expoAutolinking.reactNativeGradlePlugin)

+ 6 - 6
app.json

@@ -61,13 +61,13 @@
     "updates": {
       "enabled": true,
       "checkAutomatically": "ON_LOAD",
-      "url": "https://your-domain.com/api/manifest", // 你的服务器地址
+      "url": "https://loan.ewaga.com/airpatch/manifest", // 你的服务器地址
       "fallbackToCacheTimeout": 30000,
-      "codeSigningCertificate": "./code-signing/certificate.pem",
-      "codeSigningMetadata": {
-        "keyid": "main",
-        "alg": "rsa-v1_5-sha256"
-      }
+      // "codeSigningCertificate": "./code-signing/certificate.pem",
+      // "codeSigningMetadata": {
+      //   "keyid": "main",
+      //   "alg": "rsa-v1_5-sha256"
+      // }
     },
   }
 }

+ 3 - 0
babel.config.js

@@ -5,5 +5,8 @@ module.exports = function (api) {
       ["babel-preset-expo", { jsxImportSource: "nativewind" }],
       "nativewind/babel",
     ],
+    "plugins": [
+      ["import", { libraryName: "@ant-design/react-native" }]
+    ]
   };
 };

+ 7922 - 0
docs/antd/llms-full.txt

@@ -0,0 +1,7922 @@
+# Ant Design Mobile RN Component Documentation
+
+Aggregated content from all component docs.
+
+> 47 components
+
+## Accordion
+
+Source: https://rn.mobile.ant.design/components/accordion.md
+
+# Accordion
+
+> This package has been deprecated in `5.2.1`, recommend [components/Collapse](/components/collapse)
+
+You can collapse / expand the content area.
+
+### Rules
+- Group and hide complex areas.
+- Typically, only a single content area is allowed to expand at a time; in special cases, multiple content areas can be expanded at the same time.
+
+## Examples
+
+```tsx
+import { Accordion, List } from '@ant-design/react-native'
+import React from 'react'
+import { View } from 'react-native'
+
+export default class AccordionExmple extends React.Component<any, any> {
+  state = {
+    activeSections: [2, 0],
+  }
+  onChange = (activeSections: number[]) => {
+    this.setState({ activeSections })
+  }
+  render() {
+    return (
+      <View style={{ marginTop: 80, marginBottom: 10 }}>
+        <Accordion
+          onChange={this.onChange}
+          activeSections={this.state.activeSections}>
+          <Accordion.Panel header="Title 1">
+            <List>
+              <List.Item>Content 1</List.Item>
+              <List.Item>Content 2</List.Item>
+              <List.Item>Content 3</List.Item>
+            </List>
+          </Accordion.Panel>
+          <Accordion.Panel header="Title 2">
+            this is panel content2 or other
+          </Accordion.Panel>
+          <Accordion.Panel header="Title 3">
+            Text text text text text text text text text text text text text
+            text text
+          </Accordion.Panel>
+        </Accordion>
+      </View>
+    )
+  }
+}
+```
+
+## API
+
+### Accordion
+
+| Properties        | Descrition                                                                                       | Type                      | Default |
+| ----------------- | ------------------------------------------------------------------------------------------------ | ------------------------- | ------- |
+| onChange(indexes) | A function that is called when the currently active section(s) are updated.                      | (indexes: number[])=>void | -       |
+| activeSections    | Control which indices in the `sections` array are currently open. If empty, closes all sections. | number[]                  | []      |
+
+
+Read more https://github.com/oblador/react-native-collapsible#properties-1
+
+### Accordion.Panel
+
+| Properties | Descrition              | Type                    | Default |
+| ---------- | ----------------------- | ----------------------- | ------- |
+| key        | corresponding activeKey | String                  | -       |
+| header     | header content of Panel | React.Element or String | -       |
+
+Note: Currently does not support nested use for RN.
+
+---
+
+## ActionSheet
+
+Source: https://rn.mobile.ant.design/components/action-sheet.md
+
+# ActionSheet
+
+The modal box pops up from the bottom, providing more than two actions related to the current scene, and also support provide the title and description. Built-in fixed display style, does not support particularly flexible changes.
+
+### Rules
+
+- Provide a clear exit button.
+- Can highlight the destructive operation, e.g. "delete" use red text.
+- Do not place too much content to avoid vertical roll of the panel.
+
+## Examples
+
+```tsx
+import { ActionSheet, Button, Provider } from '@ant-design/react-native'
+import React from 'react'
+import { Platform, Text, View } from 'react-native'
+
+export default class Test extends React.Component<any, any> {
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      clicked: 'none',
+      text: '',
+    }
+  }
+  render() {
+    return (
+      <Provider>
+        <View style={{ marginTop: 30 }}>
+          <View style={[{ padding: 8 }]}>
+            <Button onPress={this.showActionSheet}>showActionSheet</Button>
+          </View>
+          <Text style={[{ padding: 8 }]}>
+            clicked button: {this.state.clicked}
+          </Text>
+          <View style={[{ padding: 8 }]}>
+            <Button onPress={this.showShareActionSheet}>
+              showShareActionSheet
+            </Button>
+          </View>
+          <Text style={[{ padding: 8 }]}>{this.state.text}</Text>
+        </View>
+      </Provider>
+    )
+  }
+  showActionSheet = () => {
+    const BUTTONS = [
+      'Operation1',
+      'Operation2',
+      'Operation3',
+      'Delete',
+      'Cancel',
+    ]
+    ActionSheet.showActionSheetWithOptions(
+      {
+        title: 'Title',
+        message: 'Description',
+        options: BUTTONS,
+        cancelButtonIndex: 4,
+        destructiveButtonIndex: 3,
+      },
+      (buttonIndex: any) => {
+        this.setState({ clicked: BUTTONS[buttonIndex] })
+      },
+    )
+  }
+  showShareActionSheet = () => {
+    const opts: any = {
+      message: 'Message to go with the shared url',
+      title: 'Share Actionsheet',
+    }
+
+    if (Platform.OS === 'ios') {
+      opts.url = 'https://www.alipay.com/'
+      opts.tintColor = '#ff0000'
+      opts.excludedActivityTypes = ['com.apple.UIKit.activity.PostToTwitter']
+    }
+
+    ActionSheet.showShareActionSheetWithOptions(
+      opts,
+      (error: any) => alert(error),
+      (success: any, method: any) => {
+        let text
+        if (success) {
+          text = `Shared with ${method}`
+        } else {
+          text = 'Did not share'
+        }
+        this.setState({ text })
+      },
+    )
+  }
+}
+
+export const title = 'ActionSheet'
+export const description = 'ActionSheet example'
+```
+
+## API
+### ActionSheet.showActionSheetWithOptions(options, callback)
+Properties | Descrition | Type | Default
+----|-----|------|------
+| options       | ActionSheet's options | Object |  -  |
+| callback       | Callback for selected item   | (index:number):void |  -  |
+
+Display a action sheet. The `options` object must contain one or more of:
+
+Properties | Descrition | Type | Default
+----|-----|------|------
+| options       | a list of button titles (required) | Array or String |  -  |
+| cancelButtonIndex       | index of cancel button in `options`  | Number |  -  |
+| destructiveButtonIndex       | index of destructive button in `options`  | Number |  -  |
+| title       | a title to show above the action sheet  | String |  -  |
+| message       | a message to show below the title  | String or React.element |  -  |
+
+### ActionSheet.showShareActionSheetWithOptions(options, failureCallback?, successCallback?)
+
+`React-Native Only, react-native@version >= 0.39`
+
+Properties | Descrition | Type | Default
+----|-----|------|------
+| options       | ShareActionSheet's options | Object |  -  |
+| failureCallback       | Callback for share failed(`iOS Only`, See [react-native/share](https://github.com/facebook/react-native/blob/master/Libraries/Share/Share.js#L80) ) | (error):void |  -  |
+| successCallback       | Callback for share successed(`iOS Only`, See [react-native/share](https://github.com/facebook/react-native/blob/master/Libraries/Share/Share.js#L80) ) | (completed:Boolean, activityType?:String):void |  -  |
+
+Display a shareable action sheet. The `options` object must contain one or more of:
+
+Properties | Descrition | Type | Default
+----|-----|------|------
+| message       | a message to share | String |  -  |
+| title       | title of the message  | String |  -  |
+| url       | an URL to share `iOS Only`  | String |  -  |
+| excludedActivityTypes       | the activities to exclude from the ShareActionSheet `iOS Only`  | Array |  -  |
+
+### ActionSheet.close()
+Close the action sheet.`Android Only`
+
+---
+
+## ActivityIndicator
+
+Source: https://rn.mobile.ant.design/components/activity-indicator.md
+
+# ActivityIndicator
+
+`ActivityIndicator` indicates that a task is currently in progress.
+
+### Rules
+- Don't stop activity indicator if the task is not completed.
+- By providing meaningful texts under certain circumstances can help user understand which task is in progress. eg: uploading photos.
+- If you know the user's waiting time, you can use `Progress` instead.
+
+## Examples
+
+```tsx
+import { ActivityIndicator, Button, Flex, WhiteSpace, WingBlank } from '@ant-design/react-native'
+import React from 'react'
+import { StyleSheet, Text, View } from 'react-native'
+
+export default class ActivityIndicatorExample extends React.Component<
+  any,
+  any
+> {
+  closeTimer: any
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      animating: false,
+    }
+    this.loadingToast = this.loadingToast.bind(this)
+  }
+
+  componentWillUnmount() {
+    clearTimeout(this.closeTimer)
+  }
+
+  loadingToast() {
+    this.setState({ animating: !this.state.animating })
+    this.closeTimer = setTimeout(() => {
+      this.setState({ animating: !this.state.animating })
+    }, 2000)
+  }
+
+  render() {
+    return (
+      <View style={[styles.demo]}>
+        <WingBlank>
+          <Flex>
+            <Flex.Item>
+              <Text>Icon without text</Text>
+            </Flex.Item>
+            <Flex.Item>
+              <ActivityIndicator />
+            </Flex.Item>
+          </Flex>
+        </WingBlank>
+        <WhiteSpace size="xl" style={{ backgroundColor: '#fff' }} />
+        <WingBlank>
+          <Flex>
+            <Flex.Item>
+              <Text>Icon with text</Text>
+            </Flex.Item>
+            <Flex.Item>
+              <ActivityIndicator text="Loading..." />
+            </Flex.Item>
+          </Flex>
+        </WingBlank>
+        <WhiteSpace size="xl" style={{ backgroundColor: '#fff' }} />
+        <WingBlank>
+          <Flex>
+            <Flex.Item>
+              <Text>Dark Background</Text>
+            </Flex.Item>
+            <Flex.Item>
+              <View style={[styles.darkBg]}>
+                <ActivityIndicator color="#fff" />
+              </View>
+            </Flex.Item>
+          </Flex>
+        </WingBlank>
+        <WhiteSpace size="xl" style={{ backgroundColor: '#fff' }} />
+        <WingBlank>
+          <Flex>
+            <Flex.Item>
+              <Text>Large Size</Text>
+            </Flex.Item>
+            <Flex.Item>
+              <ActivityIndicator size="large" />
+            </Flex.Item>
+          </Flex>
+        </WingBlank>
+        <WhiteSpace size="xl" style={{ backgroundColor: '#fff' }} />
+        <WingBlank>
+          <Button onPress={this.loadingToast}>Click to show Toast</Button>
+        </WingBlank>
+        <ActivityIndicator
+          animating={this.state.animating}
+          toast
+          size="large"
+          text="Loading..."
+        />
+      </View>
+    )
+  }
+}
+
+const styles = StyleSheet.create({
+  demo: {
+    marginTop: 20,
+  },
+  darkBg: {
+    alignItems: 'center',
+    justifyContent: 'center',
+    width: 89,
+    height: 89,
+    backgroundColor: '#2B2F42',
+  },
+  gray: {
+    backgroundColor: '#CCC',
+  },
+  horizontal: {
+    flexDirection: 'row',
+    justifyContent: 'space-around',
+    padding: 8,
+  },
+})
+```
+
+## API
+
+```jsx
+<ActivityIndicator />
+<ActivityIndicator color="white" />
+<ActivityIndicator size="large" />
+<ActivityIndicator text="loading" />
+<ActivityIndicator toast />
+<ActivityIndicator toast text="loading" />
+```
+
+### ActivityIndicator
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+|  animating  | Whether to show the indicator (true, the default) or hide it (false). | boolean  | true  |
+|  size  | Size of the indicator (`small`/`large` or number [android only]) | string\|number  | small  |
+|  toast  | Whether to use toast style | boolean  | false  |
+|  text  | loading text behind the indicator | string |  -   |
+|  color | The foreground color of the spinner (default is gray). | string  | gray  |
+
+---
+
+## Badge
+
+Source: https://rn.mobile.ant.design/components/badge.md
+
+# Badge
+
+The red dot at corner for notification and getting user attention.
+
+### When to use
+
+- Use plain dot badge when user just need to know there is something new, eg: one-to-one new messages.
+- Use numberic badge when user need to know specific number of notifications, eg: new messages from a group.
+
+## Examples
+
+```tsx
+import { Badge, WhiteSpace } from '@ant-design/react-native'
+import React from 'react'
+import { ScrollView, View } from 'react-native'
+
+export default class BasicTagExample extends React.Component<any, any> {
+  render() {
+    return (
+      <ScrollView
+        style={{ flex: 1 }}
+        automaticallyAdjustContentInsets={false}
+        showsHorizontalScrollIndicator={false}
+        showsVerticalScrollIndicator={false}>
+        <View style={{ padding: 20 }}>
+          <Badge text={9}>
+            <View
+              style={{
+                width: 52,
+                height: 52,
+                backgroundColor: 'rgba(255, 140, 101, 0.15)',
+              }}
+            />
+          </Badge>
+
+          <WhiteSpace size="lg" />
+
+          <Badge text={109} overflowCount={100}>
+            <View
+              style={{
+                width: 52,
+                height: 52,
+                backgroundColor: 'rgba(255, 140, 101, 0.15)',
+              }}
+            />
+          </Badge>
+
+          <WhiteSpace size="lg" />
+
+          <Badge text={109}>
+            <View
+              style={{
+                width: 52,
+                height: 52,
+                backgroundColor: 'rgba(255, 140, 101, 0.15)',
+              }}
+            />
+          </Badge>
+
+          <WhiteSpace size="lg" />
+
+          <Badge text="new">
+            <View
+              style={{
+                width: 52,
+                height: 52,
+                backgroundColor: 'rgba(255, 140, 101, 0.15)',
+              }}
+            />
+          </Badge>
+
+          <WhiteSpace size="lg" />
+
+          <Badge text={109} dot>
+            <View
+              style={{
+                width: 52,
+                height: 52,
+                backgroundColor: 'rgba(255, 140, 101, 0.15)',
+              }}
+            />
+          </Badge>
+
+          <WhiteSpace size="lg" />
+
+          <Badge text={33} corner>
+            <View
+              style={{
+                width: 52,
+                height: 52,
+                backgroundColor: 'rgba(255, 140, 101, 0.15)',
+              }}
+            />
+          </Badge>
+        </View>
+      </ScrollView>
+    )
+  }
+}
+```
+
+## API
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+size | size of badge, optional: `large` `small` | string | `small`
+text | text or number inside badge | string\|number | -
+corner | whether is badge at corner position | boolean | `false`
+dot | show badge as a red dot | boolean | `false`
+overflowCount | max count to show | number | `99`
+
+---
+
+## Button
+
+Source: https://rn.mobile.ant.design/components/button.md
+
+# Button
+
+To trigger an operation.
+
+## Examples
+
+```tsx
+import { Button, Icon, WhiteSpace, WingBlank } from '@ant-design/react-native'
+import React from 'react'
+
+export default () => (
+  <WingBlank>
+    <WhiteSpace />
+    <Button>default</Button>
+    <WhiteSpace />
+    <Button disabled>default disabled</Button>
+    <WhiteSpace />
+
+    <Button type="primary">primary</Button>
+    <WhiteSpace />
+    <Button type="primary" disabled>
+      primary disabled
+    </Button>
+    <WhiteSpace />
+
+    <Button type="warning">warning</Button>
+    <WhiteSpace />
+    <Button type="warning" disabled>
+      warning disabled
+    </Button>
+    <WhiteSpace />
+
+    <Button loading>loading button</Button>
+
+    <Button activeStyle={false}>No click feedback</Button>
+    <WhiteSpace />
+    <Button underlayColor={'blue'}>Custom Underlay</Button>
+    <Button activeStyle={{ backgroundColor: 'red' }}>
+      custom feedback style
+    </Button>
+    <WhiteSpace />
+
+    <Button
+      styles={{
+        rawText: { color: 'darkgray' },
+      }}
+      style={{
+        backgroundColor: 'red',
+      }}>
+      custon background and text color
+    </Button>
+
+    <WingBlank
+      style={{
+        marginTop: 20,
+        flexDirection: 'row',
+        justifyContent: 'space-between',
+        alignItems: 'center',
+      }}>
+      <Button type="ghost">ghost</Button>
+      <Button type="ghost" disabled>
+        ghost disabled
+      </Button>
+      <Button type="ghost" size="small">
+        ghost
+      </Button>
+    </WingBlank>
+    <WhiteSpace />
+
+    <Button type="primary">
+      <Icon name="login" />
+    </Button>
+  </WingBlank>
+)
+```
+
+## API
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| type     | can be set to `primary`/`ghost`/`warning` or omitted  |   string   |   -  |
+| size     | can be set to `large`、`small` or omitted | string | `large`|
+| activeStyle | the feedback's custom style (set to false to disable click feedback) | {}/false | {} |
+| activeClassName  | the feedback's custom class name | string |  |
+| disabled   | set disabled   | boolean |  false  |
+| onPress    | set the handler to handle `click` event | (e: Object): void |  -  |
+| style    | custom style |   Object  | - |
+| styles | Semantic DOM style | [ButtonStyles](#buttonStyles-interface) | - |
+| onPressIn  | same as RN Pressable onPressIn | (e: Object): void |   - |
+| onPressOut | same as RN Pressable onPressOut | (e: Object): void |  - |
+| onShowUnderlay | same as RN Pressable onPressIn but only triggered if `activeStyle` is not false | (e: Object): void | - |
+| onHideUnderlay | same as RN Pressable onPressOut but only triggered if `activeStyle` is not false | (e: Object): void | - |
+
+
+### ButtonStyles interface
+
+```typescript
+interface ButtonStyles {
+  container: ViewStyle
+  defaultHighlight: ViewStyle
+  primaryHighlight: ViewStyle
+  ghostHighlight: ViewStyle
+  warningHighlight: ViewStyle
+  wrapperStyle: ViewStyle
+  underlayStyle: ViewStyle
+  largeRaw: ViewStyle
+  largeUnderlayContainerRaw: ViewStyle
+  smallRaw: ViewStyle
+  smallUnderlayContainerRaw: ViewStyle
+  defaultRaw: ViewStyle
+  defaultUnderlayContainerRaw: ViewStyle
+  primaryRaw: ViewStyle
+  primaryUnderlayContainerRaw: ViewStyle
+  ghostRaw: ViewStyle
+  ghostUnderlayContainerRaw: ViewStyle
+  warningRaw: ViewStyle
+  warningUnderlayContainerRaw: ViewStyle
+  defaultDisabledRaw: ViewStyle
+  primaryDisabledRaw: ViewStyle
+  ghostDisabledRaw: ViewStyle
+  warningDisabledRaw: ViewStyle
+  defaultHighlightText: TextStyle
+  primaryHighlightText: TextStyle
+  ghostHighlightText: TextStyle
+  warningHighlightText: TextStyle
+  rawText: TextStyle
+  largeRawText: TextStyle
+  smallRawText: TextStyle
+  defaultRawText: TextStyle
+  primaryRawText: TextStyle
+  ghostRawText: TextStyle
+  warningRawText: TextStyle
+  defaultDisabledRawText: TextStyle
+  primaryDisabledRawText: TextStyle
+  ghostDisabledRawText: TextStyle
+  warningDisabledRawText: TextStyle
+  indicator: ViewStyle
+}
+```
+
+---
+
+## Card
+
+Source: https://rn.mobile.ant.design/components/card.md
+
+# Card
+
+Card can be used to organize information and operations, usually also as an entry for detailed information.
+
+### Rules
+- The shape is rectangular.
+- The content can consist of multiple elements of varying type, eg: images, texts, buttons, etc.
+
+## Examples
+
+```tsx
+import { Card, WhiteSpace, WingBlank } from '@ant-design/react-native'
+import React from 'react'
+import { Text, View } from 'react-native'
+
+export default class BasicCardExample extends React.Component<any, any> {
+  render() {
+    return (
+      <View style={{ paddingTop: 30 }}>
+        <WingBlank size="lg">
+          <Card>
+            <Card.Header
+              title="This is title"
+              thumbStyle={{ width: 30, height: 30 }}
+              thumb="https://gw.alipayobjects.com/zos/rmsportal/MRhHctKOineMbKAZslML.jpg"
+              extra="this is extra"
+            />
+            <Card.Body>
+              <View style={{ height: 42 }}>
+                <Text style={{ marginLeft: 16 }}>Card Content</Text>
+              </View>
+            </Card.Body>
+            <Card.Footer
+              content="footer content"
+              extra="footer extra content"
+            />
+          </Card>
+        </WingBlank>
+        <WhiteSpace size="lg" />
+        <Card full>
+          <Card.Header
+            title="Full Column"
+            thumbStyle={{ width: 30, height: 30 }}
+            thumb="https://gw.alipayobjects.com/zos/rmsportal/MRhHctKOineMbKAZslML.jpg"
+            extra="this is extra"
+          />
+          <Card.Body>
+            <View style={{ height: 42 }}>
+              <Text style={{ marginLeft: 16 }}>Card Content</Text>
+            </View>
+          </Card.Body>
+          <Card.Footer content="footer content" extra="footer extra content" />
+        </Card>
+      </View>
+    )
+  }
+}
+```
+
+## API
+
+### Card
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+|   full  |  whether is full column | boolean | `false` |
+
+### Card.Header
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+|title| title for `Card.Header` | React.Element、String | |
+|thumb| thumb to render in the left of  `Card.Header`  | String、React.Element |  |
+|thumbStyle| style of thumb | Object | {} |
+|extra| extra content to render in the right of `Card.Header` | React.Element、String |  |
+
+### Card.Body
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| | | | |
+
+### Card.Footer
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+|content| content of `Card.Footer` | React.Element、String | |
+|extra| extra content of `Card.Footer` | React.Element、String |  |
+
+---
+
+## Carousel
+
+Source: https://rn.mobile.ant.design/components/carousel.md
+
+# Carousel
+
+## Examples
+
+```tsx
+import { Button, Carousel } from '@ant-design/react-native'
+import React from 'react'
+import {
+  ScrollView,
+  StyleSheet,
+  Text,
+  TextStyle,
+  View,
+  ViewStyle,
+} from 'react-native'
+
+export default class BasicCarouselExample extends React.Component<any, any> {
+  carousel: null | Carousel
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      selectedIndex: 2,
+      autoplay: true,
+    }
+  }
+  onHorizontalSelectedIndexChange = (index: number) => {
+    /* tslint:disable: no-console */
+    console.log('horizontal change to', index)
+    this.setState({ selectedIndex: index })
+  }
+  onVerticalSelectedIndexChange(index: number) {
+    /* tslint:disable: no-console */
+    console.log('vertical change to', index)
+  }
+  render() {
+    return (
+      <ScrollView style={{ paddingTop: 30 }}>
+        <View style={{ paddingHorizontal: 15 }}>
+          <Text>horizontal</Text>
+          <Carousel
+            style={styles.wrapper}
+            selectedIndex={this.state.selectedIndex}
+            autoplay
+            infinite
+            afterChange={this.onHorizontalSelectedIndexChange}
+            ref={(ref) => (this.carousel = ref)}>
+            <View
+              style={[styles.containerHorizontal, { backgroundColor: 'red' }]}>
+              <Text>Carousel 1</Text>
+            </View>
+            <View
+              style={[styles.containerHorizontal, { backgroundColor: 'blue' }]}>
+              <Text>Carousel 2</Text>
+            </View>
+            <View
+              style={[
+                styles.containerHorizontal,
+                { backgroundColor: 'yellow' },
+              ]}>
+              <Text>Carousel 3</Text>
+            </View>
+            <View
+              style={[styles.containerHorizontal, { backgroundColor: 'aqua' }]}>
+              <Text>Carousel 4</Text>
+            </View>
+            <View
+              style={[
+                styles.containerHorizontal,
+                { backgroundColor: 'fuchsia' },
+              ]}>
+              <Text>Carousel 5</Text>
+            </View>
+          </Carousel>
+          <Button onPress={() => this.carousel && this.carousel.goTo(0)}>
+            Go to 0
+          </Button>
+        </View>
+        <View style={{ paddingHorizontal: 15 }}>
+          <Text>vertical</Text>
+          <Carousel
+            style={styles.wrapper}
+            selectedIndex={1}
+            autoplay={this.state.autoplay}
+            infinite
+            afterChange={this.onVerticalSelectedIndexChange}
+            vertical>
+            <View
+              style={[styles.containerVertical, { backgroundColor: 'red' }]}>
+              <Text>Carousel 1</Text>
+            </View>
+            <View
+              style={[styles.containerVertical, { backgroundColor: 'blue' }]}>
+              <Text>Carousel 2</Text>
+            </View>
+            <View
+              style={[styles.containerVertical, { backgroundColor: 'yellow' }]}>
+              <Text>Carousel 3</Text>
+            </View>
+            <View
+              style={[styles.containerVertical, { backgroundColor: 'aqua' }]}>
+              <Text>Carousel 4</Text>
+            </View>
+            <View
+              style={[
+                styles.containerVertical,
+                { backgroundColor: 'fuchsia' },
+              ]}>
+              <Text>Carousel 5</Text>
+            </View>
+          </Carousel>
+          <Button
+            onPress={() => this.setState({ autoplay: !this.state.autoplay })}>
+            {`Toggle autoplay ${this.state.autoplay ? 'true' : 'false'}`}
+          </Button>
+        </View>
+      </ScrollView>
+    )
+  }
+}
+
+const styles = StyleSheet.create<{
+  wrapper: ViewStyle
+  containerHorizontal: ViewStyle
+  containerVertical: ViewStyle
+  text: TextStyle
+}>({
+  wrapper: {
+    backgroundColor: '#fff',
+    width: '100%',
+    height: 150,
+  },
+  containerHorizontal: {
+    flexGrow: 1,
+    alignItems: 'center',
+    justifyContent: 'center',
+  },
+  containerVertical: {
+    flexGrow: 1,
+    alignItems: 'center',
+    justifyContent: 'center',
+  },
+  text: {
+    color: '#fff',
+    fontSize: 36,
+  },
+})
+```
+
+## API
+
+Properties | Descrition | Type | Default | Version
+-----------|------------|------|---------|----------
+| afterChange  | callback to be called after a slide is changed | (current: number) => void | | |
+| autoplay | autoplay mode active | Boolean   | false | |
+| autoplayInterval | interval for autoplay iteration | Number | 3000 | |
+| dots | whether to display the indication dots | Boolean | true | |
+| dotStyle  | style of dots | ViewStyle | | |
+| dotActiveStyle  | style of active dot | ViewStyle  | | |
+| infinite | whether is infinite loop | Boolean   | false | |
+| lazy | Function which takes an object with the current page and returns a boolean to indicate whether to lazily render the scenes. | Boolean \| `(index:number) => boolean` | false | `5.3.1` |
+| renderLazyPlaceholder | A callback that returns a custom React Element to render for pages not yet rendered. Requires the `lazy` prop to be enabled. | `(index:number) => ReactNode` | - | `5.3.1` |
+| pageStyle | style of the carousel page | ViewStyle |  | |
+| pagination | A generator function which could be used to customized pagination. | (props) => ReactNode  | | |
+| selectedIndex |  current selected index  |  number  |  0  | |
+| style | ScrollView style<br/>(`tips: Recommended setting, the overall carousel size is determined by the container scrollview and not the inner page`) | ViewStyle | | |
+| vertical | controls the pagination display direction. | Boolean   | false | |
+| onScrollAnimationEnd | Called when a scrolling animation ends. | ()=>void   | | `5.3.0` |
+
+The rest of the props of Carousel are exactly the same as the react-native [ScrollView](https://reactnative.dev/docs/scrollview.html);
+
+eg: `scrollEnabled`、`onScroll` (if it not works, it is a mandatory prop of Carousel)
+
+## Carousel ref methods
+
+Properties | Descrition | Type 
+----|-----|------
+| goTo | jump to specified index | `(index: number, animated?: boolean): void` |
+| scrollNextPage | scroll to next page | `() => void` |
+
+## FAQ
+
+### 1. On the Android platform, when using `Carousel` nested in `ScrollView`, the Carousel Item cannot slide. What should I do?
+
+Support in `5.1.3`. Set the `nestedScrollEnabled` property of `ScrollView` to `true`.
+
+```jsx
+<ScrollView nestedScrollEnabled={true}>
+  ...
+  <Carousel vertical/>
+</ScrollView>
+```
+
+### 2. Use `lazy` and `renderLazyPlaceholder` props to render routes as needed
+
+Support in `5.3.1`.
+```jsx
+// `lazy={true}` only the current page is rendered
+<Carousel 
+  lazy
+  renderLazyPlaceholder={()=> <Loading /> }
+/>
+
+// eg: Render the sibling pages, a total of 3 pages
+<Carousel 
+  lazy={(i) => Math.abs(selectedIndex - i) < 2}
+>
+```
+
+### 3. Why choose Carousel instead of `react-native-pager-view` ?
+
+First, Carousel supports the `infinite` property, which means 🌟a true infinite loop🌟. <br/>
+Second, Carousel is completely based on `ScrollView`, which is not only lighter but also more compatible.
+
+---
+
+## Checkbox
+
+Source: https://rn.mobile.ant.design/components/checkbox.md
+
+# Checkbox
+
+Checkbox
+
+## Examples
+
+```tsx
+import { Button, Checkbox, Flex, List, WingBlank } from '@ant-design/react-native'
+import React from 'react'
+import { ScrollView } from 'react-native'
+const AgreeItem = Checkbox.AgreeItem
+const CheckboxItem = Checkbox.CheckboxItem
+
+export default class BasicCheckboxExample extends React.Component<any, any> {
+  constructor(props: any, context: any) {
+    super(props, context)
+    this.state = {
+      checked: true,
+      disabled: false,
+
+      checkBox1: true,
+      agreeItem1: true,
+      checkboxItem1: true,
+    }
+  }
+
+  onChange = (e: { target: { checked: boolean } }) => {
+    console.log(`checked = ${e.target.checked}`)
+  }
+
+  toggleChecked = () => {
+    this.setState({ checked: !this.state.checked })
+  }
+
+  toggleDisable = () => {
+    this.setState({ disabled: !this.state.disabled })
+  }
+  onChange2 = (e: { target: { checked: boolean } }) => {
+    console.log('checked = ', e.target.checked)
+    this.setState({
+      checked: e.target.checked,
+    })
+  }
+
+  render() {
+    const label = `${this.state.checked ? 'Checked' : 'Unchecked'}-${
+      this.state.disabled ? 'Disabled' : 'Enabled'
+    }`
+    return (
+      <ScrollView>
+        <List renderHeader="基本用法">
+          <List.Item
+            thumb={<Checkbox onChange={this.onChange}>Checkbox</Checkbox>}
+          />
+        </List>
+        <List renderHeader="不可用">
+          <List.Item thumb={<Checkbox defaultChecked={false} disabled />} />
+          <List.Item thumb={<Checkbox defaultChecked disabled />} />
+        </List>
+        <List
+          renderHeader="受控的Checkbox"
+          renderFooter={
+            <Flex>
+              <Flex.Item style={{ margin: 10 }}>
+                <Button
+                  type="primary"
+                  size="small"
+                  onPress={this.toggleChecked}>
+                  {!this.state.checked ? 'Check' : 'Uncheck'}
+                </Button>
+              </Flex.Item>
+              <Flex.Item style={{ margin: 10 }}>
+                <Button
+                  type="primary"
+                  size="small"
+                  onPress={this.toggleDisable}>
+                  {!this.state.disabled ? 'Disable' : 'Enable'}
+                </Button>
+              </Flex.Item>
+            </Flex>
+          }>
+          <List.Item
+            thumb={
+              <Checkbox
+                checked={this.state.checked}
+                disabled={this.state.disabled}
+                onChange={this.onChange2}>
+                {label}
+              </Checkbox>
+            }
+          />
+        </List>
+        <List renderHeader="AgreeItem">
+          <AgreeItem>
+            Agree agreement agreement agreement agreement agreement agreement
+            agreement
+          </AgreeItem>
+        </List>
+        <List renderHeader="CheckboxItem">
+          <CheckboxItem
+            checked={this.state.checkboxItem1}
+            onChange={(event) => {
+              this.setState({ checkboxItem1: event.target.checked })
+            }}>
+            Option 1
+          </CheckboxItem>
+          <CheckboxItem>Option 2</CheckboxItem>
+          <CheckboxItem disabled>Option 3</CheckboxItem>
+          <CheckboxItem disabled checked right>
+            More...
+          </CheckboxItem>
+        </List>
+        <List
+          renderHeader={
+            '全选\n在实现全选效果时,你可能会用到 indeterminate 属性。'
+          }>
+          <CheckboxGroupExample />
+        </List>
+      </ScrollView>
+    )
+  }
+}
+
+const plainOptions = ['Apple', 'Pear', 'Orange']
+const defaultCheckedList = ['Apple', 'Orange']
+
+const CheckboxGroupExample = () => {
+  const [checkedList, setCheckedList] = React.useState(
+    new Set(defaultCheckedList),
+  )
+  const [indeterminate, setIndeterminate] = React.useState(true)
+  const [checkAll, setCheckAll] = React.useState(false)
+
+  const onChange = (value: any, e: { target: { checked: boolean } }) => {
+    if (e.target.checked) {
+      checkedList.add(value)
+    } else {
+      checkedList.delete(value)
+    }
+
+    setCheckedList(new Set(checkedList))
+    setIndeterminate(
+      !!checkedList.size && checkedList.size < plainOptions.length,
+    )
+    setCheckAll(checkedList.size === plainOptions.length)
+  }
+
+  const onCheckAllChange = (e: { target: { checked: boolean } }) => {
+    setCheckedList(e.target.checked ? new Set(plainOptions) : new Set())
+    setIndeterminate(false)
+    setCheckAll(e.target.checked)
+  }
+
+  return (
+    <>
+      <CheckboxItem
+        indeterminate={indeterminate}
+        onChange={onCheckAllChange}
+        checked={checkAll}>
+        Check all
+      </CheckboxItem>
+      <WingBlank>
+        {plainOptions.map((a) => (
+          <CheckboxItem
+            key={a}
+            onChange={onChange.bind(this, a)}
+            checked={checkedList.has(a)}>
+            {a}
+          </CheckboxItem>
+        ))}
+      </WingBlank>
+    </>
+  )
+}
+```
+
+## API
+
+### Checkbox
+
+```ts
+type Event = { target: { checked: boolean } }
+```
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| defaultChecked  |  whether is checked when init  | Boolean   |   |
+| checked         |  whether is checked now (Controlled Mode)   | Boolean  |   |
+| disabled        |  whether is been disabled       | Boolean |  false  |
+| indeterminate   |  The indeterminate checked state of checkbox | Boolean | false |
+| onChange        | callback when check status is changed | (e: `Event`) => void |     |
+
+### Checkbox.CheckboxItem
+
+The encapsulation about `Checkbox` based on `List.Item`, the property `thumb` of `List.Item` will be passed to `Checkbox`, while other properties remain the same.
+
+Other APIs are identical with `Checkbox`.
+
+### Checkbox.AgreeItem
+
+Almost the same as CheckboxItem and be used for special scenes. See demo for details.
+
+---
+
+## Collapse
+
+Source: https://rn.mobile.ant.design/components/collapse.md
+
+# Collapse
+
+A content area that can be collapsed/expanded.
+
+### Rules
+- Group and hide complex areas to keep pages tidy.
+- An accordion is a special type of accordion panel that only allows a single content area to expand.
+
+## Examples
+
+```tsx
+import { ActivityIndicator, Collapse, Icon, List, Result } from '@ant-design/react-native'
+import React, { useEffect, useState } from 'react'
+import { ScrollView } from 'react-native'
+
+export default function CollapseExmple() {
+  return (
+    <ScrollView>
+      <List renderHeader="手风琴模式">
+        <Collapse accordion>
+          <Collapse.Panel key="1" title="第一项">
+            手风琴模式只能同时展开一个
+          </Collapse.Panel>
+          <Collapse.Panel key="2" title="第二项">
+            手风琴模式只能同时展开一个
+          </Collapse.Panel>
+          <Collapse.Panel key="3" title="第三项">
+            手风琴模式只能同时展开一个
+          </Collapse.Panel>
+        </Collapse>
+      </List>
+      <List renderHeader="自定义折叠图标">
+        <Collapse
+          defaultActiveKey={['1']}
+          arrow={(active) =>
+            active ? <Icon name="minus" /> : <Icon name="plus" />
+          }>
+          <Collapse.Panel key="1" title="第一项">
+            你可以通过 Collapse 的 arrow 属性来控制全部面板的箭头
+          </Collapse.Panel>
+          <Collapse.Panel
+            key="2"
+            title="第二项"
+            arrow={<Icon name="down-circle" />}>
+            也可以通过 Collapse.Panel 的 arrow 属性来自定义单个面板的箭头
+          </Collapse.Panel>
+          <Collapse.Panel
+            key="3"
+            title="第三项"
+            arrow={(active) =>
+              active ? (
+                <Icon name="check-circle" />
+              ) : (
+                <Icon name="close-circle" />
+              )
+            }>
+            如果你给 arrow 属性传入的是是一个渲染函数,那么
+            @ant-design/react-native 不会为你增加动画,arrow
+            属性的效果就完全交由你自己来控制了
+          </Collapse.Panel>
+        </Collapse>
+      </List>
+
+      <List renderHeader="动态内容">
+        <Collapse accordion>
+          <Collapse.Panel key="1" title="第一项" destroyOnClose>
+            <DynamicContent message="不可见时销毁 destroyOnClose={true}" />
+          </Collapse.Panel>
+          <Collapse.Panel key="2" title="第二项" forceRender>
+            <DynamicContent message="预加载 forceRender={true}" />
+          </Collapse.Panel>
+        </Collapse>
+      </List>
+    </ScrollView>
+  )
+}
+
+function DynamicContent(props: { message: string }) {
+  const [finished, setFinished] = useState(false)
+
+  useEffect(() => {
+    const loadData = async () => {
+      setTimeout(() => {
+        setFinished(true)
+      }, 1000)
+    }
+    loadData()
+  }, [])
+
+  return finished ? (
+    <Result title="处理成功" message={props.message} />
+  ) : (
+    <ActivityIndicator />
+  )
+}
+```
+
+## API
+
+### Collapse
+
+Properties | Descrition | Type | Default |
+-----------|------------|------|---------|
+| accordion | Whether to enable accordion mode | `Boolean` | `false` |
+| activeKey | The `key` of the currently expanded panel | accordion mode: `string | null` <br/> non-accordion mode: `string[]` | - |
+| arrowIcon | Custom arrow icon. <br/>if you pass a ReactNode, will add a rotate animation for you. | `ReactNode | ((active: boolean) => React.ReactNode)` | - |
+| defaultActiveKey | The `key` of the expanded panel by default | accordion mode: `string | null` <br/> non-accordion mode: `string[]` | - |
+| onChange | Triggered when the panel is switched | accordion mode: `(activeKey: string | null) => void` <br/> non-accordion mode: `(activeKey: string[]) => void` | - |
+| styles | Semantic DOM style | Same as [ListStyle](/components/list#liststyle-interface) & [ListItemStyle](/components/list#listitemstyle-interface) | - |
+
+### Collapse.Panel
+
+Properties | Descrition | Type | Default |
+-----------|------------|------|---------|
+| arrowIcon | Custom arrow icon | `ReactNode | ((active: boolean) => React.ReactNode)` | - |
+| destroyOnClose | Destroy `dom` when not visible | `Boolean` | `false` |
+| disabled | Whether disabled or not | `Boolean` | `false` |
+| forceRender | Whether to render the `DOM` structure when hidden	| `Boolean` | `false` |
+| key | The unique identifier | `String` | - |
+| onPress | The click event of title bar | `(event: GestureResponderEvent) => void` | - |
+| styles | Semantic DOM style | Same as [ListStyle](/components/list#liststyle-interface) | - |
+| title | The content on the left side of the title bar | `ReactNode` | - |
+
+---
+
+## DatePicker
+
+Source: https://rn.mobile.ant.design/components/date-picker.md
+
+# DatePicker
+
+Used to select a date or time.
+
+### Rules
+- At most accurate to seconds.
+
+## Examples
+
+```tsx
+import { DatePicker, List, Provider } from '@ant-design/react-native'
+import React from 'react'
+
+export default class PopupExample extends React.Component<any, any> {
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      value: undefined,
+    }
+  }
+
+  onChange = (value: any) => {
+    this.setState({ value })
+  }
+
+  render() {
+    return (
+      <Provider>
+        <List>
+          <DatePicker
+            value={this.state.value}
+            precision="day"
+            minDate={new Date(2015, 7, 6)}
+            maxDate={new Date(2026, 11, 3)}
+            onChange={this.onChange}
+            format="YYYY-MM-DD">
+            <List.Item arrow="horizontal">Select Date</List.Item>
+          </DatePicker>
+        </List>
+      </Provider>
+    )
+  }
+}
+```
+
+## API
+
+```ts
+type Precision =
+  | 'week'
+  | 'week-day'
+  | 'year'
+  | 'month'
+  | 'day'
+  | 'hour'
+  | 'minute'
+  | 'second'
+
+type DatePickerFilter = Partial<
+  Record<
+    Precision,
+    (
+      val: number,
+      extend: {
+        date: Date
+      }
+    ) => boolean
+  >
+>
+```
+
+Properties | Descrition | Type | Default | Version
+-----------|------------|------|--------|--------
+| precision  | Precision | `Precision` | `day` |`5.1.0`|
+| value | the currently selected value | Date | - ||
+| defaultValue | the default selected value | Date | - ||
+| minDate   | minimum date | Date  |  2000-1-1  ||
+| maxDate   | maximum date | Date  |  2030-1-1  ||
+| onChange  | change handler | `(value: Date) => void` |  -  ||
+| onValueChange | fire when picker col change | `(value: Date, index: number) => void` | - ||
+| renderLabel | The function to custom rendering the label shown on a column. `type` means any value in `precision`, `data` means the default number | `(type:Precision / 'now', data: number) => ReactNode` | - ||
+| locale | international, can override the configuration of the global [Provider](/components/provider)'s `locale` | Object: Object: {okText, dismissText, extra, `DatePickerLocale:{ year,month,day,hour,minute,am,pm }`} | - |
+| filter  | Filter available time	 | `DatePickerFilter` | - | `5.1.0` |
+
+
+In addition, the following properties of [Picker](/components/picker) are supported: `onPickerChange` `onVisibleChange` `style` `styles` `itemStyle` `itemHeight` `numberOfLines` `title` `okText` `dismissText` `okButtonProps` `dismissButtonProps` `visible` `children` `renderMaskTop` `renderMaskBottom`
+
+### Children
+Same as [Picker](/components/picker#children), except type `format` is different:
+
+Properties | Descrition | Type | Default
+----|-----|------|------
+| format  | format the selected value |`(value: Date) => date string` | import [Day.js Format](https://day.js.org/docs/en/parse/string-format), precision:`YYYY-MM-DD`,`YYYY-MM-DD HH:mm:ss`|
+
+### Ref
+Same as [Picker](/components/picker#ref)
+
+---
+
+## DatePickerView
+
+Source: https://rn.mobile.ant.design/components/date-picker-view.md
+
+# DatePickerView
+
+DatePickerView's functions like DatePicker, but it is rendered directly in the area instead of the pop-up window.
+
+## Examples
+
+```tsx
+import { DatePickerView, DatePickerFilter } from '@ant-design/react-native'
+import React, { useState } from 'react'
+import { ScrollView, Text } from 'react-native'
+
+const now = new Date()
+
+export default () => {
+  const [value, setValue] = useState<Date>(now)
+
+  return (
+    <ScrollView nestedScrollEnabled>
+      <Text style={{ margin: 16 }}>基础用法</Text>
+      <DatePickerView />
+
+      <Text style={{ margin: 16 }}>受控模式</Text>
+      <DatePickerView
+        value={value}
+        onChange={(val) => {
+          setValue(val)
+          console.log('onChange', val)
+        }}
+      />
+
+      <Text style={{ margin: 16 }}>自定义每列的渲染内容</Text>
+      <DatePickerView defaultValue={now} renderLabel={labelRenderer} />
+
+      <Text style={{ margin: 16 }}>周选择器</Text>
+      <DatePickerView
+        onChange={(val) => console.log('onChange', val)}
+        precision="week-day"
+        defaultValue={now}
+        renderLabel={weekdayLabelRenderer}
+      />
+
+      <Text style={{ margin: 16 }}>过滤可供选择的时间</Text>
+      <DatePickerView
+        defaultValue={now}
+        precision="hour"
+        renderLabel={labelRenderer}
+        filter={dateFilter}
+      />
+    </ScrollView>
+  )
+}
+
+const labelRenderer = (type: string, data: number) => {
+  switch (type) {
+    case 'year':
+      return data + '年'
+    case 'month':
+      return data + '月'
+    case 'day':
+      return data + '日'
+    case 'hour':
+      return data + '时'
+    case 'minute':
+      return data + '分'
+    case 'second':
+      return data + '秒'
+    default:
+      return data
+  }
+}
+
+const weekdayLabelRenderer = (type: string, data: number) => {
+  switch (type) {
+    case 'year':
+      return data + '年'
+    case 'week':
+      return data + '周'
+    case 'week-day':
+      return weekdayToZh(data)
+    default:
+      return data
+  }
+}
+
+const dateFilter: DatePickerFilter = {
+  day: (_val, { date }) => {
+    // 去除所有周末
+    if (date.getDay() > 5 || date.getDay() === 0) {
+      return false
+    }
+    return true
+  },
+  hour: (val: number) => {
+    // 只保留每天的14点到18点
+    if (val < 14 || val > 18) {
+      return false
+    }
+    return true
+  },
+}
+
+const weekdayToZh = (weekday: number) => {
+  switch (weekday) {
+    case 1:
+      return '周一'
+    case 2:
+      return '周二'
+    case 3:
+      return '周三'
+    case 4:
+      return '周四'
+    case 5:
+      return '周五'
+    case 6:
+      return '周六'
+    case 7:
+      return '周日'
+    default:
+      return weekday
+  }
+}
+```
+
+## API
+
+```ts
+type Precision =
+  | 'week'
+  | 'week-day'
+  | 'year'
+  | 'month'
+  | 'day'
+  | 'hour'
+  | 'minute'
+  | 'second'
+
+type DatePickerFilter = Partial<
+  Record<
+    Precision,
+    (
+      val: number,
+      extend: {
+        date: Date
+      }
+    ) => boolean
+  >
+>
+```
+
+Properties | Descrition | Type | Default | Version
+-----------|------------|------|---------|---------
+| precision  | Precision | `Precision` | `day` |`5.1.0`|
+| value | the currently selected value | Date | - |
+| defaultValue | the default selected value | Date | - ||
+| minDate   | minimum date | Date  |  2000-1-1  |
+| maxDate   | maximum date | Date  |  2030-1-1  |
+| onChange  | change handler | `(value: Date) => void` |  -  ||
+| onValueChange | fire when picker col change | `(value: Date, index: number) => void` | - ||
+| renderLabel | The function to custom rendering the label shown on a column. `type` means any value in `precision`, `data` means the default number | `(type:Precision / 'now', data: number) => ReactNode` | - ||
+| filter  | Filter available time	 | `DatePickerFilter` | - | `5.1.0` |
+
+
+In addition, the following properties of [PickerView](/components/picker-view) are supported: `style` `styles` `itemStyle` `itemHeight` `numberOfLines` `renderMaskTop` `renderMaskBottom`
+
+---
+
+## DatePickerView
+
+Source: https://rn.mobile.ant.design/components/image-picker.md
+
+# DatePickerView
+
+Deprecated since `5.1.0`.
+
+---
+
+## Drawer
+
+Source: https://rn.mobile.ant.design/components/drawer.md
+
+# Drawer
+
+Drawer is a panel that displays the app's navigation options on the left edge of the screen.
+
+### Rules
+
+- Recommended way to show navigation options on Android, it is a common pattern found in Android APPs.
+
+## Examples
+
+```tsx
+import { Button, Drawer, List, WhiteSpace } from '@ant-design/react-native'
+import React from 'react'
+import { ScrollView, StyleSheet, Text, View } from 'react-native'
+
+const styles = StyleSheet.create({
+  container: {
+    flex: 1,
+  },
+})
+
+export default class DrawerExample extends React.Component<any, any> {
+  drawer: any
+
+  onOpenChange = (isOpen: any) => {
+    /* tslint:disable: no-console */
+    console.log('是否打开了 Drawer', isOpen.toString())
+  }
+
+  render() {
+    const itemArr = Array.apply(null, Array(20))
+      .map(function (_: any, i: any) {
+        return i
+      })
+      .map((_i: any, index: any) => {
+        if (index === 0) {
+          return (
+            <List.Item
+              key={index}
+              thumb="https://zos.alipayobjects.com/rmsportal/eOZidTabPoEbPeU.png"
+              multipleLine>
+              <View
+                style={{
+                  flexDirection: 'row',
+                  justifyContent: 'space-between',
+                  alignItems: 'center',
+                }}>
+                <Text>Categories - {index}</Text>
+                <Button
+                  type="primary"
+                  size="small"
+                  onPress={() => this.drawer.closeDrawer()}>
+                  close drawer
+                </Button>
+              </View>
+            </List.Item>
+          )
+        }
+        return (
+          <List.Item
+            key={index}
+            thumb="https://zos.alipayobjects.com/rmsportal/eOZidTabPoEbPeU.png">
+            <Text>Categories - {index}</Text>
+          </List.Item>
+        )
+      })
+
+    // Todo: https://github.com/DefinitelyTyped/DefinitelyTyped
+    const sidebar = (
+      <ScrollView style={[styles.container as any]}>
+        <List>{itemArr}</List>
+      </ScrollView>
+    )
+
+    return (
+      <Drawer
+        sidebar={sidebar}
+        position="left"
+        open={false}
+        drawerRef={(el: any) => (this.drawer = el)}
+        onOpenChange={this.onOpenChange}
+        drawerBackgroundColor="#ccc">
+        <View style={{ flex: 1, marginTop: 114, padding: 8 }}>
+          <Button onPress={() => this.drawer && this.drawer.openDrawer()}>
+            Open drawer
+          </Button>
+          <WhiteSpace />
+        </View>
+      </Drawer>
+    )
+  }
+}
+```
+
+## API
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| sidebar | The sidebar content. | ReactNode | - |
+| onOpenChange | Callback called when open state of `Drawer` changes. | (open: bool): void | - |
+| open | If the sidebar should be open. | Boolean | false |
+| position | Position of `Drawer`. | String | 'left', enum{'left', 'right'} |
+| drawerWidth | Width of `Drawer` | Number | 300 |
+| drawerBackgroundColor | Background color of `Drawer` | String | - |
+| openDrawer | Opens the `Drawer`.  | (): void | - |
+| closeDrawer | Closes the `Drawer`. | (): void | - |
+
+---
+
+## Flex
+
+Source: https://rn.mobile.ant.design/components/flex.md
+
+# Flex
+
+Flex is a wrap of  Flexible Box.
+
+## Examples
+
+```tsx
+import { Button, Flex, WhiteSpace, WingBlank } from '@ant-design/react-native'
+import React from 'react'
+import { ScrollView, Text, TouchableWithoutFeedback, View } from 'react-native'
+
+const Circle = (props: any) => {
+  const size = props.size || 20
+  const style = {
+    borderRadius: size / 2,
+    backgroundColor: '#527fe4',
+    width: size,
+    height: size,
+    margin: 1,
+  }
+  return <View style={style} />
+}
+
+export default class FlexExample extends React.Component<any, any> {
+  render() {
+    return (
+      <ScrollView
+        style={{ flex: 1 }}
+        automaticallyAdjustContentInsets={false}
+        showsHorizontalScrollIndicator={false}
+        showsVerticalScrollIndicator={false}>
+        <WingBlank style={{ marginTop: 20, marginBottom: 5 }}>
+          <Text style={{ marginBottom: 10 }}>项目的排列方向</Text>
+          <Text>direction="row":主轴为水平方向,起点在左端</Text>
+        </WingBlank>
+        <WingBlank style={{ marginBottom: 5 }}>
+          <Flex>
+            <Flex.Item style={{ paddingLeft: 4, paddingRight: 4 }}>
+              <Button size="small">按钮1</Button>
+            </Flex.Item>
+            <Flex.Item style={{ paddingLeft: 4, paddingRight: 4 }}>
+              <Button size="small">按钮2</Button>
+            </Flex.Item>
+            <Flex.Item style={{ paddingLeft: 4, paddingRight: 4 }}>
+              <Button size="small">按钮3</Button>
+            </Flex.Item>
+          </Flex>
+        </WingBlank>
+        <WingBlank style={{ marginTop: 5, marginBottom: 5 }}>
+          <Text>direction="column":主轴为垂直方向,起点在上沿</Text>
+        </WingBlank>
+        <WingBlank style={{ marginBottom: 5 }}>
+          <Flex direction="column">
+            <Flex.Item style={{ paddingBottom: 4 }}>
+              <Button size="small">按钮1</Button>
+            </Flex.Item>
+            <Flex.Item style={{ paddingBottom: 4 }}>
+              <Button size="small">按钮2</Button>
+            </Flex.Item>
+            <Flex.Item style={{ paddingBottom: 4 }}>
+              <Button size="small">按钮3</Button>
+            </Flex.Item>
+          </Flex>
+        </WingBlank>
+        <WingBlank style={{ marginTop: 5, marginBottom: 5 }}>
+          <Text style={{ marginTop: 20, marginBottom: 20 }}>
+            项目在主轴上的对齐方式
+          </Text>
+          <Text>justify="start":左对齐</Text>
+        </WingBlank>
+        <WingBlank style={{ marginBottom: 5 }}>
+          <Flex justify="start">
+            <Circle />
+            <Circle />
+            <Circle />
+            <Circle />
+            <Circle />
+          </Flex>
+        </WingBlank>
+        <WingBlank style={{ marginTop: 5, marginBottom: 5 }}>
+          <Text>justify="center":居中</Text>
+        </WingBlank>
+        <WingBlank style={{ marginBottom: 5 }}>
+          <Flex justify="center">
+            <Circle />
+            <Circle />
+            <Circle />
+            <Circle />
+            <Circle />
+          </Flex>
+        </WingBlank>
+        <WingBlank style={{ marginTop: 5, marginBottom: 5 }}>
+          <Text>justify="end":右对齐</Text>
+        </WingBlank>
+        <WingBlank style={{ marginBottom: 5 }}>
+          <Flex justify="end">
+            <Circle />
+            <Circle />
+            <Circle />
+            <Circle />
+            <Circle />
+          </Flex>
+        </WingBlank>
+        <WingBlank style={{ marginTop: 5, marginBottom: 5 }}>
+          <Text>justify="between":两端对齐,项目之间的间隔都相等</Text>
+        </WingBlank>
+        <WingBlank style={{ marginBottom: 5 }}>
+          <Flex justify="between">
+            <Circle />
+            <Circle />
+            <Circle />
+            <Circle />
+            <Circle />
+          </Flex>
+        </WingBlank>
+        <WingBlank style={{ marginTop: 5, marginBottom: 5 }}>
+          <Text>justify="around":每个项目两侧的间隔相等</Text>
+        </WingBlank>
+        <WingBlank style={{ marginBottom: 5 }}>
+          <Flex justify="around">
+            <Circle />
+            <Circle />
+            <Circle />
+            <Circle />
+            <Circle />
+          </Flex>
+        </WingBlank>
+        <WingBlank style={{ marginTop: 5, marginBottom: 5 }}>
+          <Text style={{ marginTop: 20, marginBottom: 20 }}>
+            项目在交叉轴上的对齐方式
+          </Text>
+          <Text>align="start":交叉轴的起点对齐</Text>
+        </WingBlank>
+        <WingBlank style={{ marginBottom: 5 }}>
+          <Flex align="start" style={{ height: 30 }}>
+            <Text
+              style={{
+                fontSize: 20,
+                borderWidth: 1,
+                borderStyle: 'solid',
+                borderColor: '#527fe4',
+              }}>
+              兜兜
+            </Text>
+            <Text
+              style={{
+                fontSize: 18,
+                borderWidth: 1,
+                borderStyle: 'solid',
+                borderColor: '#527fe4',
+              }}>
+              兜兜
+            </Text>
+            <Text
+              style={{
+                fontSize: 16,
+                borderWidth: 1,
+                borderStyle: 'solid',
+                borderColor: '#527fe4',
+              }}>
+              兜兜
+            </Text>
+            <Text
+              style={{
+                fontSize: 14,
+                borderWidth: 1,
+                borderStyle: 'solid',
+                borderColor: '#527fe4',
+              }}>
+              兜兜
+            </Text>
+          </Flex>
+        </WingBlank>
+        <WingBlank style={{ marginTop: 5, marginBottom: 5 }}>
+          <Text>align="center":交叉轴的中点对齐</Text>
+        </WingBlank>
+        <WingBlank style={{ marginBottom: 5 }}>
+          <Flex align="center" style={{ height: 30 }}>
+            <Text
+              style={{
+                fontSize: 20,
+                borderWidth: 1,
+                borderStyle: 'solid',
+                borderColor: '#527fe4',
+              }}>
+              兜兜
+            </Text>
+            <Text
+              style={{
+                fontSize: 18,
+                borderWidth: 1,
+                borderStyle: 'solid',
+                borderColor: '#527fe4',
+              }}>
+              兜兜
+            </Text>
+            <Text
+              style={{
+                fontSize: 16,
+                borderWidth: 1,
+                borderStyle: 'solid',
+                borderColor: '#527fe4',
+              }}>
+              兜兜
+            </Text>
+            <Text
+              style={{
+                fontSize: 14,
+                borderWidth: 1,
+                borderStyle: 'solid',
+                borderColor: '#527fe4',
+              }}>
+              兜兜
+            </Text>
+          </Flex>
+        </WingBlank>
+        <WingBlank style={{ marginTop: 5, marginBottom: 5 }}>
+          <Text>align="end":交叉轴的终点对齐</Text>
+        </WingBlank>
+        <WingBlank style={{ marginBottom: 5 }}>
+          <Flex align="end" style={{ height: 30 }}>
+            <Text
+              style={{
+                fontSize: 20,
+                borderWidth: 1,
+                borderStyle: 'solid',
+                borderColor: '#527fe4',
+              }}>
+              兜兜
+            </Text>
+            <Text
+              style={{
+                fontSize: 18,
+                borderWidth: 1,
+                borderStyle: 'solid',
+                borderColor: '#527fe4',
+              }}>
+              兜兜
+            </Text>
+            <Text
+              style={{
+                fontSize: 16,
+                borderWidth: 1,
+                borderStyle: 'solid',
+                borderColor: '#527fe4',
+              }}>
+              兜兜
+            </Text>
+            <Text
+              style={{
+                fontSize: 14,
+                borderWidth: 1,
+                borderStyle: 'solid',
+                borderColor: '#527fe4',
+              }}>
+              兜兜
+            </Text>
+          </Flex>
+        </WingBlank>
+        <WingBlank style={{ marginTop: 5, marginBottom: 5 }}>
+          <Text>
+            align="stretch":如果项目未设置高度或设为auto,将占满整个容器的高度
+          </Text>
+        </WingBlank>
+        <WingBlank style={{ marginBottom: 5 }}>
+          <WingBlank>
+            <Flex align="stretch" style={{ height: 70 }}>
+              <Text
+                style={{
+                  fontSize: 20,
+                  borderWidth: 1,
+                  borderStyle: 'solid',
+                  borderColor: '#527fe4',
+                }}>
+                兜兜
+              </Text>
+              <Text
+                style={{
+                  fontSize: 18,
+                  borderWidth: 1,
+                  borderStyle: 'solid',
+                  borderColor: '#527fe4',
+                }}>
+                兜兜
+              </Text>
+              <Text
+                style={{
+                  fontSize: 16,
+                  borderWidth: 1,
+                  borderStyle: 'solid',
+                  borderColor: '#527fe4',
+                }}>
+                兜兜
+              </Text>
+              <Text
+                style={{
+                  fontSize: 14,
+                  borderWidth: 1,
+                  borderStyle: 'solid',
+                  borderColor: '#527fe4',
+                }}>
+                兜兜
+              </Text>
+            </Flex>
+          </WingBlank>
+        </WingBlank>
+        <WingBlank style={{ marginTop: 5, marginBottom: 5 }}>
+          <Text style={{ marginBottom: 10 }}>是否折行</Text>
+          <Text>wrap="wrap":换行</Text>
+        </WingBlank>
+        <WingBlank style={{ marginBottom: 5 }}>
+          <TouchableWithoutFeedback onPress={() => ({})}>
+            <Flex wrap="wrap">
+              {'ooooooooooooooooooooooooooooo'.split('').map((char, i) => (
+                <Circle key={`${i}-${char}`} />
+              ))}
+            </Flex>
+          </TouchableWithoutFeedback>
+        </WingBlank>
+        <WingBlank style={{ marginTop: 5, marginBottom: 5 }}>
+          <Text>wrap="nowrap":不换行</Text>
+        </WingBlank>
+        <WingBlank style={{ marginBottom: 5 }}>
+          <Flex wrap="nowrap" onPress={() => ({})}>
+            {'ooooooooooooooooooooooooooooo'.split('').map((char, i) => (
+              <Circle key={`${i}-${char}`} />
+            ))}
+          </Flex>
+        </WingBlank>
+        <WhiteSpace />
+        <WhiteSpace />
+        <WhiteSpace />
+      </ScrollView>
+    )
+  }
+}
+```
+
+## API
+
+### Flex
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| direction    |   how flex items are placed in the flex container,value could be `row`,`row-reverse`,`column`,`column-reverse`, RN only support `row`,`column`  | String  | `row` |
+| wrap    |  the wrap way of sub-elements,option `nowrap`,`wrap`,`wrap-reverse`,RN only support `nowrap`,`wrap`  | String  | `nowrap` |
+| justify  | the way of alignment for sub-elements of main axis, option `start`,`end`,`center`,`between`,`around`    | String   | `start` |
+| align    | the way of alignment for sub-elements of cross-axis, option `start`,`center`,`end`,`baseline`,`stretch` RN only support `start`,`end`,`center`,`stretch`  | String   | `center` |
+
+### Flex.Item
+
+Flex.Item component has style `flex:1` as default, ensure all items average division width, Flex container‘s children maybe not Flex.Item.
+
+---
+
+## Form
+
+Source: https://rn.mobile.ant.design/components/form.md
+
+# Form
+
+High-performance form component with data domain management. Includes data entry, validation, and corresponding styles. Base on [rc-field-form](https://www.npmjs.com/package/rc-field-form).
+
+Example from https://ant.design/components/form-cn
+
+## When to use
+
+- When you need to create an instance or collect information.
+- When you need to validate fields in certain rules.
+
+## Examples
+
+```tsx
+import {
+  Button,
+  Form,
+  Input,
+  Picker,
+  Provider,
+  Radio,
+  Flex as Row,
+  Switch,
+} from '@ant-design/react-native'
+import type { FormProps } from '@ant-design/react-native/lib/form'
+import { district } from 'antd-mobile-demo-data'
+import React from 'react'
+import { KeyboardAvoidingView, Platform, ScrollView } from 'react-native'
+
+
+const Col = Row.Item
+
+type FieldType = {
+  username?: string
+  password?: string
+  remember?: string
+  isDefault?: boolean
+}
+
+const FormExample: React.FC = () => {
+  const [form] = Form.useForm()
+
+  const onSubmit = () => {
+    form.submit()
+  }
+
+  const onFinish: FormProps<FieldType>['onFinish'] = (values) => {
+    console.log('Success:', values)
+  }
+
+  const onFinishFailed: FormProps<FieldType>['onFinishFailed'] = (
+    errorInfo,
+  ) => {
+    console.log('Failed:', errorInfo)
+  }
+
+  const pickerRef = React.useRef<any>(null)
+
+  return (
+    <Provider>
+      <KeyboardAvoidingView
+        behavior="padding"
+        keyboardVerticalOffset={Platform.OS === 'ios' ? 100 : undefined}>
+        <ScrollView keyboardShouldPersistTaps="handled">
+          <Form
+            name="basic"
+            form={form}
+            onFinish={onFinish}
+            onFinishFailed={onFinishFailed}
+            initialValues={{
+              doorNumber: '',
+              username: '',
+              phoneNumber: '',
+              isDefault: false,
+            }}
+            renderHeader="水平布局菜单">
+            <Form.Item
+              label="地址"
+              name="address"
+              rules={[{ required: true, message: '地址不能为空' }]}
+              arrow="horizontal"
+              onPress={() => {
+                pickerRef.current.toggle()
+              }}>
+              <Picker data={district} cols={3} ref={pickerRef}>
+                {({ extra, value, toggle }) => (
+                  <Input
+                    value={value?.length ? extra : undefined}
+                    onFocus={toggle}
+                    placeholder="省/市/区"
+                  />
+                )}
+              </Picker>
+            </Form.Item>
+
+            <Form.Item
+              label="收货人"
+              name="username"
+              extra={
+                <Form.Item name="gender" noStyle>
+                  <Radio.Group>
+                    <Row>
+                      <Radio value={1}>先生</Radio>
+                      <Radio value={2}>女士</Radio>
+                    </Row>
+                  </Radio.Group>
+                </Form.Item>
+              }>
+              <Input placeholder="请输入收货人姓名" />
+            </Form.Item>
+
+            <Form.Item
+              label="手机号"
+              name="phoneNumber"
+              hasFeedback
+              validateDebounce={500}
+              rules={[{ pattern: /^1[3456789]\d{9}$/ }, { required: true }]}>
+              <Input type="number" placeholder="请输入手机号" />
+            </Form.Item>
+
+            <Form.Item
+              label="设为默认"
+              name="isDefault"
+              wrapperStyle={{ alignItems: 'flex-end' }}
+              valuePropName="checked">
+              <Switch />
+            </Form.Item>
+
+            <Form.Item>
+              <Row>
+                <Col style={{ marginRight: 10 }}>
+                  <Button onPress={() => form.resetFields()}>重置</Button>
+                </Col>
+                <Col>
+                  <Button type="primary" onPress={onSubmit}>
+                    保存
+                  </Button>
+                </Col>
+              </Row>
+            </Form.Item>
+          </Form>
+          <Form name="vertical" layout="vertical" renderHeader="垂直布局菜单">
+            <Form.Item label="问题描述">
+              <Input.TextArea
+                placeholder="请填写10个字以上的问题描述,以便我们提供更好的服务。"
+                maxLength={200}
+                showCount
+                rows={6}
+              />
+            </Form.Item>
+            <Form.Item
+              label="联系电话"
+              name="phone"
+              help="如您选择填写联系方式,该信息将同步至开发者">
+              <Input type="number" placeholder="选填,请填写您的手机号码" />
+            </Form.Item>
+          </Form>
+        </ScrollView>
+      </KeyboardAvoidingView>
+    </Provider>
+  )
+}
+
+export default FormExample
+```
+
+## API
+
+### Form
+
+| Property | Description | Type | Default |
+| --- | --- | --- | --- |
+| disabled | Set form component disable, only available for `@ant-design/react-native` components | boolean | false |
+| component | Set the Form rendering element. Do not create a ReactNode for `false` | ComponentType \| false | `List` |
+| fields | Control of form fields through state management (such as redux). Not recommended for non-strong demand. View [example](https://ant.design/components/form#components-form-demo-global-state) | [FieldData](#fielddata)\[] | - |
+| form | Form control instance created by `Form.useForm()`. Automatically created when not provided | [FormInstance](#forminstance) | - |
+| feedbackIcons | Can be passed custom icons while `Form.Item` element has `hasFeedback` | [FeedbackIcons](#feedbackicons) | - |
+| initialValues | Set value by Form initialization or reset | object | - |
+| labelStyle | The label style | `ViewStyle \| TextStyle` | - |
+| layout | Form layout | `horizontal` \| `vertical` | `horizontal` |
+| name | Form name. Will be the prefix of Field `id` | string | - |
+| preserve | Keep field value even when field removed. You can get the preserve field value by `getFieldsValue(true)` | boolean | true |
+| requiredMark | Required mark style. Can use required mark or optional mark. You can not config to single Form.Item since this is a Form level config | boolean \| `optional` \| ((label: ReactNode, info: { required: boolean }) => ReactNode) | true |
+| validateMessages | Validation prompt template, description [see below](#validatemessages) | [ValidateMessages](https://github.com/ant-design/ant-design/blob/6234509d18bac1ac60fbb3f92a5b2c6a6361295a/components/locale/en_US.ts#L88-L134) | - |
+| validateTrigger | Config field validate trigger | string \| string\[] | `onChange` |
+| wrapperStyle | The layout for input controls, same as `labelStyle` | `ViewStyle` | - |
+| onFieldsChange | Trigger when field updated | function(changedFields, allFields) | - |
+| onFinish | Trigger after submitting the form and verifying data successfully | function(values) | - |
+| onFinishFailed | Trigger after submitting the form and verifying data failed | function({ values, errorFields, outOfDate }) | - |
+| onValuesChange | Trigger when value updated | function(changedValues, allValues) | - |
+| styles | Semantic DOM style | Same as [ListStyle](/components/list#liststyle-interface) | - |
+
+### validateMessages
+
+Form provides [default verification error messages](https://github.com/ant-design/ant-design/blob/6234509d18bac1ac60fbb3f92a5b2c6a6361295a/components/locale/en_US.ts#L88-L134). You can modify the template by configuring `validateMessages` property. A common usage is to configure localization:
+
+```jsx
+const validateMessages = {
+  required: "'${name}' is required!",
+  // ...
+};
+
+<Form validateMessages={validateMessages} />;
+```
+
+## Form.Item
+
+Form field component for data bidirectional binding, validation, layout, and so on.
+
+| Property | Description | Type | Default |
+| --- | --- | --- | --- |
+| dependencies | Set the dependency field. See [below](#dependencies) | [NamePath](#namepath)\[] | - |
+| getValueFromEvent | Specify how to get value from event or other onChange arguments | (..args: any\[]) => any | - |
+| getValueProps | Additional props with sub component (It's not recommended to generate dynamic function prop by `getValueProps`. Please pass it to child component directly) | (value: any) => Record<string, any> | - |
+| hasFeedback | Used with `validateStatus`, this option specifies the validation status icon. Recommended to be used only with `Input`. Also, It can get feedback icons via icons prop. | boolean \| { icons: [FeedbackIcons](#feedbackicons) } | false |
+| help | The prompt message. If not provided, the prompt message will be generated by the validation rule. | ReactNode | - |
+| hidden | Whether to hide Form.Item (still collect and validate value) | boolean | false |
+| initialValue | Config sub default value. Form `initialValues` get higher priority when conflict | string | - |
+| label | Label text | ReactNode | - |
+| labelStyle | The label style. You can set `labelCol` on Form which will not affect nest Item. If both exists, use Item first | `ViewStyle \| TextStyle` | - |
+| messageVariables | The default validate field info | Record&lt;string, string> | - |
+| name | Field name, support array | [NamePath](#namepath) | - |
+| normalize | Normalize value from component value before passing to Form instance. Do not support async | (value, prevValue, prevValues) => any | - |
+| noStyle | No style for `true`, used as a pure field control. Will inherit parent Form.Item `validateStatus` if self `validateStatus` not configured | boolean | false |
+| preserve | Keep field value even when field removed | boolean | true |
+| required | Display required style. It will be generated by the validation rule | boolean | false |
+| rules | Rules for field validation. Click [here](https://ant.design/components/form#components-form-demo-basic) to see an example | [Rule](#rule)\[] | - |
+| shouldUpdate | Custom field update logic. See [below](#shouldupdate) | boolean \| (prevValue, curValue) => boolean | false |
+| styles  | Semantic DOM style | [FormItemStyle](#formitemstyle-interface) & [ValidateStatusStyle](#validatestatusstyle-interface) | - |
+| trigger | When to collect the value of children node. Click [here](https://ant.design/components/form#components-form-demo-customized-form-controls) to see an example | string | `onChange` |
+| validateDebounce | Delay milliseconds to start validation | number | - |
+| validateFirst | Whether stop validate on first rule of error for this field. Will parallel validate when `parallel` configured | boolean \| `parallel` | false |
+| validateStatus | The validation status. If not provided, it will be generated by validation rule. options: `success` `warning` `error` `validating` | string | - |
+| validateTrigger | When to validate the value of children node | string \| string\[] | `onChange` |
+| valuePropName | Props of children node, for example, the prop of Switch or Checkbox is `checked`. This prop is an encapsulation of `getValueProps`, which will be invalid after customizing `getValueProps` | string | `value` |
+| wrapperStyle | The layout for input controls, same as `labelStyle`. You can set `wrapperStyle` on Form which will not affect nest Item. If both exists, use Item first | `ViewStyle` | - |
+
+The layout of Form.Item is based on List.Item. So it also supports these props of [List.Item](/components/list/#List.Item)
+
+`arrow` `extra` `thumb`
+
+After wrapped by `Form.Item` with `name` property, `value`(or other property defined by `valuePropName`) `onChange`(or other property defined by `trigger`) props will be added to form controls, the flow of form data will be handled by Form which will cause:
+
+1. You shouldn't use `onChange` on each form control to **collect data**(use `onValuesChange` of Form), but you can still listen to `onChange`.
+2. You cannot set value for each form control via `value` or `defaultValue` prop, you should set default value with `initialValues` of Form. Note that `initialValues` cannot be updated by `setState` dynamically, you should use `setFieldsValue` in that situation.
+3. You shouldn't call `setState` manually, please use `form.setFieldsValue` to change value programmatically.
+
+### dependencies
+
+Used when there are dependencies between fields. If a field has the `dependencies` prop, this field will automatically trigger updates and validations when upstream is updated. A common scenario is a user registration form with "password" and "confirm password" fields. The "Confirm Password" validation depends on the "Password" field. After setting `dependencies`, the "Password" field update will re-trigger the validation of "Check Password".
+
+`dependencies` shouldn't be used together with `shouldUpdate`, since it may result in conflicting update logic.
+
+### FeedbackIcons
+
+`({ status: ValidateStatus, errors: ReactNode, warnings: ReactNode }) => Record<ValidateStatus, ReactNode>`
+
+### shouldUpdate
+
+Form updates only the modified field-related components for performance optimization purposes by incremental update. In most cases, you only need to write code or do validation with the [`dependencies`](#dependencies) property. In some specific cases, such as when a new field option appears with a field value changed, or you just want to keep some area updating by form update, you can modify the update logic of Form.Item via the `shouldUpdate`.
+
+When `shouldUpdate` is `true`, any Form update will cause the Form.Item to be re-rendered. This is very helpful for custom rendering some areas. It should be noted that the child component should be returned in a function, otherwise `shouldUpdate` won't behave correctly:
+
+```jsx
+<Form.Item shouldUpdate>
+  {() => {
+    return <pre>{JSON.stringify(form.getFieldsValue(), null, 2)}</pre>;
+  }}
+</Form.Item>
+```
+
+When `shouldUpdate` is a function, it will be called by form values update. Providing original values and current value to compare. This is very helpful for rendering additional fields based on values:
+
+```jsx
+<Form.Item shouldUpdate={(prevValues, curValues) => prevValues.additional !== curValues.additional}>
+  {() => {
+    return (
+      <Form.Item name="other">
+        <Input />
+      </Form.Item>
+    );
+  }}
+</Form.Item>
+```
+
+### messageVariables
+
+You can modify the default verification information of Form.Item through `messageVariables`.
+
+```jsx
+<Form>
+  <Form.Item
+    messageVariables={{ another: 'good' }}
+    label="user"
+    rules={[{ required: true, message: '${another} is required' }]}
+  >
+    <Input />
+  </Form.Item>
+  <Form.Item
+    messageVariables={{ label: 'good' }}
+    label={<span>user</span>}
+    rules={[{ required: true, message: '${label} is required' }]}
+  >
+    <Input />
+  </Form.Item>
+</Form>
+```
+
+## Form.List
+
+Provides array management for fields.
+
+| Property | Description | Type | Default |
+| --- | --- | --- | --- |
+| children | Render function | (fields: Field\[], operation: { add, remove, move }, meta: { errors }) => React.ReactNode | - |
+| initialValue | Config sub default value. Form `initialValues` get higher priority when conflict | any\[] | - |
+| name | Field name, support array. List is also a field, so it will return all the values by `getFieldsValue`. You can change this logic by [config](#getfieldsvalue) | [NamePath](#namepath) | - |
+| rules | Validate rules, only support customize validator. Should work with [ErrorList](#formerrorlist) | { validator, message }\[] | - |
+
+```tsx
+<Form.List>
+  {(fields) => (
+    <div>
+      {fields.map((field) => (
+        <Form.Item {...field}>
+          <Input />
+        </Form.Item>
+      ))}
+    </div>
+  )}
+</Form.List>
+```
+
+Note: You should not configure Form.Item `initialValue` under Form.List. It always should be configured by Form.List `initialValue` or Form `initialValues`.
+
+## operation
+
+Some operator functions in render form of Form.List.
+
+| Property | Description | Type | Default |
+| --- | --- | --- | --- |
+| add | add form item | (defaultValue?: any, insertIndex?: number) => void | insertIndex |
+| move | move form item | (from: number, to: number) => void | - |
+| remove | remove form item | (index: number \| number\[]) => void | number\[] |
+
+## Form.ErrorList
+
+Show error messages, should only work with `rules` of Form.List. See [example](https://ant.design/components/form#components-form-demo-dynamic-form-item).
+
+| Property | Description | Type         | Default |
+| -------- | ----------- | ------------ | ------- |
+| errors   | Error list  | ReactNode\[] | -       |
+| styles | Semantic DOM style | [ValidateStatusStyle](#validatestatusstyle-interface) | - |
+
+## Form.Provider
+
+Provide linkage between forms. If a sub form with `name` prop update, it will auto trigger Provider related events. See [example](https://ant.design/components/form#components-form-demo-form-context).
+
+| Property | Description | Type | Default |
+| --- | --- | --- | --- |
+| onFormChange | Triggered when a sub form field updates | function(formName: string, info: { changedFields, forms }) | - |
+| onFormFinish | Triggered when a sub form submits | function(formName: string, info: { values, forms }) | - |
+
+```jsx
+<Form.Provider
+  onFormFinish={(name) => {
+    if (name === 'form1') {
+      // Do something...
+    }
+  }}
+>
+  <Form name="form1">...</Form>
+  <Form name="form2">...</Form>
+</Form.Provider>
+```
+
+### FormInstance
+
+| Name | Description | Type |
+| --- | --- | --- |
+| getFieldError | Get the error messages by the field name | (name: [NamePath](#namepath)) => string\[] |
+| getFieldInstance | Get field instance | (name: [NamePath](#namepath)) => any |
+| getFieldsError | Get the error messages by the fields name. Return as an array | (nameList?: [NamePath](#namepath)\[]) => FieldError\[] |
+| getFieldsValue | Get values by a set of field names. Return according to the corresponding structure. Default return mounted field value, but you can use `getFieldsValue(true)` to get all values | [GetFieldsValue](#getfieldsvalue) |
+| getFieldValue | Get the value by the field name | (name: [NamePath](#namepath)) => any |
+| isFieldsTouched | Check if fields have been operated. Check if all fields is touched when `allTouched` is `true` | (nameList?: [NamePath](#namepath)\[], allTouched?: boolean) => boolean |
+| isFieldTouched | Check if a field has been operated | (name: [NamePath](#namepath)) => boolean |
+| isFieldValidating | Check field if is in validating | (name: [NamePath](#namepath)) => boolean |
+| resetFields | Reset fields to `initialValues` | (fields?: [NamePath](#namepath)\[]) => void |
+| scrollToField | Scroll to field position | (name: [NamePath](#namepath), options: \[[ScrollOptions](https://github.com/stipsan/scroll-into-view-if-needed/tree/ece40bd9143f48caf4b99503425ecb16b0ad8249#options)]) => void |
+| setFields | Set fields status | (fields: [FieldData](#fielddata)\[]) => void |
+| setFieldValue | Set fields value(Will directly pass to form store and **reset validation message**. If you do not want to modify passed object, please clone first) | (name: [NamePath](#namepath), value: any) => void |
+| setFieldsValue | Set fields value(Will directly pass to form store and **reset validation message**. If you do not want to modify passed object, please clone first). Use `setFieldValue` instead if you want to only config single value in Form.List | (values) => void |
+| submit | Submit the form. It's same as click `submit` button | () => void |
+| validateFields | Validate fields. Use `recursive` to validate all the field in the path | (nameList?: [NamePath](#namepath)\[], config?: [ValidateConfig](#validateFields)) => Promise |
+
+#### validateFields
+
+```tsx
+export interface ValidateConfig {
+  // Only validate content and not show error message on UI.
+  validateOnly?: boolean;
+  // Recursively validate the provided `nameList` and its sub-paths.
+  recursive?: boolean;
+  // Validate dirty fields (touched + validated).
+  // It's useful to validate fields only when they are touched or validated.
+  dirty?: boolean;
+}
+```
+
+return sample:
+
+```jsx
+validateFields()
+  .then((values) => {
+    /*
+  values:
+    {
+      username: 'username',
+      password: 'password',
+    }
+  */
+  })
+  .catch((errorInfo) => {
+    /*
+    errorInfo:
+      {
+        values: {
+          username: 'username',
+          password: 'password',
+        },
+        errorFields: [
+          { name: ['password'], errors: ['Please input your Password!'] },
+        ],
+        outOfDate: false,
+      }
+    */
+  });
+```
+
+### FormItemStyle interface
+
+```typescript
+interface FormItemStyle extends ListItemStyle {
+  // label prop
+  formItemLabel: ViewStyle // { minWidth: 65 }
+  formItemLabelText: ViewStyle | TextStyle
+
+  // children style
+  formItemControl: ViewStyle
+
+  // required={true}
+  asterisk: TextStyle    
+  // requiredMark="optional"               
+  optional: TextStyle   
+}
+```
+
+### ValidateStatusStyle interface
+when set `validateStatus` prop
+```typescript
+interface ValidateStatusStyle {
+  error: TextStyle
+  warning: TextStyle
+  success: TextStyle
+  validating: TextStyle
+  feedbackIcon: ViewStyle
+}
+```
+
+## Hooks
+
+### Form.useForm
+
+`type Form.useForm = (): [FormInstance]`
+
+Create Form instance to maintain data store.
+
+### Form.useFormInstance
+
+`type Form.useFormInstance = (): FormInstance`
+
+Get current context form instance to avoid pass as props between components:
+
+```tsx
+const Sub = () => {
+  const form = Form.useFormInstance();
+
+  return <Button onClick={() => form.setFieldsValue({})} />;
+};
+
+export default () => {
+  const [form] = Form.useForm();
+
+  return (
+    <Form form={form}>
+      <Sub />
+    </Form>
+  );
+};
+```
+
+### Form.useWatch
+
+`type Form.useWatch = (namePath: NamePath | (selector: (values: Store) => any), formInstance?: FormInstance | WatchOptions): Value`
+
+Watch the value of a field. You can use this to interact with other hooks like `useSWR` to reduce development costs:
+
+```tsx
+const Demo = () => {
+  const [form] = Form.useForm();
+  const userName = Form.useWatch('username', form);
+
+  const { data: options } = useSWR(`/api/user/${userName}`, fetcher);
+
+  return (
+    <Form form={form}>
+      <Form.Item name="username">
+        <AutoComplete options={options} />
+      </Form.Item>
+    </Form>
+  );
+};
+```
+
+If your component is wrapped by `Form.Item`, you can omit the second argument, `Form.useWatch` will find the nearest `FormInstance` automatically.
+
+By default `useWatch` only watches the registered field. If you want to watch the unregistered field, please use `preserve`:
+
+```tsx
+const Demo = () => {
+  const [form] = Form.useForm();
+
+  const age = Form.useWatch('age', { form, preserve: true });
+  console.log(age);
+
+  return (
+    <div>
+      <Button onClick={() => form.setFieldValue('age', 2)}>Update</Button>
+      <Form form={form}>
+        <Form.Item name="name">
+          <Input />
+        </Form.Item>
+      </Form>
+    </div>
+  );
+};
+```
+
+### Form.Item.useStatus
+
+`type Form.Item.useStatus = (): { status: ValidateStatus | undefined, errors: ReactNode[], warnings: ReactNode[] }`
+
+Could be used to get validate status of Form.Item. If this hook is not used under Form.Item, `status` would be `undefined`. `error` and `warnings` could be used to get error messages and warning messages of Form.Item:
+
+```tsx
+const CustomInput = ({ value, onChange }) => {
+  const { status, errors } = Form.Item.useStatus();
+  return (
+    <input
+      value={value}
+      onChange={onChange}
+      className={`custom-input-${status}`}
+      placeholder={(errors.length && errors[0]) || ''}
+    />
+  );
+};
+
+export default () => (
+  <Form>
+    <Form.Item name="username">
+      <CustomInput />
+    </Form.Item>
+  </Form>
+);
+```
+
+#### Difference between other data fetching method
+
+Form only update the Field which changed to avoid full refresh perf issue. Thus you can not get real time value with `getFieldsValue` in render. And `useWatch` will rerender current component to sync with latest value. You can also use Field renderProps to get better performance if only want to do conditional render. If component no need care field value change, you can use `onValuesChange` to give to parent component to avoid current one rerender.
+
+### Interface
+
+#### NamePath
+
+`string | number | (string | number)[]`
+
+#### GetFieldsValue
+
+`getFieldsValue` provides overloaded methods:
+
+##### getFieldsValue(nameList?: true | [NamePath](#namepath)\[], filterFunc?: FilterFunc)
+
+When `nameList` is empty, return all registered fields, including values of List (even if List has no Item children).
+
+When `nameList` is `true`, return all values in store, including unregistered fields. For example, if you set the value of an unregistered Item through `setFieldsValue`, you can also get all values through `true`.
+
+When `nameList` is an array, return the value of the specified path. Note that `nameList` is a nested array. For example, you need the value of a certain path as follows:
+
+```tsx
+// Single path
+form.getFieldsValue([['user', 'age']]);
+
+// multiple path
+form.getFieldsValue([
+  ['user', 'age'],
+  ['preset', 'account'],
+]);
+```
+
+##### getFieldsValue({ strict?: boolean, filter?: FilterFunc })
+
+Accept configuration parameters. When `strict` is `true`, only the value of Item will be matched. For example, in `{ list: [{ bamboo: 1, little: 2 }] }`, if List is only bound to the `bamboo` field, then `getFieldsValue({ strict: true })` will only get `{ list: [{ bamboo: 1 }] }`.
+
+#### FilterFunc
+
+To filter certain field values, `meta` will provide information related to the fields. For example, it can be used to retrieve values that have only been modified by the user, and so on.
+
+```tsx
+type FilterFunc = (meta: { touched: boolean; validating: boolean }) => boolean;
+```
+
+#### FieldData
+
+| Name       | Description              | Type                     |
+| ---------- | ------------------------ | ------------------------ |
+| errors     | Error messages           | string\[]                |
+| warnings   | Warning messages         | string\[]                |
+| name       | Field name path          | [NamePath](#namepath)\[] |
+| touched    | Whether is operated      | boolean                  |
+| validating | Whether is in validating | boolean                  |
+| value      | Field value              | any                      |
+
+#### Rule
+
+Rule supports a config object, or a function returning config object:
+
+```tsx
+type Rule = RuleConfig | ((form: FormInstance) => RuleConfig);
+```
+
+| Name | Description | Type |
+| --- | --- | --- |
+| defaultField | Validate rule for all array elements, valid when `type` is `array` | [rule](#rule) |
+| enum | Match enum value. You need to set `type` to `enum` to enable this | any\[] |
+| fields | Validate rule for child elements, valid when `type` is `array` or `object` | Record&lt;string, [rule](#rule)> |
+| len | Length of string, number, array | number |
+| max | `type` required: max length of `string`, `number`, `array` | number |
+| message | Error message. Will auto generate by [template](#validatemessages) if not provided | string |
+| min | `type` required: min length of `string`, `number`, `array` | number |
+| pattern | Regex pattern | RegExp |
+| required | Required field | boolean |
+| transform | Transform value to the rule before validation | (value) => any |
+| type | Normally `string` \|`number` \|`boolean` \|`url` \| `email`. More type to ref [here](https://github.com/yiminghe/async-validator#type) | string |
+| validateTrigger | Set validate trigger event. Must be the sub set of `validateTrigger` in Form.Item | string \| string\[] |
+| validator | Customize validation rule. Accept Promise as return. See [example](https://ant.design/components/form#components-form-demo-register) | ([rule](#rule), value) => Promise |
+| warningOnly | Warning only. Not block form submit | boolean |
+| whitespace | Failed if only has whitespace, only work with `type: 'string'` rule | boolean |
+
+#### WatchOptions
+
+| Name | Description | Type | Default |
+| --- | --- | --- | --- |
+| form | Form instance | FormInstance | Current form in context |
+| preserve | Whether to watch the field which has no matched `Form.Item` | boolean | false |
+
+## FAQ
+
+### Why can't Switch、Checkbox、Radio bind data?
+
+Form.Item default bind value to `value` prop, but Switch or Checkbox value prop is `checked`. You can use `valuePropName` to change bind value prop.
+
+```tsx | pure
+<Form.Item name="fieldA" valuePropName="checked">
+  <Switch />
+</Form.Item>
+```
+
+### How does Form.Item work with Picker / DatePicker?
+
+When Picker's `children` is `List.Item`, it can be used directly.
+<br/>Note: Form.Item need `noStyle` prop 
+```tsx
+<Form.Item name="address" noStyle>
+  <Picker data={data} cols={3}>
+   <List.Item>地址</List.Item>
+  </Picker>
+</Form.Item>
+```
+
+However, we recommend the composition layout of `Form.Item` and `Input`, so how to use it when `children` is not `List.Item`?
+<br/>
+When `children` is a **function**, the `toggle` parameter will be provided to control the display/hide of Picker.
+```tsx
+<Form.Item label="地址" name="address">
+  <Picker data={data} cols={3} >
+    {({ extra, value, toggle }: any) => (
+      <Input
+        value={value?.length ? extra : undefined}
+        onFocus={toggle}
+        placeholder="省/市/区"
+      />
+    )}
+  </Picker>
+</Form.Item>
+```
+Secondly, you can use `ref`
+```tsx
+const pickerRef = useRef();
+
+<Form.Item label="地址" name="address" onPress={()=>pickerRef.current?.toggle()}>
+  <Picker data={data} cols={3} ref={pickerRef}>
+    <Input placeholder="省/市/区"/>
+  </Picker>
+</Form.Item>
+```
+
+
+### Is there any more reference documentation?
+
+https://ant.design/components/form-cn
+
+---
+
+## Grid
+
+Source: https://rn.mobile.ant.design/components/grid.md
+
+# Grid
+
+We divided the design area into a number of aliquots in horizontal and vertical.
+
+### Rules
+- The contents of the blocks should have the same type. eg: they are all pictures or icons with text.
+
+## Examples
+
+```tsx
+import { Grid } from '@ant-design/react-native'
+import React from 'react'
+import { ScrollView, Text, View } from 'react-native'
+
+const data = Array.from(new Array(9)).map((_val, i) => ({
+  icon: 'https://os.alipayobjects.com/rmsportal/IptWdCkrtkAUfjE.png',
+  text: `Name${i}`,
+}))
+
+export default class BasicGridExample extends React.Component<any, any> {
+  render() {
+    return (
+      <ScrollView>
+        <View style={[{ margin: 10 }]}>
+          <Text>Simple</Text>
+        </View>
+        <View style={[{ padding: 10 }]}>
+          <Grid data={data} hasLine={false} />
+        </View>
+
+        <View style={[{ margin: 10 }]}>
+          <Text>Carousel</Text>
+        </View>
+        <Grid
+          data={data}
+          columnNum={3}
+          isCarousel
+          carouselProps={{
+            style: {
+              width: '100%',
+              height: 320,
+            },
+          }}
+          onPress={(_el: any, index: any) => alert(index)}
+        />
+        <View style={[{ margin: 10 }]}>
+          <Text>Custom GridCell Style</Text>
+        </View>
+        <Grid
+          data={data}
+          columnNum={3}
+          itemStyle={{ height: 150, backgroundColor: '#ffff00' }}
+        />
+      </ScrollView>
+    )
+  }
+}
+```
+
+## API
+
+| Properties     | Description                                                   | Type                              | Default     |
+| -------------- | ------------------------------------------------------------- | --------------------------------- | ----------- |
+| data           | data record array to be rendered                              | `Array<{icon, text}>`             | []          |
+| onPress        | Handler to be called when the user taps the grid              | (el: Object, index: number): void | -           |
+| columnNum      | the number of columns                                         | number                            | `4`         |
+| hasLine        | whether to show border                                        | boolean                           | `true`      |
+| isCarousel     | whether to be played as a Carousel                            | boolean                           | `false`     |
+| carouselProps  | Carousel Props                                                    | CarouselProps                     | `{}` |
+| carouselMaxRow | the max number of rows to be showed each page of the Carousel | number                            | `2`         |
+| renderItem     | custom function to create each grid item                      | (el, index) => React.Node         | -           |
+| itemStyle      | Custom GridCell Style                                         | object                            | {}          |
+When `isCarousel = true`, the APIs of [carousel](https://mobile.ant.design/components/carousel) also can be delivered.
+
+---
+
+## Icon
+
+Source: https://rn.mobile.ant.design/components/icon.md
+
+# Icon
+
+## How to Use
+
+### 安装依赖
+
+```bash
+npm install @ant-design/icons-react-native@latest
+```
+
+
+### Linking
+
+ - Add assets to your `react-native.config.js` ( If not exist, please create in project’s root directory )
+
+   ```js
+   module.exports = {
+     assets: ['node_modules/@ant-design/icons-react-native/fonts'],
+   };
+   ```
+
+ - Run the [`react-native-asset`](https://github.com/unimonkiez/react-native-asset)'s command and linking + unlinking is automatic
+
+   ```bash
+   npx react-native-asset
+   ```
+   will copy fonts to `ios` and `android` assets folder.
+ - If you have an Expo managed project, skip the previous two steps and use [expo-font](https://docs.expo.dev/versions/latest/sdk/font/) to load the font directly:
+   ```jsx
+   import { useFonts } from 'expo-font';
+
+   const [fontsLoaded] = useFonts({
+    antoutline: require('@ant-design/icons-react-native/fonts/antoutline.ttf'),
+   })
+   ```
+
+## Examples
+
+```tsx
+import {
+  outlineGlyphMap,
+  OutlineGlyphMapType,
+} from '@ant-design/icons-react-native/lib/outline'
+import { Grid, Icon, SearchBar, Toast } from '@ant-design/react-native'
+import React from 'react'
+import { ScrollView } from 'react-native'
+const data = Object.keys(outlineGlyphMap).map((item: OutlineGlyphMapType) => ({
+  icon: <Icon name={item} />,
+  text: item,
+}))
+export default class IConDemo extends React.Component<any, any> {
+  state = {
+    data,
+  }
+  handlePress = (dataItem: { icon?: any; text?: string }) => {
+    Toast.show(`<Icon name="${dataItem.text}" />`)
+  }
+  render() {
+    return (
+      <ScrollView>
+        <SearchBar
+          placeholder="Search by icon name"
+          onChange={(text) => {
+            this.setState(() => ({
+              data: data.filter((d) => d.text.match(new RegExp(text, 'gi'))),
+            }))
+          }}
+        />
+        <Grid
+          data={this.state.data}
+          columnNum={3}
+          hasLine={false}
+          onPress={this.handlePress}
+        />
+      </ScrollView>
+    )
+  }
+}
+
+export const title = 'Icon'
+export const description = 'Icon Example'
+```
+
+## API
+
+| Properties | Description         | Type                               | Default |
+| ---------- | ------------------- | ---------------------------------- | ------- |
+| name       | `OutlineGlyphMapType` | string                             |
+| size       | icon size           | 'xxs'/'xs'/'sm'/'md'/'lg' / number | `md`    |
+| color      | icon color          | Color                              | '#000'  |
+
+ - Tips1: Clicking the icon in the demo will automatically copy the code to the `<Icon />`.
+ - Tips2: By default, Icon uses the `outline` icon in `ant-design-icons`
+
+---
+
+## Input
+
+Source: https://rn.mobile.ant.design/components/input.md
+
+# Input
+
+Entering content through the keyboard is the most basic form field wrapper.
+
+### Rule
+- It is generally used in form pages to collect information, and provides two types of text boxes and text-area boxes.
+- The Input component is layout-independent. It can be used with the `List` component for quick layout; it also has built-in linkage interaction with the `Form` component.
+
+## Examples
+
+```tsx
+import { Input, List } from '@ant-design/react-native'
+import React from 'react'
+import { KeyboardAvoidingView, Platform, ScrollView } from 'react-native'
+
+export default function InputExample() {
+  const [value, setValue] = React.useState('')
+  return (
+    <KeyboardAvoidingView
+      behavior="padding"
+      keyboardVerticalOffset={Platform.OS === 'ios' ? 100 : undefined}>
+      <ScrollView keyboardShouldPersistTaps="handled">
+        <List renderHeader="基本用法">
+          <List.Item>
+            <Input placeholder="请输入内容" />
+          </List.Item>
+        </List>
+        <List renderHeader="受控模式">
+          <List.Item>
+            <Input
+              placeholder="请输入内容"
+              value={value}
+              onChangeText={setValue}
+            />
+          </List.Item>
+        </List>
+        <List renderHeader="带清除按钮">
+          <List.Item>
+            <Input allowClear placeholder="allowClear" />
+          </List.Item>
+        </List>
+        <List renderHeader="前缀和后缀">
+          <List.Item>
+            <Input prefix="前缀" suffix="后缀" placeholder="prefix / suffix" />
+          </List.Item>
+        </List>
+        <List renderHeader="带字数提示">
+          <List.Item>
+            <Input showCount placeholder="showCount" />
+          </List.Item>
+          <List.Item>
+            <Input
+              maxLength={5}
+              showCount={{
+                formatter: ({ count, maxLength }) => `${count}/${maxLength}`,
+              }}
+              placeholder="showCount.formatter"
+            />
+          </List.Item>
+        </List>
+        <List renderHeader="TextArea">
+          <List.Item>
+            <Input.TextArea
+              rows={4}
+              maxLength={100}
+              showCount
+              allowClear
+              placeholder="固定行数 row={4}"
+            />
+          </List.Item>
+        </List>
+        <List renderHeader="根据内容自动调整高度">
+          <List.Item>
+            <Input.TextArea autoSize placeholder="autoSize={true}" />
+          </List.Item>
+          <List.Item>
+            <Input.TextArea
+              autoSize={{ minRows: 2, maxRows: 6 }}
+              placeholder="autoSize={{ minRows: 2, maxRows: 6 }}"
+            />
+          </List.Item>
+        </List>
+      </ScrollView>
+    </KeyboardAvoidingView>
+  )
+}
+```
+
+## API
+
+### Input
+
+| Properties | Description | Type | Default |
+| --- | --- | --- | --- |
+| allowClear | If allow to remove input content with clear icon | `boolean` \| `{ clearIcon: ReactNode }` | - |
+| defaultValue | The initial input content | string | - |
+| disabled | Whether the input is disabled | boolean | false |
+| maxLength | The maximum number of characters in Input | number | - |
+| prefix | The prefix icon for the Input | ReactNode | - |
+| showCount | Whether to show character count | `boolean` \| `{ formatter: (info: { value: string, count: number, maxLength?: number }) => ReactNode }` | false |
+| status | Set validation status | 'error' \| 'warning' | - |
+| inputStyle | TextInput style | `StyleProp<TextStyle>` | - |
+| style  | Container style | `StyleProp<ViewStyle>` | - |
+| styles | Semantic DOM style | [InputStyle](#inputstyle-interface) | - |
+| suffix | The suffix icon for the Input | ReactNode | - |
+| type   | Declare the Input type, the same as the native [keyboardType](http://facebook.github.io/react-native/docs/textinput.html#keyboardtype) attribute | 'text' \| 'number' \| 'password' \| KeyboardTypeOptions | `text` |
+| value | The input content value | string | - |
+| onChange | Callback when user input, extra return `e.target.value` | `(e: NativeSyntheticEvent<TextInputChangeEventData>) => void;` | - |
+
+The rest of the props of Input are exactly the same as the react-native [TextInput](http://facebook.github.io/react-native/docs/textinput.html).
+
+### Input.TextArea
+
+Same as Input, and more:
+
+| Property | Description | Type | Default |
+| --- | --- | --- | --- |
+| autoSize | Height auto size feature, can be set to `true` \| `false` or an object `{ minRows: 2, maxRows: 6 }` | boolean \| object | false |
+| rows | sets the number of lines for a textarea.	Prioritize`autoSize`  | number | 2 |
+| styles | Semantic DOM style | [InputStyle](#inputstyle-interface) | - |
+
+### InputStyle interface
+
+```typescript
+interface InputStyle {
+  container: ViewStyle // Same as `style` prop
+  input: ViewStyle     // Same as `inputStyle` prop
+  clearIcon: ViewStyle
+  prefix: ViewStyle | TextStyle
+  showCount: TextStyle
+  suffix: ViewStyle | TextStyle
+  warning: TextStyle
+  error: TextStyle
+}
+```
+
+## Ref
+Ref to [TextInput](http://facebook.github.io/react-native/docs/textinput.html)
+
+## FAQ
+
+## When setting `allowClear` on the Android platform, why does it not work when I click clearIcon?
+
+In Android, clearIcon will only appear when you are in editing state (`focus`).
+<br/>When this component is wrapped by `ScrollView`, set the `keyboardShouldPersistTaps` property to `handled` or `always`, the icon will respond correctly to the click event
+
+```jsx
+<ScrollView keyboardShouldPersistTaps="always">
+...
+</ScrollView>
+```
+
+### Why Input in control can make `value` exceed `maxLength`?
+
+When in control, component should show as what it set to avoid submit value not align with store value in Form.
+
+---
+
+## InputItem
+
+Source: https://rn.mobile.ant.design/components/input-item.md
+
+# InputItem
+
+> This package has been deprecated in `5.2.1`, recommend [components/Input](/components/input)
+
+A foundational component for inputting text into the app via a keyboard.
+
+### Rule
+- Support text input via keyboard or clipboard.
+- The cursor can be moved horizontally.
+- Handle text with a specific format, eg: hide password.
+
+## Examples
+
+```tsx
+import { Button, InputItem, List } from '@ant-design/react-native'
+import React from 'react'
+import { ScrollView, Text } from 'react-native'
+
+declare var jest: any
+
+export default class BasicInputItemExample extends React.Component<any, any> {
+  inputRef: any
+
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      value: '',
+      value1: '',
+      value2: '',
+      value3: '',
+      value4: '',
+      labelnum1: '',
+      labelnum2: '',
+      labelnum3: '',
+      text: '',
+      bankCard: '',
+      phone: '',
+      password: '',
+      number: '',
+    }
+  }
+
+  render() {
+    return (
+      <ScrollView
+        style={{ flex: 1 }}
+        automaticallyAdjustContentInsets={false}
+        showsHorizontalScrollIndicator={false}
+        showsVerticalScrollIndicator={false}
+        keyboardShouldPersistTaps={'handled'}>
+        <List renderHeader={'基本'}>
+          <InputItem
+            clear
+            error
+            value={this.state.value}
+            onChange={(value: any) => {
+              this.setState({
+                value,
+              })
+            }}
+            extra="元"
+            placeholder="有标签">
+            输入框
+          </InputItem>
+          <InputItem
+            clear
+            value="不可编辑"
+            onChange={(value: any) => {
+              this.setState({
+                value,
+              })
+            }}
+            extra={<Text>元</Text>}
+            placeholder="不可编辑"
+            editable={false}>
+            输入框
+          </InputItem>
+          <InputItem
+            clear
+            value="disabled"
+            onChange={(value: any) => {
+              this.setState({
+                value,
+              })
+            }}
+            extra={<Text>元</Text>}
+            placeholder="disabled"
+            disabled>
+            输入框
+          </InputItem>
+          <InputItem
+            clear
+            value={this.state.value1}
+            onChange={(value: any) => {
+              this.setState({
+                value1: value,
+              })
+            }}
+            placeholder="无标签"
+          />
+          <InputItem
+            defaultValue="xx"
+            clear
+            placeholder="自动获取光标"
+            autoFocus={
+              /* TODO: https://github.com/facebook/jest/issues/3707  */ typeof jest ===
+              'undefined'
+            }>
+            标题
+          </InputItem>
+          <InputItem
+            clear
+            placeholder="点击下方按钮该输入框会获取光标"
+            ref={(el: any) => (this.inputRef = el)}>
+            标题
+          </InputItem>
+          <List.Item>
+            <Button
+              onPress={() => {
+                this.inputRef.focus()
+              }}
+              type="primary">
+              点击获取光标
+            </Button>
+          </List.Item>
+        </List>
+        <List renderHeader={'固定标签字数'}>
+          <InputItem
+            clear
+            value={this.state.labelnum1}
+            onChange={(value: any) => {
+              this.setState({
+                labelnum1: value,
+              })
+            }}
+            labelNumber={2}
+            placeholder="两个字标签">
+            姓名
+          </InputItem>
+          <InputItem
+            clear
+            value={this.state.labelnum2}
+            onChange={(value: any) => {
+              this.setState({
+                labelnum2: value,
+              })
+            }}
+            labelNumber={3}
+            placeholder="三个字标签">
+            校验码
+          </InputItem>
+          <InputItem
+            clear
+            value={this.state.labelnum3}
+            onChange={(value: any) => {
+              this.setState({
+                labelnum3: value,
+              })
+            }}
+            labelNumber={4}
+            placeholder="四个字标签(默认)">
+            四字标签
+          </InputItem>
+        </List>
+        <List renderHeader={'格式'}>
+          <InputItem
+            clear
+            error
+            value={this.state.text}
+            onChange={(value: any) => {
+              this.setState({
+                text: value,
+              })
+            }}
+            placeholder="text">
+            文本输入
+          </InputItem>
+          <InputItem
+            clear
+            type="bankCard"
+            value={this.state.bankcard}
+            onChange={(value: any) => {
+              this.setState({
+                bankcard: value,
+              })
+            }}
+            placeholder="bankCard">
+            银行卡
+          </InputItem>
+          <InputItem
+            clear
+            type="phone"
+            value={this.state.phone}
+            onChange={(value: any) => {
+              this.setState({
+                phone: value,
+              })
+            }}
+            placeholder="phone">
+            手机号
+          </InputItem>
+          <InputItem
+            clear
+            type="password"
+            value={this.state.password}
+            onChange={(value: any) => {
+              this.setState({
+                password: value,
+              })
+            }}
+            placeholder="password">
+            密码
+          </InputItem>
+          <InputItem
+            clear
+            type="number"
+            value={this.state.number}
+            onChange={(value: any) => {
+              this.setState({
+                number: value,
+              })
+            }}
+            placeholder="number">
+            数字
+          </InputItem>
+        </List>
+      </ScrollView>
+    )
+  }
+}
+```
+
+## API
+
+**`InputItem` must wrapped by a [List](https://mobile.ant.design/components/list)**
+
+Properties | Description | Type | Default
+-----------|------------|------|--------
+| type    | can be `bankCard`; `phone`(which the maxLength is 11 and setting will be ignored); `password`; `number`(in order to evoke the 'numeric keyboard with decimal', this type is not a native number, but `<input type="text" pattern="[0-9]*"/>`); `digit`(represent the native type number); As well as other standard html input type values. | String |  `text`  |
+| value | the value of input (see [react doc](https://facebook.github.io/react/docs/forms.html) for more information about controled component)  | String | |
+| defaultValue | provides an initial value that will change when the user starts typing. | String |  -  |
+| placeholder  | the string that will be rendered before text input has been entered. | String | ''  |
+| editable    | whether is editable        | bool |  true  |
+| disabled    | whether is disabled        | bool |  true  |
+| clear      |  whether to display clear(it takes effect only `editable` is `true` and `disabled` is `false` has been set) | bool | false  |
+| maxLength      |  limits the maximum number of characters that can be entered      | number |    |
+| onChange    | callback that is called when the text input's text changes | (val: string): void |  -  |
+| onBlur     | callback that is called when the text input is blurred | (val: string): void |   -  |
+| onFocus    | callback that is called when the text input is focused | (val: string): void |  -  |
+| error       | whether to display error       | bool |  false  |
+| onErrorClick   | callback that is called when the error icon is clicked  | (e: Object): void |   |
+| extra       | the right content of `InputItem`   | string or node |  ''  |
+| onExtraClick      | callback that is called when the extra content is clicked | (e: Object): void |  |
+| onVirtualKeyboardConfirm | callback that is called when "confirm" button of virtual keyboard is clicked | (val: string): void |  |
+| labelNumber  | number of label text, valid value is 2 to 7 | number | `5` |
+| locale   | 国际化,可覆盖全局`[LocaleProvider](https://mobile.ant.design/components/locale-provider)`的配置,  when`type`is`money`,can cunstom the keyboard confirm item's label | Object: { confirmLabel } |  无 |
+| last      |  If it is the last item, the `borderBottom` will be removed, the default has `borderBottom`   | bool | false  |
+
+> More available react-native `InputItem` API can be found at [react-native TextInput](http://facebook.github.io/react-native/docs/textinput.html)
+
+> Note: `InputItem` does not support negative number if `type` is text, you can use `type=text` to do that.
+
+## InputItem Instance methods
+
+Property | Description | Type | Default
+----|-----|------|------
+| focus    | Force focus back onto the input node  | (): void |  -  |
+
+---
+
+## List
+
+Source: https://rn.mobile.ant.design/components/list.md
+
+# List
+
+A single and continuous block content is vertically arranged to display current contents, status and available operations. eg:Contact List.
+
+In case you need an infinite scroll list - consider using [ListView](https://mobile.ant.design/components/list-view/) component.
+
+### Rule
+- Generally `List` consists of main infomation, main operations, secondary infomation and secondary operations.
+- The main infomation and main operations are placed on the left side of list, and secondary infomation and secondary operations are placed on the right side.
+
+## Examples
+
+```tsx
+import { List } from '@ant-design/react-native'
+import React from 'react'
+import { Image, ScrollView, View } from 'react-native'
+
+const Item = List.Item
+const Brief = Item.Brief
+
+export default class BasicListExample extends React.Component<any, any> {
+  render() {
+    return (
+      <ScrollView
+        style={{ flex: 1, backgroundColor: '#f5f5f9' }}
+        automaticallyAdjustContentInsets={false}
+        showsHorizontalScrollIndicator={false}
+        showsVerticalScrollIndicator={false}>
+        <List renderHeader={'basic'}>
+          <Item data-seed="logId">
+            标题文字点击无反馈,文字超长则隐藏,文字超长则隐藏
+          </Item>
+          <Item wrap>
+            文字超长折行文字超长折行文字超长折行文字超长折行文字超长折行
+          </Item>
+          <Item disabled extra="箭头向右" arrow="horizontal" onPress={() => {}}>
+            标题文字
+          </Item>
+          <Item extra="箭头向下" arrow="down" onPress={() => {}}>
+            标题文字
+          </Item>
+          <Item extra="箭头向上" arrow="up" onPress={() => {}}>
+            标题文字
+          </Item>
+          <Item extra="没有箭头" arrow="empty">
+            标题文字
+          </Item>
+          <Item
+            extra={
+              <View>
+                内容内容
+                <Brief style={{ textAlign: 'right' }}>辅助文字内容</Brief>
+              </View>
+            }
+            multipleLine>
+            垂直居中对齐
+          </Item>
+          <Item extra="内容内容" multipleLine>
+            垂直居中对齐<Brief>辅助文字内容</Brief>
+          </Item>
+          <Item
+            wrap
+            extra="文字超长折行文字超长折行文字超长折行文字超长折行文字超长折行文字超长折行文字超长折行"
+            multipleLine
+            align="top"
+            arrow="horizontal">
+            顶部对齐
+            <Brief>辅助文字内容辅助文字内容辅助文字内容辅助文字内容</Brief>
+            <Brief>辅助文字内容</Brief>
+          </Item>
+          <Item
+            extra={
+              <View>
+                内容内容
+                <Brief style={{ textAlign: 'right' }}>辅助文字内容</Brief>
+              </View>
+            }
+            multipleLine
+            align="bottom">
+            底部对齐
+          </Item>
+        </List>
+        <List renderHeader={'带缩略图'}>
+          <Item thumb="https://os.alipayobjects.com/rmsportal/mOoPurdIfmcuqtr.png">
+            thumb
+          </Item>
+          <Item
+            thumb="https://os.alipayobjects.com/rmsportal/mOoPurdIfmcuqtr.png"
+            arrow="horizontal">
+            thumb
+          </Item>
+          <Item
+            extra={
+              <Image
+                source={{
+                  uri: 'https://os.alipayobjects.com/rmsportal/mOoPurdIfmcuqtr.png',
+                }}
+                style={{ width: 29, height: 29 }}
+              />
+            }
+            arrow="horizontal">
+            extra为Image
+          </Item>
+        </List>
+      </ScrollView>
+    )
+  }
+}
+
+export const title = 'List'
+export const description = 'List Example'
+```
+
+## API
+
+### List
+
+Properties | Descrition | Type | Default | Version |
+-----------|------------|------|---------|---------|
+| renderHeader       | list heder  | (): void |    | |
+| renderFooter       | list footer  | (): void |    | |
+| styles | Semantic DOM style | [ListStyle](#liststyle-interface) | - | `5.2.1` |
+
+### List.Item
+
+Properties | Descrition | Type | Default | Version |
+-----------|------------|------|---------|---------|
+| thumb    | thumbnail on the left side of `List`(string type will be used to set img src)  | String \| React.Element | | |
+| extra    | extra content on the right side of `List` | String \| React.Element | | |
+| arrow    | arrow direction, options: `horizontal`,`up`,`down`, `empty`; `empty` option may hide the dom  | String | | |
+| align    | vertical alignment of child elements,options: `top`,`middle`,`bottom`  | String   | `middle` | | |
+| onPress  | callback is called when  list is clicked | Same as [TouchableHighlightProps['onPress']](#touchablehighlightprops) | | |
+| multipleLine | multiple line | Boolean  | `false`  | |
+| wrap     | Whether to wrap long texts, otherwise it will be hidden by default. | Boolean  | `false` | |
+| styles   | Semantic DOM style | [ListItemStyle](#listitemstyle-interface) | - | `5.2.1` |
+
+### TouchableHighlightProps
+
+New in `5.2.1`. In addition, all properties of [TouchableHighlightProps](https://reactnative.dev/docs/touchablehighlight) are supported; 
+when setting `onPress` props, it has a default touch style:
+<br/> `{ underlayColor:'#dddddd', activeOpacity: 0.5 }`
+
+### List.Item.Brief
+
+Brief infomation
+
+Properties | Descrition | Type | Default | Version |
+-----------|------------|------|---------|---------|
+| wrap     | Whether to wrap long texts, otherwise it will be hidden by default. | Boolean  | `false` | |
+| styles   | Semantic DOM style | [BriefStyle](#briefstyle-interface) | - | `5.2.1` |
+
+### ListStyle interface
+
+```typescript
+interface ListStyle {
+  List: ViewStyle
+  Header: TextStyle
+  Footer: TextStyle
+  Body: ViewStyle
+  BodyBottomLine: ViewStyle
+}
+```
+### ListItemStyle interface
+
+```typescript
+interface ListItemStyle {
+  underlayColor: ViewStyle // ListItem is a TouchableHighlight
+  
+  Item: ViewStyle // ListItem wrap
+  Line: ViewStyle // borderBottom
+
+  Thumb: ImageStyle
+  Content: TextStyle
+  Extra: TextStyle
+  
+  Arrow: TextStyle  // horizontal arrow
+  ArrowV: TextStyle // up/down arrow
+  multipleLine: ViewStyle
+  multipleThumb: ImageStyle
+}
+```
+### BriefStyle interface
+
+```typescript
+interface BriefStyle {
+  Brief: ViewStyle
+  BriefText: TextStyle
+}
+```
+
+---
+
+## ListView
+
+Source: https://rn.mobile.ant.design/components/list-view.md
+
+# ListView
+
+Documentation please checkout https://github.com/gameboyVito/react-native-ultimate-listview
+
+## Examples
+
+```tsx
+import { ListView } from '@ant-design/react-native'
+import React from 'react'
+import { Text, View } from 'react-native'
+
+export default class BasicListExample extends React.Component<any, any> {
+  state = {
+    layout: 'list',
+  }
+  sleep = (time: any) =>
+    new Promise((resolve) => setTimeout(() => resolve(''), time))
+  onFetch = async (
+    page = 1,
+    startFetch: (arg0: string[], arg1: number) => void,
+    abortFetch: () => void,
+  ) => {
+    try {
+      //This is required to determinate whether the first loading list is all loaded.
+      let pageLimit = 30
+      if (this.state.layout === 'grid') {
+        pageLimit = 60
+      }
+      const skip = (page - 1) * pageLimit
+
+      //Generate dummy data
+      let rowData = Array.from(
+        { length: pageLimit },
+        (_, index) => `item -> ${index + skip}`,
+      )
+
+      //Simulate the end of the list if there is no more data returned from the server
+      if (page === 3) {
+        rowData = []
+      }
+
+      //Simulate the network loading in ES7 syntax (async/await)
+      await this.sleep(2000)
+      startFetch(rowData, pageLimit)
+    } catch (err) {
+      abortFetch() //manually stop the refresh or pagination if it encounters network error
+    }
+  }
+
+  renderItem = (item: any) => {
+    return (
+      <View style={{ padding: 10 }}>
+        <Text>{item}</Text>
+      </View>
+    )
+  }
+
+  render() {
+    return (
+      <ListView
+        onFetch={this.onFetch}
+        keyExtractor={(item: any, index: any) =>
+          `${this.state.layout} - ${item} - ${index}`
+        }
+        renderItem={this.renderItem}
+        numColumns={this.state.layout === 'list' ? 1 : 3}
+      />
+    )
+  }
+}
+
+export const title = 'ListView'
+export const description = 'ListView Example'
+```
+
+---
+
+## Modal
+
+Source: https://rn.mobile.ant.design/components/modal.md
+
+# Modal
+
+Use to show important information for the system, and ask for user feedback. eg: When deleting an important content, pop up a Modal for secondary confirmation.
+
+### Rules
+- Use as few as possible. Modal will interrupt user operation, only use it at important situation.
+- Title should be concise, do not exceed 1 line; description should be concise and complete, generally no more than 2 lines.
+- Operation buttons are up to 3(vertical), generally 1-2(horizontal); [ActionSheet](/components/action-sheet) is preferred when there are more than 3 actions.
+- Generally put the most likely clicked button on the right side. In addition, the cancel button should always be on the left.
+
+## Examples
+
+```tsx
+import {
+  Button,
+  List,
+  Modal,
+  Provider,
+  Switch,
+  Toast,
+  WhiteSpace,
+  WingBlank,
+} from '@ant-design/react-native'
+import React from 'react'
+import { ScrollView, Text, View } from 'react-native'
+
+export default class BasicModalExample extends React.Component<any, any> {
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      visible: false,
+      visible1: false,
+      visible2: false,
+      modalType: 'portal',
+    }
+  }
+
+  onClose = () => {
+    this.setState({
+      visible: false,
+    })
+  }
+
+  onClose1 = () => {
+    this.setState({
+      visible1: false,
+    })
+  }
+
+  onClose2 = () => {
+    this.setState({
+      visible2: false,
+    })
+  }
+
+  onButtonClick = () => {
+    Modal.alert('Title', 'alert content', [
+      { text: 'Cancel', onPress: () => console.log('cancel'), style: 'cancel' },
+      { text: 'OK', onPress: () => console.log('ok') },
+    ])
+  }
+
+  onButtonClickPromise = () => {
+    Modal.alert('Title', 'promise button', [
+      {
+        text: 'Cancel',
+        onPress: () => {
+          Toast.info('onPress promise resolve', 1)
+          return new Promise((resolve) => {
+            setTimeout(resolve, 1000)
+          })
+        },
+        style: 'cancel',
+      },
+      {
+        text: 'Hold on',
+        onPress: () => {
+          Toast.info('onPress promise reject', 1)
+          return new Promise((_, reject) => {
+            setTimeout(reject, 1000)
+          })
+        },
+      },
+    ])
+  }
+
+  onButtonClick2 = () => {
+    Modal.operation([
+      { text: '标为未读', onPress: () => console.log('标为未读被点击了') },
+      { text: '置顶聊天', onPress: () => console.log('置顶聊天被点击了') },
+    ])
+  }
+
+  onButtonClick3 = () => {
+    Modal.prompt(
+      'Login',
+      'Pleas input login information',
+      (login: any, password: any) =>
+        console.log(`login: ${login}, password: ${password}`),
+      'login-password',
+      '',
+      ['Please input name', 'Please input password'],
+    )
+  }
+
+  onButtonClick4 = () => {
+    Modal.prompt(
+      'Input password',
+      'password message',
+      (password: any) => console.log(`password: ${password}`),
+      'secure-text',
+      'defaultValue',
+    )
+  }
+
+  onButtonClick5 = () => {
+    Modal.prompt(
+      'Name',
+      'name message',
+      (password: any) => console.log(`password: ${password}`),
+      'default',
+      '',
+      ['please input name'],
+    )
+  }
+
+  onButtonClick6 = () => {
+    Modal.operation(
+      [
+        { text: '标为未读', onPress: () => console.log('标为未读被点击了') },
+        { text: '置顶聊天', onPress: () => console.log('置顶聊天被点击了') },
+      ],
+      () => {
+        console.log('返回键点击')
+        return false
+      },
+    )
+  }
+  render() {
+    const footerButtons = [
+      { text: 'Cancel', onPress: () => console.log('cancel') },
+      { text: 'Ok', onPress: () => console.log('ok') },
+    ]
+    return (
+      <Provider>
+        <ScrollView style={{ marginTop: 20 }}>
+          <List>
+            <List.Item
+              extra={
+                <Switch
+                  style={{ width: 70 }}
+                  checked={this.state.modalType === 'modal'}
+                  onChange={(val) => {
+                    this.setState({ modalType: val ? 'modal' : 'portal' })
+                  }}
+                  checkedChildren="modal"
+                  unCheckedChildren="portal"
+                />
+              }>
+              切换modalType
+              <List.Item.Brief>
+                `modalType='modal'`时将调用原生Modal{' '}
+              </List.Item.Brief>
+            </List.Item>
+          </List>
+          <WingBlank>
+            <Button onPress={() => this.setState({ visible: true })}>
+              showModal
+            </Button>
+            <WhiteSpace />
+            <Button onPress={() => this.setState({ visible1: true })}>
+              transparent:false
+            </Button>
+            <WhiteSpace />
+            <Button onPress={() => this.setState({ visible2: true })}>
+              popup
+            </Button>
+            <WhiteSpace />
+            <Button onPress={this.onButtonClick}>Modal.alert</Button>
+            <WhiteSpace />
+            <Button onPress={this.onButtonClickPromise}>
+              Modal.alert (promise)
+            </Button>
+            <WhiteSpace />
+            <Button onPress={this.onButtonClick2}>Modal.opertation</Button>
+            <WhiteSpace />
+            <Button onPress={this.onButtonClick6}>
+              Modal.opertation (onBackHandler)
+            </Button>
+            <WhiteSpace />
+            <Button onPress={this.onButtonClick5}>
+              Modal.prompt (default)
+            </Button>
+            <WhiteSpace />
+            <Button onPress={this.onButtonClick3}>
+              Modal.prompt (login-password)
+            </Button>
+            <WhiteSpace />
+            <Button onPress={this.onButtonClick4}>
+              Modal.prompt (secure-text)
+            </Button>
+          </WingBlank>
+          <Modal
+            title="Title"
+            transparent
+            modalType={this.state.modalType}
+            onClose={this.onClose}
+            maskClosable
+            visible={this.state.visible}
+            closable
+            footer={footerButtons}>
+            <View style={{ paddingVertical: 20 }}>
+              <Text style={{ textAlign: 'center' }}>Content...</Text>
+              <Text style={{ textAlign: 'center' }}>Content...</Text>
+            </View>
+            <Button type="primary" onPress={this.onClose}>
+              close modal
+            </Button>
+          </Modal>
+          <Modal
+            transparent={false}
+            modalType={this.state.modalType}
+            visible={this.state.visible1}
+            animationType="slide-up"
+            onClose={this.onClose1}>
+            <View style={{ paddingVertical: 220 }}>
+              <Text style={{ textAlign: 'center' }}>Content...</Text>
+              <Text style={{ textAlign: 'center' }}>Content...</Text>
+            </View>
+            <Button
+              type="primary"
+              style={{ marginBottom: 10 }}
+              onPress={() => Toast.info('Hello Toast in Modal now works')}>
+              {this.state.modalType === 'portal'
+                ? 'Hello Toast in Modal now works'
+                : "Hello Toast not works when modalType='portal'"}
+            </Button>
+            <Button type="primary" onPress={this.onClose1}>
+              close modal
+            </Button>
+          </Modal>
+          <Modal
+            popup
+            modalType={this.state.modalType}
+            visible={this.state.visible2}
+            animationType="slide-up"
+            onClose={this.onClose2}>
+            <View style={{ paddingVertical: 20, paddingHorizontal: 20 }}>
+              <Text style={{ textAlign: 'center' }}>Content...</Text>
+              <Text style={{ textAlign: 'center' }}>Content...</Text>
+            </View>
+            <Button type="primary" onPress={this.onClose2}>
+              close modal
+            </Button>
+          </Modal>
+        </ScrollView>
+      </Provider>
+    )
+  }
+}
+```
+
+## API
+
+### Modal
+
+Properties | Descrition | Type | Default | Version
+-----------|------------|------|---------|---------|
+| visible | Determine whether a modal dialog is visible or not | Boolean | false | |
+| closable | Determine whether a close (x) button is visible or not | Boolean | false | |
+| maskClosable | Determine whether to close the modal dialog when clicked mask of it | Boolean | true | |
+| onClose | Callback for clicking close icon x or mask | (): void | - | |
+| transparent | transparent mode or full screen mode | Boolean | false | |
+| popup | popup mode | Boolean | false | |
+| animationDuration | Animation duration, in ms | Number | 300 | `5.3.0` |
+| animationType | Options: 'fade' / 'slide' | String |  |fade |
+| modalType | The type of the popup. <br/>When it is `'portal'`, it is inserted from the `<Provider />` root node (default). <br/>When it is `'modal'`, it is the same as [`react-native/Modal`](https://reactnative.dev/docs/modal) (used to get the current context). <br/>When it is `'view'`, it is the same as `react-native/View` (used to nest popups in popups). | `'portal'`\| `'modal'` \| `'view'` | `'portal'` | `5.3.0` |
+| title | title | React.Element | - | |
+| footer | footer content | Array [{text, onPress}] | [] | |
+| onRequestClose | The `onRequestClose` callback is called when the user taps the hardware back button on Android or the menu button on Apple TV. Returns `true` to prevent `BackHandler` events when modal is open.| (): boolean | false | |
+| style | style same as `styles.innerContainer` | `ViewStyle` | - | |
+| styles | Semantic DOM style | [ModalStyle](#modalstyle-interface) | - | |
+
+### ModalStyle interface
+
+```typescript
+interface ModalStyle {
+  container: ViewStyle      // Set `z-index`
+  wrap: ViewStyle           // Set modal flex layout: `{justifyContent: 'center',alignItems: 'center'}`
+  innerContainer: ViewStyle // modal content view, default: `{ widh:286 }`
+  
+  // modal content fields
+  footer: ViewStyle
+  header: TextStyle
+  body: ViewStyle
+  closeWrap: ViewStyle
+  close: TextStyle
+  buttonGroupH: ViewStyle
+  buttonGroupV: ViewStyle
+  buttonWrapH: ViewStyle
+  buttonWrapV: ViewStyle
+  buttonText: TextStyle
+
+  // popup
+  popupContainer: ViewStyle
+  popupSlideUp: ViewStyle
+  popupSlideDown: ViewStyle
+  // operation
+  operationContainer: ViewStyle
+  operationBody: ViewStyle
+  buttonTextOperation: TextStyle
+}
+```
+
+### Modal.useModal()
+
+When you need using Context, you can use `contextHolder` which created by `Modal.useModal` to insert into children. Modal created by hooks will get all the context where `contextHolder` are. Created `modal` has the same creating function with [`Modal.method`](#static-method)(Static method).
+
+```jsx
+const [modal, contextHolder] = Modal.useModal();
+
+React.useEffect(() => {
+  modal.alert(
+    // ...
+  );
+}, []);
+
+return <View>{contextHolder}</View>;
+```
+
+## Static method
+
+### Modal.alert(title, message, actions?)
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| title | title | String or React.Element | -  |
+| message | message  | String or React.Element  | -  |
+| actions | button group, [{text, onPress, style}]  | Array | -  |
+| onBackHandler | Callback of the back key (not required), returns true to close modal, false to prevent modal from closing| (): boolean | 无 |
+
+### Modal.prompt(title, message, callbackOrActions, type?, defaultValue?)
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| title | title | String or React.Element | -  |
+| message | message  | String or React.Element  | -  |
+| callbackOrActions  | button group [{text, onPress}] or callback | Array or Function | -  |
+| type  | prompt style | String (`default`, `secure-text`, `login-password`)|  `default`  |
+| defaultValue  | Default(input whick type is password is not supported) | String | -  |
+| placeholders  | ['', '']  | String[] | -  |
+| onBackHandler | Callback of the back key (not required), returns true to close modal, false to prevent modal from closing| (): boolean | 无 |
+
+### Modal.operation(actions?, onBackHandler?)
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| actions | button group, [{text, onPress, style}]  | Array | -  |
+| onBackHandler | Callback of the back key (not required), returns true to close modal, false to prevent modal from closing| (): boolean | 无 |
+
+## FAQ
+
+### How to close the static Modal.method()?
+
+You need to use `Portal.remove(key)` method; Take `Modal.alert` as an example
+```jsx
+import { Modal, Portal } from '@ant-design/react-native'
+import { useRef } from 'react'
+
+function App() {
+  const key = useRef()
+
+  const onOpen = () => {
+    key.current = Modal.alert({})
+  }
+
+  const onClose = () => {
+    // close the Modal.alert
+    Portal.remove(key)
+  }
+}
+```
+When using `Modal.useModal`, use the `modal.remove(key)` method:
+```jsx
+import { Modal, Portal } from '@ant-design/react-native'
+import { useRef } from 'react'
+
+function App() {
+  const [modal, contextHolder] = Modal.useModal();
+   const key = useRef()
+
+  const onOpen = () => {
+    key.current = modal.alert({})
+  }
+
+  const onClose = () => {
+    // close the modal.alert
+    modal.remove(key)
+  }
+
+  return (
+    <>
+     ...
+     {contextHolder}
+    </>
+  )
+}
+```
+
+### Why I can not access context,redux,useRouter in `<Modal />` or `Modal.xxx`?
+
+Rendering `<Modal>` or calling Modal methods directly is dynamically inserted into the `<Provider>` root node through `Portal.add` by default. At this time, its context is different from the context of the current code, so the context information cannot be obtained.
+
+When you need context info, <br/>
+**1.** you can use `Modal.useModal` to get `modal` instance and `contextHolder` node. And put it in your children:
+```tsx
+const [modal, contextHolder] = Modal.useModal();
+
+// then call modal.confirm instead of Modal.confirm
+
+return (
+  <Context1.Provider value="Ant">
+    {/* contextHolder is in Context1, which means modal will get context of Context1 */}
+    {contextHolder}
+    <Context2.Provider value="Design">
+      {/* contextHolder is out of Context2, which means modal will not get context of Context2 */}
+    </Context2.Provider>
+  </Context1.Provider>
+);
+```
+
+**Note**: You must insert `contextHolder` into your children with hooks. You can use origin method if you do not need context connection.
+
+**2.** When using `<Modal />`, by setting `modalType='modal'`, the **native Modal component** will be used internally to maintain the context:
+```tsx
+<Modal modelType="modal" ...>
+ ...
+</Modal>
+```
+
+---
+
+## NoticeBar
+
+Source: https://rn.mobile.ant.design/components/notice-bar.md
+
+# NoticeBar
+
+Component to display a system message, event notice and etc. Which is under the navigation bar.
+
+### Rules
+
+- Be used to attract user's attension, the importance level is lower than `Modal` and higher than `Toast`.
+- It can also achieve a lightweight marquee effect.
+
+## Examples
+
+```tsx
+import {
+  Icon,
+  List,
+  NoticeBar,
+  Picker,
+  Provider,
+  Slider,
+  Switch,
+  WhiteSpace,
+} from '@ant-design/react-native'
+import React, { useState } from 'react'
+import { ScrollView, Text } from 'react-native'
+
+export default function NoticeBarExample() {
+  return (
+    <Provider>
+      <ScrollView style={{ marginBottom: 40 }}>
+        {true && (
+          <>
+            <List renderHeader={'自定义颜色'}>
+              <WhiteSpace />
+              <NoticeBar>默认</NoticeBar>
+              <WhiteSpace />
+              <NoticeBar
+                styles={{
+                  font: { color: '#ffffff' },
+                  background: { backgroundColor: '#f4333c' },
+                }}>
+                错误
+              </NoticeBar>
+              <WhiteSpace />
+              <NoticeBar
+                styles={{
+                  font: { color: '#108ee9' },
+                  background: { backgroundColor: '#d0e4ff' },
+                }}>
+                信息
+              </NoticeBar>
+              <WhiteSpace />
+            </List>
+            <List renderHeader={'可关闭'}>
+              <NoticeBar mode="closable">这条通知可以关闭</NoticeBar>
+            </List>
+            <List renderHeader={'超长滚动'}>
+              <WhiteSpace />
+              <NoticeBar marqueeProps={{ loop: true }}>
+                Notice: I can be a React component, multiple React components,
+                or just some text.
+              </NoticeBar>
+              <WhiteSpace />
+              <NoticeBar
+                marqueeProps={{
+                  loop: true,
+                  autoFill: true,
+                  trailing: 0,
+                  spacing: 10,
+                }}>
+                autoFill&spacing
+              </NoticeBar>
+            </List>
+            <List renderHeader={'自定义'}>
+              <WhiteSpace />
+              <NoticeBar
+                mode="link"
+                onPress={() => {
+                  console.log('onPress')
+                }}>
+                mode="link"
+              </NoticeBar>
+              <WhiteSpace />
+              <NoticeBar
+                mode="closable"
+                icon={<Icon name="compass" style={{ color: '#f4333c' }} />}
+                action={
+                  <Icon name="close-circle" style={{ color: '#f4333c' }} />
+                }>
+                自定义图标
+              </NoticeBar>
+              <WhiteSpace />
+              <NoticeBar
+                marqueeProps={{ loop: true, autoFill: true }}
+                mode="closable"
+                action={<Text style={{ color: '#a1a1a1' }}>不再提示</Text>}>
+                自定义右侧功能区 Closable demo for `action`.
+              </NoticeBar>
+              <WhiteSpace />
+            </List>
+          </>
+        )}
+        <List renderHeader={'方向/播放/暂停控制'}>
+          <ControlDemo />
+        </List>
+      </ScrollView>
+    </Provider>
+  )
+}
+
+function ControlDemo() {
+  const [play, setPlay] = useState(true)
+  const [autoFill, setAutoFill] = useState(false)
+  const [direction, setDirection] = useState<'left' | 'right' | 'up' | 'down'>(
+    'left',
+  )
+  const [fps, setFps] = useState(40)
+  return (
+    <>
+      <WhiteSpace />
+      <NoticeBar
+        marqueeProps={{
+          play,
+          autoFill,
+          direction,
+          fps,
+          loop: 0,
+        }}>
+        Notice: I can be a React component, multiple React components, or just
+        some text.
+      </NoticeBar>
+      <WhiteSpace />
+      <List.Item extra={<Switch checked={play} onChange={setPlay} />}>
+        Play
+      </List.Item>
+      <List.Item extra={<Switch checked={autoFill} onChange={setAutoFill} />}>
+        AutoFill
+      </List.Item>
+      <Picker
+        data={[
+          { label: 'Left', value: 'left' },
+          { label: 'Right', value: 'right' },
+          { label: 'Up', value: 'up' },
+          { label: 'Down', value: 'down' },
+        ]}
+        value={[direction]}
+        onChange={(val) => setDirection(val[0] as any)}>
+        <List.Item arrow="horizontal">Direction</List.Item>
+      </Picker>
+      <List.Item>
+        <List.Item.Brief>速度fps: {fps}</List.Item.Brief>
+        <Slider
+          onAfterChange={setFps}
+          ticks
+          step={10}
+          defaultValue={fps}
+          popover
+        />
+      </List.Item>
+    </>
+  )
+}
+```
+
+## API
+
+| Properties | Descrition | Type | Default | Version |
+|------------|------------|------|---------|---------|
+| action | text which is used to replace right icon | `ReactNode` | - | |
+| children | The children rendered inside the marquee | `ReactNode` | - | |
+| icon | Set the icon at the start position | `ReactNode` | `<Icon name="sound" color={theme.brand_error} />`| |
+| marqueeProps | marquee params | [MarqueeProps](#marquee-props) | `{loop: false, leading: 500, trailing: 800, fps: 40}`  | |
+| mode | Type of NoticeBar. Invalid when `action` is present | `closable`\|`link` | - | |
+| onClose | A callback function, can be executed when you click the `action` icon. Only valid in `mode="closable"` | `() => void` | - | `5.2.1` |
+| onPress | A callback function, can be executed when you click on the operating area | `() => void` | - | |
+| style  | Container style | `StyleProp<ViewStyle>` | - | |
+| styles | Semantic DOM style | [NoticeBarStyle](#noticebarstyle-interface) | - | |
+
+- Theme color [theme.brand_error](https://github.com/ant-design/ant-design-mobile-rn/blob/master/components/style/themes/default.tsx#L35) = `#f4333c`
+
+### Marquee props
+
+| Properties | Descrition | Type | Default | Version |
+|------------|------------|------|---------|---------|
+| autoFill | Whether to automatically fill blank space in the marquee with copies of the children or not | `Boolean` | false | `5.2.1` |
+| direction | The direction the marquee slides | `'left'` \| `'right'` \| `'up'` \| `'down'` | `'left'` | `5.2.2` add `'up'`&`'down'`  |
+| fps | Speed calculated as pixels/second | `Number` |  40  | |
+| leading | Duration to delay the animation after first render, in millisecond | `Number` | 500 | |
+| loop | The number of times the marquee should loop, `true/0` is equivalent to infinite |  `Boolean` \| `Number` | false | |
+| onFinish | A callback for when the marquee finishes scrolling and stops. Only calls if loop is non-zero or false. | `() => void` | - | `5.2.1` |
+| onCycleComplete | A callback for when the marquee finishes a loop. Does not call if maximum loops are reached (use onFinish instead). | `() => void` | - | `5.2.1` |
+| play | Whether to play or pause the marquee | `Boolean` | true | `5.2.1` |
+| spacing | Spacing between repeting elements, valid when `autoFill={true}` | `Number` | 0 | `5.2.1` |
+| style | The marquee Text style | `TextStyle` | - | |
+| trailing | Duration to delay the animation after previous loop, valid when `autoFill={false}`, in millisecond | `Number` | 800 | |
+| wrapStyle | Marquee wrap view style | `ViewStyle` | - | |
+
+> Design Reference: [https://github.com/justin-chu/react-fast-marquee](https://github.com/justin-chu/react-fast-marquee), can be used as a marquee component alone
+
+```jsx
+// New in 5.2.2
+import { Marquee } from '@ant-design/react-native'
+```
+
+## NoticeBarStyle interface
+
+`5.2.1`refactored the styles
+
+```ts
+interface NoticeBarStyle {
+    container: ViewStyle,   // Outermost container style, default: {minHeight: 36(theme.notice_bar_height)}
+    font: TextStyle,        // Font style, default: {color: #f4333c(theme.brand_error)}
+    background: ViewStyle,  // Background color, default: {backgroundColor: #fffada}
+
+    marquee: TextStyle,     // marquee font style
+
+    iconWrap: ViewStyle,    // left icon wrap
+    actionWrap: ViewStyle,  // right action wrap
+    close: ViewStyle,       // mode="closeable" icon
+    link: ViewStyle         // mode="link" icon
+}
+```
+
+## Ref
+
+New in `5.2.1`. Ref to MarqueeActions.
+
+| Properties | Descrition | Type|
+|-----|------|------|
+| play | Start the marquee text rolling | `() => void` |
+| pause | Pause the marquee text | `() => void` |
+| stop | Return the marquee text to the original position | `() => void` |
+
+---
+
+## Pagination
+
+Source: https://rn.mobile.ant.design/components/pagination.md
+
+# Pagination
+
+A long list can be divided into several pages by `Pagination`, and only one page will be loaded at a time.
+
+### Rule
+
+- When it will take a long time to load/render all items.
+
+## Examples
+
+```tsx
+import { Pagination, WhiteSpace, WingBlank } from '@ant-design/react-native'
+import React from 'react'
+
+const locale = {
+  prevText: '上一步',
+  nextText: '下一步',
+}
+
+export default class BasicPaginationExample extends React.Component<any, any> {
+  render() {
+    return (
+      <WingBlank size="lg">
+        <WhiteSpace size="lg" />
+        <Pagination total={5} current={1} locale={locale} />
+
+        <WhiteSpace size="lg" />
+        <Pagination simple total={5} current={1} locale={locale} />
+
+        <WhiteSpace size="lg" />
+        <Pagination mode="number" total={5} current={3} />
+
+        <WhiteSpace size="lg" />
+        <Pagination mode="pointer" total={5} current={2} />
+      </WingBlank>
+    )
+  }
+}
+```
+
+## API
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+|  mode  | the mode of `Pagination` which can be one of `button`,`number`,`pointer` | string | `button`  |
+|  current  | current page index | number  |  1 |
+|  total  | total number of data | number  |  0  |
+|  simple  | whether to hide number | boolean | false  |
+|  disabled  | whether is disabled | boolean | false  |
+| locale |  [i18n](/components/locale-provider/) setting, you can override the configuration of the global `LocaleProvider | Object:{prevText, nextText} |  |
+|  onChange | invoked with the new index when the value changes. | (index: Number): void |  |
+
+---
+
+## Picker
+
+Source: https://rn.mobile.ant.design/components/picker.md
+
+# Picker
+
+Choose from a set of data, e.g. Country choice.
+
+### Rules
+- Try to use Picker to help users complete the input, to avoid the user through the keyboard directly input.
+- DatePicker is Picker's specific pattern.
+
+## Examples
+
+```tsx
+import {
+  Button,
+  List,
+  Picker,
+  PickerValue,
+  PickerValueExtend,
+  Provider,
+} from '@ant-design/react-native'
+import { district } from 'antd-mobile-demo-data'
+import React, { useState } from 'react'
+import { Text, TouchableOpacity, View } from 'react-native'
+
+const CustomChildren = (props: any) => (
+  <TouchableOpacity onPress={props.onPress}>
+    <View
+      style={{
+        height: 36,
+        paddingLeft: 15,
+        flexDirection: 'row',
+        alignItems: 'center',
+      }}>
+      <Text style={{ flex: 1 }}>{props.children}</Text>
+      <Text style={{ textAlign: 'right', color: '#888', marginRight: 15 }}>
+        {props.extra}
+      </Text>
+    </View>
+  </TouchableOpacity>
+)
+
+// visible用法
+function BasicDemo() {
+  const [visible, setVisible] = useState(false)
+  const [value, setValue] = useState<any[]>([])
+  const [extend, setExtend] = useState<any>()
+  return (
+    <View
+      style={{
+        flexDirection: 'row',
+        alignItems: 'center',
+        paddingVertical: 5,
+        paddingLeft: 16,
+      }}>
+      <Button
+        type="primary"
+        onPress={() => {
+          setVisible(true)
+        }}>
+        选择
+      </Button>
+
+      {/* extend渲染所选值 */}
+      <Text>
+        {extend?.items?.map((item: any) => item.label).join(',') || ' 未选择'}
+      </Text>
+
+      {/* visible控制显示/隐藏 */}
+      <Picker
+        data={district}
+        cols={3}
+        onChange={setValue}
+        onVisibleChange={(v) => {
+          setVisible(v)
+        }}
+        visible={visible}
+        value={value}
+        onOk={(v: PickerValue[], ext: PickerValueExtend) => {
+          setValue(v)
+          setExtend(ext)
+        }}
+      />
+    </View>
+  )
+}
+
+export default class PopupExample extends React.Component<any, any> {
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      data: [],
+      value: [],
+      pickerValue: [],
+    }
+  }
+  onPress = () => {
+    setTimeout(() => {
+      this.setState({
+        data: district,
+      })
+    }, 500)
+  }
+  onChange = (value: any) => {
+    this.setState({ value })
+  }
+
+  render() {
+    return (
+      <Provider>
+        <List renderHeader={'List Children'}>
+          <Picker
+            data={district}
+            cols={3}
+            value={this.state.value}
+            onChange={this.onChange}>
+            <List.Item arrow="horizontal">省市选择</List.Item>
+          </Picker>
+          <Picker
+            data={this.state.data}
+            cols={2}
+            value={this.state.value}
+            onChange={this.onChange}>
+            <List.Item arrow="horizontal" onPress={this.onPress}>
+              省市选择(异步加载)
+            </List.Item>
+          </Picker>
+          <Picker
+            title="选择地区"
+            data={district}
+            cols={2}
+            value={this.state.pickerValue}
+            onChange={(v: any) => this.setState({ pickerValue: v })}
+            onOk={(v: any) => this.setState({ pickerValue: v })}>
+            <CustomChildren>Customized children</CustomChildren>
+          </Picker>
+        </List>
+        <List renderHeader={'visible 控制显示/隐藏'}>
+          <BasicDemo />
+        </List>
+      </Provider>
+    )
+  }
+}
+```
+
+## API
+
+### Props
+
+```ts
+type PickerColumnItem = {
+  label: string | ReactNode
+  value: string | number
+  key?: string | number
+  children?: PickerColumnItem[]
+}
+
+type PickerColumn = PickerColumnItem[]
+
+type PickerValue = string | number
+
+type PickerValueExtend = {
+  columns: PickerColumn[]
+  items: (PickerColumnItem | undefined)[]
+}
+```
+
+Properties | Descrition | Type | Default | Version
+-----------|------------|------|--------|--------
+| data     | data source     | `PickerColumn` / `PickerColumn[]` | -   |  |
+| value    | Selected options  | `PickerValue[]`  | -   |  |
+| defaultValue  | Default selected options  | `PickerValue[]`  | -   |  |
+| cascade  | whether cascade <br/>child cascade get from `data[].children`   | Boolean | `true` |  |
+| cols     | col numbers    | Number | `3` |  |
+| onChange | selected callback function, can use [Form](/components/form) | `(value: PickerValue[], extend: PickerValueExtend) => void`      | -   |  |
+| onPickerChange | trigger on each column of selected data is changed   | `(value: PickerValue[], index: number) => void` | - |  |
+| onVisibleChange  | visible state change callback    | `(visible: bool): void` |  -   |  |
+| renderLabel | 	The function to custom rendering the label shown on a column  |   `(item: PickerColumnItem, itemIndex: number, colIndex: number) => ReactNode`   | `(item) => item.label`  | `5.2.2` |
+| locale | international, can override the configuration of the global [Provider](/components/provider)'s `locale` | Object: Object: {okText, dismissText, extra} | - |  |
+| title  | title | ReactNode | - |  |
+| okText | ok text | String |  `确定`  |  |
+| dismissText  | dismiss text | String |  `取消`  |  |
+| onOk   | handler called when click ok  | `(value: PickerValue[], extend: PickerValueExtend) => void`  |  - |  |
+| onDismiss  | handler called when click cancel | (): void  |  -  |  |
+| okButtonProps  | The ok button props | [TouchableHighlightProps](https://reactnative.dev/docs/touchablehighlight)  |  `{ activeOpacity:1, underlayColor:'#ddd' }`  | `5.1.3` |
+| dismissButtonProps  | The dismiss button props | [TouchableHighlightProps](https://reactnative.dev/docs/touchablehighlight)  |  `{ activeOpacity:1, underlayColor:'#ddd' }`  | `5.1.3` |
+| visible  | Whether to show or hide the Picker  | Boolean | -  |  |
+| loading  | Should the Picker displays as loading state	  | Boolean | -  | `5.1.0` |
+| loadingContent  | The loading content displayed in loading state	  | ReactNode | -  | `5.1.0` |
+| indicatorStyle  | style of default Indicator  | Object | -  |  |
+
+### Custom Style
+
+Properties | Descrition | Type | Default | Version
+-----------|------------|------|---------|---------
+| style    | style   | `StyleProp<ViewStyle>` | -   | |
+| styles   | inner component styles  | [PickerStyle](#pickerstyle-interface) & [PickerViewStyle](/components/picker-view/#pickerviewstyle-interface) | -   | `5.1.0`refactored |
+| itemStyle| style to apply to each of the item labels   | `StyleProp<TextStyle>` | -   | |
+| itemHeight | Height of option item, calculated by `numberOfLines` when without value; `itemStyle` was not allowed to set `{height}`  |   Number   | -  | |
+| numberOfLines | Used to truncate the text with an ellipsis after computing the text layout, including line wrapping, such that the total number of lines does not exceed this number  |   Number   | `1`  | |
+
+### PickerStyle interface
+```jsx
+interface PickerStyle extends Partial<PickerViewStyle> {
+  // modal style
+  modal: ViewStyle
+  container: ViewStyle
+  header: ViewStyle
+  headerItem: ViewStyle
+  actionText: TextStyle
+  title: TextStyle
+  okText: TextStyle
+  dismissText: TextStyle
+}
+```
+
+#### Mask View
+
+New in `5.1.0`. Support custom mask style, such as using the gradient component `<LinearGradient />`. Default is white translucency.
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| renderMaskTop | The function to custom rendering the mask top half view | `()=> ReactNode` | `<View style={{ flex: 1, opacity:0.8, backgroundColor: theme.fill_base }} />` |
+| renderMaskBottom | The function to custom rendering the mask bottom half view | `()=> ReactNode` | `<View style={{ flex: 1, opacity:0.8, backgroundColor: theme.fill_base }} />` |
+
+- Theme color [theme.fill_base](https://github.com/ant-design/ant-design-mobile-rn/blob/master/components/style/themes/default.tsx#L24) = `#ffffff`
+
+### Custom Children
+Picker's children is best to [List.Item](/components/list/#List.Item), if not, need to be a custom component (the `onPress`/`extra` props need to be handled in the component):
+
+Properties | Descrition | Type | Default | Version |
+-----------|------------|------|--------|--------
+| children| usually `List.Item` | `ReactNode`/`({disabled, extra, value, toggle})=>ReactNode` | -  | `5.2.1` add function as Children |
+| extra   | Picker's children `extra` prop, display when no `value`(Similar to a placeholder) | String |  `please select`  |  |
+| format  | a function that formats the selected value	  | (labels: string[]): any | `(labels) => { return labels.join(','); } ` |  |
+| triggerType  | Press event name | String | `onPress` |  |
+| disabled  | set disabled	 | Boolean | `false` |  |
+
+### PickerActions
+Properties | Descrition | Type
+-----------|------------|-----
+| close    | Close Picker | `() => void` |
+| open     | Open Picker  | `() => void` |
+| toggle   | Toggle the visible state of Picker | `() => void` |
+
+### Ref
+Same as PickerActions
+
+
+## FAQ
+
+### Why is the Picker hidden when it popup in the native Modal?
+
+By default, `<Picker />` is dynamically inserted into the `<Provider>` root node via `Portal.add`, and the zIndex level of the native Modal is above everything, including its root node.
+
+So if you must use the `<Picker />` component in the native Modal, you can set `modalType='modal'` to keep it at the same level as the native Modal.
+
+```tsx
+import {Modal} from 'react-native';
+import {Picker} from '@ant-design/react-native';
+
+<Modal>
+  ...
+  
+  <Picker
+    modalType="modal" // add here
+    visible={visible}
+    data={data}>
+    <List.Item arrow="horizontal">省市选择</List.Item>
+  </Picker>
+
+</Modal>
+```
+
+---
+
+## PickerView
+
+Source: https://rn.mobile.ant.design/components/picker-view.md
+
+# PickerView
+
+PickerView's functions like Picker, but it is rendered directly in the area instead of the pop-up window.
+
+## Examples
+
+```tsx
+import { List, PickerView } from '@ant-design/react-native'
+import React from 'react'
+import { ScrollView } from 'react-native'
+
+const basicColumns = [
+  [
+    { label: '周一', value: 'Mon' },
+    { label: '周二', value: 'Tues' },
+    { label: '周三', value: 'Wed' },
+    { label: '周四', value: 'Thur' },
+    { label: '周五', value: 'Fri' },
+  ],
+  [
+    { label: '上午', value: 'am' },
+    { label: '下午', value: 'pm' },
+  ],
+]
+
+export default class PickerViewExample extends React.Component {
+  state = {
+    value: undefined,
+  }
+  onChange = (value: any) => {
+    this.setState({
+      value,
+    })
+  }
+  render() {
+    return (
+      <ScrollView
+        nestedScrollEnabled // 🚩 Enables nested scrolling for Android API level 21+. Nested scrolling is supported by default on iOS.
+      >
+        <List renderHeader={'基础用法'}>
+          <PickerView data={basicColumns} cascade={false} />
+        </List>
+        <List renderHeader={'自定义高度'}>
+          <PickerView
+            data={basicColumns}
+            cascade={false}
+            style={{ height: 450 }}
+            itemHeight={55}
+            itemStyle={{
+              padding: 0,
+            }}
+          />
+        </List>
+        <List renderHeader={'受控模式'}>
+          <PickerView
+            onChange={this.onChange}
+            value={this.state.value}
+            data={basicColumns}
+            cascade={false}
+          />
+        </List>
+      </ScrollView>
+    )
+  }
+}
+```
+
+## API
+
+### Props
+
+Properties | Descrition | Type | Default | Version
+-----------|------------|------|---------|---------
+| data     | data source     | `PickerColumn` / `PickerColumn[]` | -   | |
+| value    | Selected options	  | `PickerValue[]`  | -   | |
+| defaultValue  | Default selected options  | `PickerValue[]`  | -   | |
+| cascade  | whether cascade <br/>child cascade get from `data[].children`   | Boolean | `true` | |
+| cols     | col numbers    | Number | `3` | |
+| onChange | selected callback function, can use [Form](/components/form) | `(value: PickerValue[], extend: PickerValueExtend) => void`      | -   | |
+| renderLabel | 	The function to custom rendering the label shown on a column  |   `(item: PickerColumnItem, itemIndex: number, colIndex: number) => ReactNode`   | `(item) => item.label`  | `5.2.2` |
+| loading  | Should the Picker displays as loading state	  | Boolean | -  | `5.1.0` |
+| loadingContent  | The loading content displayed in loading state	  | ReactNode | `<ActivityIndicator/>`  | `5.1.0` |
+| indicatorStyle  | style of default Indicator  | Object | -  | |
+
+For the type definition of  `PickerColumnItem` `PickerColumn` `PickerValue` `PickerValueExtend`, please refer to the document of [Picker](/components/picker/).
+
+### Custom Style
+
+Properties | Descrition | Type | Default | Version
+-----------|------------|------|---------|---------
+| style    | style   | `StyleProp<ViewStyle>` | -   | |
+| styles   | Semantic DOM style   | [PickerViewStyle](#pickerviewstyle-interface) | -   | `5.1.0`refactored |
+| itemStyle| style to apply to each of the item labels   | `StyleProp<TextStyle>` | -   | |
+| itemHeight | Height of option item, calculated by `numberOfLines` when without value; `itemStyle` was not allowed to set `{height}`  |   Number   | -  | |
+| numberOfLines | Used to truncate the text with an ellipsis after computing the text layout, including line wrapping, such that the total number of lines does not exceed this number  |   Number   | `1`  | |
+
+#### PickerViewStyle interface
+
+```jsx
+interface PickerViewStyle {
+  wrappper: ViewStyle
+  wheelWrapper: ViewStyle
+
+  // item style
+  itemWrap: ViewStyle
+  itemStyle: TextStyle
+  itemActiveStyle: TextStyle // New in `5.2.2`
+
+  // mask view
+  mask: ViewStyle
+  maskTop: ViewStyle
+  maskMiddle: ViewStyle
+  maskBottom: ViewStyle
+}
+```
+
+#### Mask View
+
+New in `5.1.0`. Support custom mask style, such as using the gradient component `<LinearGradient />`. Default is white translucency.
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| renderMaskTop | The function to custom rendering the mask top half view | `()=> ReactNode` | `<View style={{ flex: 1, opacity:0.8, backgroundColor: theme.fill_base }} />` |
+| renderMaskBottom | The function to custom rendering the mask bottom half view | `()=> ReactNode` | `<View style={{ flex: 1, opacity:0.8, backgroundColor: theme.fill_base }} />` |
+
+- Theme color [theme.fill_base](https://github.com/ant-design/ant-design-mobile-rn/blob/master/components/style/themes/default.tsx#L24) = `#ffffff`
+
+## FAQ
+
+### On the Android platform, when using `PickerView` nested in `ScrollView`, the Picker Item cannot slide. What should I do?
+
+Support in `5.1.3`. Set the `nestedScrollEnabled` property of `ScrollView` to `true`.
+
+```jsx
+<ScrollView nestedScrollEnabled={true}>
+  ...
+  <PickerView />
+</ScrollView>
+```
+
+---
+
+## Popover
+
+Source: https://rn.mobile.ant.design/components/popover.md
+
+# Popover
+
+> This package has been deprecated in `5.2.1`, recommend [components/Tooltip](/components/tooltip)
+
+After clicking on a control or an area, a Popover menu appears for doing more.
+If set mask prop, it is recommended to exit by clicking on any of the mask layers.
+
+## Examples
+
+```tsx
+import { List, Popover } from '@ant-design/react-native'
+import React from 'react'
+import { Easing, StyleSheet, Text, View } from 'react-native'
+
+const Item = Popover.Item
+
+export default class PopoverExample extends React.Component<any, any> {
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      selected: '',
+    }
+  }
+
+  onSelect = (value: any) => {
+    this.setState({
+      // visible: false,
+      selected: value,
+    })
+  }
+  render() {
+    let overlay = [1, 2, 3].map((i, index) => (
+      <Item key={index} value={`option ${i}`}>
+        <Text>option {i}</Text>
+      </Item>
+    ))
+    overlay = overlay.concat([
+      <Item key="4" value="disabled" disabled>
+        <Text style={{ color: '#ddd' }}>disabled opt</Text>
+      </Item>,
+      <Item key="6" value="button ct" style={{ backgroundColor: '#efeff4' }}>
+        <Text>关闭</Text>
+      </Item>,
+    ])
+    return (
+      <React.Fragment>
+        <List>
+          {[1, 2, 3, 4, 5, 6, 7, 8].map((item) =>
+            this.renderList(overlay, item),
+          )}
+        </List>
+        <Popover
+          overlay={
+            <Popover.Item value={'test'}>
+              <Text>自定义组件 x</Text>
+            </Popover.Item>
+          }
+          renderOverlayComponent={(nodes) => (
+            <View>
+              <Text
+                style={{
+                  paddingHorizontal: 9,
+                  paddingTop: 16,
+                  color: '#2b2b2b',
+                  fontWeight: 'bold',
+                }}>
+                我是自定义组件title
+              </Text>
+              {nodes}
+            </View>
+          )}>
+          <Text
+            style={{
+              margin: 16,
+            }}>
+            自定义组件
+          </Text>
+        </Popover>
+        <Popover
+          overlay={overlay}
+          useNativeDriver
+          duration={200}
+          easing={(show) => (show ? Easing.in(Easing.ease) : Easing.step0)}>
+          <Text
+            style={{
+              margin: 16,
+            }}>
+            自定义动画
+          </Text>
+        </Popover>
+        <View style={{ alignItems: 'center' }}>
+          <Text
+            style={{
+              margin: 16,
+              color: 'red',
+            }}>
+            如果你设置了 placement 属性请确保你的内容够位置显示,默认是 auto
+            自动计算位置
+          </Text>
+          {['left', 'right', 'top', 'bottom'].map((p) => (
+            <Popover
+              key={p}
+              overlay={
+                <Popover.Item value={p}>
+                  <Text>自定义组件 {p}</Text>
+                </Popover.Item>
+              }
+              placement={p as any}>
+              <Text
+                style={{
+                  margin: 16,
+                }}>
+                {p}
+              </Text>
+            </Popover>
+          ))}
+        </View>
+      </React.Fragment>
+    )
+  }
+
+  private renderList(overlay: React.ReactNode[], key: number) {
+    return (
+      <List.Item
+        key={key}
+        extra={
+          <Popover
+            overlay={overlay}
+            triggerStyle={styles.triggerStyle}
+            onSelect={(v) =>
+              this.setState({
+                [`selected${key}`]: v,
+              })
+            }>
+            <Text>菜单</Text>
+          </Popover>
+        }>
+        <View>
+          <Text>选择了:{this.state[`selected${key}`]}</Text>
+        </View>
+      </List.Item>
+    )
+  }
+}
+
+const styles = StyleSheet.create({
+  triggerStyle: {
+    paddingHorizontal: 6,
+  },
+})
+
+export const title = 'Popover'
+export const description = 'Popover example'
+```
+
+## API
+
+### Popover
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| overlay   | Popup layer content  | ReactNode |  -   |
+| placement   |   How to position the popover  | 'top | right | bottom | left | auto' |  auto   |
+| onSelect   | when an option is selected    | (value: any): void |  -   |
+| triggerStyle  | trigger style  | ViewStyle |  -   |
+| renderOverlayComponent  | A function that renders takes in the MenuOptions element and renders a container element that contains the options. Default function wraps options with a `ScrollView`. e.g. `(nodes) => <View>{nodes}</View>`  | (node: React.ReactNode) => React.ReactNode |  -   |
+| duration | Animation duration | number | 300 |
+| easing | Function that returns easing function for show or hide animation, depending on `show` argument | (show: boolean) => (value: number) => number | show => show ? Easing.out(Easing.back(1.70158)) : Easing.inOut(Easing.quad) |
+| useNativeDriver | Defines if animations should use native driver | boolean | false |
+| onDismiss | Callback to be fired after the popup closes | function | - |
+
+### Popover.Item
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| disabled   | set disabled    | Boolean |  false   |
+| style  | item style   | ViewStyle |  -   |
+| value | can be used as the selected option ID  | any |  -   |
+
+---
+
+## Progress
+
+Source: https://rn.mobile.ant.design/components/progress.md
+
+# Progress
+
+Progress Bar to indicate your task's progress.
+
+### Rules
+
+- When you need a accurate progress,otherwise you should use ActivityIndicator.
+- Hide the unfilled part when used with NavBar for better visual feeling.
+
+## Examples
+
+```tsx
+import { Button, Progress, WhiteSpace } from '@ant-design/react-native'
+import React from 'react'
+import { Text, View, ViewStyle } from 'react-native'
+
+export default class BasicProgressExample extends React.Component<any, any> {
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      percent: 40,
+    }
+  }
+
+  onAdd = () => {
+    let p = this.state.percent + 10
+    if (this.state.percent >= 100) {
+      p = 0
+    }
+    this.setState({ percent: p })
+  }
+
+  render() {
+    const style = {
+      marginTop: 80,
+      flexDirection: 'row',
+      justifyContent: 'space-between',
+      alignItems: 'center',
+    }
+    return (
+      <View>
+        <Progress percent={90} position="fixed" />
+
+        <View style={[style as ViewStyle]}>
+          <View style={{ marginRight: 10, height: 4, flex: 1 }}>
+            <Progress percent={this.state.percent} />
+          </View>
+          <Text>{this.state.percent}%</Text>
+        </View>
+        <Button
+          style={{ width: 50, marginLeft: 10 }}
+          type="ghost"
+          size="small"
+          onPress={this.onAdd}>
+          (+-)10
+        </Button>
+
+        <WhiteSpace />
+        <Progress percent={5} />
+      </View>
+    )
+  }
+}
+```
+
+## API
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+percent | percent value of progress | number | 0
+position | position of progress bar, optional:`fixed` `normal` | string | `fixed`
+unfilled | whether to fill unfinished part of progress | boolean | true
+style | the style of container | object | {}
+barStyle | the style of bar | object | {}
+
+---
+
+## Provider
+
+Source: https://rn.mobile.ant.design/components/provider.md
+
+# Provider
+
+`Provider` provides a uniform localization support for built-in text of components.
+
+## When to use
+
+ - You want to use other languages than `Chinese`
+ - You want to change the default theme color.
+ - You want to add vibration feedback to built-in component.
+ - You want to use the `Portal component`.
+
+## Examples
+
+```tsx
+import {
+  DatePicker,
+  List,
+  Pagination,
+  Picker,
+  Provider,
+  SearchBar,
+  WhiteSpace,
+  WingBlank,
+} from '@ant-design/react-native'
+import enUS from '@ant-design/react-native/lib/locale-provider/en_US'
+import esES from '@ant-design/react-native/lib/locale-provider/es_ES'
+import faIR from '@ant-design/react-native/lib/locale-provider/fa_IR'
+import koKR from '@ant-design/react-native/lib/locale-provider/ko_KR'
+import ptBR from '@ant-design/react-native/lib/locale-provider/pt_BR'
+import ruRU from '@ant-design/react-native/lib/locale-provider/ru_RU'
+import svSE from '@ant-design/react-native/lib/locale-provider/sv_SE'
+import zhCN from '@ant-design/react-native/lib/locale-provider/zh_CN'
+import React from 'react'
+import { View } from 'react-native'
+
+const maxDate = new Date(2018, 11, 3, 22, 0)
+const minDate = new Date(2015, 7, 6, 8, 30)
+
+const seasons = [
+  [
+    {
+      label: '2013',
+      value: '2013',
+    },
+    {
+      label: '2014',
+      value: '2014',
+    },
+  ],
+  [
+    {
+      label: '春',
+      value: '春',
+    },
+    {
+      label: '夏',
+      value: '夏',
+    },
+  ],
+]
+
+const Page = React.memo(() => (
+  <View>
+    <Pagination total={5} current={1} />
+    <WhiteSpace />
+    <List style={{ backgroundColor: 'white' }}>
+      <DatePicker
+        mode="date"
+        title="Select date"
+        minDate={minDate}
+        maxDate={maxDate}>
+        <List.Item arrow="horizontal">DatePicker</List.Item>
+      </DatePicker>
+      <Picker data={seasons} cascade={false}>
+        <List.Item arrow="horizontal">Picker</List.Item>
+      </Picker>
+      <WhiteSpace />
+      <SearchBar placeholder="Search" showCancelButton />
+    </List>
+  </View>
+))
+
+export default class LocaleProviderExample extends React.Component<any, any> {
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      locale: 'English',
+    }
+  }
+
+  onChange = (value: any) => {
+    this.setState({
+      locale: value[0],
+    })
+  }
+
+  render() {
+    const { locale } = this.state
+    const languages: Array<any> = [
+      {
+        value: '中国',
+        label: '中国',
+        language: zhCN,
+      },
+      {
+        value: 'English',
+        label: 'English',
+        language: enUS,
+      },
+      {
+        value: 'Русский',
+        label: 'Русский',
+        language: ruRU,
+      },
+      {
+        value: 'Español',
+        label: 'Español',
+        language: esES,
+      },
+      {
+        value: 'Português - BR',
+        label: 'Português - BR',
+        language: ptBR,
+      },
+      {
+        value: 'Sverige',
+        label: 'Sverige',
+        language: svSE,
+      },
+      {
+        value: 'Persian',
+        label: 'Persian',
+        language: faIR,
+      },
+      {
+        value: '한국',
+        label: '한국',
+        language: koKR,
+      },
+    ]
+    const currentLocale = languages.find(
+      (item) => item.value === locale,
+    ).language
+
+    return (
+      <Provider locale={currentLocale}>
+        <WingBlank>
+          <Picker
+            data={languages}
+            onChange={this.onChange}
+            cols={1}
+            value={[locale]}>
+            <List.Item arrow="horizontal">Choose language</List.Item>
+          </Picker>
+          <WhiteSpace />
+          <Page />
+        </WingBlank>
+      </Provider>
+    )
+  }
+}
+```
+
+### Portal Component
+
+`ActionSheet` `Modal` `Picker` `Toast` `ToolTip` belongs to Portal component;
+
+To use these components, you must wrap your root component (usually in App.js) with `Provider` component.
+
+## API
+
+| Property | Description | Type | Default | Version |
+| -----|-----|-----|-------|------|
+| locale | Language package setting(`The default language is Chinese`), <br/>you can find the packages in this path: [`@ant-design/react-native/lib/locale-provider/`](https://github.com/ant-design/ant-design-mobile-rn/blob/master/components/locale-provider) | [Locale](https://github.com/ant-design/ant-design-mobile-rn/blob/master/components/locale-provider/index.tsx#L4) | - | |
+| theme  | Theme customization, you can override some or all variables as needed | [Theme](https://github.com/ant-design/ant-design-mobile-rn/blob/master/components/style/themes/default.tsx) | - | |
+| onHaptics | Set the vibration engine. This method will be triggered when the built-in component needs vibration feedback. | `(componentName: 'picker' | 'stepper' | 'slider' | 'switch') => void` | - | `5.2.1` |
+| isRTL | Whether use Right-to-Left (RTL) languages. <br/>Currently only applies to `<SwipeAction/>` | `Boolean` | `I18nManager.isRTL` | `5.2.1` |
+
+## FAQ
+
+### How do I customize my theme?
+
+For example: Modifying the following theme variables has a relatively large impact
+```jsx
+<Provider theme={{
+    brand_primary: palette[5],  // Brand base color #108ee9
+    fill_base: palette[0],      // Component default background color #ffffff
+    primary_button_fill: palette[5],     // <Button type="primary"> background color
+    primary_button_fill_tap: palette[3], // <Button type="primary"> onTap background color
+    color_icon_base: palette[4],         // Background color for many icons
+}}>
+...
+</Provider>
+```
+
+### Dark Mode
+```json
+{
+    "fill_body": "#262629",
+    "fill_base": "#1a1a1a",
+    "fill_tap": "#2b2b2b",
+    "fill_grey": "#0a0a0a",
+    "color_text_base": "#e6e6e6",
+    "color_text_placeholder": "#4d4d4d",
+    "border_color_base": "#2b2b2b",
+    "border_color_thin": "#2b2b2b",
+}
+```
+
+### How to activate component vibration?
+Since the vibration engines of different platforms are different, we expose the vibration events and execute them by the plug-in engine.
+
+Usually, the `expo-haptics` engine is used in Expo; the `react-native-haptic-feedback` engine is used in React-Native-CLI;
+
+Here we take Expo CLI as an example
+```jsx
+import * as Haptics from 'expo-haptics'
+import { Platform } from 'react-native'
+
+<Provider 
+    onHaptics={() => Platform.OS !== 'web' && Haptics.impactAsync('light')}
+>
+...
+</Provider>
+```
+
+---
+
+## Radio
+
+Source: https://rn.mobile.ant.design/components/radio.md
+
+# Radio
+
+Radio.
+
+## Examples
+
+```tsx
+import { Button, Flex, List, Radio, WingBlank } from '@ant-design/react-native'
+import React from 'react'
+import { ScrollView } from 'react-native'
+const RadioItem = Radio.RadioItem
+
+type RadioValue = string | number
+interface EventRadioGroup {
+  target: { value: RadioValue }
+}
+
+interface EventRadioItem {
+  target: { checked: boolean }
+}
+export default class BasicRadioExample extends React.Component<any, any> {
+  state = {
+    disabled: false,
+    part1Value: 1,
+    part2Value: 1,
+    part3Value: 1,
+  }
+
+  toggleDisabled = () => {
+    this.setState({
+      disabled: !this.state.disabled,
+    })
+  }
+
+  onChange = (part1Value: any, e: EventRadioItem) => {
+    if (e.target.checked) {
+      this.setState({ part1Value })
+    }
+  }
+
+  onGroupChange2 = (e: EventRadioGroup) => {
+    this.setState({
+      part2Value: e.target.value,
+    })
+  }
+
+  onGroupChange3 = (e: EventRadioGroup) => {
+    this.setState({
+      part3Value: e.target.value,
+    })
+  }
+
+  render() {
+    return (
+      <ScrollView>
+        <List renderHeader="基本用法">
+          <List.Item thumb={<Radio>Radio</Radio>} />
+        </List>
+        <List
+          renderHeader="不可用"
+          renderFooter={
+            <Button type="primary" onPress={this.toggleDisabled}>
+              Toggle disabled
+            </Button>
+          }>
+          <List.Item>
+            <Flex>
+              <Radio defaultChecked={false} disabled={this.state.disabled}>
+                Disabled
+              </Radio>
+              <WingBlank />
+              <Radio disabled={this.state.disabled}>Disabled</Radio>
+            </Flex>
+          </List.Item>
+        </List>
+        <List renderHeader="RadioItem">
+          <RadioItem
+            checked={this.state.part1Value === 1}
+            onChange={this.onChange.bind(this, 1)}>
+            Use Ant Design Component
+          </RadioItem>
+          <RadioItem
+            checked={this.state.part1Value === 2}
+            onChange={this.onChange.bind(this, 2)}>
+            Use Ant Design Component
+          </RadioItem>
+        </List>
+        <List renderHeader={'单选组合 RadioGroup\n一组互斥的 Radio 配合使用'}>
+          <Radio.Group
+            onChange={this.onGroupChange2}
+            value={this.state.part2Value}
+            style={{
+              flexDirection: 'row',
+              justifyContent: 'space-around',
+              paddingVertical: 6,
+            }}>
+            <Radio value={1}>A</Radio>
+            <Radio value={2}>B</Radio>
+            <Radio value={3}>C</Radio>
+            <Radio value={4}>D</Radio>
+          </Radio.Group>
+        </List>
+        <List
+          renderHeader={
+            'Radio.Group 垂直\n垂直的 Radio.Group,配合更多输入框选项'
+          }>
+          <Radio.Group
+            onChange={this.onGroupChange3}
+            value={this.state.part3Value}>
+            <RadioItem value={1}>Option A</RadioItem>
+            <RadioItem value={2}>Option B</RadioItem>
+            <RadioItem value={3}>Option C</RadioItem>
+            <RadioItem value={4} left>
+              More...
+            </RadioItem>
+          </Radio.Group>
+        </List>
+        <List
+          renderHeader={
+            'Radio.Group 组合 - 配置方式\n可通过配置 options 参数来渲染单选框。'
+          }>
+          <RadioGroupExample />
+        </List>
+      </ScrollView>
+    )
+  }
+}
+
+const plainOptions = ['Apple', 'Pear', 'Orange']
+const options = [
+  { label: 'Apple', value: 'Apple' },
+  { label: 'Pear', value: 'Pear' },
+  { label: 'Orange', value: 'Orange' },
+]
+const optionsWithDisabled = [
+  { label: 'Apple', value: 'Apple' },
+  { label: 'Pear', value: 'Pear' },
+  { label: 'Orange', value: 'Orange', disabled: true },
+]
+
+class RadioGroupExample extends React.Component {
+  state = {
+    value1: 'Apple',
+    value2: 'Apple',
+    value3: 'Apple',
+  }
+
+  onChange1 = (e: EventRadioGroup) => {
+    console.log('radio1 checked', e.target.value)
+    this.setState({
+      value1: e.target.value,
+    })
+  }
+
+  onChange2 = (e: EventRadioGroup) => {
+    console.log('radio2 checked', e.target.value)
+    this.setState({
+      value2: e.target.value,
+    })
+  }
+
+  onChange3 = (e: EventRadioGroup) => {
+    console.log('radio3 checked', e.target.value)
+    this.setState({
+      value3: e.target.value,
+    })
+  }
+
+  render() {
+    const { value1, value2, value3 } = this.state
+    return (
+      <>
+        <List renderHeader="PlainOptions">
+          <Radio.Group
+            options={plainOptions}
+            onChange={this.onChange1}
+            value={value1}
+          />
+        </List>
+        <List renderHeader="Options">
+          <Radio.Group
+            options={options}
+            onChange={this.onChange2}
+            value={value2}
+          />
+        </List>
+        <List renderHeader="OptionsWithDisabled">
+          <Radio.Group
+            options={optionsWithDisabled}
+            onChange={this.onChange3}
+            value={value3}
+          />
+        </List>
+      </>
+    )
+  }
+}
+```
+
+## API
+
+### Type
+```ts
+type RadioValue = string | number
+```
+
+### Radio
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| defaultChecked |   the initial checked state   | Boolean  | -  |
+| checked    |   to set the current checked state  | Boolean  | -  |
+| disabled      |  whether disabled  | Boolean |  false  |
+| onChange    | a callback function, can be executed when the checked state changes | (e: { target: { checked: boolean } }) => void |  -  |
+| value | Value is carrying identification, used in `Group` mode | `RadioValue` | - |
+
+### Radio.RadioItem
+
+The encapsulation about `Radio` based on `List.Item`, the property `extra` of `List.Item` will be passed to `Radio`, while other properties remain the same.
+
+Other APIs are identical with `Radio`.
+
+### Radio.Group `v5.0.0`
+
+Radio group can wrap a group of `Radio`。
+
+```ts
+type Event = { target: { value: RadioValue } }
+```
+
+Properties | Descrition | Type | Default
+----|-----|------|------
+| defaultValue |   	Default selected value   | `RadioValue`  | -  |
+| disabled |  Disable all radio buttons  | Boolean |  false  |
+| options  | Set children optional | `string[]` \| `number[]` \| `Array<{ label: string value: string disabled?: boolean }>` | - |
+| value    |   Used for setting the currently selected value  | `RadioValue`  | -  |
+| onChange | The callback function that is triggered when the state changes | (e: `Event`) => void |   -  |
+
+---
+
+## Result
+
+Source: https://rn.mobile.ant.design/components/result.md
+
+# Result
+
+Result page contains feedback like illustrations, icons and text.
+
+### Rules
+
+- Use for significant feedback like payment success or network failure.
+- Improve brand value with beautiful illustrations.
+- Provide obvious operation point for error type result page, eg: reload page.
+
+## Examples
+
+```tsx
+import { Result } from '@ant-design/react-native'
+import React from 'react'
+import { Image, ScrollView, Text } from 'react-native'
+
+export default class ResultExample extends React.Component<any, any> {
+  render() {
+    return (
+      <ScrollView style={{ backgroundColor: '#F5F5F9', flex: 1 }}>
+        <Text style={{ margin: 10, color: '#999' }}>URI 图片</Text>
+        <Result
+          imgUrl={{
+            uri: 'https://zos.alipayobjects.com/rmsportal/GcBguhrOdlYvGfnsXgrE.png',
+          }}
+          title="验证成功"
+          message="所提交内容已成功完成验证"
+        />
+
+        <Text style={{ margin: 10, color: '#999' }}>Image source</Text>
+        <Result
+          imgUrl={require('./alipay.png')}
+          title="验证成功"
+          message="所提交内容已成功完成验证"
+        />
+
+        <Text style={{ margin: 10, color: '#999' }}>Image element</Text>
+        <Result
+          img={
+            <Image
+              source={require('./alipay.png')}
+              style={{ width: 60, height: 60 }}
+            />
+          }
+          title="验证成功"
+          message={<Text>所提交内容已成功完成验证</Text>}
+        />
+
+        <Text style={{ margin: 10, color: '#999' }}>含 button 操作</Text>
+        <Result
+          img={
+            <Image
+              source={require('./alipay.png')}
+              style={{ width: 60, height: 60 }}
+            />
+          }
+          title="验证成功"
+          message="所提交内容已成功完成验证"
+          buttonText="完成"
+          buttonType="primary"
+          onButtonClick={(e: any) => alert(e.toString())}
+        />
+      </ScrollView>
+    )
+  }
+}
+```
+
+## API
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+imgUrl | image url | string / Image Source(rn)  | -
+img | image node (could be `<img src="" />` or `<Icon type="" />`), which will override `imgUrl` | ReactNode | -
+title | title of result page | ReactNode | -
+message | message text of result page | ReactNode | -
+buttonText | text of built-in button | string | -
+buttonType | type of built-in button | string | -
+onButtonClick | callback of clicking built-in button | (e: Object): void | -
+
+---
+
+## SearchBar
+
+Source: https://rn.mobile.ant.design/components/search-bar.md
+
+# SearchBar
+
+Normally located below NavBar, the activation status is exited by the Cancel button.
+
+### Rules
+
+- Should fill some text in placeholder to remind the user to enter the relevant content, such as: "双11特卖".
+- Below the SearchBar, you can provide useful labels copy to help users complete the input directly by clicking, such as: List some of the most recent search keywords.
+
+## Examples
+
+```tsx
+import { SearchBar } from '@ant-design/react-native'
+import React from 'react'
+import { Alert, View } from 'react-native'
+
+export default class SearchBarDemo extends React.Component<any, any> {
+  state = {
+    value: '美食',
+  }
+
+  onChange = (value: any) => {
+    this.setState({ value })
+  }
+
+  clear = () => {
+    this.setState({ value: '' })
+  }
+
+  render() {
+    return (
+      <View style={{ marginTop: 30 }}>
+        <SearchBar defaultValue="初始值" placeholder="搜索" />
+        <SearchBar
+          value={this.state.value}
+          placeholder="搜索"
+          onSubmit={(value: any) => Alert.alert(value)}
+          onCancel={this.clear}
+          onChange={this.onChange}
+          showCancelButton
+        />
+      </View>
+    )
+  }
+}
+```
+
+## API
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| defaultValue |  the uncontrolled default value    | String |    |
+| value      |  the controlled current value  | String |    |
+| placeholder    |    placeholder   | String |    |
+| onSubmit    |  submit event (click the enter on the keyboard) | (val: string): void |    |
+| onChange    |    change event callback     | (val: string): void |    |
+| onFocus    |    focus event callback     | (): void |    |
+| onBlur    |    blur event callback     | (): void |    |
+| onCancel  | Click the `Cancel` button to trigger (The text of the input box is no longer automatically cleared) | (val: string): void |    |
+| showCancelButton |  Whether the `Cancel` button is always displayed  | bool |  `false`  |
+| cancelText  |  Customize the text of the `Cancel` button   | String |  `取消`  |
+| disabled    |   Set disabled  | bool |  `false`  |
+
+Note: RN version more API please refer to [http://facebook.github.io/react-native/docs/textinput.html](http://facebook.github.io/react-native/docs/textinput.html)
+
+---
+
+## SegmentedControl
+
+Source: https://rn.mobile.ant.design/components/segmented-control.md
+
+# SegmentedControl
+
+Deprecated since `5.2.1`.
+
+Please use [@react-native-community/segmented-control](https://github.com/react-native-community/segmented-control#usage) instead.
+
+---
+
+## Slider
+
+Source: https://rn.mobile.ant.design/components/slider.md
+
+# Slider
+
+A Slider component for selecting particular value in range, eg: controls the display brightness of the screen.
+
+### Rule
+- By default, the minimum value in the left and maximum value in the right of `Slider` .
+- Generally `Slider` is positioned horizontally.
+
+## Examples
+
+```tsx
+import { List, Provider, Slider, Switch, Toast } from '@ant-design/react-native'
+import React, { useEffect, useState } from 'react'
+import { ScrollView } from 'react-native'
+
+export default function StepperExample() {
+  useEffect(() => {
+    Toast.config({ stackable: false })
+  }, [])
+
+  const [disabledStep, setDisabledStep] = useState(false)
+  const [tapToSeek, setTapToSeek] = useState(true)
+  const marks = {
+    0: 0,
+    // 20: 20,
+    40: 40,
+    60: '',
+    80: 80,
+    100: 100,
+  }
+
+  const toastValue = (value: number | [number, number]) => {
+    let text = ''
+    if (typeof value === 'number') {
+      text = `${value}`
+    } else {
+      text = `[${value.join(',')}]`
+    }
+    Toast.show({ content: `当前选中值为:${text}`, position: 'top' })
+  }
+
+  return (
+    <Provider>
+      <ScrollView>
+        <List>
+          <List.Item
+            extra={
+              <Switch
+                checked={disabledStep}
+                onChange={(val) => {
+                  setDisabledStep(val)
+                }}
+              />
+            }>
+            Disabled Step
+            <List.Item.Brief>
+              是否禁用步距;禁用后`onChange`将返回带有小数点的值
+            </List.Item.Brief>
+          </List.Item>
+          <List.Item
+            extra={
+              <Switch
+                checked={tapToSeek}
+                onChange={(val) => {
+                  setTapToSeek(val)
+                }}
+              />
+            }>
+            Tap To Seek
+            <List.Item.Brief>
+              是否允许点击滑块轨道来设置slider值
+            </List.Item.Brief>
+          </List.Item>
+        </List>
+        <List
+          renderHeader={'基础用法'}
+          onStartShouldSetResponder={() => true}
+          onTouchStart={(e) => e.stopPropagation()}>
+          <List.Item>
+            <Slider
+              max={1}
+              disabledStep={disabledStep}
+              tapToSeek={tapToSeek}
+              onChange={toastValue}
+              onAfterChange={toastValue}
+              onSlidingStart={(val, index) =>
+                console.log('onSlidingStart', { val, index })
+              }
+              onSlidingComplete={(val, index) =>
+                console.log('onSlidingComplete', { val, index })
+              }
+            />
+          </List.Item>
+        </List>
+        <List renderHeader={'显示刻度(ticks)并指定步距(step)'}>
+          <List.Item>
+            <Slider
+              ticks
+              step={10}
+              defaultValue={40}
+              disabledStep={disabledStep}
+              tapToSeek={tapToSeek}
+            />
+          </List.Item>
+        </List>
+        <List renderHeader={'传入刻度标记(marks)'}>
+          <List.Item>
+            <Slider
+              marks={marks}
+              ticks
+              disabledStep={disabledStep}
+              tapToSeek={tapToSeek}
+            />
+          </List.Item>
+        </List>
+        <List renderHeader={'最大(max)/最小值(min)'}>
+          <List.Item>
+            <Slider
+              step={100}
+              min={100}
+              max={1000}
+              ticks
+              onAfterChange={toastValue}
+              disabledStep={disabledStep}
+              tapToSeek={tapToSeek}
+            />
+          </List.Item>
+        </List>
+        <List renderHeader={'双滑块(range)'}>
+          <List.Item>
+            <Slider
+              marks={marks}
+              ticks
+              range
+              defaultValue={[60, 40]}
+              disabledStep={disabledStep}
+              tapToSeek={tapToSeek}
+            />
+          </List.Item>
+        </List>
+        <List renderHeader={'在拖动时显示悬浮提示'}>
+          <List.Item>
+            <Slider popover disabledStep={disabledStep} tapToSeek={tapToSeek} />
+          </List.Item>
+        </List>
+      </ScrollView>
+    </Provider>
+  )
+}
+```
+
+## API
+
+| Properties | Description | Type | Default | Version |
+| --- | --- | --- | --- | --- |
+| defaultValue | Default value | `number` \|<br/> `[number, number]` | `range ? [0, 0] : 0` | |
+| disabled | Whether disabled | `boolean` | `false` | |
+| disabledStep | Whether disabled step; if `true`, `onChange` will return a value with a decimal point | `boolean` | `false` | `5.3.0` |
+| icon | The thumb icon of slider | `ReactNode` | - | |
+| marks | Tick marks | `{ [key: number]: React.ReactNode }` | - | `5.2.1` |
+| max | Max value | `number` | `100` | |
+| min | Min value | `number` | `0` | |
+| onAfterChange | Consistent with the trigger timing of `touchend`, pass the current value as a parameter | `(value: number | [number, number]) => void` | - | |
+| onChange | Triggered when the slider is dragged, and the current dragged value is passed in as a parameter | `(value: number | [number, number]) => void` | - | |
+| onSlidingStart | Callback that is called when the user picks up the slider.<br/>The initial value is passed as an argument to the callback handler. | `(value: number | [number, number], index: number) => void` | - | `5.3.0` |
+| onSlidingComplete | Callback that is called when the user releases the slider, regardless if the value has changed.<br/>The current value is passed as an argument to the callback handler. | `(value: number | [number, number], index: number) => void` | - | `5.3.0` |
+| popover | Whether to display the popover when dragging. Support passing in function to customize the rendering content. | `boolean | ((value: number) => ReactNode)` | `false` | `5.2.1` |
+| residentPopover | Whether the `popover` is permanently displayed , this attribute takes effect when `popover` exists | `boolean ` | `false` | `5.2.1` |
+| range | Whether it is a double sliders | `boolean` | `false` | `5.2.1` |
+| step | Step distance, the value must be greater than `0`, and `(max-min)` can be divisible by `step`. When `marks` is not null, the configuration of `step` is invalid | `number` | `1` | `5.2.1` |
+| style  | Container style | `StyleProp<ViewStyle>` | - | |
+| styles | Semantic DOM style | [SliderStyle](#sliderstyle-interface) | - | `5.2.1` |
+| tapToSeek | Permits tapping on the slider track to set the thumb icon position. | `boolean` | `true` | `5.3.0` |
+| ticks | Whether to display the scale | `boolean` | `false` | `5.2.1` |
+| value | Current value | `number` \|<br/> `[number, number]` | - | |
+
+> The returned `value` format is `[number, number]` when `range={true}`, otherwise it is `number`.
+
+### SliderStyle interface
+
+```typescript
+interface SliderStyle {
+  // Same as `style`
+  slider: ViewStyle // belongs to PanGesture area when `range=false`
+  disabled: ViewStyle
+
+  // Track
+  trackContianer: ViewStyle // track container
+  track: ViewStyle // track line
+  fill: ViewStyle // Filled portion of the track line
+
+  // Track button wrap + shadow style
+  thumb: ViewStyle
+
+  // Tick
+  ticks: ViewStyle
+  tick: ViewStyle
+  tickActive: ViewStyle
+
+  // Mark within the tick
+  mark: ViewStyle
+  markText: TextStyle
+}
+```
+
+---
+
+## Stepper
+
+Source: https://rn.mobile.ant.design/components/stepper.md
+
+# Stepper
+
+`Stepper` can be used to increase or decrease value step by step.
+
+### Rule
+- When you want to make small adjustments to the value, you can use `Stepper`. eg: Adjust the annual return from 4.00% to 4.05%.
+
+## Examples
+
+```tsx
+import { List, Provider, Stepper, Toast } from '@ant-design/react-native'
+import React from 'react'
+import { KeyboardAvoidingView, Platform, ScrollView } from 'react-native'
+
+export default function StepperExample() {
+  return (
+    <Provider>
+      <KeyboardAvoidingView
+        behavior="padding"
+        keyboardVerticalOffset={Platform.OS === 'ios' ? 100 : undefined}>
+        <ScrollView>
+          <List renderHeader={'基础用法'}>
+            <List.Item
+              extra={
+                <Stepper
+                  defaultValue={1}
+                  onChange={(value) => {
+                    console.log(value)
+                  }}
+                />
+              }>
+              基础用法
+            </List.Item>
+            <List.Item extra={<Stepper step={10} defaultValue={10} />}>
+              步长设置
+            </List.Item>
+            <List.Item extra={<Stepper min={-5} max={5} />}>
+              限制输入范围
+            </List.Item>
+            <List.Item extra={<Stepper digits={1} />}>
+              格式化到一位小数
+            </List.Item>
+            <List.Item
+              extra={
+                <Stepper
+                  defaultValue={93}
+                  formatter={(value) => `$ ${value}`}
+                  parser={(text) => parseFloat(text.replace('$', ''))}
+                  onChange={(value) => {
+                    console.log(value, typeof value)
+                  }}
+                />
+              }>
+              自定义格式
+            </List.Item>
+          </List>
+          <List renderHeader={'状态/样式'}>
+            <List.Item extra={<Stepper disabled />}>禁用状态</List.Item>
+            <List.Item extra={<Stepper readOnly />}>输入框只读状态</List.Item>
+            <List.Item
+              extra={
+                <Stepper
+                  onFocus={() => {
+                    Toast.info('获得焦点')
+                  }}
+                  onBlur={() => {
+                    Toast.info('失去焦点')
+                  }}
+                />
+              }>
+              获得/失去焦点
+            </List.Item>
+            <List.Item
+              extra={
+                <Stepper
+                  allowEmpty={true}
+                  min={10}
+                  max={20}
+                  onChange={(value) => {
+                    console.log(value)
+                  }}
+                />
+              }>
+              允许清空
+            </List.Item>
+            <List.Item extra={<Stepper defaultValue={10000} step={10000} />}>
+              自定义样式
+            </List.Item>
+          </List>
+          <StringModeExample />
+        </ScrollView>
+      </KeyboardAvoidingView>
+    </Provider>
+  )
+}
+
+const StringModeExample = () => {
+  const [value, setValue] = React.useState('9999999999999999')
+  return (
+    <List renderHeader={'stringMode'}>
+      <List.Item>
+        <Stepper
+          stringMode
+          defaultValue="0.000000000000002"
+          step="0.000000000000001"
+          onChange={console.log}
+          style={{ width: '100%' }}
+        />
+      </List.Item>
+      <List renderHeader={'stringMode control'}>
+        <List.Item>
+          <Stepper
+            stringMode
+            value={value}
+            step="13579"
+            onChange={setValue}
+            style={{ width: '100%' }}
+          />
+        </List.Item>
+      </List>
+    </List>
+  )
+}
+```
+
+## API
+
+| Name | Description | Type | Default | Version |
+| --- | --- | --- | --- | --- |
+| allowEmpty | Whether to allow empty content. | `boolean` | `false` |
+| defaultValue | Default value | `number \| null` | `0` |
+| digits | Format to a fixed number of digits after the decimal point, set to `0` means format to integer. Will use `formatter` as display value when configured | `number` | - | 5.2.1 |
+| disabled | Whether to disabled Stepper | `boolean` | `false` |
+| formatter | Format value in input | `(value?: number) => string` | - | 5.2.1 |
+| inputStyle | TextInput style | `StyleProp<TextStyle>` | - |
+| max | Max value | `number` | - |
+| min | Min value | `number` | - |
+| minusButtonProps | The minus button props | [TouchableHighlightProps](https://reactnative.dev/docs/touchablehighlight) | `{ activeOpacity:1, underlayColor:'#ddd', children: <Text>-</Text>, delayLongPress:500  }` | 5.2.1 |
+| plusButtonProps | The plus button props | [TouchableHighlightProps](https://reactnative.dev/docs/touchablehighlight) | `{ activeOpacity:1, underlayColor:'#ddd', children: <Text>+</Text>, delayLongPress:500  }` | 5.2.1 |
+| onChange | Callback when value is changed | `(value: number \| null) => void` | - |
+| parser | Parse input text into number which should work with `formatter` | `(text: string) => number` | - | 5.2.1 |
+| step | The value to increase or decrease each time, can be a decimal | `number` | `1` |
+| stringMode | Set value as string to support high precision decimals. Will set `defaultValue`,`value`, `min`, `max`, `onChange` to `string` type | `boolean` | `false` | 5.2.1 |
+| styles | Semantic DOM style | [StepperStyle](#stepperstyle-interface) | - | 5.2.1 |
+| value | Current number, controlled value | `number \| null` | - |
+
+ - New in `5.2.1`. In addition, all properties of react-native [TextInput](http://facebook.github.io/react-native/docs/textinput.html) are supported, eg: **`readOnly`** **`onFocus`** **`onBlur`**
+
+ - New in `5.2.1`. Support **Long Press To Trigger** increment or decrement; customizable execution timing: `plusButtonProps={{ delayLongPress: 500 }}`.
+
+ - When `allowEmpty` is `true`, the `value` parameter of `onChange` may be **`null`**, please pay attention when using it.
+
+### StepperStyle interface
+
+`5.2.1`refactored the styles
+
+```typescript
+export interface StepperStyle extends Partial<InputStyle> {
+  // extends InputStyle
+  container: ViewStyle
+  input: ViewStyle
+  prefix: ViewStyle // for minus button
+  suffix: ViewStyle // for plus button
+
+  // StepperStyle
+  inputDisabled: TextStyle
+  stepWrap: ViewStyle // step button wrap
+  stepText: TextStyle // step button text
+  stepDisabled: ViewStyle // step button disabled
+  disabledStepTextColor: TextStyle
+}
+```
+
+## Ref
+Same as [component/Input](/components/input#ref)
+
+---
+
+## Steps
+
+Source: https://rn.mobile.ant.design/components/steps.md
+
+# Steps
+
+Steps is typically used for displaying the progress of a task, or guiding users through the steps of a complex flow.
+
+### Rules
+
+- Suitable for step-by-step and long-lasting task, e.g. the process of transfer accounts. If the task is continuous and short, such as opening a page, component `Progress` will fit better.
+- When the task is complicated or has a certain sequence in the series of subtasks, we can decompose it into several steps to make things easier, e.g. register new account.
+
+## Examples
+
+```tsx
+import { Icon, Steps, WingBlank } from '@ant-design/react-native'
+import React from 'react'
+import { ScrollView, Text, View } from 'react-native'
+const Step = Steps.Step
+
+export default class BasicTimelineExample extends React.Component<any, any> {
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      steps1: [
+        { title: 'Finished', description: 'This is description' },
+        { title: 'In Progress', description: 'This is description' },
+        { title: 'Waiting', description: 'This is description' },
+      ],
+      steps2: [
+        {
+          title: 'Finished',
+          description: 'This is description',
+          status: 'finish',
+        },
+        {
+          title: 'In Progress',
+          description: 'This is description',
+          status: 'process',
+        },
+        {
+          title: 'Waiting',
+          description: 'This is description',
+          status: 'error',
+        },
+        {
+          title: 'Waiting',
+          description: 'This is description',
+          status: 'wait',
+        },
+      ],
+    }
+  }
+  render() {
+    return (
+      <ScrollView
+        style={{ flex: 1 }}
+        automaticallyAdjustContentInsets={false}
+        showsHorizontalScrollIndicator={false}
+        showsVerticalScrollIndicator={false}>
+        <View style={{ marginTop: 60 }}>
+          <WingBlank size="lg">
+            <Steps size="small" current={1} direction="horizontal">
+              {this.state.steps1.map((item: any, index: any) => (
+                <Step
+                  key={index}
+                  title={
+                    <View>
+                      <Text>title:{item.title}</Text>
+                    </View>
+                  }
+                  status={item.status}
+                />
+              ))}
+            </Steps>
+          </WingBlank>
+        </View>
+        <View style={{ marginTop: 60 }}>
+          <WingBlank size="lg">
+            <Steps size="small" current={1}>
+              {this.state.steps1.map((item: any, index: any) => (
+                <Step
+                  key={index}
+                  title={
+                    <View>
+                      <Text>title:{item.title}</Text>
+                    </View>
+                  }
+                  description={
+                    <View>
+                      <Text>desc:{item.description}</Text>
+                    </View>
+                  }
+                  status={item.status}
+                />
+              ))}
+            </Steps>
+          </WingBlank>
+        </View>
+        <View>
+          <WingBlank size="lg">
+            <Steps size="small">
+              {this.state.steps2.map((item: any, index: any) => (
+                <Step
+                  key={index}
+                  title={item.title}
+                  description={item.description}
+                  status={item.status}
+                />
+              ))}
+            </Steps>
+          </WingBlank>
+        </View>
+        <View>
+          <WingBlank size="lg">
+            <Steps current={1}>
+              {this.state.steps1.map((item: any, index: any) => (
+                <Step
+                  key={index}
+                  title={item.title}
+                  description={item.description}
+                  status={item.status}
+                />
+              ))}
+            </Steps>
+          </WingBlank>
+        </View>
+        <View>
+          <WingBlank size="lg">
+            <Steps>
+              {this.state.steps2.map((item: any, index: any) => (
+                <Step
+                  key={index}
+                  title={item.title}
+                  description={item.description}
+                  status={item.status}
+                />
+              ))}
+            </Steps>
+          </WingBlank>
+        </View>
+        <View>
+          <WingBlank size="lg">
+            <Steps current={1}>
+              <Step
+                key={0}
+                title="Finished"
+                description="This is description"
+                status="finish"
+              />
+              <Step
+                key={1}
+                title="Progress"
+                description="This is description"
+                status="progress"
+              />
+              <Step
+                key={2}
+                title="Wait"
+                description="This is description"
+                status="wait"
+                icon={<Icon name="down" size={20} color="white" />}
+              />
+            </Steps>
+          </WingBlank>
+        </View>
+        <View>
+          <WingBlank size="lg">
+            <Steps current={1}>
+              <Step
+                key={0}
+                title="Finished"
+                description="This is description"
+                status="finish"
+                renderIcon={({ starting, waiting, error }) => {
+                  let icon
+                  if (starting) {
+                    icon = <Icon name="home" />
+                  } else if (waiting) {
+                    icon = <Icon name="user" />
+                  } else if (error) {
+                    icon = <Icon name="star" />
+                  }
+                  return icon
+                }}
+              />
+              <Step
+                key={1}
+                title="Progress"
+                description="This is description"
+                status="progress"
+                renderIcon={({ starting, waiting, error }) => {
+                  let icon
+                  if (starting) {
+                    icon = <Icon name="home" />
+                  } else if (waiting) {
+                    icon = <Icon name="user" />
+                  } else if (error) {
+                    icon = <Icon name="star" />
+                  }
+                  return icon
+                }}
+              />
+              <Step
+                key={2}
+                title="Wait"
+                description="This is description"
+                status="wait"
+                renderIcon={({ starting, waiting, error }) => {
+                  let icon
+                  if (starting) {
+                    icon = <Icon name="home" />
+                  } else if (waiting) {
+                    icon = <Icon name="user" />
+                  } else if (error) {
+                    icon = <Icon name="star" />
+                  }
+                  return icon
+                }}
+              />
+              <Step
+                key={3}
+                title="Wait"
+                description="This is description"
+                status="error"
+                renderIcon={({ starting, waiting, error }) => {
+                  let icon
+                  if (starting) {
+                    icon = <Icon name="home" />
+                  } else if (waiting) {
+                    icon = <Icon name="user" />
+                  } else if (error) {
+                    icon = <Icon name="star" />
+                  }
+                  return icon
+                }}
+              />
+            </Steps>
+          </WingBlank>
+        </View>
+      </ScrollView>
+    )
+  }
+}
+```
+
+## API
+
+```jsx
+<Steps>
+  <Step title="First" />
+  <Step title="Second" />
+  <Step title="Third" />
+</Steps>
+```
+
+### Steps
+
+The Steps container.
+
+| Properties | Descrition                                                                                         | Type                              | Default    |
+| ---------- | -------------------------------------------------------------------------------------------------- | --------------------------------- | ---------- |
+| current    | To set the current step, counting from 0. You can overwrite this state by using `status` of `Step` | number                            | `0`        |
+| size       | To specify the size of the step bar, a smaller size can be achieved by setting it to `small`       | string                            | -          |
+| direction  | To specify the direction of the step bar(now only support `vertical` for react-native)             | Enum { 'vertical', 'horizontal' } | `vertical` |
+
+### Steps.Step
+
+A single step used as child component of the Step.
+
+| Properties  | Descrition                                                                                     | Type                                                                                  | Default |
+| ----------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------- |
+| status      | To specify the status. It will be automatically set by `current` of `Steps` if not configured. | Enum { 'wait', 'process', 'finish', 'error' }                                         | `wait`  |
+| title       | Title of the step                                                                              | React.Element                                                                         | -       |
+| description | Detail of the step(optional property)                                                          | React.Element                                                                         | -       |
+| icon        | Icon of the step(optional property)                                                            | object/React.Element                                                                  | -       |
+| renderIcon  | customize step icon(optional)                                                                  | (params: { starting: boolean; waiting: boolean; error: boolean; }) => React.ReactNode | -       |
+
+---
+
+## SwipeAction
+
+Source: https://rn.mobile.ant.design/components/swipe-action.md
+
+# SwipeAction
+
+iOS-style swipeout buttons that appear from behind a component.
+
+### Definition
+
+Call out operations from one side of screen with gesture.
+
+### Rules
+1. Only one row can be swiped at a time.
+2. Can hide operations by clicking outside of buttons or swiping the list backforwards.
+
+## Examples
+
+```tsx
+import { List, SwipeAction } from '@ant-design/react-native'
+import React from 'react'
+import { View } from 'react-native'
+
+export default class BasicSwipeActionExample extends React.Component<any, any> {
+  asyncFunction = () => {
+    return new Promise((resolve) => {
+      setTimeout(() => {
+        console.log('asd')
+        resolve(123)
+      }, 1500)
+    })
+  }
+
+  render() {
+    const right = [
+      {
+        text: 'More',
+        onPress: async () => {
+          await this.asyncFunction()
+        },
+        backgroundColor: 'orange',
+        color: 'white',
+      },
+      {
+        text: 'Delete',
+        onPress: () => console.log('delete'),
+        backgroundColor: 'red',
+        color: 'white',
+      },
+    ]
+    const left = [
+      {
+        text: 'Read',
+        onPress: () => console.log('read'),
+        backgroundColor: 'blue',
+        color: 'white',
+      },
+      {
+        text: 'Reply',
+        onPress: () => console.log('reply'),
+        backgroundColor: 'green',
+        color: 'white',
+      },
+    ]
+
+    return (
+      <View style={{ paddingTop: 30 }}>
+        <List>
+          <SwipeAction
+            right={right}
+            left={left}
+            closeOnAction
+            closeOnTouchOutside>
+            <List.Item extra="extra content">
+              Simple example: left and right buttons
+            </List.Item>
+          </SwipeAction>
+        </List>
+        <List>
+          <SwipeAction
+            right={right}
+            left={left}
+            closeOnAction={false}
+            closeOnTouchOutside
+            onSwipeableOpen={() => console.log('open')}
+            onSwipeableClose={() => console.log('close')}>
+            <List.Item extra="extra content">
+              Simple example: left and right buttons
+            </List.Item>
+          </SwipeAction>
+        </List>
+      </View>
+    )
+  }
+}
+```
+
+## API
+
+### SwipeAction
+
+| Properties | Descrition | Type | Default | Version |
+|-----|-----|------|-------|------|
+| closeOnAction | Whether to return to the position automatically when the operation button is clicked | `boolean` | `true` | `5.2.1` |
+| closeOnTouchOutside | Whether to return to the position automatically when other areas is clicked | `boolean` | `false` | `5.2.1` |
+| left          | List of operation buttons on the left | [SwipeoutButtonProps](/components/swipe-action#swipeoutbuttonprops)[] | `[]` | |
+| right         | List of operation buttons on the right | [SwipeoutButtonProps](/components/swipe-action#swipeoutbuttonprops)[] | `[]` | |
+| styles        | Semantic DOM style | [SwipeActionStyle](/components/swipe-action#swipeactionstyle-interface) | - | `5.2.1` |
+
+The rest of the props of `SwipeAction` are exactly the same as [react-native-gesture-handler/Swipeable](https://docs.swmansion.com/react-native-gesture-handler/docs/components/swipeable/),
+
+**eg: `onSwipeableOpen` , `onSwipeableClose` , `renderLeftActions` , `renderRightActions`**
+
+
+When you set `renderLeftActions` prop, it will override `left` prop; <br/>
+when you set `renderRightActions` prop, it will override `right` prop.
+
+### SwipeoutButtonProps
+
+| Properties | Descrition | Type | Default | Version |
+|-----|------|------|------|------|
+| backgroundColor | background color | `string` | - | |
+| color | font color | `string` | - | |
+| disabled | Whether disabled | `boolean` | - | |
+| onPress | Trigger when clicked | `() => void | Promise<any>` | - | `5.2.1` support async |
+| style | Aaction button style, effective when `text` is `string` | `StyleProp<TextStyle>` | - | |
+| text | Text | `string | ReactNode` | - | |
+| actionButtonProps | Rest props | [RectButtonProps](https://docs.swmansion.com/react-native-gesture-handler/docs/components/buttons/#rectbutton) | - | `5.2.1` |
+
+### SwipeActionStyle interface
+
+```typescript
+export interface SwipeActionStyle {
+  actionButton: ViewStyle
+  actionText: TextStyle
+}
+```
+
+### Ref
+
+New in `5.2.1`. Ref to Swipeable[#Ref](https://docs.swmansion.com/react-native-gesture-handler/docs/components/swipeable/#methods)
+
+| Properties | Descrition | Type|
+|-----|------|------|
+| close | method that closes component | `() => void` |
+| openLeft | method that opens component on left side. | `() => void` |
+| openRight | method that opens component on right side. | `() => void` |
+| reset | method that resets the swiping states of this `Swipeable` component.<br/>Unlike method `close`, this method does not trigger any animation. | `() => void` |
+
+---
+
+## Switch
+
+Source: https://rn.mobile.ant.design/components/switch.md
+
+# Switch
+
+Select between two status, e.g. Select On or Off.
+
+### Rules
+- This is a **controlled component** that requires an `onChange` callback that updates the `checked` prop in order for the component to reflect user actions. 
+
+## Examples
+
+```tsx
+import { Button, Icon, List, Switch, WhiteSpace, WingBlank } from '@ant-design/react-native'
+import React from 'react'
+import { ScrollView } from 'react-native'
+
+export default class SwitchExample extends React.Component<any, any> {
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      disabled: true,
+      checked: false,
+    }
+  }
+
+  toggle = () => {
+    this.setState({
+      disabled: !this.state.disabled,
+    })
+  }
+
+  sleep1s = () => {
+    return new Promise((resolve) => {
+      setTimeout(resolve, 1000)
+    })
+  }
+
+  onChangeAsync = async (val: boolean) => {
+    await this.sleep1s()
+    this.setState({
+      checked: val,
+    })
+  }
+
+  render() {
+    return (
+      <ScrollView>
+        <List renderHeader="基本">
+          <List.Item extra={<Switch />}>最简单的用法</List.Item>
+        </List>
+        <List renderHeader="不可用">
+          <List.Item extra={<Switch disabled={this.state.disabled} />}>
+            Switch 失效状态
+          </List.Item>
+          <WhiteSpace />
+          <WingBlank>
+            <Button type="primary" onPress={this.toggle}>
+              Toggle disabled
+            </Button>
+          </WingBlank>
+        </List>
+        <List renderHeader="文字和图标">
+          <List.Item
+            extra={
+              <Switch
+                checkedChildren="开"
+                unCheckedChildren="关"
+                defaultChecked
+              />
+            }
+          />
+          <List.Item
+            extra={<Switch checkedChildren="1" unCheckedChildren="0" />}
+          />
+          <List.Item
+            extra={
+              <Switch
+                checkedChildren={<Icon name="check" color="white" />}
+                unCheckedChildren={<Icon name="close" color="white" />}
+                defaultChecked
+              />
+            }
+          />
+        </List>
+        <List renderHeader="加载中">
+          <List.Item extra={<Switch checked loading />}>
+            标识开关操作仍在执行中
+          </List.Item>
+          <List.Item extra={<Switch loading />} />
+        </List>
+        <List renderHeader="颜色">
+          <List.Item extra={<Switch checked color="red" />}>
+            color="red"
+          </List.Item>
+        </List>
+        <List renderHeader="异步">
+          <List.Item
+            extra={
+              <Switch
+                checked={this.state.checked}
+                onChange={this.onChangeAsync}
+              />
+            }>
+            onChange 返回 Promise
+          </List.Item>
+        </List>
+      </ScrollView>
+    )
+  }
+}
+```
+
+## API
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| checked    | Whether is checked by default    | Boolean       |   false  |
+| defaultChecked | Whether to open initially	 | Boolean   |   false     |
+| disabled   | whether is disabled    | Boolean       |   false  |
+| loading    | Loading status | Boolean | false |
+| onChange   | The callback function when changing, when the Promise is returned, the loading status will be displayed automatically	 | `(val: boolean) => void \| Promise<void>` |  -  |
+| color | Background color when the switch is turned on. | String | #4dd865 |
+| checkedChildren | Selected content | ReactNode   |   -     |
+| unCheckedChildren | Non-selected content | ReactNode   |   -     |
+| styles     | Semantic DOM style | [SwitchStyle](#switchstyle-interface) | - |
+
+### SwitchStyle interface
+
+```typescript
+interface SwitchStyle {
+  switch: ViewStyle
+  switch_inner: ViewStyle
+  switch_handle: ViewStyle
+  switch_checked: ViewStyle
+  switch_unchecked: ViewStyle
+  switch_inner_checked: ViewStyle
+  switch_inner_unchecked: ViewStyle
+  switch_handle_checked: ViewStyle
+  switch_handle_unchecked: ViewStyle
+  switch_checked_disabled: ViewStyle
+  switch_unchecked_disabled: ViewStyle
+  switch_handle_disabled: ViewStyle
+}
+```
+
+---
+
+## TabBar
+
+Source: https://rn.mobile.ant.design/components/tab-bar.md
+
+# TabBar
+
+Located at the bottom of the APP, to facilitate users to quickly switch between different functional modules。
+
+### Rule
+- Used as a class of APP classification, the number of tab between 3-5 is better。
+- Even if a Tab is not available, do not disable or remove the Tab。
+- Use Badge make a hint,stay can also know that there is content update。
+
+## Examples
+
+```tsx
+import { Icon, SearchBar, TabBar } from '@ant-design/react-native'
+import React from 'react'
+import { Text, View } from 'react-native'
+
+export default class BasicTabBarExample extends React.Component<any, any> {
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      selectedTab: 'redTab',
+    }
+  }
+
+  renderContent(pageText: any) {
+    return (
+      <View style={{ flex: 1, alignItems: 'center', backgroundColor: 'white' }}>
+        <SearchBar placeholder="Search" showCancelButton />
+        <Text style={{ margin: 50 }}>{pageText}</Text>
+      </View>
+    )
+  }
+
+  onChangeTab(tabName: any) {
+    this.setState({
+      selectedTab: tabName,
+    })
+  }
+
+  render() {
+    return (
+      <TabBar
+        unselectedTintColor="#949494"
+        tintColor="#33A3F4"
+        barTintColor="#f5f5f5">
+        <TabBar.Item
+          title="Life"
+          icon={<Icon name="home" />}
+          selected={this.state.selectedTab === 'blueTab'}
+          onPress={() => this.onChangeTab('blueTab')}>
+          {this.renderContent('Life Tab')}
+        </TabBar.Item>
+        <TabBar.Item
+          icon={<Icon name="ordered-list" />}
+          title="Koubei"
+          badge={2}
+          selected={this.state.selectedTab === 'redTab'}
+          onPress={() => this.onChangeTab('redTab')}>
+          {this.renderContent('Koubei Tab')}
+        </TabBar.Item>
+        <TabBar.Item
+          icon={<Icon name="like" />}
+          title="Friend"
+          selected={this.state.selectedTab === 'greenTab'}
+          onPress={() => this.onChangeTab('greenTab')}>
+          {this.renderContent('Friend Tab')}
+        </TabBar.Item>
+        <TabBar.Item
+          icon={<Icon name="user" />}
+          title="My"
+          selected={this.state.selectedTab === 'yellowTab'}
+          onPress={() => this.onChangeTab('yellowTab')}>
+          {this.renderContent('My Tab')}
+        </TabBar.Item>
+      </TabBar>
+    )
+  }
+}
+```
+
+## API
+
+### TabBar
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| barTintColor  | tabbar's background color     | String   | `white`    |
+| tintColor  | selected's font color   | String | `#108ee9`   |
+| unselectedTintColor | unselected's font color  | String | '#888'    |
+| hidden   | whether it is hidden  | Boolean | false   |
+
+### TabBar.Item
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| badge  | badge number  | Number \ String           | 无     |
+| onPress  | on press the bar, need change component by yourself. state & selecte={true} | Function | `(){}`     |
+| selected  | whether it is selected | Boolean | false     |
+| icon  | the default icon | `Image Source | React.ReactNode` |      |
+| selectedIcon  |  the icon of selected | `Image Source | React.ReactNode` |      |
+| title  |  title | String |      |
+| key  |  unique identification | String |   无   |
+| iconStyle  |  icon style | String | { width: 28, height: 28 }     |
+
+---
+
+## Tabs
+
+Source: https://rn.mobile.ant.design/components/tabs.md
+
+# Tabs
+
+A `Tabs` is used to allow users to switch between different views.
+
+### Rule
+
+- Generally a `Tabs` should have 2-4 tab pane, the title of each tab pane should be concise,normally has 2-4 words..
+- In the secondary page of iOS, it is not recommended to use left and right swipe to switch tab, which conflicts with back swipe gestrue in iOS. eg:  tabs in details page.
+
+## Examples
+
+```tsx
+import React from 'react'
+import { ScrollView, Text, TouchableOpacity, View } from 'react-native'
+import Tabs from '..'
+
+const renderContent = (tab: any, index: any) => {
+  const style = {
+    paddingVertical: 40,
+    justifyContent: 'center',
+    alignItems: 'center',
+    margin: 10,
+    backgroundColor: '#ddd',
+  } as any
+  const content = [1, 2, 3, 4, 5, 6, 7, 8].map((i) => {
+    return (
+      <View key={`${index}_${i}`} style={style}>
+        <Text>
+          {tab.title} - {i}
+        </Text>
+      </View>
+    )
+  })
+  return (
+    <ScrollView key={index} style={{ backgroundColor: '#fff' }}>
+      {content}
+    </ScrollView>
+  )
+}
+
+export default class BasicTabsExample extends React.Component<any, any> {
+  render() {
+    const tabs = [
+      { title: 'First Tab' },
+      { title: 'Second Tab' },
+      { title: 'Third Tab' },
+    ]
+    const tabs2 = [
+      { title: '1st Tab' },
+      { title: '2nd Tab' },
+      { title: '3rd Tab' },
+      { title: '4th Tab' },
+      { title: '5th Tab' },
+      { title: '6th Tab' },
+      { title: '7th Tab' },
+      { title: '8th Tab' },
+      { title: '9th Tab' },
+    ]
+    const style = {
+      alignItems: 'center',
+      justifyContent: 'center',
+      height: 150,
+      backgroundColor: '#fff',
+    } as any
+    return (
+      <View style={{ flex: 1 }}>
+        <Tabs tabs={tabs}>
+          <View style={style}>
+            <Text>Content of First Tab</Text>
+          </View>
+          <View style={style}>
+            <Text>Content of Second Tab</Text>
+          </View>
+          <View style={style}>
+            <Text>Content of Third Tab</Text>
+          </View>
+        </Tabs>
+        <Text style={{ margin: 16 }}>Custom RenderTabBar</Text>
+        <Tabs
+          tabs={tabs}
+          renderTabBar={(tabProps) => (
+            <View
+              style={{
+                paddingHorizontal: 16,
+                flexDirection: 'row',
+                alignItems: 'center',
+                justifyContent: 'space-evenly',
+              }}>
+              {tabProps.tabs.map((tab, i) => (
+                // change the style to fit your needs
+                <TouchableOpacity
+                  activeOpacity={0.9}
+                  key={tab.key || i}
+                  style={{
+                    // width: '30%',
+                    padding: 6,
+                  }}
+                  onPress={() => {
+                    const { goToTab, onTabClick } = tabProps
+                    // tslint:disable-next-line:no-unused-expression
+                    onTabClick && onTabClick(tabs[i], i)
+                    // tslint:disable-next-line:no-unused-expression
+                    goToTab && goToTab(i)
+                  }}>
+                  <Text
+                    style={{
+                      color: tabProps.activeTab === i ? 'green' : '#333333',
+                    }}>
+                    {tab.title}
+                  </Text>
+                </TouchableOpacity>
+              ))}
+            </View>
+          )}>
+          <View style={style}>
+            <Text>Content of First Tab</Text>
+          </View>
+          <View style={style}>
+            <Text>Content of Second Tab</Text>
+          </View>
+          <View style={style}>
+            <Text>Content of Third Tab</Text>
+          </View>
+        </Tabs>
+        <View style={{ flex: 2 }}>
+          <Tabs tabs={tabs2} initialPage={1} tabBarPosition="top">
+            {tabs2.map((tab, index) => renderContent(tab, index))}
+          </Tabs>
+        </View>
+      </View>
+    )
+  }
+}
+
+export const title = 'Tabs'
+export const description = 'Tabs example'
+```
+
+## API
+
+### Tabs
+
+Properties | Descrition | Type | Default | Required
+-----------|------------|------|--------|--------
+tabs | tabs data | Models.TabData[] |  | true
+tabBarPosition | TabBar's position | 'top' \| 'bottom' |  top | false
+renderTabBar | replace the TabBar | ((props: TabBarPropsType) => React.ReactNode) \| false |  | false
+initialPage | the tab when inital, index or key | number \| string |  | false
+page | current tab, index or key | number \| string |  | false
+swipeable | Whether to switch tabs with swipe gestrue in the content | boolean |  true | false
+useOnPan | use hand scroll | boolean |  true | false
+prerenderingSiblingsNumber  | pre-render nearby # sibling, Infinity: render all the siblings, 0: render current page. | number | 1 | false
+animated | Whether to change tabs with animation | boolean |  true | false
+onChange | Callback when tab is switched | (tab: Models.TabData, index: number) => void |  | false
+onTabClick  | on tab click | (tab: Models.TabData, index: number) => void |  | false
+destroyInactiveTab | destroy inactive tab | boolean |  false | false
+distanceToChangeTab | distance to change tab, width ratio | number |  0.3 | false
+usePaged | use paged | boolean |  true | false
+tabBarUnderlineStyle | style of the default tab bar's underline | React.CSSProperties \| any |  | false
+tabBarBackgroundColor | color of the default tab bar's background | string |  | false
+tabBarActiveTextColor | color of the default tab bar's text when active | string |  | false
+tabBarInactiveTextColor | color of the default tab bar's text when inactive | string |  | false
+tabBarTextStyle | tional styles to the tab bar's text | React.CSSProperties \| any |  | false
+renderTab | render for replace the tab of tabbar | (tab: Models.TabData) => React.ReactNode | | false
+renderUnderline | renderUnderline | (style: any) => React.ReactNode | | false
+
+### Tabs.DefaultTabBar
+
+Properties | Descrition | Type | Default | Required
+-----------|------------|------|--------|--------
+goToTab | call this function to switch Tab | (index: number) => boolean | | true
+tabs | tabs data | Models.TabData[] | | true
+activeTab | current tab | number | | true
+animated | Whether to change tabs with animation | boolean | | true
+renderTab | render for replace the tab of tabbar | (tab: Models.TabData) => React.ReactNode | | false
+page | the size for the tab of tabbar | number | 5 | false
+onTabClick  | on tab click | (tab: Models.TabData, index: number) => void |  | false
+
+---
+
+## Tag
+
+Source: https://rn.mobile.ant.design/components/tag.md
+
+# Tag
+
+Tag for categorizing or markuping, can be used to make classification or mark the attributes and dimensions of objects.
+
+### Rules
+
+- The content should be displayed completely.
+
+## Examples
+
+```tsx
+import { Tag, WhiteSpace } from '@ant-design/react-native'
+import React from 'react'
+import { View } from 'react-native'
+
+function onChange(selected: any) {
+  console.log(`tag selected: ${selected}`)
+}
+
+export default class BasicTagExample extends React.Component<any, any> {
+  render() {
+    return (
+      <View style={{ padding: 10 }}>
+        <Tag>Basic</Tag>
+        <WhiteSpace />
+        <Tag selected>Selected</Tag>
+        <WhiteSpace />
+        <Tag disabled>Disabled</Tag>
+        <WhiteSpace />
+        <Tag onChange={onChange}>Callback</Tag>
+        <WhiteSpace />
+        <Tag
+          closable
+          onClose={() => {
+            console.log('onClose')
+          }}
+          afterClose={() => {
+            console.log('afterClose')
+          }}>
+          Closable
+        </Tag>
+        <WhiteSpace />
+        <Tag small>Small and Readonly</Tag>
+        <WhiteSpace />
+        <Tag
+          onLongPress={() => {
+            console.log('onLongPress')
+          }}>
+          LongPress
+        </Tag>
+      </View>
+    )
+  }
+}
+```
+
+## API
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| small   |  Whether to show a smaller size  |   Boolean    |  `false`  |
+| disabled   | Whether is disabled      | Boolean |    `false`  |
+| closable   | Whether can be closed(invalid in `small` or `disabled` mode) | Boolean | `false` |
+| selected   | Whether is selected by default     | Boolean |   `false`  |
+| onChange   | The callback function that is triggered when the selected state changes. | (selected: bool): void |   -  |
+| onClose   | The callback function that is triggered when the tag is closed. | (): void |   -  |
+| afterClose   | The callback function that is triggered after close. | (): void |   -  |
+| onLongPress   | The callback function that is triggered when the tag is long pressed. | (): void |   -  |
+
+---
+
+## TextareaItem
+
+Source: https://rn.mobile.ant.design/components/textarea-item.md
+
+# TextareaItem
+
+> This package has been deprecated in `5.2.1`, recommend [components/Input.TextArea](/components/input#inputtextarea)
+
+A foundational component for inputting multi-line text into the app via a keyboard.
+
+### Rule
+- Support text input via keyboard or clipboard.
+- The cursor can be moved horizontally.
+
+## Examples
+
+```tsx
+import { List, TextareaItem, Toast } from '@ant-design/react-native'
+import React from 'react'
+import { ScrollView } from 'react-native'
+
+export default class BasicTextAreaItemExample extends React.Component<
+  any,
+  any
+> {
+  constructor(props: any) {
+    super(props)
+    this.state = {
+      val: '默认带value',
+    }
+  }
+
+  onChange = (val: any) => {
+    // console.log(val);
+    this.setState({ val })
+  }
+
+  render() {
+    return (
+      <ScrollView
+        style={{ flex: 1 }}
+        automaticallyAdjustContentInsets={false}
+        showsHorizontalScrollIndicator={false}
+        showsVerticalScrollIndicator={false}>
+        <List renderHeader={'基本'}>
+          <TextareaItem rows={4} placeholder="固定行数" />
+
+          <TextareaItem rows={4} placeholder="多行带计数" count={100} />
+
+          <TextareaItem
+            rows={4}
+            placeholder="高度自适应"
+            autoHeight
+            style={{ paddingVertical: 5 }}
+          />
+
+          <TextareaItem value={this.state.val} onChange={this.onChange} />
+
+          <TextareaItem value="不可编辑 editable = {false}" editable={false} />
+
+          <TextareaItem clear={false} placeholder="不显示清除按钮" />
+
+          <TextareaItem
+            error
+            defaultValue="报错样式 error={true}"
+            onErrorClick={() => Toast.fail('Error message')}
+          />
+        </List>
+      </ScrollView>
+    )
+  }
+}
+```
+
+## API
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| value | the value to show for the textarea (see [react doc](https://facebook.github.io/react/docs/forms.html) for more information about controlled component)  | String | |
+| defaultValue | provides an initial value that will change when the user starts typing.  | String |  -  |
+| placeholder      | the string that will be rendered before text input has been entered. | String | ''  |
+| editable    | whether is editable         | bool |  true  |
+| disabled    | whether is disabled         | bool |  false  |
+| clear       | whether to display the clear icon (it takes effect only if `editable` is `true` and `disabled` is `false`) | bool | false  |
+| rows        | sets the number of lines for a textarea     | number |   1 |
+| count |  it is used for word count and maxlength, the default is 0 which indicates that word count is turned off. | number | -  |
+| onChange    | callback that is called when the textarea's text changes. | (val: string): void |  -  |
+| error       | whether to display error         | bool |  false  |
+| onErrorClick   | callback that is called when the error icon is clicked   | (): void |    |
+| autoHeight | auto adjust height (only use one of `autoHeight` and `rows` properties) | bool  | false  |
+| labelNumber  | number of label text, valid value is 2 to 7 | number | `5` |
+| last      |  If it is the last item, the `borderBottom` will be removed, the default has `borderBottom`   | bool | false  |
+
+> More available react-native `TextareaItem` API can be found at [react-native TextInput](http://facebook.github.io/react-native/docs/textinput.html)
+
+---
+
+## Toast
+
+Source: https://rn.mobile.ant.design/components/toast.md
+
+# Toast
+
+A lightweight feedback or tips, used to display content that does not interrupt user operations. Suitable for page transitions, data interaction and other scenes.
+
+### Rules
+- Toast with Icon, 4-6 words is recommended; Toast without Icon, the number of words should not exceed 14.
+
+## Examples
+
+```tsx
+import { Button, List, Provider, Switch, Toast } from '@ant-design/react-native'
+import React, { useEffect, useRef, useState } from 'react'
+import { ActivityIndicator, ScrollView, Text } from 'react-native'
+
+const ToastExample = () => {
+  const handler = useRef<number>()
+  const [enableMask, setEnableMask] = useState(Toast.getConfig().mask)
+  const [enableStack, setEnableStack] = useState(Toast.getConfig().stackable)
+
+  return (
+    <Provider>
+      <ScrollView>
+        <List>
+          <List.Item
+            extra={
+              <Switch
+                checked={enableMask}
+                onChange={(mask) => {
+                  Toast.config({ mask })
+                  setEnableMask(Toast.getConfig().mask)
+                }}
+              />
+            }>
+            Enable mask
+            <List.Item.Brief>是否显示透明蒙层,防止触摸穿透</List.Item.Brief>
+          </List.Item>
+          <List.Item
+            extra={
+              <Switch
+                checked={enableStack}
+                onChange={(stackable) => {
+                  Toast.config({ stackable })
+                  setEnableStack(Toast.getConfig().stackable)
+                }}
+              />
+            }>
+            Enable stackable
+            <List.Item.Brief>是否允许叠加显示</List.Item.Brief>
+          </List.Item>
+        </List>
+        <List renderHeader="图标">
+          <Button
+            onPress={() => {
+              Toast.success('Success')
+            }}>
+            成功
+          </Button>
+          <Button
+            onPress={() => {
+              Toast.fail('Fail')
+            }}>
+            失败
+          </Button>
+          <Button
+            onPress={() => {
+              Toast.offline('Network connection failed !!!')
+            }}>
+            网络失败
+          </Button>
+          <Button
+            onPress={() => {
+              Toast.loading('loading...')
+            }}>
+            加载中
+          </Button>
+          <Button
+            onPress={() => {
+              Toast.show({
+                content: '上传中',
+                icon: <ActivityIndicator />,
+              })
+            }}>
+            自定义图标
+          </Button>
+        </List>
+        <List renderHeader="更多功能">
+          <Button
+            onPress={() => {
+              Toast.show({
+                content: 'Hello World',
+                position: 'top',
+              })
+            }}>
+            顶部提示
+          </Button>
+          <Button
+            onPress={() => {
+              Toast.show({
+                content: 'Hello World',
+                position: 'bottom',
+              })
+            }}>
+            底部提示
+          </Button>
+          <Button
+            onPress={() => {
+              Toast.show({
+                icon: 'loading',
+                content: <CountDownText />,
+                duration: 5,
+              })
+            }}>
+            动态内容
+          </Button>
+        </List>
+        <List renderHeader="手动清除">
+          <Button
+            onPress={() => {
+              handler.current = Toast.show({
+                content: '这条提示不会自动消失',
+                duration: 0,
+                position: 'top',
+                mask: false,
+              })
+            }}>
+            显示
+          </Button>
+          <Button
+            onPress={() => {
+              handler.current && Toast.remove(handler.current)
+            }}>
+            清除
+          </Button>
+          <Button
+            onPress={() => {
+              Toast.removeAll()
+            }}>
+            关闭所有
+          </Button>
+        </List>
+      </ScrollView>
+    </Provider>
+  )
+}
+
+export default ToastExample
+
+const CountDownText = () => {
+  const [count, setCount] = useState(5)
+  const interval = useRef<any>()
+  useEffect(() => {
+    interval.current = setInterval(() => {
+      setCount((x) => {
+        if (x > 1) {
+          return x - 1
+        } else {
+          return x
+        }
+      })
+    }, 1000)
+    return () => {
+      interval.current && clearInterval(interval.current)
+    }
+  }, [])
+  return <Text style={{ color: '#ffffff' }}>还剩 {count} 秒</Text>
+}
+```
+
+## API
+
+`Toast` only supports Imperative calls. The argument type is `string | ToastProps`.
+
+- `Toast.show(props)` - New in `5.2.1`
+- `Toast.success(props)`
+- `Toast.fail(props)`
+- `Toast.info(props)`
+- `Toast.loading(props)`
+- `Toast.offline(props)`
+
+`Toast.show(string)`'s default config is `{duration:1.5, mask: false}`. Another method is to specify a shortcut to the `icon`.
+
+ToastProps has these fields:
+
+| Properties | Descrition | Type |  Required  | Default | Version |
+| ---------- | ---------- | -----| -----------| --------|---------|
+| content    | Toast content | `String | React.ReactNode` | Yes | - | |
+| duration   | Delay time to close, which units is second | number |  No  | 3 | |
+| icon       | Toast icon | `'success' | 'fail' | 'offline' | 'loading' | React.ReactNode` | No | - | `5.2.1` |
+| mask       | Whether to show a transparent mask, which will prevent touch event of the whole page | Boolean |  No  | true | |
+| onClose    | A callback function Triggered when the Toast is closed | Function | No | - | |
+| position  | Vertical display position | `'top' | 'bottom' | 'center'` | No  | `'center'` | `5.2.1` |
+| stackable |  Whether to allow toast overlay | Boolean  |  No | true | |
+| styles    | Semantic DOM style              | [ToastStyle](#toaststyle-interface) | No | - | `5.2.1` |
+
+> **Notice:** OnClose is invalid and Toast does not hide, If set duration = 0, toast will not auto hide, you have to manually do it.
+
+```js
+import { Toast } from '@ant-design/react-native';
+
+const key = Toast.loading('message');
+Toast.remove(key);
+```
+
+### Toast.removeAll
+
+Turn off `Toast` in all displays.
+
+```ts
+Toast.removeAll()
+```
+
+### Toast.config
+
+Methods for global configuration. Support `duration`、`mask`、`onClose`、`position`、`stackable` and `style`. The configuration method is as follows:
+
+```ts
+Toast.config({ duration: 1, position: 'top' })
+
+// get current config
+Toast.getConfig()
+```
+
+### Toast.useToast()
+
+New in `5.3.0`.  antd-mobile-rn will inserted into the root node of `<Provider>` through `Portal.add` when call toast methods. Whose context is different with origin code located context.
+<br/>
+When you need context info (like **Modal** context), you can use `toast.useToast` to get `toastApi` instance and `contextHolder` node. And put it in your children:
+
+```jsx
+import { Modal } from 'react-native'
+import { Toast } from '@ant-design/react-native'
+
+const [toastApi, contextHolder] = Toast.useToast();
+
+const showLoading = () => {
+  toastApi.loading(
+    // ...
+  );
+}
+
+return (
+  <Modal>
+    {contextHolder}
+    <View>
+      ...
+    </View>
+  </Modal>
+);
+```
+
+### InputStyle interface
+
+```typescript
+interface ToastStyle {
+  container: ViewStyle
+  innerContainer: ViewStyle
+  innerWrap: ViewStyle
+  iconToast: ViewStyle
+  textToast: ViewStyle
+  content: TextStyle
+  image: TextStyle
+  centering: ViewStyle
+}
+```
+
+---
+
+## Tooltip
+
+Source: https://rn.mobile.ant.design/components/tooltip.md
+
+# Tooltip
+
+After clicking on a control or an area, a Tooltip menu appears for doing more.
+If set mask prop, it is recommended to exit by clicking on any of the mask layers.
+
+## Examples
+
+```tsx
+import {
+  Button,
+  Icon,
+  List,
+  Provider,
+  Toast,
+  Tooltip,
+} from '@ant-design/react-native'
+import React, { useEffect, useState } from 'react'
+import { ScrollView, Text, View } from 'react-native'
+import { Action, TooltipProps } from '../PropsType'
+
+const actions: Action[] = [
+  { key: 'scan', icon: <Icon name="scan" />, text: '扫一扫' },
+  { key: 'payment', icon: <Icon name="pay-circle" />, text: '付钱/收钱' },
+  { key: 'bus', icon: <Icon name="qrcode" />, text: '乘车码' },
+  { key: 'assistant', icon: <Icon name="ant-design" />, text: '智能助理' },
+]
+
+export default function TooltipExample() {
+  const [placement, setPlacement] =
+    useState<TooltipProps['placement']>('top-start')
+
+  useEffect(() => {
+    let current = 0
+
+    const timer = setInterval(() => {
+      if (current >= directionList.length - 1) {
+        current = 0
+      } else {
+        current += 1
+      }
+      setPlacement(directionList[current])
+    }, 2000)
+
+    return () => {
+      clearInterval(timer)
+    }
+  }, [])
+
+  return (
+    <Provider>
+      <ScrollView {...Tooltip.scrollProps}>
+        <List renderHeader="基本用法">
+          <Tooltip
+            content="Hello World"
+            trigger="onPress"
+            placement="right"
+            defaultVisible>
+            <Button style={{ alignSelf: 'flex-start', margin: 10 }}>
+              点我
+            </Button>
+          </Tooltip>
+        </List>
+        <List renderHeader="深色气泡">
+          <Tooltip content="Hello World" placement="bottom" mode="dark" visible>
+            <Button
+              style={{ alignSelf: 'flex-start', margin: 10, marginBottom: 30 }}>
+              点我
+            </Button>
+          </Tooltip>
+        </List>
+        <List renderHeader="气泡位置">
+          <Tooltip
+            visible
+            content={
+              <View>
+                <Text>Popover</Text>
+                <Text>Content</Text>
+              </View>
+            }
+            styles={{ arrow: { borderTopColor: 'yellow' } }}
+            placement={placement}>
+            <Button style={{ alignSelf: 'center', margin: 10 }}>
+              {placement}
+            </Button>
+          </Tooltip>
+        </List>
+        <List renderHeader="浅色气泡菜单">
+          <Tooltip.Menu
+            actions={actions}
+            placement="bottom-start"
+            onAction={(node) => Toast.show(`选择了 ${node.text}`)}
+            trigger="onPress">
+            <Button style={{ alignSelf: 'flex-start', margin: 10 }}>
+              点我
+            </Button>
+          </Tooltip.Menu>
+        </List>
+        <List renderHeader="深色气泡菜单">
+          <Tooltip.Menu
+            mode="dark"
+            actions={actions}
+            placement="bottom-start"
+            onAction={(node) => Toast.show(`选择了 ${node.text}`)}
+            trigger="onPress">
+            <Button style={{ alignSelf: 'flex-start', margin: 10 }}>
+              点我
+            </Button>
+          </Tooltip.Menu>
+        </List>
+        <List renderHeader="超过最大数量,隐藏滚动">
+          <Tooltip.Menu
+            actions={actions}
+            maxCount={2}
+            onAction={(node) => Toast.show(`选择了 ${node.text}`)}
+            placement="bottom-start"
+            trigger="onPress">
+            <Button style={{ alignSelf: 'flex-start', margin: 10 }}>
+              点我
+            </Button>
+          </Tooltip.Menu>
+        </List>
+      </ScrollView>
+    </Provider>
+  )
+}
+
+const directionList = [
+  'top-start',
+  'top',
+  'top-end',
+  'right-start',
+  'right',
+  'right-end',
+  'bottom-end',
+  'bottom',
+  'bottom-start',
+  'left-end',
+  'left',
+  'left-start',
+] as const
+```
+
+## API
+
+### Tooltip
+
+| Name | Description | Type | Default |
+| --- | --- | --- | --- |
+| children | The element that triggered the Tooltip | `React.ReactElement` | - |
+| content | The content of the Tooltip | `React.ReactNode` | - |
+| defaultVisible | Whether to show or hide by default | `boolean` | `false` |
+| mode | Set bright color mode or black mode | `'light' | 'dark'` | `'light'` |
+| crossOffset | Set the offset of the pop-up window position; Top: Additional offset applied along the main axis between the element and its triggering element. Left: Additional offset applied along the horizontal axis between the element and its triggering element.     | `{ top: number, left: number }`      | `'{ top: StatusBar.currentHeight, left: 0 } '` |
+| onVisibleChange | Callback when the visible prop is changed | `(visible: boolean) => void` | - |
+| placement | The position of the Tooltip | `'top' | 'top-start' | 'top-end' | 'right' | 'right-start' | 'right-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end'` | `'top'` |
+| styles | Semantic DOM style | [TooltipStyle](#tooltipstyle-interface) | - |
+| trigger | Event to trigger | `'onPress'` | - |
+| visible | Whether to display pop-up content in controlled mode | `boolean` | - |
+
+### Ref
+
+| Name    | Description                      | Type         |
+| ------- | -------------------------------- | ------------ |
+| hide    | Hide the Tooltip                 | `() => void` |
+| show    | Show the Tooltip                 | `() => void` |
+| visible | Whether the Tooltip is diplaying | `boolean`    |
+
+## Tooltip.scrollProps
+
+While `Tooltip` is inside a `<ScrollView />`, please pread `Tooltip.scrollProps` to the ScrollView,
+<br/>
+otherwise it will not follow the scroll
+
+```jsx
+import { ScrollView } from 'react-native'
+import { Tooltip } from '@ant-design/react-native'
+
+<ScrollView {...Tooltip.scrollProps}>
+  <Tooltip>...</Tooltip>
+<ScrollView>
+```
+
+## Tooltip.Menu
+
+### Props
+
+Except for `content`, all other attributes are inherited from `Tooltip`, the unique attributes are as follows:
+
+| Name | Description | Type | Default |
+| --- | --- | --- | --- |
+| actions | Menu list, used when the pop-up content is a standard menu | `Action[]` | - |
+| maxCount | Maximum number of menu lists, if exceeded, hide for scrolling | `number` | - |
+| onAction | Callback of the selected menum, when the menu list is used | `(item: Action) => void` | - |
+
+### Action
+
+| Name | Description | Type | Default |
+| --- | --- | --- | --- |
+| disabled | Whether disabled | `boolean` | `false` |
+| icon | The icon of the menu item | `ReactNode` | `null` |
+| key | The unique identifier of the menu, the default is `index` | `string | number` | `actions` array's `index` |
+| onPress | Triggered on click | `() => void` | - |
+| text | Menu list, used when the pop-up content is a standard menu | `ReactNode` | - |
+
+### TooltipStyle interface
+
+```typescript
+interface TooltipStyle extends ListItemStyle {
+  tooltip: ViewStyle
+  tooltipText: TextStyle
+  arrow: ViewStyle // `borderTopColor` sets the arrow bg color
+}
+```
+
+### Ref
+
+Same as Tooltip.
+
+## FAQ
+
+### Why can't some children components wrapped by Tooltip be opened onPress?
+
+First, Tooltip's children must be `React.ReactElement`, which is a JSX Element rather than a variable.
+
+```jsx
+const element = <Button>press</Button>
+
+<Tooltip
+  content="Hello World"
+  defaultVisible>
+  {element} // ❌ DO NOT USE
+  <Button>press</Button> // ✅ YES
+</Tooltip>
+```
+Secondly, the positioning of Tooltip is calculated based on `View.onLayout`, so the children component must support the [onLayout](https://reactnative.dev/docs/view#onlayout) event.
+
+```jsx
+const CustomButton = (props: {
+    onLayout: (event: LayoutChangeEvent) => void
+  }) => (
+    <View onLayout={props.onLayout}>
+      ...
+    </View>
+  )
+
+<Tooltip
+  content="Hello World"
+  defaultVisible>
+  <CustomButton>press<CustomButton>
+</Tooltip>
+```
+
+---
+
+## View
+
+Source: https://rn.mobile.ant.design/components/view.md
+
+# View
+
+Safe View
+
+### Rules
+
+- Support `string`/`number` ReactNode
+
+## Examples
+
+```tsx
+import { View } from '@ant-design/react-native'
+import React from 'react'
+
+export default class SafeViewExample extends React.Component<any, any> {
+  render() {
+    return (
+      <View
+        style={{
+          flexDirection: 'row',
+          height: 100,
+          padding: 20,
+        }}>
+        <View style={{ backgroundColor: 'blue', flex: 0.3 }} />
+        <View style={{ backgroundColor: 'red', flex: 0.5 }} />
+        <View>Hello World!</View>
+      </View>
+    )
+  }
+}
+```
+
+## API
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| children | child component | `React.ReactNode` \| `React.ReactText` |  -  |
+| style    | style | `StyleProp<ViewStyle>` \| `StyleProp<TextStyle>` | - |
+
+> More available react-native `View` API can be found at [react-native View](http://facebook.github.io/react-native/docs/view.html)
+
+## FAQ
+
+### What difference between it and React Native's built-in components View and Text?
+
+React Native's View does not support `children` of type `string` / `number`. 
+
+Misinformation will cause crash and no Code Line Numbers 
+
+**This component can be used to evacuate errors once, giving priority to ensuring that the device does not crash.**
+
+Common mistakes:
+```jsx
+const length = arr.length;
+
+<View>
+  {length && <Component />}
+</View>
+
+// when length=0, actually render:
+<View>
+  0
+</View>
+```
+
+Attention, only one layer of protection can be achieved,  even `<React.Fragment>` children maked worng type:
+```jsx
+import {View} from '@ant-design/react-native'
+
+<View>
+  {/* still crash */}
+  <React.Fragment>
+    0
+  </React.Fragment>
+
+  {/* still crash */}
+  <>''</>
+</View>
+```
+
+---
+
+## WhiteSpace
+
+Source: https://rn.mobile.ant.design/components/white-space.md
+
+# WhiteSpace
+
+Layout controls
+
+## Examples
+
+```tsx
+import { WhiteSpace } from '@ant-design/react-native'
+import React from 'react'
+import { Text, View } from 'react-native'
+
+const PlaceHolder = (props: any) => (
+  <View
+    style={{
+      backgroundColor: '#fff',
+      height: 30,
+      alignItems: 'center',
+      justifyContent: 'center',
+    }}
+    {...props}>
+    <Text style={{ color: '#bbb' }}>Block</Text>
+  </View>
+)
+
+export default class WhiteSpaceExample extends React.Component<any, any> {
+  render() {
+    return (
+      <View>
+        <WhiteSpace size="xs" />
+        <PlaceHolder />
+
+        <WhiteSpace size="sm" />
+        <PlaceHolder />
+
+        <WhiteSpace />
+        <PlaceHolder />
+
+        <WhiteSpace size="lg" />
+        <PlaceHolder />
+
+        <WhiteSpace size="xl" />
+        <PlaceHolder />
+      </View>
+    )
+  }
+}
+```
+
+## API
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| size   |  up and down margins, optional values:`xs`,`sm`,`md`,`lg`,`xl` | string | `md`  |
+
+---
+
+## WingBlank
+
+Source: https://rn.mobile.ant.design/components/wing-blank.md
+
+# WingBlank
+
+Layout controls
+
+## Examples
+
+```tsx
+import { WhiteSpace, WingBlank } from '@ant-design/react-native'
+import React from 'react'
+import { Text, View } from 'react-native'
+
+const PlaceHolder = (props: any) => (
+  <View
+    style={{
+      backgroundColor: '#fff',
+      height: 30,
+      alignItems: 'center',
+      justifyContent: 'center',
+    }}
+    {...props}>
+    <Text style={{ color: '#bbb' }}>Block</Text>
+  </View>
+)
+
+export default class WingBlankExample extends React.Component<any, any> {
+  render() {
+    return (
+      <View>
+        <WhiteSpace />
+        <WingBlank>
+          <PlaceHolder />
+        </WingBlank>
+
+        <WhiteSpace size="lg" />
+        <WingBlank size="md">
+          <PlaceHolder />
+        </WingBlank>
+
+        <WhiteSpace size="lg" />
+        <WingBlank size="sm">
+          <PlaceHolder />
+        </WingBlank>
+      </View>
+    )
+  }
+}
+```
+
+## API
+
+Properties | Descrition | Type | Default
+-----------|------------|------|--------
+| size    | left and right blank space, optional values:`sm`,`md`,`lg`  | string |  `lg`  |
+
+---

+ 5019 - 0
docs/antd/llms-semantic.md

@@ -0,0 +1,5019 @@
+# Ant Design Mobile RN Semantic Documentation
+
+Aggregated semantic descriptions for all components.
+
+> 34 components with semantic descriptions
+
+# accordion Semantic
+
+Source: https://rn.mobile.ant.design/components/accordion/semantic.md
+
+# Accordion Semantic
+
+## Component Description
+
+You can collapse / expand the content area.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": "container",
+  "children": [
+    {
+      "component": "View",
+      "style": "header",
+      "children": [
+        {
+          "component": "View",
+          "style": "headerWrap",
+          "children": [
+            {
+              "component": "Text",
+              "style": "headerText"
+            }
+          ]
+        },
+        {
+          "component": "View",
+          "style": "arrow",
+          "children": [
+            {
+              "component": "Icon",
+              "style": "arrow"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "component": "View",
+      "style": "content",
+      "children": [
+        {
+          "component": "Text",
+          "style": "contentText"
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "container": {
+    "type": "ViewStyle",
+    "description": "Container that wraps the entire accordion panel, layout outer container",
+    "defaultValue": { "borderTopWidth": 0.5, "borderTopColor": "#dddddd" }
+  },
+  "header": {
+    "type": "ViewStyle",
+    "description": "Accordion panel header, header area for each panel item",
+    "defaultValue": {
+      "flexDirection": "row",
+      "alignItems": "center",
+      "paddingLeft": 15,
+      "paddingRight": 30,
+      "borderBottomWidth": 0.5,
+      "borderBottomColor": "#dddddd"
+    }
+  },
+  "arrow": {
+    "type": "ViewStyle",
+    "description": "Arrow icon container that displays up or down arrow",
+    "defaultValue": { "color": "#cccccc" }
+  },
+  "headerWrap": {
+    "type": "ViewStyle",
+    "description": "Wrapper container for header content, used to display text content when header is not a React element",
+    "defaultValue": {
+      "flex": 1,
+      "height": 44,
+      "alignItems": "center",
+      "flexDirection": "row"
+    }
+  },
+  "headerText": {
+    "type": "TextStyle",
+    "description": "Header text content",
+    "defaultValue": { "color": "#000000", "fontSize": 17 }
+  },
+  "content": {
+    "type": "ViewStyle",
+    "description": "Accordion panel content area",
+    "defaultValue": {
+      "paddingVertical": 9,
+      "paddingHorizontal": 8,
+      "borderBottomWidth": 0.5,
+      "borderBottomColor": "#dddddd"
+    }
+  },
+  "contentText": {
+    "type": "TextStyle",
+    "description": "Accordion content text",
+    "defaultValue": { "fontSize": 15, "color": "#333333" }
+  }
+}
+```
+
+---
+
+# action-sheet Semantic
+
+Source: https://rn.mobile.ant.design/components/action-sheet/semantic.md
+
+# ActionSheet Semantic
+
+## Component Description
+
+The modal box pops up from the bottom, providing more than two actions related to the current scene, and also support provide the title and description. Built-in fixed display style, does not support particularly flexible changes.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": "container",
+  "children": [
+    {
+      "component": "Modal",
+      "style": "content",
+      "children": [
+        {
+          "component": "View",
+          "children": [
+            {
+              "component": "View",
+              "style": "title",
+              "children": [
+                {
+                  "component": "Text",
+                  "style": "titleText"
+                }
+              ]
+            },
+            {
+              "component": "AntmView",
+              "style": "message"
+            },
+            {
+              "component": "View",
+              "children": [
+                {
+                  "component": "View",
+                  "style": "cancelBtn",
+                  "children": [
+                    {
+                      "component": "TouchableHighlight",
+                      "style": "btn"
+                    },
+                    {
+                      "component": "Text",
+                      "style": ["btnText", "destructiveBtn"]
+                    },
+                    {
+                      "component": "View",
+                      "style": "cancelBtnMask"
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "container": {
+    "type": "ViewStyle",
+    "description": "Container area, overall wrapper for ActionSheet, handles layout",
+    "defaultValue": { "zIndex": 1000 }
+  },
+  "wrap": {
+    "type": "ViewStyle",
+    "description": "Wrap style",
+    "defaultValue": { "position": "absolute", "left": 0, "right": 0, "top": 0 }
+  },
+  "content": {
+    "type": "ViewStyle",
+    "description": "Content style",
+    "defaultValue": {
+      "position": "absolute",
+      "left": 0,
+      "right": 0,
+      "bottom": 0,
+      "backgroundColor": "#ffffff"
+    }
+  },
+  "mask": {
+    "type": "ViewStyle",
+    "description": "Mask style",
+    "defaultValue": {
+      "position": "absolute",
+      "top": 0,
+      "bottom": 0,
+      "left": 0,
+      "right": 0,
+      "backgroundColor": "rgba(0, 0, 0, .4)"
+    }
+  },
+  "title": {
+    "type": "ViewStyle",
+    "description": "Title area, displays title text, only rendered when title is configured",
+    "defaultValue": {
+      "flex": 1,
+      "alignItems": "center",
+      "marginTop": 15,
+      "marginBottom": 15
+    }
+  },
+  "titleText": {
+    "type": "TextStyle",
+    "description": "Title text",
+    "defaultValue": { "fontWeight": "500", "color": "#000000" }
+  },
+  "message": {
+    "type": "ViewStyle",
+    "description": "Message area, displays extra text information, only rendered when message is configured",
+    "defaultValue": {
+      "flex": 1,
+      "alignItems": "center",
+      "marginBottom": 15,
+      "color": "#000000",
+      "textAlign": "center"
+    }
+  },
+  "btn": {
+    "type": "ViewStyle",
+    "description": "Button touch area, supports button base style btn",
+    "defaultValue": {
+      "alignItems": "center",
+      "justifyContent": "center",
+      "height": 50,
+      "borderStyle": "solid",
+      "borderTopWidth": 1,
+      "borderTopColor": "#dddddd"
+    }
+  },
+  "btnText": {
+    "type": "TextStyle",
+    "description": "Button text, base style btnText, destructive button style destructiveBtn conditionally applied",
+    "defaultValue": { "color": "#000000" }
+  },
+  "cancelBtn": {
+    "type": "ViewStyle",
+    "description": "Option container, supports cancel button style conditionally applied (cancelBtn)",
+    "defaultValue": { "marginTop": 9, "position": "relative" }
+  },
+  "cancelBtnMask": {
+    "type": "ViewStyle",
+    "description": "Cancel button mask layer, conditionally rendered",
+    "defaultValue": {
+      "position": "absolute",
+      "top": "-theme.v_spacing_md",
+      "left": 0,
+      "right": 0,
+      "height": 9,
+      "backgroundColor": "#f7f7f7",
+      "borderStyle": "solid",
+      "borderTopWidth": 1,
+      "borderTopColor": "#dddddd"
+    }
+  },
+  "destructiveBtn": {
+    "type": "TextStyle",
+    "description": "Destructive button style",
+    "defaultValue": { "color": "#f4333c", "fontSize": 18 }
+  }
+}
+```
+
+---
+
+# activity-indicator Semantic
+
+Source: https://rn.mobile.ant.design/components/activity-indicator/semantic.md
+
+# ActivityIndicator Semantic
+
+## Component Description
+
+Properties | Descrition | Type | Default -----------|------------|------|--------
+
+---
+
+## DOM Structure
+
+```json
+[
+  {
+    "component": "View",
+    "style": "container",
+    "children": [
+      {
+        "component": "View",
+        "style": "innerContainer",
+        "children": [
+          {
+            "component": "View",
+            "style": "wrapper",
+            "children": [
+              {
+                "component": "ActivityIndicator"
+              },
+              {
+                "component": "Text",
+                "style": "toast"
+              }
+            ]
+          }
+        ]
+      }
+    ]
+  },
+  {
+    "component": "View",
+    "style": "spinner",
+    "children": [
+      {
+        "component": "ActivityIndicator"
+      },
+      {
+        "component": "Text",
+        "style": "tip"
+      }
+    ]
+  }
+]
+```
+
+## Styles Schema
+
+```json
+{
+  "container": {
+    "type": "ViewStyle",
+    "description": "Container layout style",
+    "defaultValue": {
+      "position": "absolute",
+      "top": 0,
+      "left": 0,
+      "bottom": 0,
+      "right": 0,
+      "backgroundColor": "transparent",
+      "zIndex": 1999
+    }
+  },
+  "innerContainer": {
+    "type": "ViewStyle",
+    "description": "Inner layer container style",
+    "defaultValue": {
+      "flex": 1,
+      "alignItems": "center",
+      "justifyContent": "center",
+      "backgroundColor": "transparent"
+    }
+  },
+  "wrapper": {
+    "type": "ViewStyle",
+    "description": "Wrapper for loading indicator and text area",
+    "defaultValue": {
+      "alignItems": "center",
+      "justifyContent": "center",
+      "width": 89,
+      "height": 89,
+      "borderRadius": 5,
+      "backgroundColor": "rgba(0, 0, 0, .8)"
+    }
+  },
+  "tip": {
+    "type": "TextStyle",
+    "description": "Spinner text style",
+    "defaultValue": { "color": "#000000", "fontSize": 14, "marginLeft": 8 }
+  },
+  "toast": {
+    "type": "TextStyle",
+    "description": "Toast text style",
+    "defaultValue": { "color": "#ffffff", "fontSize": 14, "marginTop": 6 }
+  },
+  "spinner": {
+    "type": "ViewStyle",
+    "description": "Normal mode container style",
+    "defaultValue": {
+      "flexDirection": "row",
+      "justifyContent": "center",
+      "alignItems": "center"
+    }
+  }
+}
+```
+
+---
+
+# badge Semantic
+
+Source: https://rn.mobile.ant.design/components/badge/semantic.md
+
+# Badge Semantic
+
+## Component Description
+
+The red dot at corner for notification and getting user attention.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": "wrap",
+  "children": [
+    {
+      "component": "View",
+      "style": ["textCornerWrap", "textDomWrap"],
+      "children": [
+        {
+          "component": "View",
+          "style": ["textDom", "textDomlarge"],
+          "children": [
+            {
+              "component": "Text",
+              "style": "text"
+            }
+          ]
+        },
+        {
+          "component": "View",
+          "style": ["dot", "dotSizelarge"]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "wrap": {
+    "type": "ViewStyle",
+    "description": "Wrapper layer style",
+    "defaultValue": { "flexDirection": "row" }
+  },
+  "textCornerWrap": {
+    "type": "ViewStyle",
+    "description": "Text corner wrapper style",
+    "defaultValue": { "overflow": "hidden" }
+  },
+  "dot": {
+    "type": "ViewStyle",
+    "description": "Dot style",
+    "defaultValue": {
+      "width": "2 * grid",
+      "height": "2 * grid",
+      "borderRadius": "grid",
+      "backgroundColor": "#ff5b05",
+      "position": "absolute",
+      "top": "-1 * grid",
+      "right": "-1 * grid"
+    }
+  },
+  "dotSizelarge": {
+    "type": "ViewStyle",
+    "description": "Dot size large style",
+    "defaultValue": {
+      "width": "4 * grid",
+      "height": "4 * grid",
+      "borderRadius": "2 * grid"
+    }
+  },
+  "textDom": {
+    "type": "ViewStyle",
+    "description": "Text DOM style",
+    "defaultValue": {
+      "paddingVertical": "0.5 * grid",
+      "paddingHorizontal": "(Platform.OS === 'ios' ? 1.5 : 2) * grid",
+      "backgroundColor": "#ff5b05",
+      "borderRadius": 12,
+      "borderStyle": "solid",
+      "position": "absolute",
+      "top": -10,
+      "right": -15
+    }
+  },
+  "textCorner": {
+    "type": "ViewStyle",
+    "description": "Text corner style",
+    "defaultValue": {
+      "width": "18 * grid",
+      "backgroundColor": "#ff5b05",
+      "transform": "[",
+      "rotate": "45deg",
+      "position": "absolute",
+      "top": "2 * grid"
+    }
+  },
+  "textCornerlarge": {
+    "type": "ViewStyle",
+    "description": "Text corner large style",
+    "defaultValue": { "width": "26 * grid", "top": "3 * grid" }
+  },
+  "text": {
+    "type": "TextStyle",
+    "description": "Text style",
+    "defaultValue": { "color": "#ffffff", "textAlign": "center" }
+  }
+}
+```
+
+---
+
+# button Semantic
+
+Source: https://rn.mobile.ant.design/components/button/semantic.md
+
+# Button Semantic
+
+## Component Description
+
+To trigger an operation.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "Pressable",
+  "style": [
+    "wrapperStyle",
+    "largeRaw",
+    "smallRaw",
+    "defaultRaw",
+    "primaryRaw",
+    "ghostRaw",
+    "warningRaw",
+    "defaultDisabledRaw",
+    "primaryDisabledRaw",
+    "ghostDisabledRaw",
+    "warningDisabledRaw"
+  ],
+  "children": [
+    {
+      "component": "View",
+      "style": [
+        "underlayStyle",
+        "largeUnderlayContainerRaw",
+        "smallUnderlayContainerRaw",
+        "defaultUnderlayContainerRaw",
+        "primaryUnderlayContainerRaw",
+        "ghostUnderlayContainerRaw",
+        "warningUnderlayContainerRaw",
+        "defaultHighlight",
+        "primaryHighlight",
+        "ghostHighlight",
+        "warningHighlight"
+      ]
+    },
+    {
+      "component": "View",
+      "style": "container",
+      "children": [
+        {
+          "component": "ActivityIndicator",
+          "style": "indicator"
+        },
+        {
+          "component": "AntmView",
+          "style": [
+            "rawText",
+            "largeRawText",
+            "smallRawText",
+            "defaultRawText",
+            "primaryRawText",
+            "ghostRawText",
+            "warningRawText",
+            "defaultDisabledRawText",
+            "primaryDisabledRawText",
+            "ghostDisabledRawText",
+            "warningDisabledRawText",
+            "defaultHighlightText",
+            "primaryHighlightText",
+            "ghostHighlightText",
+            "warningHighlightText"
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "container": {
+    "type": "ViewStyle",
+    "description": "Button content container, layouts button text and loading indicator, fixed style container",
+    "defaultValue": {
+      "flexDirection": "row",
+      "height": "100%",
+      "alignItems": "center",
+      "justifyContent": "center",
+      "overflow": "hidden"
+    }
+  },
+  "defaultHighlight": {
+    "type": "ViewStyle",
+    "description": "Default highlight style",
+    "defaultValue": { "backgroundColor": "#dddddd4D", "borderColor": "#dddddd" }
+  },
+  "primaryHighlight": {
+    "type": "ViewStyle",
+    "description": "Primary highlight style",
+    "defaultValue": { "backgroundColor": "#1284d64D", "borderColor": "#108ee9" }
+  },
+  "ghostHighlight": {
+    "type": "ViewStyle",
+    "description": "Ghost highlight style",
+    "defaultValue": {
+      "backgroundColor": "transparent",
+      "borderColor": "#108ee999"
+    }
+  },
+  "warningHighlight": {
+    "type": "ViewStyle",
+    "description": "Warning highlight style",
+    "defaultValue": { "backgroundColor": "#d247474D", "borderColor": "#e94f4f" }
+  },
+  "wrapperStyle": {
+    "type": "ViewStyle",
+    "description": "Wrapper style",
+    "defaultValue": {
+      "alignItems": "center",
+      "justifyContent": "center",
+      "borderRadius": 5,
+      "borderWidth": 1
+    }
+  },
+  "underlayStyle": {
+    "type": "ViewStyle",
+    "description": "Underlay style",
+    "defaultValue": {
+      "width": "100%",
+      "height": "100%",
+      "alignItems": "center",
+      "justifyContent": "center"
+    }
+  },
+  "largeRaw": {
+    "type": "ViewStyle",
+    "description": "Large raw style",
+    "defaultValue": { "height": 47 }
+  },
+  "largeUnderlayContainerRaw": {
+    "type": "ViewStyle",
+    "description": "Large underlay container raw style",
+    "defaultValue": { "paddingLeft": 15, "paddingRight": 15 }
+  },
+  "smallRaw": {
+    "type": "ViewStyle",
+    "description": "Small raw style",
+    "defaultValue": { "height": 23 }
+  },
+  "smallUnderlayContainerRaw": {
+    "type": "ViewStyle",
+    "description": "Small underlay container raw style",
+    "defaultValue": { "paddingLeft": 5, "paddingRight": 5 }
+  },
+  "defaultRaw": {
+    "type": "ViewStyle",
+    "description": "Default raw style",
+    "defaultValue": { "backgroundColor": "#ffffff", "borderColor": "#dddddd" }
+  },
+  "defaultUnderlayContainerRaw": {
+    "type": "ViewStyle",
+    "description": "Default underlay container raw style",
+    "defaultValue": {}
+  },
+  "primaryRaw": {
+    "type": "ViewStyle",
+    "description": "Primary raw style",
+    "defaultValue": { "backgroundColor": "#108ee9", "borderColor": "#108ee9" }
+  },
+  "primaryUnderlayContainerRaw": {
+    "type": "ViewStyle",
+    "description": "Primary underlay container raw style",
+    "defaultValue": {}
+  },
+  "ghostRaw": {
+    "type": "ViewStyle",
+    "description": "Ghost raw style",
+    "defaultValue": {
+      "backgroundColor": "transparent",
+      "borderColor": "#108ee9"
+    }
+  },
+  "ghostUnderlayContainerRaw": {
+    "type": "ViewStyle",
+    "description": "Ghost underlay container raw style",
+    "defaultValue": {}
+  },
+  "warningRaw": {
+    "type": "ViewStyle",
+    "description": "Warning raw style",
+    "defaultValue": { "backgroundColor": "#e94f4f", "borderColor": "#e94f4f" }
+  },
+  "warningUnderlayContainerRaw": {
+    "type": "ViewStyle",
+    "description": "Warning underlay container raw style",
+    "defaultValue": {}
+  },
+  "defaultDisabledRaw": {
+    "type": "ViewStyle",
+    "description": "Default disabled raw style",
+    "defaultValue": { "backgroundColor": "#dddddd", "borderColor": "#dddddd" }
+  },
+  "primaryDisabledRaw": {
+    "type": "ViewStyle",
+    "description": "Primary disabled raw style",
+    "defaultValue": { "opacity": 0.4 }
+  },
+  "ghostDisabledRaw": {
+    "type": "ViewStyle",
+    "description": "Ghost disabled raw style",
+    "defaultValue": { "borderColor": "#0000001A" }
+  },
+  "warningDisabledRaw": {
+    "type": "ViewStyle",
+    "description": "Warning disabled raw style",
+    "defaultValue": { "opacity": 0.4 }
+  },
+  "defaultHighlightText": {
+    "type": "TextStyle",
+    "description": "Default highlight text style",
+    "defaultValue": { "color": "#0000004D" }
+  },
+  "primaryHighlightText": {
+    "type": "TextStyle",
+    "description": "Primary highlight text style",
+    "defaultValue": { "color": "#ffffff4D" }
+  },
+  "ghostHighlightText": {
+    "type": "TextStyle",
+    "description": "Ghost highlight text style",
+    "defaultValue": { "color": "#108ee999" }
+  },
+  "warningHighlightText": {
+    "type": "TextStyle",
+    "description": "Warning highlight text style",
+    "defaultValue": { "color": "#ffffff4D" }
+  },
+  "rawText": {
+    "type": "TextStyle",
+    "description": "Raw text style",
+    "defaultValue": {}
+  },
+  "largeRawText": {
+    "type": "TextStyle",
+    "description": "Large raw text style",
+    "defaultValue": { "fontSize": 18 }
+  },
+  "smallRawText": {
+    "type": "TextStyle",
+    "description": "Small raw text style",
+    "defaultValue": { "fontSize": 12 }
+  },
+  "defaultRawText": {
+    "type": "TextStyle",
+    "description": "Default raw text style",
+    "defaultValue": { "color": "#000000" }
+  },
+  "primaryRawText": {
+    "type": "TextStyle",
+    "description": "Primary raw text style",
+    "defaultValue": { "color": "#ffffff" }
+  },
+  "ghostRawText": {
+    "type": "TextStyle",
+    "description": "Ghost raw text style",
+    "defaultValue": { "color": "#108ee9" }
+  },
+  "warningRawText": {
+    "type": "TextStyle",
+    "description": "Warning raw text style",
+    "defaultValue": { "color": "#ffffff" }
+  },
+  "defaultDisabledRawText": {
+    "type": "TextStyle",
+    "description": "Default disabled raw text style",
+    "defaultValue": { "color": "#0000004D" }
+  },
+  "primaryDisabledRawText": {
+    "type": "TextStyle",
+    "description": "Primary disabled raw text style",
+    "defaultValue": { "color": "#ffffff99" }
+  },
+  "ghostDisabledRawText": {
+    "type": "TextStyle",
+    "description": "Ghost disabled raw text style",
+    "defaultValue": { "color": "#0000001A" }
+  },
+  "warningDisabledRawText": {
+    "type": "TextStyle",
+    "description": "Warning disabled raw text style",
+    "defaultValue": { "color": "#ffffff99" }
+  },
+  "indicator": {
+    "type": "ViewStyle",
+    "description": "Conditionally rendered loading indicator, displays based on loading state, fixed size, color dynamically calculated based on pressed state and disabled state",
+    "defaultValue": { "marginRight": 8 }
+  }
+}
+```
+
+---
+
+# card Semantic
+
+Source: https://rn.mobile.ant.design/components/card/semantic.md
+
+# Card Semantic
+
+## Component Description
+
+Card can be used to organize information and operations, usually also as an entry for detailed information.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": ["card", "full"],
+  "children": [
+    {
+      "component": "View",
+      "style": "headerWrap",
+      "children": [
+        {
+          "component": "View",
+          "style": "headerTitle",
+          "children": [
+            {
+              "component": "Image",
+              "style": "headerImage"
+            },
+            {
+              "component": "View",
+              "style": "headerContentWrap"
+            },
+            {
+              "component": "Text",
+              "style": "headerContent"
+            }
+          ]
+        },
+        {
+          "component": "View",
+          "style": "headerExtraWrap"
+        },
+        {
+          "component": "Text",
+          "style": "headerExtra"
+        }
+      ]
+    },
+    {
+      "component": "View",
+      "style": "body"
+    },
+    {
+      "component": "View",
+      "style": "footerWrap",
+      "children": [
+        {
+          "component": "View"
+        },
+        {
+          "component": "Text",
+          "style": "footerContent"
+        },
+        {
+          "component": "View"
+        },
+        {
+          "component": "Text",
+          "style": "footerExtra"
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "card": {
+    "type": "ViewStyle",
+    "description": "card base container style",
+    "defaultValue": {
+      "borderWidth": 1,
+      "borderColor": "#dddddd",
+      "borderRadius": 5,
+      "paddingBottom": 6,
+      "flexDirection": "column",
+      "backgroundColor": "#ffffff"
+    }
+  },
+  "full": {
+    "type": "ViewStyle",
+    "description": "full style",
+    "defaultValue": {
+      "borderRadius": 0,
+      "borderLeftWidth": 0,
+      "borderRightWidth": 0
+    }
+  },
+  "headerWrap": {
+    "type": "ViewStyle",
+    "description": "header container style",
+    "defaultValue": {
+      "flexDirection": "row",
+      "paddingVertical": 6,
+      "paddingRight": 15,
+      "marginLeft": 15,
+      "alignItems": "center"
+    }
+  },
+  "headerTitle": {
+    "type": "ViewStyle",
+    "description": "title container style",
+    "defaultValue": {
+      "flex": 1,
+      "flexDirection": "row",
+      "alignItems": "center"
+    }
+  },
+  "headerImage": {
+    "type": "ImageStyle",
+    "description": "thumbnail image style",
+    "defaultValue": {
+      "marginRight": 5,
+    }
+  },
+  "headerContentWrap": {
+    "type": "ViewStyle",
+    "description": "title content wrapper (when title is a JSX element)",
+    "defaultValue": {
+      "flex": 1
+    }
+  },
+  "headerContent": {
+    "type": "TextStyle",
+    "description": "title text style (when title is a string or text)",
+    "defaultValue": {
+      "color": "#000000",
+      "fontSize": "17",
+      "flex": 1
+    }
+  },
+  "headerExtraWrap": {
+    "type": "ViewStyle",
+    "description": "extra content wrapper (when extra content is a JSX element)",
+    "defaultValue": {
+      "flex": 1
+    }
+  },
+  "headerExtra": {
+    "type": "TextStyle",
+    "description": "extra content text style (when extra content is text)",
+    "defaultValue": {
+      "flex": 1,
+      "fontSize": "17",
+      "color": "#888888",
+      "textAlign": "right"
+    }
+  },
+  "body": {
+    "type": "ViewStyle",
+    "description": "body container style",
+    "defaultValue": {
+      "flexGrow": 1,
+      "paddingVertical": 9,
+      "minHeight": 48,
+      "borderTopWidth": 1,
+      "borderColor": "#dddddd"
+    }
+  },
+  "footerWrap": {
+    "type": "ViewStyle",
+    "description": "footer container style",
+    "defaultValue": {
+      "flexDirection": "row",
+      "paddingHorizontal": 15
+    }
+  },
+  "footerContent": {
+    "type": "TextStyle",
+    "description": "footer content text style",
+    "defaultValue": {
+      "flex": 1,
+      "fontSize": "14",
+      "color": "#888888",
+    }
+  },
+  "footerExtra": {
+    "type": "TextStyle",
+    "description": "footer extra text style",
+    "defaultValue": {
+      "textAlign": "right",
+      "fontSize": "14",
+      "color": "#888888",
+    }
+  }
+}
+```
+
+---
+
+# carousel Semantic
+
+Source: https://rn.mobile.ant.design/components/carousel/semantic.md
+
+# Carousel Semantic
+
+## Component Description
+
+Properties | Descrition | Type | Default | Version -----------|------------|------|---------|----------
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "children": [
+    {
+      "component": "ScrollView",
+      "style": "wrapperStyle",
+      "children": [
+        {
+          "component": "View",
+          "style": "wrapperStyle"
+        }
+      ]
+    },
+    {
+      "component": "View",
+      "style": ["pagination", "paginationX", "paginationY"],
+      "children": [
+        {
+          "component": "View",
+          "children": [
+            {
+              "component": "View",
+              "style": ["pointStyle", "spaceStyle", "pointActiveStyle"]
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "pagination": {
+    "type": "ViewStyle",
+    "description": "pagination style",
+    "defaultValue": {
+      "position": "absolute",
+      "alignItems": "center"
+    }
+  },
+  "paginationX": {
+    "type": "ViewStyle",
+    "description": "paginationX style",
+    "defaultValue": {
+      "bottom": 10,
+      "left": 0,
+      "right": 0
+    }
+  },
+  "paginationY": {
+    "type": "ViewStyle",
+    "description": "paginationY style",
+    "defaultValue": {
+      "right": 10,
+      "top": 0,
+      "bottom": 0
+    }
+  },
+  "pointStyle": {
+    "type": "ViewStyle",
+    "description": "pointStyle style",
+    "defaultValue": {
+      "width": 8,
+      "height": 8,
+      "borderRadius": 8,
+      "backgroundColor": "#cccccc"
+    }
+  },
+  "pointActiveStyle": {
+    "type": "ViewStyle",
+    "description": "pointActiveStyle style",
+    "defaultValue": {
+      "backgroundColor": "#888"
+    }
+  },
+  "spaceStyle": {
+    "type": "ViewStyle",
+    "description": "spaceStyle style",
+    "defaultValue": {
+      "marginHorizontal": 5 / 2,
+      "marginVertical": 6 / 2
+    }
+  },
+  "wrapperStyle": {
+    "type": "ViewStyle",
+    "description": "wrapperStyle style",
+    "defaultValue": {
+      "overflow": "hidden"
+    }
+  }
+}
+```
+
+---
+
+# checkbox Semantic
+
+Source: https://rn.mobile.ant.design/components/checkbox/semantic.md
+
+# Checkbox Semantic
+
+## Component Description
+
+Checkbox
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "Pressable",
+  "style": "checkbox_wrapper",
+  "children": [
+    {
+      "component": "View",
+      "style": "checkbox_wave",
+      "children": [
+        {
+          "component": "View",
+          "style": ["checkbox", "checkbox_checked", "checkbox_disabled"],
+          "children": [
+            {
+              "component": "Animated.View",
+              "style": [
+                "checkbox_inner",
+                "checkbox_inner_disabled",
+                "checkbox_inner_indeterminate"
+              ]
+            },
+            {
+              "component": "Animated.View",
+              "style": [
+                "checkbox_inner_before",
+                "checkbox_inner_before_disabled",
+                "checkbox_inner_before_indeterminate"
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "component": "AntmView",
+      "style": ["checkbox_label", "checkbox_label_disabled"]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "checkbox_wrapper": {
+    "type": "ViewStyle",
+    "description": "container overall style, supports style base property pass-through",
+    "defaultValue": {
+      "margin": 0,
+      "padding": 0,
+      "position": "relative",
+      "display": "flex",
+      "flexDirection": "row",
+      "alignItems": "center"
+    }
+  },
+  "checkbox_wave": {
+    "type": "ViewStyle",
+    "description": "ripple animation outer",
+    "defaultValue": {
+      "width": 20,
+      "height": 20,
+      "padding": 2,
+      "overflow": "hidden"
+    }
+  },
+  "checkbox": {
+    "type": "ViewStyle",
+    "description": "checkbox style",
+    "defaultValue": {
+      "position": "relative",
+      "width": "100%",
+      "height": "100%",
+      "borderRadius": 2,
+      "borderWidth": 1,
+      "borderStyle": "solid",
+      "borderColor": "#d9d9d9",
+      "backgroundColor": "transparent",
+      "justifyContent": "center",
+      "alignItems": "center"
+    }
+  },
+  "checkbox_checked": {
+    "type": "ViewStyle",
+    "description": "checkbox_checked style",
+    "defaultValue": {
+      "borderColor": "#108ee9"
+    }
+  },
+  "checkbox_disabled": {
+    "type": "ViewStyle",
+    "description": "checkbox_disabled style",
+    "defaultValue": {
+      "borderColor": "#b9b9b9",
+      "backgroundColor": "#f5f5f5"
+    }
+  },
+  "checkbox_inner": {
+    "type": "ViewStyle",
+    "description": "checkbox_inner style",
+    "defaultValue": {
+      "width": "103%",
+      "height": "103%",
+      "backgroundColor": "#108ee9"
+    }
+  },
+  "checkbox_inner_disabled": {
+    "type": "ViewStyle",
+    "description": "checkbox_inner_disabled style",
+    "defaultValue": {
+      "backgroundColor": "#f5f5f5"
+    }
+  },
+  "checkbox_inner_before": {
+    "type": "ViewStyle",
+    "description": "checkbox_inner_before style"
+  },
+  "checkbox_inner_before_disabled": {
+    "type": "ViewStyle",
+    "description": "checkbox_inner_before_disabled style",
+    "defaultValue": {
+      "borderColor": "#b9b9b9"
+    }
+  },
+  "checkbox_label": {
+    "type": "ViewStyle",
+    "description": "checkbox_label style",
+    "defaultValue": {
+      "backgroundColor": "transparent",
+      "marginRight": "8",
+      "marginLeft": "8",
+      "color": "#000000"
+    }
+  },
+  "checkbox_label_disabled": {
+    "type": "ViewStyle",
+    "description": "checkbox_label_disabled style",
+    "defaultValue": {
+      "color": "#bbbbbb"
+    }
+  },
+  "checkbox_inner_indeterminate": {
+    "type": "ViewStyle",
+    "description": "checkbox_inner_indeterminate style",
+    "defaultValue": {
+      "backgroundColor": "transparent"
+    }
+  },
+  "checkbox_inner_before_indeterminate": {
+    "type": "ViewStyle",
+    "description": "checkbox_inner_before_indeterminate style",
+    "defaultValue": {
+      "position": "absolute",
+      "width": 8,
+      "height": 8,
+      "backgroundColor": "#108ee9"
+    }
+  }
+}
+```
+
+---
+
+# form Semantic
+
+Source: https://rn.mobile.ant.design/components/form/semantic.md
+
+# Form Semantic
+
+## Component Description
+
+High-performance form component with data domain management. Includes data entry, validation, and corresponding styles. Base on rc-field-form.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "FieldForm",
+  "style": "List",
+  "children": [
+    {
+      "component": "AntmList",
+      "style": "List",
+      "children": [
+        {
+          "component": "List.Item",
+          "style": "Item",
+          "children": [
+            {
+              "component": "View",
+              "style": "formItemLabel",
+              "children": [
+                {
+                  "component": "Text",
+                  "style": "asterisk"
+                },
+                {
+                  "component": "AntdView",
+                  "style": "formItemLabelText"
+                },
+                {
+                  "component": "Text",
+                  "style": "optional"
+                }
+              ]
+            },
+            {
+              "component": "View",
+              "style": "formItemControl",
+              "children": [
+                {
+                  "component": "Brief",
+                  "style": ["error", "warning", "success", "validating"]
+                }
+              ]
+            },
+            {
+              "component": "View",
+              "style": "feedbackIcon",
+              "children": [
+                {
+                  "component": "Icon",
+                  "style": ["success", "warning", "error", "validating"]
+                },
+                {
+                  "component": "ActivityIndicator",
+                  "style": "validating"
+                }
+              ]
+            },
+            {
+              "component": "View",
+              "style": "Line"
+            },
+            {
+              "component": "Image",
+              "style": "Thumb"
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "formItemLabel": {
+    "type": "ViewStyle",
+    "description": "form item label container, responsible for rendering label and required mark",
+    "defaultValue": {
+      "minWidth": "65",
+      "position": "relative",
+      "flexDirection": "row",
+      "paddingTop": "6"
+    }
+  },
+  "formItemLabelText": {
+    "type": "ViewStyle",
+    "description": "label text style",
+    "defaultValue": {
+      "color": "#000000",
+      "fontSize": "17"
+    }
+  },
+  "formItemControl": {
+    "type": "ViewStyle",
+    "description": "form control container, contains form control and validation error hints",
+    "defaultValue": {
+      "flex": 1,
+      "flexDirection": "column",
+      "justifyContent": "center"
+    }
+  },
+  "asterisk": {
+    "type": "TextStyle",
+    "description": "required asterisk style",
+    "defaultValue": {
+      "position": "absolute",
+      "left": "-17 / 2",
+      "top": "6",
+      "color": "#f4333c",
+      "fontSize": "17"
+    }
+  },
+  "optional": {
+    "type": "TextStyle",
+    "description": "optional mark style",
+    "defaultValue": {
+      "color": "rgba(0, 0, 0, 0.45)",
+      "fontSize": "17"
+    }
+  },
+  "error": {
+    "type": "TextStyle",
+    "description": "error hint list, conditional rendering, displayed when there is error or help hint",
+    "defaultValue": {
+      "color": "#f4333c"
+    }
+  },
+  "warning": {
+    "type": "TextStyle",
+    "description": "warning style",
+    "defaultValue": {
+      "color": "#faad14"
+    }
+  },
+  "success": {
+    "type": "TextStyle",
+    "description": "success style",
+    "defaultValue": {
+      "color": "#6abf47"
+    }
+  },
+  "validating": {
+    "type": "TextStyle",
+    "description": "validating style",
+    "defaultValue": {
+      "color": "#108ee9"
+    }
+  },
+  "feedbackIcon": {
+    "type": "ViewStyle",
+    "description": "validation state feedback icon, conditional rendering when hasFeedback is true, dynamic style",
+    "defaultValue": {}
+  }
+}
+```
+
+---
+
+# grid Semantic
+
+Source: https://rn.mobile.ant.design/components/grid/semantic.md
+
+# Grid Semantic
+
+## Component Description
+
+We divided the design area into a number of aliquots in horizontal and vertical.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "children": [
+    {
+      "component": "Flex",
+      "style": "grayBorderBox",
+      "children": [
+        {
+          "component": "Flex.Item",
+          "children": [
+            {
+              "component": "Flex",
+              "children": [
+                {
+                  "component": "Image",
+                  "style": "icon"
+                },
+                {
+                  "component": "Text",
+                  "style": "text"
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "component": "Carousel",
+      "children": [
+        {
+          "component": "View",
+          "style": "grayBorderBox",
+          "children": [
+            {
+              "component": "Flex",
+              "style": "grayBorderBox",
+              "children": [
+                {
+                  "component": "Flex.Item"
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "grayBorderBox": {
+    "type": "ViewStyle",
+    "description": "gray border box, used to separate rows",
+    "defaultValue": { "borderColor": "#dddddd" }
+  },
+  "icon": {
+    "type": "ImageStyle",
+    "description": "image style, size and color",
+    "defaultValue": {
+      "width": "22",
+      "height": "22"
+    }
+  },
+  "text": {
+    "type": "TextStyle",
+    "description": "text style",
+    "defaultValue": {
+      "fontSize": "12",
+      "color": "#000000",
+      "marginTop": "9"
+    }
+  }
+}
+```
+
+---
+
+# input Semantic
+
+Source: https://rn.mobile.ant.design/components/input/semantic.md
+
+# Input Semantic
+
+## Component Description
+
+Entering content through the keyboard is the most basic form field wrapper.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": ["container", "style"],
+  "children": [
+    {
+      "component": "AntmView",
+      "style": "prefix"
+    },
+    {
+      "component": "TextInput",
+      "style": "input"
+    },
+    {
+      "component": "TouchableOpacity",
+      "style": "clearIcon"
+    },
+    {
+      "component": "Text",
+      "style": "showCount"
+    },
+    {
+      "component": "AntmView",
+      "style": "suffix"
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "container": {
+    "type": "ViewStyle",
+    "description": "input box overall layout style",
+    "defaultValue": {
+      "width": "100%",
+      "maxWidth": "100%",
+      "maxHeight": "100%",
+      "minHeight": 24,
+      "display": "flex",
+      "flexDirection": "row",
+      "alignItems": "center",
+      "position": "relative"
+    }
+  },
+  "input": {
+    "type": "ViewStyle",
+    "description": "input box base style; dynamic state style statusClassName (styles.error, styles.warning); supports outer inputStyle pass-through",
+    "defaultValue": {
+      "flex": 1,
+      "overflow": "hidden",
+      "width": "100%",
+      "maxWidth": "100%",
+      "maxHeight": "100%",
+      "minHeight": 24,
+      "fontSize": "17",
+      "color": "#000000",
+      "paddingVertical": "6",
+      "textAlignVertical": "center",
+      "includeFontPadding": "true"
+    }
+  },
+  "clearIcon": {
+    "type": "ViewStyle",
+    "description": "clear button style",
+    "defaultValue": {
+      "backgroundColor": "rgba(0,0,0,0.2)",
+      "borderRadius": 15,
+      "padding": 2,
+      "marginLeft": "6"
+    }
+  },
+  "prefix": {
+    "type": "ViewStyle",
+    "description": "prefix area style; dynamic state style statusClassName (styles.error, styles.warning)",
+    "defaultValue": {
+      "fontSize": "17",
+      "color": "#000000",
+      "marginRight": "6"
+    }
+  },
+  "showCount": {
+    "type": "TextStyle",
+    "description": "count text style; dynamic state style statusClassName (styles.error, styles.warning)",
+    "defaultValue": {
+      "fontSize": "17",
+      "color": "#bbbbbb",
+      "paddingLeft": "6"
+    }
+  },
+  "suffix": {
+    "type": "ViewStyle",
+    "description": "suffix area style; dynamic state style statusClassName (styles.error, styles.warning)",
+    "defaultValue": {
+      "fontSize": "17",
+      "color": "#000000",
+      "marginLeft": "6"
+    }
+  },
+  "warning": {
+    "type": "TextStyle",
+    "description": "warning style",
+    "defaultValue": { "color": "#faad14" }
+  },
+  "error": {
+    "type": "TextStyle",
+    "description": "error style",
+    "defaultValue": { "color": "#f4333c" }
+  }
+}
+```
+
+---
+
+# input-item Semantic
+
+Source: https://rn.mobile.ant.design/components/input-item/semantic.md
+
+# InputItem Semantic
+
+## Component Description
+
+A foundational component for inputting text into the app via a keyboard.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": "container",
+  "children": [
+    {
+      "component": "Text",
+      "style": "text"
+    },
+    {
+      "component": "View"
+    },
+    {
+      "component": "Input",
+      "style": ["input", "inputErrorColor", "inputDisabled"]
+    },
+    {
+      "component": "TouchableOpacity",
+      "style": "clear"
+    },
+    {
+      "component": "TouchableWithoutFeedback",
+      "children": [
+        {
+          "component": "View",
+          "children": [
+            {
+              "component": "Text",
+              "style": "extra"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "component": "TouchableWithoutFeedback",
+      "children": [
+        {
+          "component": "View",
+          "style": "errorIcon",
+          "children": [
+            {
+              "component": "Icon"
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "container": {
+    "type": "ViewStyle",
+    "description": "container overall style, includes border style",
+    "defaultValue": {
+      "height": "44 + 0.5",
+      "borderBottomWidth": "StyleSheet.hairlineWidth",
+      "borderBottomColor": "#dddddd",
+      "marginLeft": "15",
+      "paddingRight": "15",
+      "marginTop": 0,
+      "marginBottom": 0,
+      "flexDirection": "row",
+      "alignItems": "center"
+    }
+  },
+  "text": {
+    "type": "TextStyle",
+    "description": "label text style, width can be adjusted by labelNumber variable",
+    "defaultValue": {
+      "marginRight": "5",
+      "textAlignVertical": "center",
+      "fontSize": "17",
+      "color": "#000000"
+    }
+  },
+  "input": {
+    "type": "TextStyle",
+    "description": "input box text style",
+    "defaultValue": {
+      "flex": 1,
+      "backgroundColor": "transparent",
+      "fontSize": "17",
+      "color": "#000000"
+    }
+  },
+  "inputDisabled": {
+    "type": "TextStyle",
+    "description": "inputDisabled style",
+    "defaultValue": {
+      "backgroundColor": "#dddddd",
+      "color": "#bbbbbb"
+    }
+  },
+  "inputErrorColor": {
+    "type": "TextStyle",
+    "description": "inputErrorColor style",
+    "defaultValue": { "color": "#f50" }
+  },
+  "clear": {
+    "type": "ViewStyle",
+    "description": "clear button area style",
+    "defaultValue": {
+      "backgroundColor": "#cccccc",
+      "borderRadius": 15,
+      "padding": 2
+    }
+  },
+  "extra": {
+    "type": "TextStyle",
+    "description": "extra description text style",
+    "defaultValue": {
+      "marginLeft": "5",
+      "fontSize": "15",
+      "color": "#888888"
+    }
+  },
+  "errorIcon": {
+    "type": "ViewStyle",
+    "description": "error icon container style",
+    "defaultValue": {
+      "marginLeft": "5",
+      "width": "21",
+      "height": "21"
+    }
+  }
+}
+```
+
+---
+
+# list Semantic
+
+Source: https://rn.mobile.ant.design/components/list/semantic.md
+
+# List Semantic
+
+## Component Description
+
+A single and continuous block content is vertically arranged to display current contents, status and available operations. eg:Contact List.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": "List",
+  "children": [
+    {
+      "component": "Text",
+      "style": "Header"
+    },
+    {
+      "component": "View",
+      "style": "Body",
+      "children": [
+        {
+          "component": "View",
+          "style": "Item",
+          "children": [
+            {
+              "component": "Image",
+              "style": "Thumb"
+            },
+            {
+              "component": "View",
+              "style": "Line",
+              "children": [
+                {
+                  "component": "Text",
+                  "style": "Content"
+                },
+                {
+                  "component": "Text",
+                  "style": "Extra"
+                },
+                {
+                  "component": "Text",
+                  "style": "Arrow"
+                },
+                {
+                  "component": "Text",
+                  "style": "ArrowV"
+                }
+              ]
+            }
+          ]
+        },
+        {
+          "component": "View",
+          "style": "BodyBottomLine"
+        }
+      ]
+    },
+    {
+      "component": "Text",
+      "style": "Footer"
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "List": {
+    "type": "ViewStyle",
+    "description": "overall list container area, wraps entire list content",
+    "defaultValue": { "backgroundColor": "#f5f5f9" }
+  },
+  "Header": {
+    "type": "TextStyle",
+    "description": "list header text style",
+    "defaultValue": {
+      "fontSize": "14",
+      "color": "#888888",
+      "paddingHorizontal": "15",
+      "paddingTop": "15",
+      "paddingBottom": "9"
+    }
+  },
+  "Footer": {
+    "type": "TextStyle",
+    "description": "list footer text style",
+    "defaultValue": {
+      "fontSize": "14",
+      "color": "#888888",
+      "paddingHorizontal": "15",
+      "paddingVertical": "9"
+    }
+  },
+  "Body": {
+    "type": "ViewStyle",
+    "description": "list body content area, contains all child elements",
+    "defaultValue": {
+      "position": "relative",
+      "borderTopWidth": "StyleSheet.hairlineWidth",
+      "borderTopColor": "#eeeeee"
+    }
+  },
+  "BodyBottomLine": {
+    "type": "ViewStyle",
+    "description": "list body footer divider",
+    "defaultValue": {
+      "position": "absolute",
+      "bottom": 0,
+      "left": 0,
+      "right": 0,
+      "height": "StyleSheet.hairlineWidth",
+      "backgroundColor": "#eeeeee"
+    }
+  },
+  "underlayColor": {
+    "type": "ViewStyle",
+    "description": "underlayColor style",
+    "defaultValue": { "backgroundColor": "#dddddd" }
+  },
+  "Item": {
+    "type": "ViewStyle",
+    "description": "generally rendered by List.Item, shown here as placeholder example",
+    "defaultValue": {
+      "flexGrow": 1,
+      "alignItems": "center",
+      "flexDirection": "row",
+      "paddingLeft": "15",
+      "backgroundColor": "#ffffff"
+    }
+  },
+  "Line": {
+    "type": "ViewStyle",
+    "description": "content area, displays main text and extra information",
+    "defaultValue": {
+      "flex": 1,
+      "flexDirection": "row",
+      "alignItems": "center",
+      "paddingRight": "15",
+      "paddingVertical": "6",
+      "minHeight": "44",
+      "borderBottomWidth": "StyleSheet.hairlineWidth",
+      "borderBottomColor": "#dddddd"
+    }
+  },
+  "Thumb": {
+    "type": "ImageStyle",
+    "description": "left thumbnail area",
+    "defaultValue": {
+      "width": "22",
+      "height": "22",
+      "marginRight": "15"
+    }
+  },
+  "Content": {
+    "type": "TextStyle",
+    "description": "main content text",
+    "defaultValue": {
+      "color": "#000000",
+      "fontSize": "17",
+      "textAlignVertical": "center",
+      "flex": 1
+    }
+  },
+  "Extra": {
+    "type": "TextStyle",
+    "description": "extra content text",
+    "defaultValue": {
+      "color": "#888888",
+      "fontSize": "17",
+      "textAlign": "right",
+      "textAlignVertical": "center",
+      "paddingLeft": "8",
+      "maxWidth": "70%"
+    }
+  },
+  "Arrow": {
+    "type": "TextStyle",
+    "description": "arrow icon",
+    "defaultValue": {
+      "marginLeft": "8",
+      "marginTop": "3"
+    }
+  },
+  "ArrowV": {
+    "type": "TextStyle",
+    "description": "or vertical arrow style",
+    "defaultValue": { "marginLeft": "8" }
+  },
+  "multipleLine": {
+    "type": "ViewStyle",
+    "description": "multipleLine style",
+    "defaultValue": { "paddingVertical": "6" }
+  },
+  "multipleThumb": {
+    "type": "ImageStyle",
+    "description": "multipleThumb style",
+    "defaultValue": {
+      "width": "36",
+      "height": "36"
+    }
+  },
+  "Brief": {
+    "type": "ViewStyle",
+    "description": "Brief style",
+    "defaultValue": { "minHeight": "10" }
+  },
+  "BriefText": {
+    "type": "TextStyle",
+    "description": "BriefText style",
+    "defaultValue": {
+      "color": "#888888",
+      "fontSize": "15",
+      "paddingTop": "3",
+      "textAlignVertical": "center"
+    }
+  }
+}
+```
+
+---
+
+# modal Semantic
+
+Source: https://rn.mobile.ant.design/components/modal/semantic.md
+
+# Modal Semantic
+
+## Component Description
+
+Use to show important information for the system, and ask for user feedback. eg: When deleting an important content, pop up a Modal for secondary confirmation.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": "container",
+  "children": [
+    {
+      "component": "View",
+      "style": "wrap",
+      "children": [
+        {
+          "component": "TouchableWithoutFeedback",
+          "children": [
+            {
+              "component": "Animated.View",
+              "style": "maskClosable",
+              "children": [
+                {
+                  "component": "View",
+                  "style": "maskClosable"
+                }
+              ]
+            }
+          ]
+        },
+        {
+          "component": "Animated.View",
+          "style": "container",
+          "children": [
+            {
+              "component": "View",
+              "style": [
+                "innerContainer",
+                "popupContainer",
+                "popupSlideUp",
+                "popupSlideDown"
+              ],
+              "children": [
+                {
+                  "component": "Text",
+                  "style": "header"
+                },
+                {
+                  "component": "View",
+                  "style": "body"
+                },
+                {
+                  "component": "View",
+                  "style": ["footer", "buttonGroupV", "buttonGroupH"],
+                  "children": [
+                    {
+                      "component": "TouchableHighlight",
+                      "children": [
+                        {
+                          "component": "View",
+                          "style": ["buttonWrapV", "buttonWrapH"],
+                          "children": [
+                            {
+                              "component": "Text",
+                              "style": ["buttonText", "buttonTextOperation"]
+                            }
+                          ]
+                        }
+                      ]
+                    }
+                  ]
+                },
+                {
+                  "component": "View",
+                  "style": "closeWrap",
+                  "children": [
+                    {
+                      "component": "TouchableWithoutFeedback",
+                      "children": [
+                        {
+                          "component": "View",
+                          "children": [
+                            {
+                              "component": "Text",
+                              "style": "close"
+                            }
+                          ]
+                        }
+                      ]
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "container": {
+    "type": "ViewStyle",
+    "description": "mask layer container, full screen, floating mask",
+    "defaultValue": { "zIndex": "999" }
+  },
+  "wrap": {
+    "type": "ViewStyle",
+    "description": "mask layer wrapper container",
+    "defaultValue": {
+      "justifyContent": "center",
+      "alignItems": "center",
+      "backgroundColor": "transparent"
+    }
+  },
+  "popupContainer": {
+    "type": "ViewStyle",
+    "description": "popupContainer style",
+    "defaultValue": {}
+  },
+  "innerContainer": {
+    "type": "ViewStyle",
+    "description": "dialog content wrapper container, for popup mode applies popupContainer, popupSlideUp, popupSlideDown dynamic styles",
+    "defaultValue": {
+      "borderRadius": "5",
+      "width": 286,
+      "paddingTop": "21",
+      "overflow": "hidden",
+      "backgroundColor": "#ffffff"
+    }
+  },
+  "popupSlideUp": {
+    "type": "ViewStyle",
+    "description": "popupSlideUp style",
+    "defaultValue": {
+      "position": "absolute",
+      "left": 0,
+      "right": 0,
+      "bottom": 0
+    }
+  },
+  "popupSlideDown": {
+    "type": "ViewStyle",
+    "description": "popupSlideDown style",
+    "defaultValue": {}
+  },
+  "footer": {
+    "type": "ViewStyle",
+    "description": "footer button area, footer area",
+    "defaultValue": {}
+  },
+  "header": {
+    "type": "TextStyle",
+    "description": "header title area, displays title text",
+    "defaultValue": {
+      "fontSize": "18",
+      "color": "#000000",
+      "textAlign": "center",
+      "paddingHorizontal": "15"
+    }
+  },
+  "body": {
+    "type": "ViewStyle",
+    "description": "content area, wraps children view, supports body and bodyStyle pass-through",
+    "defaultValue": {
+      "paddingTop": 0,
+      "paddingBottom": "15",
+      "paddingHorizontal": "15"
+    }
+  },
+  "maskClosable": {
+    "type": "ViewStyle",
+    "description": "maskClosable style",
+    "defaultValue": {
+      "position": "absolute",
+      "top": 0,
+      "bottom": 0,
+      "left": 0,
+      "right": 0,
+      "backgroundColor": "transparent"
+    }
+  },
+  "closeWrap": {
+    "type": "ViewStyle",
+    "description": "close button area (conditional rendering, when closable is true)",
+    "defaultValue": {
+      "position": "absolute",
+      "top": "21",
+      "left": "15"
+    }
+  },
+  "close": {
+    "type": "TextStyle",
+    "description": "close style",
+    "defaultValue": {
+      "fontSize": 40,
+      "fontWeight": "200",
+      "color": "#bcbcbc",
+      "lineHeight": 30
+    }
+  },
+  "buttonGroupH": {
+    "type": "ViewStyle",
+    "description": "buttonGroupH style",
+    "defaultValue": { "flexGrow": 1, "flexDirection": "row" }
+  },
+  "buttonGroupV": {
+    "type": "ViewStyle",
+    "description": "buttonGroupV style",
+    "defaultValue": { "flexGrow": 1, "flexDirection": "column" }
+  },
+  "buttonWrapH": {
+    "type": "ViewStyle",
+    "description": "buttonWrapH style",
+    "defaultValue": {
+      "height": "50",
+      "flexGrow": 1,
+      "justifyContent": "center",
+      "borderColor": "#dddddd",
+      "borderTopWidth": "StyleSheet.hairlineWidth",
+      "borderRightWidth": "StyleSheet.hairlineWidth",
+      "paddingVertical": 11
+    }
+  },
+  "buttonWrapV": {
+    "type": "ViewStyle",
+    "description": "buttonWrapV style",
+    "defaultValue": {
+      "flexGrow": 1,
+      "borderTopWidth": "StyleSheet.hairlineWidth",
+      "borderColor": "#dddddd",
+      "paddingVertical": 11
+    }
+  },
+  "buttonText": {
+    "type": "TextStyle",
+    "description": "buttonText style",
+    "defaultValue": {
+      "textAlign": "center",
+      "color": "#108ee9",
+      "fontSize": "18",
+      "backgroundColor": "transparent"
+    }
+  },
+  "operationContainer": {
+    "type": "ViewStyle",
+    "description": "operationContainer style",
+    "defaultValue": { "paddingTop": 0 }
+  },
+  "operationBody": {
+    "type": "ViewStyle",
+    "description": "operationBody style",
+    "defaultValue": { "paddingBottom": 0, "paddingHorizontal": 0 }
+  },
+  "buttonTextOperation": {
+    "type": "TextStyle",
+    "description": "buttonTextOperation style",
+    "defaultValue": {
+      "color": "#000000",
+      "textAlign": "left",
+      "paddingHorizontal": 15
+    }
+  }
+}
+```
+
+---
+
+# notice-bar Semantic
+
+Source: https://rn.mobile.ant.design/components/notice-bar/semantic.md
+
+# NoticeBar Semantic
+
+## Component Description
+
+Component to display a system message, event notice and etc. Which is under the navigation bar.
+
+---
+
+## DOM Structure
+
+```json
+[
+  {
+    "component": "View",
+    "style": ["container", "background", "style"],
+    "children": [
+      {
+        "component": "View",
+        "style": "iconWrap"
+      },
+      {
+        "component": "Marquee",
+        "style": ["font", "marquee"]
+      },
+      {
+        "component": "View",
+        "style": "actionWrap",
+        "children": [
+          {
+            "component": "Text",
+            "style": ["font", "close"]
+          },
+          {
+            "component": "Text",
+            "style": ["font", "link"]
+          }
+        ]
+      }
+    ]
+  },
+  {
+    "component": "TouchableWithoutFeedback"
+  }
+]
+```
+
+## Styles Schema
+
+```json
+{
+  "container": {
+    "type": "ViewStyle",
+    "description": "container area style",
+    "defaultValue": {
+      "minHeight": "36",
+      "overflow": "hidden",
+      "flexDirection": "row",
+      "alignItems": "center"
+    }
+  },
+  "font": {
+    "type": "TextStyle",
+    "description": "font style",
+    "defaultValue": { "color": "#f4333c" }
+  },
+  "background": {
+    "type": "ViewStyle",
+    "description": "background style",
+    "defaultValue": { "backgroundColor": "#fffada" }
+  },
+  "marquee": {
+    "type": "TextStyle",
+    "description": "scrolling text container style, styles.font: text font style, supports style pass-through",
+    "defaultValue": { "fontSize": "15" }
+  },
+  "iconWrap": {
+    "type": "ViewStyle",
+    "description": "icon wrapper area",
+    "defaultValue": {
+      "marginLeft": "15",
+      "marginRight": "5"
+    }
+  },
+  "actionWrap": {
+    "type": "ViewStyle",
+    "description": "action area wrapper container",
+    "defaultValue": {
+      "justifyContent": "center",
+      "paddingRight": "15",
+      "paddingLeft": "5"
+    }
+  },
+  "close": {
+    "type": "TextStyle",
+    "description": "close button text style, styles.font: font style",
+    "defaultValue": { "fontSize": 18, "fontWeight": "200", "textAlign": "left" }
+  },
+  "link": {
+    "type": "TextStyle",
+    "description": "link text style, styles.font: font style",
+    "defaultValue": {
+      "transform": "[{ rotate: '225deg' }]",
+      "fontWeight": "500",
+      "textAlign": "left"
+    }
+  }
+}
+```
+
+---
+
+# pagination Semantic
+
+Source: https://rn.mobile.ant.design/components/pagination/semantic.md
+
+# Pagination Semantic
+
+## Component Description
+
+A long list can be divided into several pages by `Pagination`, and only one page will be loaded at a time.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": "container",
+  "children": [
+    {
+      "component": "Flex",
+      "children": [
+        {
+          "component": "Flex.Item",
+          "children": [
+            {
+              "component": "Button"
+            }
+          ]
+        },
+        {
+          "component": "Flex.Item",
+          "children": [
+            {
+              "component": "View",
+              "style": "numberStyle",
+              "children": [
+                {
+                  "component": "Text",
+                  "style": "activeTextStyle"
+                },
+                {
+                  "component": "Text",
+                  "style": "totalStyle"
+                }
+              ]
+            }
+          ]
+        },
+        {
+          "component": "Flex.Item",
+          "children": [
+            {
+              "component": "Button"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "component": "View",
+      "style": "numberStyle",
+      "children": [
+        {
+          "component": "Text",
+          "style": "activeTextStyle"
+        },
+        {
+          "component": "Text",
+          "style": "totalStyle"
+        }
+      ]
+    },
+    {
+      "component": "View",
+      "style": "indicatorStyle",
+      "children": [
+        {
+          "component": "View",
+          "style": [
+            "pointStyle",
+            "spaceStyle"
+          ]
+        },
+        {
+          "component": "View",
+          "style": [
+            "pointStyle",
+            "spaceStyle",
+            "pointActiveStyle"
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "container": {
+    "type": "ViewStyle",
+    "description": "Overall container style",
+    "defaultValue": {
+      "justifyContent": "center"
+    }
+  },
+  "numberStyle": {
+    "type": "ViewStyle",
+    "description": "Style for the area displaying current page and total pages when mode is 'number'",
+    "defaultValue": {
+      "flexDirection": "row",
+      "justifyContent": "center"
+    }
+  },
+  "totalStyle": {
+    "type": "TextStyle",
+    "description": "Style for displaying total page count",
+    "defaultValue": {
+      "fontSize": 18,
+      "color": "theme.color_text_base"
+    }
+  },
+  "activeTextStyle": {
+    "type": "TextStyle",
+    "description": "Style for highlighting the current page number",
+    "defaultValue": {
+      "fontSize": 18,
+      "color": "theme.color_link"
+    }
+  },
+  "indicatorStyle": {
+    "type": "ViewStyle",
+    "description": "Style for the dot indicator container when mode is 'pointer'",
+    "defaultValue": {
+      "flexDirection": "row",
+      "alignSelf": "center"
+    }
+  },
+  "pointStyle": {
+    "type": "ViewStyle",
+    "description": "Style for individual dot",
+    "defaultValue": {
+      "width": 8,
+      "height": 8,
+      "borderRadius": 8,
+      "backgroundColor": "theme.color_icon_base"
+    }
+  },
+  "pointActiveStyle": {
+    "type": "ViewStyle",
+    "description": "Style for the active dot",
+    "defaultValue": {
+      "backgroundColor": "#888"
+    }
+  },
+  "spaceStyle": {
+    "type": "ViewStyle",
+    "description": "Style for spacing between dots",
+    "defaultValue": {
+      "marginHorizontal": "theme.h_spacing_sm / 2",
+      "marginVertical": "theme.v_spacing_sm / 2"
+    }
+  }
+}
+```
+
+---
+
+# picker Semantic
+
+Source: https://rn.mobile.ant.design/components/picker/semantic.md
+
+# Picker Semantic
+
+## Component Description
+
+Choose from a set of data, e.g. Country choice.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "Modal",
+  "style": ["modal", "container"],
+  "children": [
+    {
+      "component": "View",
+      "style": "header",
+      "children": [
+        {
+          "component": "TouchableHighlight",
+          "style": "headerItem",
+          "children": [
+            {
+              "component": "Text",
+              "style": ["actionText", "dismissText"]
+            }
+          ]
+        },
+        {
+          "component": "View",
+          "style": "headerItem",
+          "children": [
+            {
+              "component": "Text",
+              "style": "title"
+            }
+          ]
+        },
+        {
+          "component": "TouchableHighlight",
+          "style": "headerItem",
+          "children": [
+            {
+              "component": "Text",
+              "style": ["actionText", "okText"]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "component": "RMCPickerView",
+      "style": [
+        "wrappper",
+        "wheelWrapper",
+        "itemWrap",
+        "itemStyle",
+        "itemActiveStyle",
+        "mask",
+        "maskTop",
+        "maskMiddle",
+        "maskBottom"
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "modal": {
+    "type": "ViewStyle",
+    "description": "Popup layer wrapper style (positioning, background mask, etc.)",
+    "defaultValue": {
+      "flex": 1,
+      "flexDirection": "column",
+      "justifyContent": "flex-end"
+    }
+  },
+  "container": {
+    "type": "ViewStyle",
+    "description": "Popup layer content container (layout and background)",
+    "defaultValue": {}
+  },
+  "header": {
+    "type": "ViewStyle",
+    "description": "Header container layout",
+    "defaultValue": {
+      "height": "theme.picker_header_height",
+      "alignItems": "center",
+      "flexDirection": "row",
+      "justifyContent": "center",
+      "borderBottomWidth": "StyleSheet.hairlineWidth",
+      "borderBottomColor": "theme.border_color_thin",
+      "backgroundColor": "theme.fill_base"
+    }
+  },
+  "headerItem": {
+    "type": "ViewStyle",
+    "description": "Button position and size",
+    "defaultValue": {
+      "height": "theme.picker_header_height",
+      "flex": 1,
+      "alignItems": "center",
+      "justifyContent": "center"
+    }
+  },
+  "actionText": {
+    "type": "TextStyle",
+    "description": "Button text base style",
+    "defaultValue": {
+      "color": "theme.brand_primary",
+      "fontSize": "theme.font_size_heading",
+      "textAlign": "center"
+    }
+  },
+  "title": {
+    "type": "TextStyle",
+    "description": "Title text style",
+    "defaultValue": {
+      "color": "theme.color_text_caption",
+      "fontSize": "theme.font_size_heading",
+      "textAlign": "center"
+    }
+  },
+  "okText": {
+    "type": "TextStyle",
+    "description": "Confirm button text variant style",
+    "defaultValue": {}
+  },
+  "dismissText": {
+    "type": "TextStyle",
+    "description": "Cancel button text variant style",
+    "defaultValue": {}
+  }
+}
+```
+
+---
+
+# picker-view Semantic
+
+Source: https://rn.mobile.ant.design/components/picker-view/semantic.md
+
+# PickerView Semantic
+
+## Component Description
+
+PickerView's functions like Picker, but it is rendered directly in the area instead of the pop-up window.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": "wrappper",
+  "children": [
+    {
+      "component": "View",
+      "style": "wheelWrapper",
+      "children": [
+        {
+          "component": "View",
+          "children": [
+            {
+              "component": "ActivityIndicator"
+            }
+          ]
+        },
+        {
+          "component": "Wheel",
+          "style": "itemWrap",
+          "children": [
+            {
+              "component": "Text",
+              "style": ["itemStyle", "itemActiveStyle"]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "component": "View",
+      "style": "mask",
+      "children": [
+        {
+          "component": "View",
+          "style": "maskTop"
+        },
+        {
+          "component": "View",
+          "style": "maskMiddle"
+        },
+        {
+          "component": "View",
+          "style": "maskBottom"
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "wrappper": {
+    "type": "ViewStyle",
+    "description": "Container overall layout style",
+    "defaultValue": {
+      "display": "flex",
+      "flexDirection": "column",
+      "justifyContent": "center",
+      "overflow": "hidden",
+      "backgroundColor": "theme.fill_base"
+    }
+  },
+  "wheelWrapper": {
+    "type": "ViewStyle",
+    "description": "Wheel area wrapper style",
+    "defaultValue": {
+      "zIndex": 1,
+      "display": "flex",
+      "flexDirection": "row"
+    }
+  },
+  "itemWrap": {
+    "type": "ViewStyle",
+    "description": "Item wrapper style",
+    "defaultValue": {
+      "overflow": "hidden",
+      "justifyContent": "center",
+      "height": "theme.picker_item_height",
+      "paddingHorizontal": "theme.h_spacing_sm"
+    }
+  },
+  "itemStyle": {
+    "type": "TextStyle",
+    "description": "Single option container with fixed height, wrapping text",
+    "defaultValue": {
+      "fontSize": "theme.font_size_caption",
+      "color": "theme.color_text_base",
+      "textAlign": "center",
+      "includeFontPadding": "false"
+    }
+  },
+  "itemActiveStyle": {
+    "type": "TextStyle",
+    "description": "Active item style",
+    "defaultValue": {}
+  },
+  "mask": {
+    "type": "ViewStyle",
+    "description": "Mask layer container style",
+    "defaultValue": {
+      "position": "absolute",
+      "zIndex": 2,
+      "left": 0,
+      "top": 0,
+      "width": "100%",
+      "height": "100%",
+      "display": "flex",
+      "flexDirection": "column"
+    }
+  },
+  "maskTop": {
+    "type": "ViewStyle",
+    "description": "Top gradient mask style",
+    "defaultValue": {
+      "flex": 1,
+      "overflow": "hidden"
+    }
+  },
+  "maskMiddle": {
+    "type": "ViewStyle",
+    "description": "Middle area highlight mask style",
+    "defaultValue": {
+      "borderColor": "theme.border_color_thin",
+      "borderTopWidth": "StyleSheet.hairlineWidth",
+      "borderBottomWidth": "StyleSheet.hairlineWidth"
+    }
+  },
+  "maskBottom": {
+    "type": "ViewStyle",
+    "description": "Footer gradient mask style",
+    "defaultValue": {
+      "flex": 1,
+      "overflow": "hidden"
+    }
+  }
+}
+```
+
+---
+
+# popover Semantic
+
+Source: https://rn.mobile.ant.design/components/popover/semantic.md
+
+# Popover Semantic
+
+## Component Description
+
+After clicking on a control or an area, a Popover menu appears for doing more. If set mask prop, it is recommended to exit by clicking on any of the mask layers.
+
+---
+
+## DOM Structure
+
+```json
+[
+  {
+    "component": "TouchableOpacity"
+  },
+  {
+    "component": "View",
+    "style": "content",
+    "children": [
+      {
+        "component": "View",
+        "style": "arrow"
+      },
+      {
+        "component": "View",
+        "style": "background"
+      },
+      {
+        "component": "ScrollView",
+        "children": [
+          {
+            "component": "TouchableOpacity"
+          }
+        ]
+      }
+    ]
+  }
+]
+```
+
+## Styles Schema
+
+```json
+{
+  "content": {
+    "type": "ViewStyle",
+    "description": "Popup layer container. The popup layer content area appearance can be controlled via styles.content",
+    "defaultValue": {
+      "backgroundColor": "theme.fill_base",
+      "borderRadius": "theme.radius_sm",
+      "padding": 0,
+      "elevation": 3
+    }
+  },
+  "arrow": {
+    "type": "ViewStyle",
+    "description": "Popup layer indicator arrow. The arrow appearance can be controlled via styles.arrow",
+    "defaultValue": {
+      "borderTopColor": "transparent"
+    }
+  },
+  "background": {
+    "type": "ViewStyle",
+    "description": "Popup layer background mask. The mask layer visual can be controlled via styles.background",
+    "defaultValue": {
+      "backgroundColor": "transparent"
+    }
+  }
+}
+```
+
+---
+
+# progress Semantic
+
+Source: https://rn.mobile.ant.design/components/progress/semantic.md
+
+# Progress Semantic
+
+## Component Description
+
+Progress Bar to indicate your task's progress.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "children": [
+    {
+      "component": "View"
+    },
+    {
+      "component": "Animated.View"
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "progressOuter": {
+    "type": "ViewStyle",
+    "description": "Base style of the outer container, such as background color, size, etc.",
+    "defaultValue": {
+      "backgroundColor": "theme.border_color_base",
+      "flex": 1
+    }
+  },
+  "progressBar": {
+    "type": "ViewStyle",
+    "description": "Base style of the progress bar fill color and height, etc.",
+    "defaultValue": {
+      "borderBottomWidth": 4,
+      "borderStyle": "solid",
+      "borderColor": "theme.brand_primary"
+    }
+  }
+}
+```
+
+---
+
+# radio Semantic
+
+Source: https://rn.mobile.ant.design/components/radio/semantic.md
+
+# Radio Semantic
+
+## Component Description
+
+Radio.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "List.Item",
+  "children": [
+    {
+      "component": "Text"
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "radioItemContent": {
+    "type": "TextStyle",
+    "description": "Text content style, such as font color, size, etc.",
+    "defaultValue": {
+      "color": "theme.color_text_base",
+      "marginRight": "theme.h_spacing_md",
+      "marginLeft": "theme.h_spacing_md"
+    }
+  },
+  "radioItemContentDisable": {
+    "type": "TextStyle",
+    "description": "Text style when disabled",
+    "defaultValue": {
+      "color": "theme.color_text_disabled"
+    }
+  }
+}
+```
+
+---
+
+# result Semantic
+
+Source: https://rn.mobile.ant.design/components/result/semantic.md
+
+# Result Semantic
+
+## Component Description
+
+Result page contains feedback like illustrations, icons and text.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "children": [
+    {
+      "component": "View"
+    },
+    {
+      "component": "View",
+      "children": [
+        {
+          "component": "Text"
+        }
+      ]
+    },
+    {
+      "component": "View",
+      "children": [
+        {
+          "component": "Text"
+        }
+      ]
+    },
+    {
+      "component": "View",
+      "children": [
+        {
+          "component": "Button"
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "result": {
+    "type": "ViewStyle",
+    "description": "Result container layout",
+    "defaultValue": {
+      "alignItems": "center",
+      "paddingVertical": "theme.v_spacing_xl",
+      "backgroundColor": "theme.fill_base",
+      "borderBottomColor": "theme.border_color_base"
+    }
+  },
+  "imgWrap": {
+    "type": "ViewStyle",
+    "description": "Icon container positioning and size",
+    "defaultValue": {
+      "margin": 0
+    }
+  },
+  "img": {
+    "type": "ImageStyle",
+    "description": "Image style",
+    "defaultValue": {
+      "width": 60,
+      "height": 60
+    }
+  },
+  "title": {
+    "type": "ViewStyle",
+    "description": "Title container layout",
+    "defaultValue": {
+      "marginTop": "theme.v_spacing_lg",
+      "paddingHorizontal": "theme.h_spacing_lg"
+    }
+  },
+  "titleText": {
+    "type": "TextStyle",
+    "description": "Title text style",
+    "defaultValue": {
+      "fontSize": 21,
+      "color": "theme.color_text_base"
+    }
+  },
+  "message": {
+    "type": "ViewStyle",
+    "description": "Information area layout",
+    "defaultValue": {
+      "marginTop": "theme.v_spacing_lg",
+      "paddingHorizontal": "theme.h_spacing_lg"
+    }
+  },
+  "messageText": {
+    "type": "TextStyle",
+    "description": "Information text style",
+    "defaultValue": {
+      "fontSize": "theme.font_size_caption",
+      "color": "theme.color_text_caption"
+    }
+  },
+  "buttonWrap": {
+    "type": "ViewStyle",
+    "description": "Button container layout",
+    "defaultValue": {
+      "flexDirection": "row",
+      "marginTop": "theme.v_spacing_lg",
+      "paddingHorizontal": "theme.h_spacing_lg"
+    }
+  },
+  "button": {
+    "type": "ViewStyle",
+    "description": "Button style",
+    "defaultValue": {
+      "flex": 1
+    }
+  }
+}
+```
+
+---
+
+# search-bar Semantic
+
+Source: https://rn.mobile.ant.design/components/search-bar/semantic.md
+
+# SearchBar Semantic
+
+## Component Description
+
+Normally located below NavBar, the activation status is exited by the Cancel button.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": "wrapper",
+  "children": [
+    {
+      "component": "View",
+      "style": "inputWrapper",
+      "children": [
+        {
+          "component": "TextInput",
+          "style": "input"
+        }
+      ]
+    },
+    {
+      "component": "Icon",
+      "style": "search"
+    },
+    {
+      "component": "View",
+      "style": "cancelTextContainer",
+      "children": [
+        {
+          "component": "Text",
+          "style": "cancelText"
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "input": {
+    "type": "TextStyle",
+    "description": "Text input box, supports style base property pass-through, used for input search content",
+    "defaultValue": {
+      "borderRadius": "theme.radius_md",
+      "backgroundColor": "theme.fill_grey",
+      "borderColor": "theme.border_color_base",
+      "borderWidth": "theme.border_width_sm",
+      "height": "theme.search_bar_input_height",
+      "color": "theme.color_text_base",
+      "fontSize": "theme.font_size_base",
+      "flex": 1,
+      "paddingTop": 0,
+      "paddingBottom": 0
+    }
+  },
+  "inputWrapper": {
+    "type": "ViewStyle",
+    "description": "Input box outer container, used for input box layout",
+    "defaultValue": {
+      "flex": 1,
+      "flexDirection": "row"
+    }
+  },
+  "wrapper": {
+    "type": "ViewStyle",
+    "description": "Overall container, wraps the entire search bar area",
+    "defaultValue": {
+      "backgroundColor": "theme.fill_base",
+      "height": "theme.search_bar_height",
+      "paddingLeft": "theme.h_spacing_md",
+      "paddingRight": "theme.h_spacing_md",
+      "flexDirection": "row",
+      "alignItems": "center"
+    }
+  },
+  "cancelTextContainer": {
+    "type": "ViewStyle",
+    "description": "Cancel button container, conditionally rendered, displayed when showCancelButton or input box is focused",
+    "defaultValue": {
+      "height": "theme.search_bar_input_height",
+      "justifyContent": "center",
+      "alignItems": "center"
+    }
+  },
+  "cancelText": {
+    "type": "TextStyle",
+    "description": "Cancel button text, click to trigger cancel action",
+    "defaultValue": {
+      "fontSize": "theme.link_button_font_size",
+      "color": "theme.color_link",
+      "paddingLeft": "theme.h_spacing_lg"
+    }
+  },
+  "search": {
+    "type": "TextStyle",
+    "description": "Search icon, displays search magnifying glass icon",
+    "defaultValue": {
+      "color": "theme.color_icon_base",
+      "position": "absolute",
+      "left": "theme.h_spacing_md + 8",
+      "top": "(theme.search_bar_height - theme.icon_size_xxs) / 2",
+      "fontSize": "theme.icon_size_xxs"
+    }
+  }
+}
+```
+
+---
+
+# slider Semantic
+
+Source: https://rn.mobile.ant.design/components/slider/semantic.md
+
+# Slider Semantic
+
+## Component Description
+
+A Slider component for selecting particular value in range, eg: controls the display brightness of the screen.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "GestureDetector",
+  "children": [
+    {
+      "component": "View",
+      "children": [
+        {
+          "component": "View",
+          "children": [
+            {
+              "component": "View"
+            },
+            {
+              "component": "Animated.View"
+            },
+            {
+              "component": "View",
+              "children": [
+                {
+                  "component": "Animated.View"
+                }
+              ]
+            },
+            {
+              "component": "Animated.View",
+              "children": [
+                {
+                  "component": "View"
+                }
+              ]
+            },
+            {
+              "component": "Animated.View",
+              "children": [
+                {
+                  "component": "View"
+                }
+              ]
+            }
+          ]
+        },
+        {
+          "component": "View",
+          "children": [
+            {
+              "component": "View",
+              "children": [
+                {
+                  "component": "View"
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "slider": {
+    "type": "ViewStyle",
+    "description": "Slider 组件主 container style",
+    "defaultValue": {
+      "paddingVertical": 5,
+      "paddingHorizontal": 14
+    }
+  },
+  "disabled": {
+    "type": "ViewStyle",
+    "description": "disabled 时叠加 style",
+    "defaultValue": {}
+  },
+  "trackContianer": {
+    "type": "ViewStyle",
+    "description": "滑轨 container style",
+    "defaultValue": {
+      "paddingVertical": 8,
+      "position": "relative",
+      "width": "100%",
+      "display": "flex",
+      "flexDirection": "row",
+      "alignItems": "center"
+    }
+  },
+  "track": {
+    "type": "ViewStyle",
+    "description": "Slider track background style",
+    "defaultValue": {
+      "position": "absolute",
+      "width": "100%",
+      "zIndex": 1,
+      "height": 3,
+      "borderRadius": 3,
+      "backgroundColor": "theme.fill_grey"
+    }
+  },
+  "fill": {
+    "type": "ViewStyle",
+    "description": "Fill bar style",
+    "defaultValue": {
+      "position": "absolute",
+      "zIndex": 1,
+      "height": 3,
+      "borderRadius": 3,
+      "backgroundColor": "theme.brand_primary"
+    }
+  },
+  "thumb": {
+    "type": "ViewStyle",
+    "description": "Handle button style",
+    "defaultValue": {
+      "zIndex": 3
+    }
+  },
+  "ticks": {
+    "type": "ViewStyle",
+    "description": "Tick mark container style",
+    "defaultValue": {
+      "position": "absolute",
+      "width": "100%",
+      "height": 3,
+      "backgroundColor": "transparent",
+      "zIndex": 2
+    }
+  },
+  "tick": {
+    "type": "ViewStyle",
+    "description": "Tick mark default style",
+    "defaultValue": {
+      "position": "absolute",
+      "top": -2,
+      "width": 7,
+      "height": 7,
+      "marginLeft": -3,
+      "backgroundColor": "theme.fill_grey",
+      "borderRadius": 7
+    }
+  },
+  "tickActive": {
+    "type": "ViewStyle",
+    "description": "Active state tick mark style",
+    "defaultValue": {
+      "backgroundColor": "theme.brand_primary"
+    }
+  },
+  "mark": {
+    "type": "ViewStyle",
+    "description": "Mark container style",
+    "defaultValue": {
+      "position": "relative",
+      "width": "100%",
+      "height": 11
+    }
+  },
+  "markText": {
+    "type": "TextStyle",
+    "description": "Mark text style",
+    "defaultValue": {
+      "transform": "[{ translateX: -theme.font_size_caption_sm / 2 }]",
+      "fontSize": "theme.font_size_caption_sm",
+      "color": "theme.color_text_paragraph"
+    }
+  }
+}
+```
+
+---
+
+# stepper Semantic
+
+Source: https://rn.mobile.ant.design/components/stepper/semantic.md
+
+# Stepper Semantic
+
+## Component Description
+
+- New in `5.2.1`. In addition, all properties of react-native TextInput are supported, eg: **`readOnly`** **`onFocus`** **`onBlur`**
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "Input",
+  "style": ["container", "input", "inputDisabled"],
+  "children": [
+    {
+      "component": "TouchableHighlight",
+      "children": [
+        {
+          "component": "Text"
+        }
+      ]
+    },
+    {
+      "component": "TouchableHighlight",
+      "children": [
+        {
+          "component": "Text"
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "inputDisabled": {
+    "type": "TextStyle",
+    "description": "Input disabled style",
+    "defaultValue": {
+      "opacity": 0.4
+    }
+  },
+  "stepWrap": {
+    "type": "ViewStyle",
+    "description": "Step button wrapper style",
+    "defaultValue": {
+      "width": 28,
+      "flex": 1,
+      "justifyContent": "center",
+      "borderRadius": "theme.radius_xs",
+      "backgroundColor": "theme.fill_grey"
+    }
+  },
+  "stepText": {
+    "type": "TextStyle",
+    "description": "Step button text style",
+    "defaultValue": {
+      "textAlign": "center",
+      "fontSize": 20,
+      "color": "theme.brand_primary",
+      "backgroundColor": "transparent"
+    }
+  },
+  "stepDisabled": {
+    "type": "ViewStyle",
+    "description": "Step button disabled style",
+    "defaultValue": {
+      "opacity": 0.4
+    }
+  },
+  "disabledStepTextColor": {
+    "type": "TextStyle",
+    "description": "Disabled step button text color style",
+    "defaultValue": {
+      "color": "theme.color_text_disabled"
+    }
+  }
+}
+```
+
+---
+
+# steps Semantic
+
+Source: https://rn.mobile.ant.design/components/steps/semantic.md
+
+# Steps Semantic
+
+## Component Description
+
+Steps is typically used for displaying the progress of a task, or guiding users through the steps of a complex flow.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "children": [
+    {
+      "component": "View",
+      "children": [
+        {
+          "component": "View",
+          "children": [
+            {
+              "component": "Icon"
+            }
+          ]
+        },
+        {
+          "component": "View"
+        },
+        {
+          "component": "View"
+        }
+      ]
+    },
+    {
+      "component": "View",
+      "children": [
+        {
+          "component": "Text"
+        },
+        {
+          "component": "Text"
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "head_default_s": {
+    "type": "ViewStyle",
+    "description": "Default small step head style",
+    "defaultValue": {
+      "width": 18,
+      "height": 18,
+      "backgroundColor": "#ffffff",
+      "borderRadius": 18,
+      "borderWidth": 2,
+      "borderColor": "#108ee9",
+      "borderStyle": "solid",
+      "overflow": "hidden"
+    }
+  },
+  "head_blue_s": {
+    "type": "ViewStyle",
+    "description": "Blue small step head style",
+    "defaultValue": {
+      "borderColor": "#108ee9"
+    }
+  },
+  "head_gray_s": {
+    "type": "ViewStyle",
+    "description": "Gray small step head style",
+    "defaultValue": {
+      "borderColor": "#bbbbbb"
+    }
+  },
+  "head_red_s": {
+    "type": "ViewStyle",
+    "description": "Red small step head style",
+    "defaultValue": {
+      "borderColor": "#f4333c"
+    }
+  },
+  "icon_s": {
+    "type": "TextStyle",
+    "description": "Small icon style inside step head",
+    "defaultValue": {
+      "fontSize": 14
+    }
+  },
+  "head_default_l": {
+    "type": "ViewStyle",
+    "description": "Default large step head style",
+    "defaultValue": {
+      "width": 24,
+      "height": 24,
+      "backgroundColor": "#ffffff",
+      "borderRadius": 18,
+      "borderWidth": 2,
+      "borderColor": "#108ee9",
+      "borderStyle": "solid",
+      "overflow": "hidden"
+    }
+  },
+  "head_blue_l": {
+    "type": "ViewStyle",
+    "description": "Blue large step head style",
+    "defaultValue": {
+      "borderColor": "#108ee9",
+      "backgroundColor": "#108ee9"
+    }
+  },
+  "head_gray_l": {
+    "type": "ViewStyle",
+    "description": "Gray large step head style",
+    "defaultValue": {
+      "borderColor": "#bbbbbb",
+      "backgroundColor": "#bbbbbb"
+    }
+  },
+  "head_red_l": {
+    "type": "ViewStyle",
+    "description": "Red large step head style",
+    "defaultValue": {
+      "borderColor": "#f4333c",
+      "backgroundColor": "#f4333c"
+    }
+  },
+  "tail_default_l": {
+    "type": "ViewStyle",
+    "description": "Default large tail line style",
+    "defaultValue": {
+      "width": 2,
+      "height": 30,
+      "marginLeft": 11
+    }
+  },
+  "icon_l": {
+    "type": "TextStyle",
+    "description": "Large icon style inside step head",
+    "defaultValue": {
+      "fontSize": 20
+    }
+  },
+  "tail_default_s": {
+    "type": "ViewStyle",
+    "description": "Default small tail line style",
+    "defaultValue": {
+      "width": 2,
+      "flex": 1,
+      "marginLeft": "2 * grid"
+    }
+  },
+  "tail_default_s_h": {
+    "type": "ViewStyle",
+    "description": "Default small horizontal tail line style",
+    "defaultValue": {
+      "height": 2,
+      "width": 50,
+      "marginTop": "2 * grid"
+    }
+  },
+  "tail_gray": {
+    "type": "ViewStyle",
+    "description": "Gray tail line style",
+    "defaultValue": {
+      "backgroundColor": "#bbbbbb"
+    }
+  },
+  "tail_blue": {
+    "type": "ViewStyle",
+    "description": "Blue tail line style",
+    "defaultValue": {
+      "backgroundColor": "#108ee9"
+    }
+  },
+  "tail_error": {
+    "type": "ViewStyle",
+    "description": "Error tail line style",
+    "defaultValue": {
+      "backgroundColor": "#f4333c"
+    }
+  },
+  "tail_last": {
+    "type": "ViewStyle",
+    "description": "Last step tail line style (transparent)",
+    "defaultValue": {
+      "backgroundColor": "transparent"
+    }
+  },
+  "content_s": {
+    "type": "ViewStyle",
+    "description": "Small size content container style",
+    "defaultValue": {
+      "paddingLeft": 8
+    }
+  },
+  "content_s_h": {
+    "type": "ViewStyle",
+    "description": "Small size horizontal content container style",
+    "defaultValue": {
+      "paddingTop": 9
+    }
+  },
+  "content_l": {
+    "type": "ViewStyle",
+    "description": "Large size content container style",
+    "defaultValue": {
+      "paddingLeft": 15
+    }
+  },
+  "title_s": {
+    "type": "TextStyle",
+    "description": "Small size title text style",
+    "defaultValue": {
+      "fontWeight": "bold",
+      "fontSize": 16,
+      "paddingBottom": 9,
+      "color": "#000000"
+    }
+  },
+  "description_s": {
+    "type": "TextStyle",
+    "description": "Small size description text style",
+    "defaultValue": {
+      "fontSize": 12,
+      "color": "#000000"
+    }
+  },
+  "title_l": {
+    "type": "TextStyle",
+    "description": "Large size title text style",
+    "defaultValue": {
+      "fontWeight": "bold",
+      "fontSize": 17,
+      "paddingBottom": 9,
+      "color": "#000000"
+    }
+  },
+  "description_l": {
+    "type": "TextStyle",
+    "description": "Large size description text style",
+    "defaultValue": {
+      "fontSize": 15,
+      "color": "#000000"
+    }
+  }
+}
+```
+
+---
+
+# swipe-action Semantic
+
+Source: https://rn.mobile.ant.design/components/swipe-action/semantic.md
+
+# SwipeAction Semantic
+
+## Component Description
+
+iOS-style swipeout buttons that appear from behind a component.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "Swipeable",
+  "children": [
+    {
+      "component": "View",
+      "children": [
+        {
+          "component": "Animated.View",
+          "children": [
+            {
+              "component": "RectButton",
+              "style": "actionButton",
+              "children": [
+                {
+                  "component": "Text",
+                  "style": "actionText"
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "actionButton": {
+    "type": "ViewStyle",
+    "description": "action button container style",
+    "defaultValue": {
+      "flex": 1,
+      "alignItems": "center",
+      "justifyContent": "center"
+    }
+  },
+  "actionText": {
+    "type": "TextStyle",
+    "description": "Action button text style",
+    "defaultValue": {
+      "color": "theme.color_text_base_inverse",
+      "fontSize": "theme.font_size_base",
+      "backgroundColor": "transparent",
+      "padding": 10
+    }
+  }
+}
+```
+
+---
+
+# switch Semantic
+
+Source: https://rn.mobile.ant.design/components/switch/semantic.md
+
+# Switch Semantic
+
+## Component Description
+
+Select between two status, e.g. Select On or Off.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "Pressable",
+  "children": [
+    {
+      "component": "View",
+      "style": [
+        "switch",
+        "switch_checked",
+        "switch_unchecked",
+        "switch_checked_disabled",
+        "switch_unchecked_disabled"
+      ],
+      "children": [
+        {
+          "component": "Animated.View",
+          "style": [
+            "switch_handle",
+            "switch_handle_checked",
+            "switch_handle_unchecked",
+            "switch_handle_disabled"
+          ],
+          "children": [
+            {
+              "component": "RNActivityIndicator"
+            }
+          ]
+        },
+        {
+          "component": "AnimatedView",
+          "style": [
+            "switch_inner",
+            "switch_inner_checked",
+            "switch_inner_unchecked"
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "switch": {
+    "type": "ViewStyle",
+    "description": "开关 track base style",
+    "defaultValue": {
+      "position": "relative",
+      "width": 55,
+      "height": 31,
+      "display": "flex",
+      "flexDirection": "row",
+      "alignItems": "center",
+      "padding": 0,
+      "borderRadius": 31
+    }
+  },
+  "switch_inner": {
+    "type": "ViewStyle",
+    "description": "内 layer container base style",
+    "defaultValue": {
+      "color": "#fff",
+      "fontSize": 12,
+      "flex": 1,
+      "textAlign": "center",
+      "alignItems": "center",
+      "justifyContent": "center",
+      "zIndex": -1
+    }
+  },
+  "switch_handle": {
+    "type": "ViewStyle",
+    "description": "手柄 base style",
+    "defaultValue": {
+      "position": "absolute",
+      "width": 27,
+      "height": 27,
+      "borderRadius": 27,
+      "display": "flex",
+      "justifyContent": "center",
+      "alignItems": "center",
+      "backgroundColor": "#ffffff",
+      "shadowColor": "rgb(0, 35, 11)",
+      "shadowOffset": {
+        "width": 0,
+        "height": 2
+      },
+      "shadowOpacity": 0.2,
+      "shadowRadius": 10,
+      "elevation": 10
+    }
+  },
+  "switch_checked": {
+    "type": "ViewStyle",
+    "description": "Switch track style when active",
+    "defaultValue": {
+      "borderColor": "theme.brand_primary",
+      "backgroundColor": "theme.brand_primary"
+    }
+  },
+  "switch_unchecked": {
+    "type": "ViewStyle",
+    "description": "Switch track style when not active",
+    "defaultValue": {
+      "borderColor": "theme.switch_unchecked",
+      "backgroundColor": "theme.switch_unchecked"
+    }
+  },
+  "switch_inner_checked": {
+    "type": "ViewStyle",
+    "description": "active state 下内 layer 变化 style",
+    "defaultValue": {
+      "marginLeft": 7,
+      "marginRight": 27
+    }
+  },
+  "switch_inner_unchecked": {
+    "type": "ViewStyle",
+    "description": "未 active state 下内 layer 变化 style",
+    "defaultValue": {
+      "marginLeft": 27,
+      "marginRight": 7
+    }
+  },
+  "switch_handle_checked": {
+    "type": "ViewStyle",
+    "description": "手柄 active state style",
+    "defaultValue": {
+      "right": 0
+    }
+  },
+  "switch_handle_unchecked": {
+    "type": "ViewStyle",
+    "description": "手柄未 active state style",
+    "defaultValue": {
+      "left": 0
+    }
+  },
+  "switch_checked_disabled": {
+    "type": "ViewStyle",
+    "description": "active 且 disabled state track style",
+    "defaultValue": {
+      "borderColor": "#108ee966",
+      "backgroundColor": "#108ee966"
+    }
+  },
+  "switch_unchecked_disabled": {
+    "type": "ViewStyle",
+    "description": "未 active 且 disabled state track style",
+    "defaultValue": {
+      "borderColor": "#cccccc66",
+      "backgroundColor": "#cccccc66"
+    }
+  },
+  "switch_handle_disabled": {
+    "type": "ViewStyle",
+    "description": "手柄 disabled state style",
+    "defaultValue": {}
+  }
+}
+```
+
+---
+
+# tab-bar Semantic
+
+Source: https://rn.mobile.ant.design/components/tab-bar/semantic.md
+
+# TabBar Semantic
+
+## Component Description
+
+Located at the bottom of the APP, to facilitate users to quickly switch between different functional modules。
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "SafeAreaView",
+  "children": [
+    {
+      "component": "View",
+      "style": "tabbar",
+      "children": [
+        {
+          "component": "View",
+          "style": "content",
+          "children": [
+            {
+              "component": "View",
+              "style": ["contentItem", "contentItemSelected"]
+            }
+          ]
+        },
+        {
+          "component": "View",
+          "style": "tabs",
+          "children": [
+            {
+              "component": "TouchableWithoutFeedback",
+              "children": [
+                {
+                  "component": "View",
+                  "style": "barItem",
+                  "children": [
+                    {
+                      "component": "View",
+                      "children": [
+                        {
+                          "component": "ImageOrIcon",
+                          "style": "barIcon"
+                        },
+                        {
+                          "component": "View",
+                          "style": "badge",
+                          "children": [
+                            {
+                              "component": "Text",
+                              "style": "badgeText"
+                            }
+                          ]
+                        }
+                      ]
+                    },
+                    {
+                      "component": "Text",
+                      "style": "barItemTitle"
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "tabbar": {
+    "type": "ViewStyle",
+    "description": "TabBar 主 container style",
+    "defaultValue": {
+      "flex": 1
+    }
+  },
+  "content": {
+    "type": "ViewStyle",
+    "description": "content 区 container style",
+    "defaultValue": {
+      "flex": 1
+    }
+  },
+  "tabs": {
+    "type": "ViewStyle",
+    "description": "Footer label bar container style",
+    "defaultValue": {
+      "height": "theme.tab_bar_height",
+      "borderTopWidth": "theme.border_width_md",
+      "borderColor": "theme.border_color_base",
+      "borderStyle": "solid",
+      "flexDirection": "row"
+    }
+  },
+  "barItem": {
+    "type": "ViewStyle",
+    "description": "Label item default style",
+    "defaultValue": {
+      "flex": 1,
+      "alignItems": "center",
+      "justifyContent": "center"
+    }
+  },
+  "barIcon": {
+    "type": "ImageStyle",
+    "description": "Icon style",
+    "defaultValue": {
+      "width": 28,
+      "height": 28,
+      "marginTop": 2
+    }
+  },
+  "barItemSelected": {
+    "type": "ViewStyle",
+    "description": "Active label item style, dynamic decoration",
+    "defaultValue": {}
+  },
+  "barItemTitle": {
+    "type": "TextStyle",
+    "description": "Label text style",
+    "defaultValue": {
+      "fontSize": "theme.font_size_icontext",
+      "marginTop": 2
+    }
+  },
+  "contentItem": {
+    "type": "ViewStyle",
+    "description": "Content item style",
+    "defaultValue": {
+      "position": "absolute",
+      "top": 0,
+      "left": 0,
+      "right": 0,
+      "bottom": 0,
+      "backgroundColor": "white",
+      "height": 0
+    }
+  },
+  "contentItemSelected": {
+    "type": "ViewStyle",
+    "description": "Active content item extra style",
+    "defaultValue": {
+      "height": "undefined"
+    }
+  },
+  "badge": {
+    "type": "ViewStyle",
+    "description": "Badge background style",
+    "defaultValue": {
+      "minWidth": 20,
+      "height": 20,
+      "borderRadius": 10,
+      "backgroundColor": "theme.brand_important",
+      "position": "absolute",
+      "top": 0,
+      "left": 20,
+      "paddingHorizontal": "theme.h_spacing_sm"
+    }
+  },
+  "badgeText": {
+    "type": "TextStyle",
+    "description": "Badge text style",
+    "defaultValue": {
+      "textAlign": "center",
+      "color": "white"
+    }
+  }
+}
+```
+
+---
+
+# tabs Semantic
+
+Source: https://rn.mobile.ant.design/components/tabs/semantic.md
+
+# Tabs Semantic
+
+## Component Description
+
+A `Tabs` is used to allow users to switch between different views.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": "container",
+  "children": [
+    {
+      "component": "View",
+      "children": [
+        {
+          "component": "View",
+          "style": "container",
+          "children": [
+            {
+              "component": "ScrollView",
+              "children": [
+                {
+                  "component": "View",
+                  "style": "tabs",
+                  "children": [
+                    {
+                      "component": "TouchableOpacity",
+                      "children": [
+                        {
+                          "component": "View",
+                          "style": "tab",
+                          "children": [
+                            {
+                              "component": "Text",
+                              "style": "textStyle"
+                            }
+                          ]
+                        }
+                      ]
+                    },
+                    {
+                      "component": "Animated.View",
+                      "style": "underline"
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "component": "Carousel",
+      "children": [
+        {
+          "component": "View"
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "container": {
+    "type": "ViewStyle",
+    "description": "Overall container view that holds the entire Tabs component",
+    "defaultValue": {}
+  },
+  "tabs": {
+    "type": "ViewStyle",
+    "description": "Container for tab labels, holding all label items and underline",
+    "defaultValue": {
+      "flex": 1,
+      "flexDirection": "row",
+      "backgroundColor": "#ffffff",
+      "justifyContent": "space-around",
+      "shadowRadius": 0,
+      "shadowOpacity": 0,
+      "elevation": 0
+    }
+  },
+  "tab": {
+    "type": "ViewStyle",
+    "description": "Label base layout style",
+    "defaultValue": {
+      "height": 42,
+      "alignItems": "center",
+      "justifyContent": "center",
+      "padding": 0,
+      "flexDirection": "row"
+    }
+  },
+  "underline": {
+    "type": "ViewStyle",
+    "description": "Underline base style",
+    "defaultValue": {
+      "height": 2,
+      "backgroundColor": "#108ee9"
+    }
+  },
+  "textStyle": {
+    "type": "TextStyle",
+    "description": "Text base style",
+    "defaultValue": {
+      "fontSize": 15
+    }
+  }
+}
+```
+
+---
+
+# tag Semantic
+
+Source: https://rn.mobile.ant.design/components/tag/semantic.md
+
+# Tag Semantic
+
+## Component Description
+
+Tag for categorizing or markuping, can be used to make classification or mark the attributes and dimensions of objects.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": "tag",
+  "children": [
+    {
+      "component": "TouchableWithoutFeedback",
+      "children": [
+        {
+          "component": "View",
+          "style": [
+            "wrap",
+            "normalWrap",
+            "wrapSmall",
+            "activeWrap",
+            "disabledWrap"
+          ],
+          "children": [
+            {
+              "component": "Text",
+              "style": [
+                "text",
+                "textSmall",
+                "normalText",
+                "activeText",
+                "disabledText"
+              ]
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "component": "Icon",
+      "style": "close"
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "tag": {
+    "type": "ViewStyle",
+    "description": "Tag root container style",
+    "defaultValue": {
+      "position": "relative",
+      "flexDirection": "row",
+      "overflow": "visible"
+    }
+  },
+  "wrap": {
+    "type": "ViewStyle",
+    "description": "Tag default outer container style",
+    "defaultValue": {
+      "height": 25,
+      "justifyContent": "center",
+      "borderRadius": 3,
+      "borderWidth": 0.5,
+      "borderStyle": "solid",
+      "paddingVertical": 0,
+      "paddingHorizontal": 15
+    }
+  },
+  "wrapSmall": {
+    "type": "ViewStyle",
+    "description": "Small size tag container style (dynamically applied)",
+    "defaultValue": {
+      "height": "theme.tag_height_sm",
+      "paddingVertical": 0,
+      "paddingHorizontal": 5
+    }
+  },
+  "text": {
+    "type": "TextStyle",
+    "description": "Tag text base style",
+    "defaultValue": {
+      "fontSize": 12,
+      "textAlign": "center"
+    }
+  },
+  "textSmall": {
+    "type": "TextStyle",
+    "description": "Small size tag text style (dynamically applied)",
+    "defaultValue": {
+      "fontSize": 10
+    }
+  },
+  "normalWrap": {
+    "type": "ViewStyle",
+    "description": "Non-disabled and non-active tag container style (dynamically applied)",
+    "defaultValue": {
+      "backgroundColor": "#ffffff",
+      "borderColor": "#dddddd"
+    }
+  },
+  "normalText": {
+    "type": "TextStyle",
+    "description": "Non-disabled and non-active tag text style (dynamically applied)",
+    "defaultValue": {
+      "color": "#888888"
+    }
+  },
+  "activeWrap": {
+    "type": "ViewStyle",
+    "description": "Active and non-disabled tag container style (dynamically applied)",
+    "defaultValue": {
+      "backgroundColor": "#ffffff",
+      "borderColor": "#108ee9"
+    }
+  },
+  "activeText": {
+    "type": "TextStyle",
+    "description": "Active and non-disabled tag text style (dynamically applied)",
+    "defaultValue": {
+      "color": "#108ee9"
+    }
+  },
+  "disabledWrap": {
+    "type": "ViewStyle",
+    "description": "Disabled state tag container style (dynamically applied)",
+    "defaultValue": {
+      "backgroundColor": "#dddddd",
+      "borderColor": "#dddddd"
+    }
+  },
+  "disabledText": {
+    "type": "TextStyle",
+    "description": "Disabled state tag text style (dynamically applied)",
+    "defaultValue": {
+      "color": "#bbbbbb"
+    }
+  },
+  "close": {
+    "type": "ViewStyle",
+    "description": "Close icon style",
+    "defaultValue": {
+      "position": "absolute",
+      "top": -6,
+      "left": -6,
+      "color": "#bbbbbb",
+      "backgroundColor": "transparent",
+      "borderRadius": 999,
+      "fontSize": 16
+    }
+  }
+}
+```
+
+---
+
+# textarea-item Semantic
+
+Source: https://rn.mobile.ant.design/components/textarea-item/semantic.md
+
+# TextareaItem Semantic
+
+## Component Description
+
+A foundational component for inputting multi-line text into the app via a keyboard.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": "container",
+  "children": [
+    {
+      "component": "TextInput",
+      "style": "input"
+    },
+    {
+      "component": "TouchableWithoutFeedback",
+      "children": [
+        {
+          "component": "View",
+          "style": "errorIcon",
+          "children": [
+            {
+              "component": "Icon"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "component": "View",
+      "style": "count",
+      "children": [
+        {
+          "component": "Text",
+          "style": "countText"
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "container": {
+    "type": "ViewStyle",
+    "description": "Container overall style",
+    "defaultValue": {
+      "borderBottomWidth": 0.5,
+      "borderBottomColor": "#dddddd"
+    }
+  },
+  "input": {
+    "type": "TextStyle",
+    "description": "Text input field style",
+    "defaultValue": {
+      "paddingHorizontal": 8,
+      "backgroundColor": "#ffffff",
+      "fontSize": 17,
+      "lineHeight": "Math.round(1.3 * theme.font_size_heading)",
+      "textAlignVertical": "top"
+    }
+  },
+  "icon": {
+    "type": "ViewStyle",
+    "description": "Icon style",
+    "defaultValue": {
+      "position": "absolute",
+      "top": 8,
+      "width": 18,
+      "height": 18
+    }
+  },
+  "errorIcon": {
+    "type": "ViewStyle",
+    "description": "Error icon container style",
+    "defaultValue": {
+      "position": "absolute",
+      "right": 18,
+      "top": 12
+    }
+  },
+  "count": {
+    "type": "ViewStyle",
+    "description": "Character count container style",
+    "defaultValue": {
+      "position": "absolute",
+      "right": 8,
+      "bottom": 8
+    }
+  },
+  "countText": {
+    "type": "TextStyle",
+    "description": "Character count text style",
+    "defaultValue": {}
+  }
+}
+```
+
+---
+
+# toast Semantic
+
+Source: https://rn.mobile.ant.design/components/toast/semantic.md
+
+# Toast Semantic
+
+## Component Description
+
+A lightweight feedback or tips, used to display content that does not interrupt user operations. Suitable for page transitions, data interaction and other scenes.
+
+---
+
+## DOM Structure
+
+```json
+{
+  "component": "View",
+  "style": "container",
+  "children": [
+    {
+      "component": "View",
+      "style": "innerContainer",
+      "children": [
+        {
+          "component": "Animated.View",
+          "children": [
+            {
+              "component": "View",
+              "style": ["innerWrap", "iconToast", "textToast"]
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
+```
+
+## Styles Schema
+
+```json
+{
+  "container": {
+    "type": "ViewStyle",
+    "description": "Top layer positioning container, controls modal position (top/bottom/center) and overall container style",
+    "defaultValue": {
+      "position": "absolute",
+      "top": 0,
+      "left": 0,
+      "bottom": 0,
+      "right": 0,
+      "backgroundColor": "transparent",
+      "alignItems": "center",
+      "zIndex": 1999
+    }
+  },
+  "innerContainer": {
+    "type": "ViewStyle",
+    "description": "Inner container, background layer style",
+    "defaultValue": {
+      "backgroundColor": "transparent"
+    }
+  },
+  "innerWrap": {
+    "type": "ViewStyle",
+    "description": "Content wrapper container, selects iconToast or textToast style based on whether there is an icon",
+    "defaultValue": {
+      "alignItems": "center",
+      "backgroundColor": "rgba(0, 0, 0, .8)",
+      "minWidth": 100
+    }
+  },
+  "iconToast": {
+    "type": "ViewStyle",
+    "description": "Icon toast style",
+    "defaultValue": {
+      "borderRadius": 7,
+      "padding": 15
+    }
+  },
+  "textToast": {
+    "type": "ViewStyle",
+    "description": "Text toast style",
+    "defaultValue": {
+      "borderRadius": 3,
+      "paddingVertical": 9,
+      "paddingHorizontal": 15
+    }
+  },
+  "content": {
+    "type": "TextStyle",
+    "description": "Content style",
+    "defaultValue": {
+      "color": "#ffffff",
+      "fontSize": 15
+    }
+  },
+  "image": {
+    "type": "TextStyle",
+    "description": "Image style",
+    "defaultValue": {
+      "marginBottom": 3
+    }
+  },
+  "centering": {
+    "type": "ViewStyle",
+    "description": "Centering style",
+    "defaultValue": {
+      "alignItems": "center",
+      "justifyContent": "center",
+      "padding": 9
+    }
+  }
+}
+```
+
+---
+
+# tooltip Semantic
+
+Source: https://rn.mobile.ant.design/components/tooltip/semantic.md
+
+# Tooltip Semantic
+
+## Component Description
+
+After clicking on a control or an area, a Tooltip menu appears for doing more. If set mask prop, it is recommended to exit by clicking on any of the mask layers.
+
+---
+
+## DOM Structure
+
+```json
+[
+  {
+    "component": "Wrapper"
+  },
+  {
+    "component": "View",
+    "style": "tooltip",
+    "children": [
+      {
+        "component": "View",
+        "style": "arrow"
+      },
+      {
+        "component": "AntmView",
+        "style": "tooltipText"
+      }
+    ]
+  }
+]
+```
+
+## Styles Schema
+
+```json
+{
+  "tooltip": {
+    "type": "ViewStyle",
+    "description": "Main container style, defines layout, background, etc.",
+    "defaultValue": {
+      "zIndex": 999,
+      "backgroundColor": "mode === 'dark' ? theme.tooltip_dark : theme.fill_base",
+      "borderRadius": 8,
+      "shadowColor": "rgba(51, 51, 51, 1)",
+      "shadowOffset": {
+        "width": 1,
+        "height": 1
+      },
+      "shadowOpacity": 0.2,
+      "shadowRadius": 12,
+      "elevation": 12,
+      "minWidth": 32,
+      "paddingVertical": 8,
+      "paddingHorizontal": 12
+    }
+  },
+  "tooltipText": {
+    "type": "TextStyle",
+    "description": "Content text style, controls font color, size, etc.",
+    "defaultValue": {
+      "color": "mode === 'dark' ? '#ffffff' : theme.color_text_base"
+    }
+  },
+  "arrow": {
+    "type": "ViewStyle",
+    "description": "Arrow style, includes size, color, and rotation (dynamically applied)",
+    "defaultValue": {
+      "width": 0,
+      "height": 0,
+      "borderRightColor": "transparent",
+      "borderBottomColor": "transparent",
+      "borderLeftColor": "transparent",
+      "borderStyle": "solid",
+      "borderWidth": 8,
+      "position": "absolute"
+    }
+  }
+}
+```
+
+---

+ 202 - 0
docs/antd/llms.txt

@@ -0,0 +1,202 @@
+# Ant Design Mobile RN
+
+- Ant Design Mobile RN is a React Native UI library that provides high-quality components for mobile application development.
+
+## Navigation
+
+- [Full Documentation (EN)](https://rn.mobile.ant.design/llms-full.txt)
+- [Full Documentation (CN)](https://rn.mobile.ant.design/llms-full-cn.txt)
+- [Semantic Documentation (EN)](https://rn.mobile.ant.design/llms-semantic.md)
+- [Semantic Documentation (CN)](https://rn.mobile.ant.design/llms-semantic-cn.md)
+
+## Docs (EN)
+
+- [Ant Design Mobile RN of React](https://rn.mobile.ant.design/docs/react/introduce.md)
+- [changelog](https://rn.mobile.ant.design/changelog.md)
+- [Support us](https://rn.mobile.ant.design/docs/react/support.md)
+- [Upgrade](https://rn.mobile.ant.design/docs/react/upgrade-notes.md)
+- [Use Headless style to transform antd](https://rn.mobile.ant.design/docs/blog/headless.md)
+- [What is styles?](https://rn.mobile.ant.design/docs/blog/what-is-styles.md)
+
+## Docs (CN)
+
+- [升级指南](https://rn.mobile.ant.design/docs/react/upgrade-notes-cn.md)
+- [使用Headless风格改造antd](https://rn.mobile.ant.design/docs/blog/headless-cn.md)
+- [支持我们](https://rn.mobile.ant.design/docs/react/support-cn.md)
+- [Ant Design Mobile RN of React](https://rn.mobile.ant.design/docs/react/introduce-cn.md)
+- [changelog-cn](https://rn.mobile.ant.design/changelog-cn.md)
+- [styles是什么?](https://rn.mobile.ant.design/docs/blog/what-is-styles-cn.md)
+
+## Components (EN)
+
+- [Accordion](https://rn.mobile.ant.design/components/accordion.md)
+- [ActionSheet](https://rn.mobile.ant.design/components/action-sheet.md)
+- [ActivityIndicator](https://rn.mobile.ant.design/components/activity-indicator.md)
+- [Badge](https://rn.mobile.ant.design/components/badge.md)
+- [Button](https://rn.mobile.ant.design/components/button.md)
+- [Card](https://rn.mobile.ant.design/components/card.md)
+- [Carousel](https://rn.mobile.ant.design/components/carousel.md)
+- [Checkbox](https://rn.mobile.ant.design/components/checkbox.md)
+- [Collapse](https://rn.mobile.ant.design/components/collapse.md)
+- [DatePicker](https://rn.mobile.ant.design/components/date-picker.md)
+- [DatePickerView](https://rn.mobile.ant.design/components/date-picker-view.md)
+- [DatePickerView](https://rn.mobile.ant.design/components/image-picker.md)
+- [Drawer](https://rn.mobile.ant.design/components/drawer.md)
+- [Flex](https://rn.mobile.ant.design/components/flex.md)
+- [Form](https://rn.mobile.ant.design/components/form.md)
+- [Grid](https://rn.mobile.ant.design/components/grid.md)
+- [Icon](https://rn.mobile.ant.design/components/icon.md)
+- [Input](https://rn.mobile.ant.design/components/input.md)
+- [InputItem](https://rn.mobile.ant.design/components/input-item.md)
+- [List](https://rn.mobile.ant.design/components/list.md)
+- [ListView](https://rn.mobile.ant.design/components/list-view.md)
+- [Modal](https://rn.mobile.ant.design/components/modal.md)
+- [NoticeBar](https://rn.mobile.ant.design/components/notice-bar.md)
+- [Pagination](https://rn.mobile.ant.design/components/pagination.md)
+- [Picker](https://rn.mobile.ant.design/components/picker.md)
+- [PickerView](https://rn.mobile.ant.design/components/picker-view.md)
+- [Popover](https://rn.mobile.ant.design/components/popover.md)
+- [Progress](https://rn.mobile.ant.design/components/progress.md)
+- [Provider](https://rn.mobile.ant.design/components/provider.md)
+- [Radio](https://rn.mobile.ant.design/components/radio.md)
+- [Result](https://rn.mobile.ant.design/components/result.md)
+- [SearchBar](https://rn.mobile.ant.design/components/search-bar.md)
+- [SegmentedControl](https://rn.mobile.ant.design/components/segmented-control.md)
+- [Slider](https://rn.mobile.ant.design/components/slider.md)
+- [Stepper](https://rn.mobile.ant.design/components/stepper.md)
+- [Steps](https://rn.mobile.ant.design/components/steps.md)
+- [SwipeAction](https://rn.mobile.ant.design/components/swipe-action.md)
+- [Switch](https://rn.mobile.ant.design/components/switch.md)
+- [TabBar](https://rn.mobile.ant.design/components/tab-bar.md)
+- [Tabs](https://rn.mobile.ant.design/components/tabs.md)
+- [Tag](https://rn.mobile.ant.design/components/tag.md)
+- [TextareaItem](https://rn.mobile.ant.design/components/textarea-item.md)
+- [Toast](https://rn.mobile.ant.design/components/toast.md)
+- [Tooltip](https://rn.mobile.ant.design/components/tooltip.md)
+- [View](https://rn.mobile.ant.design/components/view.md)
+- [WhiteSpace](https://rn.mobile.ant.design/components/white-space.md)
+- [WingBlank](https://rn.mobile.ant.design/components/wing-blank.md)
+
+## Components (CN)
+
+- [Accordion](https://rn.mobile.ant.design/components/accordion-cn.md)
+- [ActionSheet](https://rn.mobile.ant.design/components/action-sheet-cn.md)
+- [ActivityIndicator](https://rn.mobile.ant.design/components/activity-indicator-cn.md)
+- [Badge](https://rn.mobile.ant.design/components/badge-cn.md)
+- [Button](https://rn.mobile.ant.design/components/button-cn.md)
+- [Card](https://rn.mobile.ant.design/components/card-cn.md)
+- [Carousel](https://rn.mobile.ant.design/components/carousel-cn.md)
+- [Checkbox](https://rn.mobile.ant.design/components/checkbox-cn.md)
+- [Collapse](https://rn.mobile.ant.design/components/collapse-cn.md)
+- [DatePicker](https://rn.mobile.ant.design/components/date-picker-cn.md)
+- [DatePickerView](https://rn.mobile.ant.design/components/date-picker-view-cn.md)
+- [Drawer](https://rn.mobile.ant.design/components/drawer-cn.md)
+- [Flex](https://rn.mobile.ant.design/components/flex-cn.md)
+- [Form](https://rn.mobile.ant.design/components/form-cn.md)
+- [Grid](https://rn.mobile.ant.design/components/grid-cn.md)
+- [Icon](https://rn.mobile.ant.design/components/icon-cn.md)
+- [ImagePicker](https://rn.mobile.ant.design/components/image-picker-cn.md)
+- [Input](https://rn.mobile.ant.design/components/input-cn.md)
+- [InputItem](https://rn.mobile.ant.design/components/input-item-cn.md)
+- [List](https://rn.mobile.ant.design/components/list-cn.md)
+- [ListView](https://rn.mobile.ant.design/components/list-view-cn.md)
+- [Modal](https://rn.mobile.ant.design/components/modal-cn.md)
+- [NoticeBar](https://rn.mobile.ant.design/components/notice-bar-cn.md)
+- [Pagination](https://rn.mobile.ant.design/components/pagination-cn.md)
+- [Picker](https://rn.mobile.ant.design/components/picker-cn.md)
+- [PickerView](https://rn.mobile.ant.design/components/picker-view-cn.md)
+- [Popover](https://rn.mobile.ant.design/components/popover-cn.md)
+- [Progress](https://rn.mobile.ant.design/components/progress-cn.md)
+- [Provider](https://rn.mobile.ant.design/components/provider-cn.md)
+- [Radio](https://rn.mobile.ant.design/components/radio-cn.md)
+- [Result](https://rn.mobile.ant.design/components/result-cn.md)
+- [SearchBar](https://rn.mobile.ant.design/components/search-bar-cn.md)
+- [SegmentedControl](https://rn.mobile.ant.design/components/segmented-control-cn.md)
+- [Slider](https://rn.mobile.ant.design/components/slider-cn.md)
+- [Stepper](https://rn.mobile.ant.design/components/stepper-cn.md)
+- [Steps](https://rn.mobile.ant.design/components/steps-cn.md)
+- [SwipeAction](https://rn.mobile.ant.design/components/swipe-action-cn.md)
+- [Switch](https://rn.mobile.ant.design/components/switch-cn.md)
+- [TabBar](https://rn.mobile.ant.design/components/tab-bar-cn.md)
+- [Tabs](https://rn.mobile.ant.design/components/tabs-cn.md)
+- [Tag](https://rn.mobile.ant.design/components/tag-cn.md)
+- [TextareaItem](https://rn.mobile.ant.design/components/textarea-item-cn.md)
+- [Toast](https://rn.mobile.ant.design/components/toast-cn.md)
+- [Tooltip](https://rn.mobile.ant.design/components/tooltip-cn.md)
+- [View](https://rn.mobile.ant.design/components/view-cn.md)
+- [WhiteSpace](https://rn.mobile.ant.design/components/white-space-cn.md)
+- [WingBlank](https://rn.mobile.ant.design/components/wing-blank-cn.md)
+
+## Semantic (EN)
+
+- [accordion Semantic](https://rn.mobile.ant.design/components/accordion/semantic.md)
+- [action-sheet Semantic](https://rn.mobile.ant.design/components/action-sheet/semantic.md)
+- [activity-indicator Semantic](https://rn.mobile.ant.design/components/activity-indicator/semantic.md)
+- [badge Semantic](https://rn.mobile.ant.design/components/badge/semantic.md)
+- [button Semantic](https://rn.mobile.ant.design/components/button/semantic.md)
+- [card Semantic](https://rn.mobile.ant.design/components/card/semantic.md)
+- [carousel Semantic](https://rn.mobile.ant.design/components/carousel/semantic.md)
+- [checkbox Semantic](https://rn.mobile.ant.design/components/checkbox/semantic.md)
+- [form Semantic](https://rn.mobile.ant.design/components/form/semantic.md)
+- [grid Semantic](https://rn.mobile.ant.design/components/grid/semantic.md)
+- [input Semantic](https://rn.mobile.ant.design/components/input/semantic.md)
+- [input-item Semantic](https://rn.mobile.ant.design/components/input-item/semantic.md)
+- [list Semantic](https://rn.mobile.ant.design/components/list/semantic.md)
+- [modal Semantic](https://rn.mobile.ant.design/components/modal/semantic.md)
+- [notice-bar Semantic](https://rn.mobile.ant.design/components/notice-bar/semantic.md)
+- [pagination Semantic](https://rn.mobile.ant.design/components/pagination/semantic.md)
+- [picker Semantic](https://rn.mobile.ant.design/components/picker/semantic.md)
+- [picker-view Semantic](https://rn.mobile.ant.design/components/picker-view/semantic.md)
+- [popover Semantic](https://rn.mobile.ant.design/components/popover/semantic.md)
+- [progress Semantic](https://rn.mobile.ant.design/components/progress/semantic.md)
+- [radio Semantic](https://rn.mobile.ant.design/components/radio/semantic.md)
+- [result Semantic](https://rn.mobile.ant.design/components/result/semantic.md)
+- [search-bar Semantic](https://rn.mobile.ant.design/components/search-bar/semantic.md)
+- [slider Semantic](https://rn.mobile.ant.design/components/slider/semantic.md)
+- [stepper Semantic](https://rn.mobile.ant.design/components/stepper/semantic.md)
+- [steps Semantic](https://rn.mobile.ant.design/components/steps/semantic.md)
+- [swipe-action Semantic](https://rn.mobile.ant.design/components/swipe-action/semantic.md)
+- [switch Semantic](https://rn.mobile.ant.design/components/switch/semantic.md)
+- [tab-bar Semantic](https://rn.mobile.ant.design/components/tab-bar/semantic.md)
+- [tabs Semantic](https://rn.mobile.ant.design/components/tabs/semantic.md)
+- [tag Semantic](https://rn.mobile.ant.design/components/tag/semantic.md)
+- [textarea-item Semantic](https://rn.mobile.ant.design/components/textarea-item/semantic.md)
+- [toast Semantic](https://rn.mobile.ant.design/components/toast/semantic.md)
+- [tooltip Semantic](https://rn.mobile.ant.design/components/tooltip/semantic.md)
+
+## Semantic (CN)
+
+- [accordion Semantic](https://rn.mobile.ant.design/components/accordion-cn/semantic.md)
+- [action-sheet Semantic](https://rn.mobile.ant.design/components/action-sheet-cn/semantic.md)
+- [activity-indicator Semantic](https://rn.mobile.ant.design/components/activity-indicator-cn/semantic.md)
+- [badge Semantic](https://rn.mobile.ant.design/components/badge-cn/semantic.md)
+- [button Semantic](https://rn.mobile.ant.design/components/button-cn/semantic.md)
+- [card Semantic](https://rn.mobile.ant.design/components/card-cn/semantic.md)
+- [carousel Semantic](https://rn.mobile.ant.design/components/carousel-cn/semantic.md)
+- [checkbox Semantic](https://rn.mobile.ant.design/components/checkbox-cn/semantic.md)
+- [form Semantic](https://rn.mobile.ant.design/components/form-cn/semantic.md)
+- [grid Semantic](https://rn.mobile.ant.design/components/grid-cn/semantic.md)
+- [input Semantic](https://rn.mobile.ant.design/components/input-cn/semantic.md)
+- [input-item Semantic](https://rn.mobile.ant.design/components/input-item-cn/semantic.md)
+- [list Semantic](https://rn.mobile.ant.design/components/list-cn/semantic.md)
+- [modal Semantic](https://rn.mobile.ant.design/components/modal-cn/semantic.md)
+- [notice-bar Semantic](https://rn.mobile.ant.design/components/notice-bar-cn/semantic.md)
+- [pagination Semantic](https://rn.mobile.ant.design/components/pagination-cn/semantic.md)
+- [picker Semantic](https://rn.mobile.ant.design/components/picker-cn/semantic.md)
+- [picker-view Semantic](https://rn.mobile.ant.design/components/picker-view-cn/semantic.md)
+- [popover Semantic](https://rn.mobile.ant.design/components/popover-cn/semantic.md)
+- [progress Semantic](https://rn.mobile.ant.design/components/progress-cn/semantic.md)
+- [radio Semantic](https://rn.mobile.ant.design/components/radio-cn/semantic.md)
+- [result Semantic](https://rn.mobile.ant.design/components/result-cn/semantic.md)
+- [search-bar Semantic](https://rn.mobile.ant.design/components/search-bar-cn/semantic.md)
+- [slider Semantic](https://rn.mobile.ant.design/components/slider-cn/semantic.md)
+- [stepper Semantic](https://rn.mobile.ant.design/components/stepper-cn/semantic.md)
+- [steps Semantic](https://rn.mobile.ant.design/components/steps-cn/semantic.md)
+- [swipe-action Semantic](https://rn.mobile.ant.design/components/swipe-action-cn/semantic.md)
+- [switch Semantic](https://rn.mobile.ant.design/components/switch-cn/semantic.md)
+- [tab-bar Semantic](https://rn.mobile.ant.design/components/tab-bar-cn/semantic.md)
+- [tabs Semantic](https://rn.mobile.ant.design/components/tabs-cn/semantic.md)
+- [tag Semantic](https://rn.mobile.ant.design/components/tag-cn/semantic.md)
+- [textarea-item Semantic](https://rn.mobile.ant.design/components/textarea-item-cn/semantic.md)
+- [toast Semantic](https://rn.mobile.ant.design/components/toast-cn/semantic.md)
+- [tooltip Semantic](https://rn.mobile.ant.design/components/tooltip-cn/semantic.md)

+ 10 - 0
eslint.config.js

@@ -0,0 +1,10 @@
+// https://docs.expo.dev/guides/using-eslint/
+const { defineConfig } = require('eslint/config');
+const expoConfig = require("eslint-config-expo/flat");
+
+module.exports = defineConfig([
+  expoConfig,
+  {
+    ignores: ["dist/*"],
+  }
+]);

+ 30 - 0
ios/.gitignore

@@ -0,0 +1,30 @@
+# OSX
+#
+.DS_Store
+
+# Xcode
+#
+build/
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+*.xccheckout
+*.moved-aside
+DerivedData
+*.hmap
+*.ipa
+*.xcuserstate
+project.xcworkspace
+.xcode.env.local
+
+# Bundle artifacts
+*.jsbundle
+
+# CocoaPods
+/Pods/

+ 11 - 0
ios/.xcode.env

@@ -0,0 +1,11 @@
+# This `.xcode.env` file is versioned and is used to source the environment
+# used when running script phases inside Xcode.
+# To customize your local environment, you can create an `.xcode.env.local`
+# file that is not versioned.
+
+# NODE_BINARY variable contains the PATH to the node executable.
+#
+# Customize the NODE_BINARY variable here.
+# For example, to use nvm with brew, add the following line
+# . "$(brew --prefix nvm)/nvm.sh" --no-use
+export NODE_BINARY=$(command -v node)

+ 556 - 0
ios/LoanAssistant.xcodeproj/project.pbxproj

@@ -0,0 +1,556 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 54;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
+		3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; };
+		741809C43E0BA3056882CBE3 /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9271B0FE64F985DB4D801AF /* ExpoModulesProvider.swift */; };
+		751C7DD35EBB3056E76A6F2C /* libPods-LoanAssistant.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A3731E8B9B332CA1D60D90F /* libPods-LoanAssistant.a */; };
+		BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; };
+		D195A72EF70B809ACBBB5310 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 896C66999EAED2D809921425 /* PrivacyInfo.xcprivacy */; };
+		F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F11748412D0307B40044C1D9 /* AppDelegate.swift */; };
+		F35F090C028F438E8AF75EA2 /* expo.icon in Resources */ = {isa = PBXBuildFile; fileRef = E22F90D43ED048F7A9A7B848 /* expo.icon */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		13B07F961A680F5B00A75B9A /* LoanAssistant.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LoanAssistant.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = LoanAssistant/Images.xcassets; sourceTree = "<group>"; };
+		13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = LoanAssistant/Info.plist; sourceTree = "<group>"; };
+		2B165FFC21E25966387498A3 /* Pods-LoanAssistant.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LoanAssistant.debug.xcconfig"; path = "Target Support Files/Pods-LoanAssistant/Pods-LoanAssistant.debug.xcconfig"; sourceTree = "<group>"; };
+		54D0AF108507783DA002BD5E /* Pods-LoanAssistant.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LoanAssistant.release.xcconfig"; path = "Target Support Files/Pods-LoanAssistant/Pods-LoanAssistant.release.xcconfig"; sourceTree = "<group>"; };
+		5A3731E8B9B332CA1D60D90F /* libPods-LoanAssistant.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LoanAssistant.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		896C66999EAED2D809921425 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; name = PrivacyInfo.xcprivacy; path = LoanAssistant/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
+		AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = LoanAssistant/SplashScreen.storyboard; sourceTree = "<group>"; };
+		BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = "<group>"; };
+		D9271B0FE64F985DB4D801AF /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-LoanAssistant/ExpoModulesProvider.swift"; sourceTree = "<group>"; };
+		E22F90D43ED048F7A9A7B848 /* expo.icon */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = expo.icon; path = LoanAssistant/expo.icon; sourceTree = "<group>"; };
+		ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
+		F11748412D0307B40044C1D9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = LoanAssistant/AppDelegate.swift; sourceTree = "<group>"; };
+		F11748442D0722820044C1D9 /* LoanAssistant-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "LoanAssistant-Bridging-Header.h"; path = "LoanAssistant/LoanAssistant-Bridging-Header.h"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				751C7DD35EBB3056E76A6F2C /* libPods-LoanAssistant.a in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		13B07FAE1A68108700A75B9A /* LoanAssistant */ = {
+			isa = PBXGroup;
+			children = (
+				F11748412D0307B40044C1D9 /* AppDelegate.swift */,
+				F11748442D0722820044C1D9 /* LoanAssistant-Bridging-Header.h */,
+				BB2F792B24A3F905000567C9 /* Supporting */,
+				13B07FB51A68108700A75B9A /* Images.xcassets */,
+				13B07FB61A68108700A75B9A /* Info.plist */,
+				AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */,
+				E22F90D43ED048F7A9A7B848 /* expo.icon */,
+				896C66999EAED2D809921425 /* PrivacyInfo.xcprivacy */,
+			);
+			name = LoanAssistant;
+			sourceTree = "<group>";
+		};
+		2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
+				5A3731E8B9B332CA1D60D90F /* libPods-LoanAssistant.a */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		41E29765C668880EF789D3C4 /* Pods */ = {
+			isa = PBXGroup;
+			children = (
+				2B165FFC21E25966387498A3 /* Pods-LoanAssistant.debug.xcconfig */,
+				54D0AF108507783DA002BD5E /* Pods-LoanAssistant.release.xcconfig */,
+			);
+			name = Pods;
+			path = Pods;
+			sourceTree = "<group>";
+		};
+		832341AE1AAA6A7D00B99B32 /* Libraries */ = {
+			isa = PBXGroup;
+			children = (
+			);
+			name = Libraries;
+			sourceTree = "<group>";
+		};
+		83CBB9F61A601CBA00E9B192 = {
+			isa = PBXGroup;
+			children = (
+				13B07FAE1A68108700A75B9A /* LoanAssistant */,
+				832341AE1AAA6A7D00B99B32 /* Libraries */,
+				83CBBA001A601CBA00E9B192 /* Products */,
+				2D16E6871FA4F8E400B85C8A /* Frameworks */,
+				41E29765C668880EF789D3C4 /* Pods */,
+				8E45A47C3D48AB03F0051663 /* ExpoModulesProviders */,
+			);
+			indentWidth = 2;
+			sourceTree = "<group>";
+			tabWidth = 2;
+			usesTabs = 0;
+		};
+		83CBBA001A601CBA00E9B192 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				13B07F961A680F5B00A75B9A /* LoanAssistant.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		8E45A47C3D48AB03F0051663 /* ExpoModulesProviders */ = {
+			isa = PBXGroup;
+			children = (
+				CE82B57DA73DE49400C00D39 /* LoanAssistant */,
+			);
+			name = ExpoModulesProviders;
+			sourceTree = "<group>";
+		};
+		BB2F792B24A3F905000567C9 /* Supporting */ = {
+			isa = PBXGroup;
+			children = (
+				BB2F792C24A3F905000567C9 /* Expo.plist */,
+			);
+			name = Supporting;
+			path = LoanAssistant/Supporting;
+			sourceTree = "<group>";
+		};
+		CE82B57DA73DE49400C00D39 /* LoanAssistant */ = {
+			isa = PBXGroup;
+			children = (
+				D9271B0FE64F985DB4D801AF /* ExpoModulesProvider.swift */,
+			);
+			name = LoanAssistant;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		13B07F861A680F5B00A75B9A /* LoanAssistant */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "LoanAssistant" */;
+			buildPhases = (
+				08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */,
+				0392B0FA9EB316068D4A30C1 /* [Expo] Configure project */,
+				13B07F871A680F5B00A75B9A /* Sources */,
+				13B07F8C1A680F5B00A75B9A /* Frameworks */,
+				13B07F8E1A680F5B00A75B9A /* Resources */,
+				00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
+				800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */,
+				2DB1CDB37E29DC7A8F1EDD35 /* [CP] Embed Pods Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = LoanAssistant;
+			productName = LoanAssistant;
+			productReference = 13B07F961A680F5B00A75B9A /* LoanAssistant.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		83CBB9F71A601CBA00E9B192 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 1130;
+				TargetAttributes = {
+					13B07F861A680F5B00A75B9A = {
+						LastSwiftMigration = 1250;
+					};
+				};
+			};
+			buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "LoanAssistant" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = en;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+				Base,
+			);
+			mainGroup = 83CBB9F61A601CBA00E9B192;
+			productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				13B07F861A680F5B00A75B9A /* LoanAssistant */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		13B07F8E1A680F5B00A75B9A /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				BB2F792D24A3F905000567C9 /* Expo.plist in Resources */,
+				13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
+				3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */,
+				F35F090C028F438E8AF75EA2 /* expo.icon in Resources */,
+				D195A72EF70B809ACBBB5310 /* PrivacyInfo.xcprivacy in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
+			isa = PBXShellScriptBuildPhase;
+			alwaysOutOfDate = 1;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"$(SRCROOT)/.xcode.env",
+				"$(SRCROOT)/.xcode.env.local",
+			);
+			name = "Bundle React Native code and images";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "if [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n  source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n  source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n  export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n  # Set the entry JS file using the bundler's entry resolution.\n  export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n  # Use Expo CLI\n  export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n  # Default Expo CLI command for bundling\n  export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n# Source .xcode.env.updates if it exists to allow\n# SKIP_BUNDLING to be unset if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.updates\" ]]; then\n  source \"$PODS_ROOT/../.xcode.env.updates\"\nfi\n# Source local changes to allow overrides\n# if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n  source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"`\n\n";
+		};
+		0392B0FA9EB316068D4A30C1 /* [Expo] Configure project */ = {
+			isa = PBXShellScriptBuildPhase;
+			alwaysOutOfDate = 1;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+				"$(SRCROOT)/.xcode.env",
+				"$(SRCROOT)/.xcode.env.local",
+				"$(SRCROOT)/LoanAssistant/LoanAssistant.entitlements",
+				"$(SRCROOT)/Pods/Target Support Files/Pods-LoanAssistant/expo-configure-project.sh",
+			);
+			name = "[Expo] Configure project";
+			outputFileListPaths = (
+			);
+			outputPaths = (
+				"$(SRCROOT)/Pods/Target Support Files/Pods-LoanAssistant/ExpoModulesProvider.swift",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-LoanAssistant/expo-configure-project.sh\"\n";
+		};
+		08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputFileListPaths = (
+			);
+			inputPaths = (
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
+			);
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/Pods-LoanAssistant-checkManifestLockResult.txt",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+			showEnvVarsInLog = 0;
+		};
+		2DB1CDB37E29DC7A8F1EDD35 /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-LoanAssistant/Pods-LoanAssistant-frameworks.sh",
+				"${PODS_XCFRAMEWORKS_BUILD_DIR}/React-Core-prebuilt/React.framework/React",
+				"${PODS_XCFRAMEWORKS_BUILD_DIR}/ReactNativeDependencies/ReactNativeDependencies.framework/ReactNativeDependencies",
+				"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermesvm.framework/hermesvm",
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputPaths = (
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/React.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactNativeDependencies.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermesvm.framework",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-LoanAssistant/Pods-LoanAssistant-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+		800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-LoanAssistant/Pods-LoanAssistant-resources.sh",
+				"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
+				"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/ExpoConstants_privacy.bundle",
+				"${PODS_CONFIGURATION_BUILD_DIR}/ExpoDevice/ExpoDevice_privacy.bundle",
+				"${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle",
+				"${PODS_CONFIGURATION_BUILD_DIR}/ExpoSystemUI/ExpoSystemUI_privacy.bundle",
+				"${PODS_CONFIGURATION_BUILD_DIR}/RNFSTurbo/RNFSTurbo_PrivacyInfo.bundle",
+				"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
+				"${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle",
+				"${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.bundle",
+			);
+			name = "[CP] Copy Pods Resources";
+			outputPaths = (
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle",
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoConstants_privacy.bundle",
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoDevice_privacy.bundle",
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle",
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoSystemUI_privacy.bundle",
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNFSTurbo_PrivacyInfo.bundle",
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.bundle",
+				"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SDWebImage.bundle",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-LoanAssistant/Pods-LoanAssistant-resources.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		13B07F871A680F5B00A75B9A /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F11748422D0307B40044C1D9 /* AppDelegate.swift in Sources */,
+				741809C43E0BA3056882CBE3 /* ExpoModulesProvider.swift in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		13B07F941A680F5B00A75B9A /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 2B165FFC21E25966387498A3 /* Pods-LoanAssistant.debug.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = expo;
+				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = LoanAssistant/LoanAssistant.entitlements;
+				CURRENT_PROJECT_VERSION = 1;
+				ENABLE_BITCODE = NO;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"$(inherited)",
+					"FB_SONARKIT_ENABLED=1",
+				);
+				INFOPLIST_FILE = LoanAssistant/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 15.1;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				MARKETING_VERSION = 1.0;
+				OTHER_LDFLAGS = (
+					"$(inherited)",
+					"-ObjC",
+					"-lc++",
+				);
+				OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
+				PRODUCT_BUNDLE_IDENTIFIER = com.cdloan.assistant;
+				PRODUCT_NAME = LoanAssistant;
+				SWIFT_OBJC_BRIDGING_HEADER = "LoanAssistant/LoanAssistant-Bridging-Header.h";
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+				SWIFT_VERSION = 5.0;
+				TARGETED_DEVICE_FAMILY = 1;
+				VERSIONING_SYSTEM = "apple-generic";
+			};
+			name = Debug;
+		};
+		13B07F951A680F5B00A75B9A /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 54D0AF108507783DA002BD5E /* Pods-LoanAssistant.release.xcconfig */;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = expo;
+				CLANG_ENABLE_MODULES = YES;
+				CODE_SIGN_ENTITLEMENTS = LoanAssistant/LoanAssistant.entitlements;
+				CURRENT_PROJECT_VERSION = 1;
+				INFOPLIST_FILE = LoanAssistant/Info.plist;
+				IPHONEOS_DEPLOYMENT_TARGET = 15.1;
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				MARKETING_VERSION = 1.0;
+				OTHER_LDFLAGS = (
+					"$(inherited)",
+					"-ObjC",
+					"-lc++",
+				);
+				OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
+				PRODUCT_BUNDLE_IDENTIFIER = com.cdloan.assistant;
+				PRODUCT_NAME = LoanAssistant;
+				SWIFT_OBJC_BRIDGING_HEADER = "LoanAssistant/LoanAssistant-Bridging-Header.h";
+				SWIFT_VERSION = 5.0;
+				TARGETED_DEVICE_FAMILY = 1;
+				VERSIONING_SYSTEM = "apple-generic";
+			};
+			name = Release;
+		};
+		83CBBA201A601CBA00E9B192 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "c++20";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 15.1;
+				LD_RUNPATH_SEARCH_PATHS = (
+					/usr/lib/swift,
+					"$(inherited)",
+				);
+				LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift\"$(inherited)\"";
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				OTHER_CFLAGS = "$(inherited)";
+				OTHER_CPLUSPLUSFLAGS = "$(inherited)";
+				REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
+				SDKROOT = iphoneos;
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
+				SWIFT_ENABLE_EXPLICIT_MODULES = NO;
+				USE_HERMES = true;
+			};
+			name = Debug;
+		};
+		83CBBA211A601CBA00E9B192 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "c++20";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				COPY_PHASE_STRIP = YES;
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 15.1;
+				LD_RUNPATH_SEARCH_PATHS = (
+					/usr/lib/swift,
+					"$(inherited)",
+				);
+				LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift\"$(inherited)\"";
+				MTL_ENABLE_DEBUG_INFO = NO;
+				OTHER_CFLAGS = "$(inherited)";
+				OTHER_CPLUSPLUSFLAGS = "$(inherited)";
+				REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
+				SDKROOT = iphoneos;
+				SWIFT_ENABLE_EXPLICIT_MODULES = NO;
+				USE_HERMES = true;
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "LoanAssistant" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				13B07F941A680F5B00A75B9A /* Debug */,
+				13B07F951A680F5B00A75B9A /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "LoanAssistant" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				83CBBA201A601CBA00E9B192 /* Debug */,
+				83CBBA211A601CBA00E9B192 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
+}

+ 88 - 0
ios/LoanAssistant.xcodeproj/xcshareddata/xcschemes/LoanAssistant.xcscheme

@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1130"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
+               BuildableName = "LoanAssistant.app"
+               BlueprintName = "LoanAssistant"
+               ReferencedContainer = "container:LoanAssistant.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+         <TestableReference
+            skipped = "NO">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "00E356ED1AD99517003FC87E"
+               BuildableName = "LoanAssistantTests.xctest"
+               BlueprintName = "LoanAssistantTests"
+               ReferencedContainer = "container:LoanAssistant.xcodeproj">
+            </BuildableReference>
+         </TestableReference>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
+            BuildableName = "LoanAssistant.app"
+            BlueprintName = "LoanAssistant"
+            ReferencedContainer = "container:LoanAssistant.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
+            BuildableName = "LoanAssistant.app"
+            BlueprintName = "LoanAssistant"
+            ReferencedContainer = "container:LoanAssistant.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 10 - 0
ios/LoanAssistant.xcworkspace/contents.xcworkspacedata

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "group:LoanAssistant.xcodeproj">
+   </FileRef>
+   <FileRef
+      location = "group:Pods/Pods.xcodeproj">
+   </FileRef>
+</Workspace>

+ 69 - 0
ios/LoanAssistant/AppDelegate.swift

@@ -0,0 +1,69 @@
+internal import Expo
+import React
+import ReactAppDependencyProvider
+
+@main
+class AppDelegate: ExpoAppDelegate {
+  var window: UIWindow?
+
+  var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
+  var reactNativeFactory: RCTReactNativeFactory?
+
+  public override func application(
+    _ application: UIApplication,
+    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
+  ) -> Bool {
+    let delegate = ReactNativeDelegate()
+    let factory = ExpoReactNativeFactory(delegate: delegate)
+    delegate.dependencyProvider = RCTAppDependencyProvider()
+
+    reactNativeDelegate = delegate
+    reactNativeFactory = factory
+
+#if os(iOS) || os(tvOS)
+    window = UIWindow(frame: UIScreen.main.bounds)
+    factory.startReactNative(
+      withModuleName: "main",
+      in: window,
+      launchOptions: launchOptions)
+#endif
+
+    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+  }
+
+  // Linking API
+  public override func application(
+    _ app: UIApplication,
+    open url: URL,
+    options: [UIApplication.OpenURLOptionsKey: Any] = [:]
+  ) -> Bool {
+    return super.application(app, open: url, options: options) || RCTLinkingManager.application(app, open: url, options: options)
+  }
+
+  // Universal Links
+  public override func application(
+    _ application: UIApplication,
+    continue userActivity: NSUserActivity,
+    restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
+  ) -> Bool {
+    let result = RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
+    return super.application(application, continue: userActivity, restorationHandler: restorationHandler) || result
+  }
+}
+
+class ReactNativeDelegate: ExpoReactNativeFactoryDelegate {
+  // Extension point for config-plugins
+
+  override func sourceURL(for bridge: RCTBridge) -> URL? {
+    // needed to return the correct URL for expo-dev-client.
+    bridge.bundleURL ?? bundleURL()
+  }
+
+  override func bundleURL() -> URL? {
+#if DEBUG
+    return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")
+#else
+    return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
+#endif
+  }
+}

+ 13 - 0
ios/LoanAssistant/Images.xcassets/AppIcon.appiconset/Contents.json

@@ -0,0 +1,13 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "platform" : "ios",
+      "size" : "1024x1024"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "expo"
+  }
+}

+ 6 - 0
ios/LoanAssistant/Images.xcassets/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "version" : 1,
+    "author" : "expo"
+  }
+}

+ 20 - 0
ios/LoanAssistant/Images.xcassets/SplashScreenBackground.colorset/Contents.json

@@ -0,0 +1,20 @@
+{
+  "colors": [
+    {
+      "color": {
+        "components": {
+          "alpha": "1.000",
+          "blue": "0.937254901960784",
+          "green": "0.541176470588235",
+          "red": "0.125490196078431"
+        },
+        "color-space": "srgb"
+      },
+      "idiom": "universal"
+    }
+  ],
+  "info": {
+    "version": 1,
+    "author": "expo"
+  }
+}

+ 78 - 0
ios/LoanAssistant/Info.plist

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CADisableMinimumFrameDurationOnPhone</key>
+	<true/>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
+	<key>CFBundleDisplayName</key>
+	<string>借贷助手</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleURLTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>loanassistant</string>
+				<string>com.cdloan.assistant</string>
+			</array>
+		</dict>
+	</array>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>12.0</string>
+	<key>LSRequiresIPhoneOS</key>
+	<true/>
+	<key>NSAppTransportSecurity</key>
+	<dict>
+		<key>NSAllowsArbitraryLoads</key>
+		<false/>
+		<key>NSAllowsLocalNetworking</key>
+		<true/>
+	</dict>
+	<key>NSCameraUsageDescription</key>
+	<string>需要访问相机权限以扫描二维码</string>
+	<key>NSPhotoLibraryUsageDescription</key>
+	<string>需要访问照片权限以选择图片</string>
+	<key>NSUserActivityTypes</key>
+	<array>
+		<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
+	</array>
+	<key>RCTNewArchEnabled</key>
+	<true/>
+	<key>UILaunchStoryboardName</key>
+	<string>SplashScreen</string>
+	<key>UIRequiredDeviceCapabilities</key>
+	<array>
+		<string>arm64</string>
+	</array>
+	<key>UIRequiresFullScreen</key>
+	<false/>
+	<key>UIStatusBarStyle</key>
+	<string>UIStatusBarStyleDefault</string>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationPortrait</string>
+		<string>UIInterfaceOrientationPortraitUpsideDown</string>
+	</array>
+	<key>UIUserInterfaceStyle</key>
+	<string>Light</string>
+	<key>UIViewControllerBasedStatusBarAppearance</key>
+	<false/>
+</dict>
+</plist>

+ 3 - 0
ios/LoanAssistant/LoanAssistant-Bridging-Header.h

@@ -0,0 +1,3 @@
+//
+// Use this file to import your target's public headers that you would like to expose to Swift.
+//

+ 5 - 0
ios/LoanAssistant/LoanAssistant.entitlements

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict/>
+</plist>

+ 48 - 0
ios/LoanAssistant/PrivacyInfo.xcprivacy

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>NSPrivacyAccessedAPITypes</key>
+	<array>
+		<dict>
+			<key>NSPrivacyAccessedAPIType</key>
+			<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
+			<key>NSPrivacyAccessedAPITypeReasons</key>
+			<array>
+				<string>CA92.1</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSPrivacyAccessedAPIType</key>
+			<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
+			<key>NSPrivacyAccessedAPITypeReasons</key>
+			<array>
+				<string>35F9.1</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSPrivacyAccessedAPIType</key>
+			<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
+			<key>NSPrivacyAccessedAPITypeReasons</key>
+			<array>
+				<string>0A2A.1</string>
+				<string>3B52.1</string>
+				<string>C617.1</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSPrivacyAccessedAPIType</key>
+			<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
+			<key>NSPrivacyAccessedAPITypeReasons</key>
+			<array>
+				<string>E174.1</string>
+				<string>85F4.1</string>
+			</array>
+		</dict>
+	</array>
+	<key>NSPrivacyCollectedDataTypes</key>
+	<array/>
+	<key>NSPrivacyTracking</key>
+	<false/>
+</dict>
+</plist>

+ 39 - 0
ios/LoanAssistant/SplashScreen.storyboard

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24093.7" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="EXPO-VIEWCONTROLLER-1">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24053.1"/>
+        <capability name="Named colors" minToolsVersion="9.0"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <scenes>
+        <scene sceneID="EXPO-SCENE-1">
+            <objects>
+                <viewController storyboardIdentifier="SplashScreenViewController" id="EXPO-VIEWCONTROLLER-1" sceneMemberID="viewController">
+                    <view key="view" userInteractionEnabled="NO" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="EXPO-ContainerView" userLabel="ContainerView">
+                        <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                        <subviews/>
+                        <viewLayoutGuide key="safeArea" id="Rmq-lb-GrQ"/>
+                        <constraints>
+                            <constraint firstItem="EXPO-SplashScreen" firstAttribute="centerY" secondItem="EXPO-ContainerView" secondAttribute="centerY" id="0VC-Wk-OaO"/>
+                            <constraint firstItem="EXPO-SplashScreen" firstAttribute="centerX" secondItem="EXPO-ContainerView" secondAttribute="centerX" id="zR4-NK-mVN"/>
+                        </constraints>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="EXPO-PLACEHOLDER-1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="0.0" y="0.0"/>
+        </scene>
+    </scenes>
+    <resources>
+        <image name="SplashScreenLogo" width="100" height="90.333335876464844"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 16 - 0
ios/LoanAssistant/Supporting/Expo.plist

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict>
+    <key>EXUpdatesCheckOnLaunch</key>
+    <string>ALWAYS</string>
+    <key>EXUpdatesEnabled</key>
+    <true/>
+    <key>EXUpdatesLaunchWaitMs</key>
+    <integer>30000</integer>
+    <key>EXUpdatesRuntimeVersion</key>
+    <string>1.0.0</string>
+    <key>EXUpdatesURL</key>
+    <string>https://loan.ewaga.com/airpatch/manifest</string>
+  </dict>
+</plist>

+ 3 - 0
ios/LoanAssistant/expo.icon/Assets/expo-symbol 2.svg

@@ -0,0 +1,3 @@
+<svg width="652" height="606" viewBox="0 0 652 606" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M353.554 0H298.446C273.006 0 249.684 14.6347 237.962 37.9539L4.37994 502.646C-1.04325 513.435 -1.45067 526.178 3.2716 537.313L22.6123 582.918C34.6475 611.297 72.5404 614.156 88.4414 587.885L309.863 222.063C313.34 216.317 319.439 212.826 326 212.826C332.561 212.826 338.659 216.317 342.137 222.063L563.559 587.885C579.46 614.156 617.352 611.297 629.388 582.918L648.728 537.313C653.451 526.178 653.043 513.435 647.62 502.646L414.038 37.9539C402.316 14.6347 378.994 0 353.554 0Z" fill="white"/>
+</svg>

binární
ios/LoanAssistant/expo.icon/Assets/grid.png


+ 40 - 0
ios/LoanAssistant/expo.icon/icon.json

@@ -0,0 +1,40 @@
+{
+  "fill" : {
+    "automatic-gradient" : "extended-srgb:0.00000,0.47843,1.00000,1.00000"
+  },
+  "groups" : [
+    {
+      "layers" : [
+        {
+          "image-name" : "expo-symbol 2.svg",
+          "name" : "expo-symbol 2",
+          "position" : {
+            "scale" : 1,
+            "translation-in-points" : [
+              1.1008400065293245e-05,
+              -16.046875
+            ]
+          }
+        },
+        {
+          "image-name" : "grid.png",
+          "name" : "grid"
+        }
+      ],
+      "shadow" : {
+        "kind" : "neutral",
+        "opacity" : 0.5
+      },
+      "translucency" : {
+        "enabled" : true,
+        "value" : 0.5
+      }
+    }
+  ],
+  "supported-platforms" : {
+    "circles" : [
+      "watchOS"
+    ],
+    "squares" : "shared"
+  }
+}

+ 65 - 0
ios/Podfile

@@ -0,0 +1,65 @@
+# Set by expo-router. This enables Fabric-only features from react-native-screens
+ENV['RNS_GAMMA_ENABLED'] ||= '1'
+require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
+require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
+
+require 'json'
+podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
+
+def ccache_enabled?(podfile_properties)
+  # Environment variable takes precedence
+  return ENV['USE_CCACHE'] == '1' if ENV['USE_CCACHE']
+
+  # Fall back to Podfile properties
+  podfile_properties['apple.ccacheEnabled'] == 'true'
+end
+
+ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] ||= podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR']
+ENV['RCT_USE_RN_DEP'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true'
+ENV['RCT_USE_PREBUILT_RNCORE'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true'
+ENV['RCT_HERMES_V1_ENABLED'] ||= '1' if podfile_properties['expo.useHermesV1'] == 'true'
+platform :ios, podfile_properties['ios.deploymentTarget'] || '15.1'
+
+prepare_react_native_project!
+
+target 'LoanAssistant' do
+  use_expo_modules!
+
+  if ENV['EXPO_USE_COMMUNITY_AUTOLINKING'] == '1'
+    config_command = ['node', '-e', "process.argv=['', '', 'config'];require('@react-native-community/cli').run()"];
+  else
+    config_command = [
+      'node',
+      '--no-warnings',
+      '--eval',
+      'require(\'expo/bin/autolinking\')',
+      'expo-modules-autolinking',
+      'react-native-config',
+      '--json',
+      '--platform',
+      'ios'
+    ]
+  end
+
+  config = use_native_modules!(config_command)
+
+  use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
+  use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS']
+
+  use_react_native!(
+    :path => config[:reactNativePath],
+    :hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes',
+    # An absolute path to your application root.
+    :app_path => "#{Pod::Config.instance.installation_root}/..",
+    :privacy_file_aggregation_enabled => podfile_properties['apple.privacyManifestAggregationEnabled'] != 'false',
+  )
+
+  post_install do |installer|
+    react_native_post_install(
+      installer,
+      config[:reactNativePath],
+      :mac_catalyst_enabled => false,
+      :ccache_enabled => ccache_enabled?(podfile_properties),
+    )
+  end
+end

+ 2689 - 0
ios/Podfile.lock

@@ -0,0 +1,2689 @@
+PODS:
+  - EXConstants (55.0.12):
+    - ExpoModulesCore
+  - Expo (55.0.12):
+    - ExpoModulesCore
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTAppDelegate
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactAppDependencyProvider
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - ExpoAsset (55.0.13):
+    - ExpoModulesCore
+  - ExpoDevice (55.0.13):
+    - ExpoModulesCore
+  - ExpoDomWebView (55.0.5):
+    - ExpoModulesCore
+  - ExpoFileSystem (55.0.15):
+    - ExpoModulesCore
+  - ExpoFont (55.0.6):
+    - ExpoModulesCore
+  - ExpoGlassEffect (55.0.10):
+    - ExpoModulesCore
+  - ExpoImage (55.0.8):
+    - ExpoModulesCore
+    - libavif/libdav1d
+    - SDWebImage (~> 5.21.0)
+    - SDWebImageAVIFCoder (~> 0.11.0)
+    - SDWebImageSVGCoder (~> 1.7.0)
+    - SDWebImageWebPCoder (~> 0.14.6)
+  - ExpoKeepAwake (55.0.6):
+    - ExpoModulesCore
+  - ExpoLinking (55.0.11):
+    - ExpoModulesCore
+  - ExpoLogBox (55.0.10):
+    - React-Core
+  - ExpoModulesCore (55.0.21):
+    - ExpoModulesJSI
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-jsi
+    - React-jsinspector
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - RNWorklets
+    - Yoga
+  - ExpoModulesJSI (55.0.21):
+    - hermes-engine
+    - React-Core
+    - React-runtimescheduler
+    - ReactCommon
+  - ExpoRouter (55.0.11):
+    - ExpoModulesCore
+    - RNScreens
+  - ExpoSplashScreen (55.0.16):
+    - ExpoModulesCore
+  - ExpoSymbols (55.0.7):
+    - ExpoModulesCore
+  - ExpoSystemUI (55.0.14):
+    - ExpoModulesCore
+  - ExpoWebBrowser (55.0.13):
+    - ExpoModulesCore
+  - FBLazyVector (0.83.4)
+  - hermes-engine (0.14.1):
+    - hermes-engine/Pre-built (= 0.14.1)
+  - hermes-engine/Pre-built (0.14.1)
+  - libavif/core (0.11.1)
+  - libavif/libdav1d (0.11.1):
+    - libavif/core
+    - libdav1d (>= 0.6.0)
+  - libdav1d (1.2.0)
+  - libwebp (1.5.0):
+    - libwebp/demux (= 1.5.0)
+    - libwebp/mux (= 1.5.0)
+    - libwebp/sharpyuv (= 1.5.0)
+    - libwebp/webp (= 1.5.0)
+  - libwebp/demux (1.5.0):
+    - libwebp/webp
+  - libwebp/mux (1.5.0):
+    - libwebp/demux
+  - libwebp/sharpyuv (1.5.0)
+  - libwebp/webp (1.5.0):
+    - libwebp/sharpyuv
+  - MMKVCore (2.4.0)
+  - NitroMmkv (4.3.1):
+    - hermes-engine
+    - MMKVCore (= 2.4.0)
+    - NitroModules
+    - RCTRequired
+    - RCTTypeSafety
+    - React-callinvoker
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - NitroModules (0.35.3):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-callinvoker
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - RCTDeprecation (0.83.4)
+  - RCTRequired (0.83.4)
+  - RCTSwiftUI (0.83.4)
+  - RCTSwiftUIWrapper (0.83.4):
+    - RCTSwiftUI
+  - RCTTypeSafety (0.83.4):
+    - FBLazyVector (= 0.83.4)
+    - RCTRequired (= 0.83.4)
+    - React-Core (= 0.83.4)
+  - React (0.83.4):
+    - React-Core (= 0.83.4)
+    - React-Core/DevSupport (= 0.83.4)
+    - React-Core/RCTWebSocket (= 0.83.4)
+    - React-RCTActionSheet (= 0.83.4)
+    - React-RCTAnimation (= 0.83.4)
+    - React-RCTBlob (= 0.83.4)
+    - React-RCTImage (= 0.83.4)
+    - React-RCTLinking (= 0.83.4)
+    - React-RCTNetwork (= 0.83.4)
+    - React-RCTSettings (= 0.83.4)
+    - React-RCTText (= 0.83.4)
+    - React-RCTVibration (= 0.83.4)
+  - React-callinvoker (0.83.4)
+  - React-Core (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-Core/Default (= 0.83.4)
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-Core-prebuilt (0.83.4):
+    - ReactNativeDependencies
+  - React-Core/CoreModulesHeaders (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-Core/Default
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-Core/Default (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-Core/DevSupport (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-Core/Default (= 0.83.4)
+    - React-Core/RCTWebSocket (= 0.83.4)
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-Core/RCTActionSheetHeaders (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-Core/Default
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-Core/RCTAnimationHeaders (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-Core/Default
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-Core/RCTBlobHeaders (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-Core/Default
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-Core/RCTImageHeaders (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-Core/Default
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-Core/RCTLinkingHeaders (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-Core/Default
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-Core/RCTNetworkHeaders (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-Core/Default
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-Core/RCTSettingsHeaders (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-Core/Default
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-Core/RCTTextHeaders (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-Core/Default
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-Core/RCTVibrationHeaders (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-Core/Default
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-Core/RCTWebSocket (0.83.4):
+    - hermes-engine
+    - RCTDeprecation
+    - React-Core-prebuilt
+    - React-Core/Default (= 0.83.4)
+    - React-cxxreact
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsitooling
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-CoreModules (0.83.4):
+    - RCTTypeSafety (= 0.83.4)
+    - React-Core-prebuilt
+    - React-Core/CoreModulesHeaders (= 0.83.4)
+    - React-debug
+    - React-jsi (= 0.83.4)
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsinspectortracing
+    - React-NativeModulesApple
+    - React-RCTBlob
+    - React-RCTFBReactNativeSpec
+    - React-RCTImage (= 0.83.4)
+    - React-runtimeexecutor
+    - React-utils
+    - ReactCommon
+    - ReactNativeDependencies
+  - React-cxxreact (0.83.4):
+    - hermes-engine
+    - React-callinvoker (= 0.83.4)
+    - React-Core-prebuilt
+    - React-debug (= 0.83.4)
+    - React-jsi (= 0.83.4)
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsinspectortracing
+    - React-logger (= 0.83.4)
+    - React-perflogger (= 0.83.4)
+    - React-runtimeexecutor
+    - React-timing (= 0.83.4)
+    - React-utils
+    - ReactNativeDependencies
+  - React-debug (0.83.4)
+  - React-defaultsnativemodule (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-domnativemodule
+    - React-featureflags
+    - React-featureflagsnativemodule
+    - React-idlecallbacksnativemodule
+    - React-intersectionobservernativemodule
+    - React-jsi
+    - React-jsiexecutor
+    - React-microtasksnativemodule
+    - React-RCTFBReactNativeSpec
+    - React-webperformancenativemodule
+    - ReactNativeDependencies
+    - Yoga
+  - React-domnativemodule (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-Fabric
+    - React-Fabric/bridging
+    - React-FabricComponents
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-RCTFBReactNativeSpec
+    - React-runtimeexecutor
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-Fabric (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric/animated (= 0.83.4)
+    - React-Fabric/animationbackend (= 0.83.4)
+    - React-Fabric/animations (= 0.83.4)
+    - React-Fabric/attributedstring (= 0.83.4)
+    - React-Fabric/bridging (= 0.83.4)
+    - React-Fabric/componentregistry (= 0.83.4)
+    - React-Fabric/componentregistrynative (= 0.83.4)
+    - React-Fabric/components (= 0.83.4)
+    - React-Fabric/consistency (= 0.83.4)
+    - React-Fabric/core (= 0.83.4)
+    - React-Fabric/dom (= 0.83.4)
+    - React-Fabric/imagemanager (= 0.83.4)
+    - React-Fabric/leakchecker (= 0.83.4)
+    - React-Fabric/mounting (= 0.83.4)
+    - React-Fabric/observers (= 0.83.4)
+    - React-Fabric/scheduler (= 0.83.4)
+    - React-Fabric/telemetry (= 0.83.4)
+    - React-Fabric/templateprocessor (= 0.83.4)
+    - React-Fabric/uimanager (= 0.83.4)
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/animated (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/animationbackend (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/animations (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/attributedstring (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/bridging (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/componentregistry (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/componentregistrynative (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/components (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric/components/legacyviewmanagerinterop (= 0.83.4)
+    - React-Fabric/components/root (= 0.83.4)
+    - React-Fabric/components/scrollview (= 0.83.4)
+    - React-Fabric/components/view (= 0.83.4)
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/components/legacyviewmanagerinterop (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/components/root (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/components/scrollview (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/components/view (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-renderercss
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-Fabric/consistency (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/core (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/dom (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/imagemanager (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/leakchecker (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/mounting (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/observers (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric/observers/events (= 0.83.4)
+    - React-Fabric/observers/intersection (= 0.83.4)
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/observers/events (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/observers/intersection (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/scheduler (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric/observers/events
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-performancecdpmetrics
+    - React-performancetimeline
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/telemetry (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/templateprocessor (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/uimanager (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric/uimanager/consistency (= 0.83.4)
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererconsistency
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-Fabric/uimanager/consistency (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-rendererconsistency
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-FabricComponents (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-FabricComponents/components (= 0.83.4)
+    - React-FabricComponents/textlayoutmanager (= 0.83.4)
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/components (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-FabricComponents/components/inputaccessory (= 0.83.4)
+    - React-FabricComponents/components/iostextinput (= 0.83.4)
+    - React-FabricComponents/components/modal (= 0.83.4)
+    - React-FabricComponents/components/rncore (= 0.83.4)
+    - React-FabricComponents/components/safeareaview (= 0.83.4)
+    - React-FabricComponents/components/scrollview (= 0.83.4)
+    - React-FabricComponents/components/switch (= 0.83.4)
+    - React-FabricComponents/components/text (= 0.83.4)
+    - React-FabricComponents/components/textinput (= 0.83.4)
+    - React-FabricComponents/components/unimplementedview (= 0.83.4)
+    - React-FabricComponents/components/virtualview (= 0.83.4)
+    - React-FabricComponents/components/virtualviewexperimental (= 0.83.4)
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/components/inputaccessory (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/components/iostextinput (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/components/modal (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/components/rncore (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/components/safeareaview (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/components/scrollview (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/components/switch (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/components/text (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/components/textinput (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/components/unimplementedview (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/components/virtualview (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/components/virtualviewexperimental (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricComponents/textlayoutmanager (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-logger
+    - React-RCTFBReactNativeSpec
+    - React-rendererdebug
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-FabricImage (0.83.4):
+    - hermes-engine
+    - RCTRequired (= 0.83.4)
+    - RCTTypeSafety (= 0.83.4)
+    - React-Core-prebuilt
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-jsi
+    - React-jsiexecutor (= 0.83.4)
+    - React-logger
+    - React-rendererdebug
+    - React-utils
+    - ReactCommon
+    - ReactNativeDependencies
+    - Yoga
+  - React-featureflags (0.83.4):
+    - React-Core-prebuilt
+    - ReactNativeDependencies
+  - React-featureflagsnativemodule (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-featureflags
+    - React-jsi
+    - React-jsiexecutor
+    - React-RCTFBReactNativeSpec
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-graphics (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-jsi
+    - React-jsiexecutor
+    - React-utils
+    - ReactNativeDependencies
+  - React-hermes (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-cxxreact (= 0.83.4)
+    - React-jsi
+    - React-jsiexecutor (= 0.83.4)
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsinspectortracing
+    - React-oscompat
+    - React-perflogger (= 0.83.4)
+    - React-runtimeexecutor
+    - ReactNativeDependencies
+  - React-idlecallbacksnativemodule (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-jsi
+    - React-jsiexecutor
+    - React-RCTFBReactNativeSpec
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-ImageManager (0.83.4):
+    - React-Core-prebuilt
+    - React-Core/Default
+    - React-debug
+    - React-Fabric
+    - React-graphics
+    - React-rendererdebug
+    - React-utils
+    - ReactNativeDependencies
+  - React-intersectionobservernativemodule (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-Fabric
+    - React-Fabric/bridging
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-RCTFBReactNativeSpec
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-jserrorhandler (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-jsi
+    - ReactCommon/turbomodule/bridging
+    - ReactNativeDependencies
+  - React-jsi (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - ReactNativeDependencies
+  - React-jsiexecutor (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-jsi
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsinspectortracing
+    - React-perflogger
+    - React-runtimeexecutor
+    - React-utils
+    - ReactNativeDependencies
+  - React-jsinspector (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-featureflags
+    - React-jsi
+    - React-jsinspectorcdp
+    - React-jsinspectornetwork
+    - React-jsinspectortracing
+    - React-oscompat
+    - React-perflogger (= 0.83.4)
+    - React-runtimeexecutor
+    - React-utils
+    - ReactNativeDependencies
+  - React-jsinspectorcdp (0.83.4):
+    - React-Core-prebuilt
+    - ReactNativeDependencies
+  - React-jsinspectornetwork (0.83.4):
+    - React-Core-prebuilt
+    - React-jsinspectorcdp
+    - ReactNativeDependencies
+  - React-jsinspectortracing (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-jsi
+    - React-jsinspectornetwork
+    - React-oscompat
+    - React-timing
+    - ReactNativeDependencies
+  - React-jsitooling (0.83.4):
+    - React-Core-prebuilt
+    - React-cxxreact (= 0.83.4)
+    - React-debug
+    - React-jsi (= 0.83.4)
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsinspectortracing
+    - React-runtimeexecutor
+    - React-utils
+    - ReactNativeDependencies
+  - React-jsitracing (0.83.4):
+    - React-jsi
+  - React-logger (0.83.4):
+    - React-Core-prebuilt
+    - ReactNativeDependencies
+  - React-Mapbuffer (0.83.4):
+    - React-Core-prebuilt
+    - React-debug
+    - ReactNativeDependencies
+  - React-microtasksnativemodule (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-jsi
+    - React-jsiexecutor
+    - React-RCTFBReactNativeSpec
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - react-native-safe-area-context (5.6.2):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-jsi
+    - react-native-safe-area-context/common (= 5.6.2)
+    - react-native-safe-area-context/fabric (= 5.6.2)
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - react-native-safe-area-context/common (5.6.2):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - react-native-safe-area-context/fabric (5.6.2):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-jsi
+    - react-native-safe-area-context/common
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - React-NativeModulesApple (0.83.4):
+    - hermes-engine
+    - React-callinvoker
+    - React-Core
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-jsi
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-runtimeexecutor
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - React-networking (0.83.4):
+    - React-Core-prebuilt
+    - React-featureflags
+    - React-jsinspectornetwork
+    - React-jsinspectortracing
+    - React-performancetimeline
+    - React-timing
+    - ReactNativeDependencies
+  - React-oscompat (0.83.4)
+  - React-perflogger (0.83.4):
+    - React-Core-prebuilt
+    - ReactNativeDependencies
+  - React-performancecdpmetrics (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-jsi
+    - React-performancetimeline
+    - React-runtimeexecutor
+    - React-timing
+    - ReactNativeDependencies
+  - React-performancetimeline (0.83.4):
+    - React-Core-prebuilt
+    - React-featureflags
+    - React-jsinspectortracing
+    - React-perflogger
+    - React-timing
+    - ReactNativeDependencies
+  - React-RCTActionSheet (0.83.4):
+    - React-Core/RCTActionSheetHeaders (= 0.83.4)
+  - React-RCTAnimation (0.83.4):
+    - RCTTypeSafety
+    - React-Core-prebuilt
+    - React-Core/RCTAnimationHeaders
+    - React-featureflags
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFBReactNativeSpec
+    - ReactCommon
+    - ReactNativeDependencies
+  - React-RCTAppDelegate (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-CoreModules
+    - React-debug
+    - React-defaultsnativemodule
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-hermes
+    - React-jsitooling
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-RCTFBReactNativeSpec
+    - React-RCTImage
+    - React-RCTNetwork
+    - React-RCTRuntime
+    - React-rendererdebug
+    - React-RuntimeApple
+    - React-RuntimeCore
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactCommon
+    - ReactNativeDependencies
+  - React-RCTBlob (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-Core/RCTBlobHeaders
+    - React-Core/RCTWebSocket
+    - React-jsi
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-NativeModulesApple
+    - React-RCTFBReactNativeSpec
+    - React-RCTNetwork
+    - ReactCommon
+    - ReactNativeDependencies
+  - React-RCTFabric (0.83.4):
+    - hermes-engine
+    - RCTSwiftUIWrapper
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-FabricComponents
+    - React-FabricImage
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-jsi
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsinspectortracing
+    - React-networking
+    - React-performancecdpmetrics
+    - React-performancetimeline
+    - React-RCTAnimation
+    - React-RCTFBReactNativeSpec
+    - React-RCTImage
+    - React-RCTText
+    - React-rendererconsistency
+    - React-renderercss
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+    - Yoga
+  - React-RCTFBReactNativeSpec (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFBReactNativeSpec/components (= 0.83.4)
+    - ReactCommon
+    - ReactNativeDependencies
+  - React-RCTFBReactNativeSpec/components (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-NativeModulesApple
+    - React-rendererdebug
+    - React-utils
+    - ReactCommon
+    - ReactNativeDependencies
+    - Yoga
+  - React-RCTImage (0.83.4):
+    - RCTTypeSafety
+    - React-Core-prebuilt
+    - React-Core/RCTImageHeaders
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFBReactNativeSpec
+    - React-RCTNetwork
+    - ReactCommon
+    - ReactNativeDependencies
+  - React-RCTLinking (0.83.4):
+    - React-Core/RCTLinkingHeaders (= 0.83.4)
+    - React-jsi (= 0.83.4)
+    - React-NativeModulesApple
+    - React-RCTFBReactNativeSpec
+    - ReactCommon
+    - ReactCommon/turbomodule/core (= 0.83.4)
+  - React-RCTNetwork (0.83.4):
+    - RCTTypeSafety
+    - React-Core-prebuilt
+    - React-Core/RCTNetworkHeaders
+    - React-debug
+    - React-featureflags
+    - React-jsi
+    - React-jsinspectorcdp
+    - React-jsinspectornetwork
+    - React-NativeModulesApple
+    - React-networking
+    - React-RCTFBReactNativeSpec
+    - ReactCommon
+    - ReactNativeDependencies
+  - React-RCTRuntime (0.83.4):
+    - hermes-engine
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-jsi
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsinspectortracing
+    - React-jsitooling
+    - React-RuntimeApple
+    - React-RuntimeCore
+    - React-runtimeexecutor
+    - React-RuntimeHermes
+    - React-utils
+    - ReactNativeDependencies
+  - React-RCTSettings (0.83.4):
+    - RCTTypeSafety
+    - React-Core-prebuilt
+    - React-Core/RCTSettingsHeaders
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFBReactNativeSpec
+    - ReactCommon
+    - ReactNativeDependencies
+  - React-RCTText (0.83.4):
+    - React-Core/RCTTextHeaders (= 0.83.4)
+    - Yoga
+  - React-RCTVibration (0.83.4):
+    - React-Core-prebuilt
+    - React-Core/RCTVibrationHeaders
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFBReactNativeSpec
+    - ReactCommon
+    - ReactNativeDependencies
+  - React-rendererconsistency (0.83.4)
+  - React-renderercss (0.83.4):
+    - React-debug
+    - React-utils
+  - React-rendererdebug (0.83.4):
+    - React-Core-prebuilt
+    - React-debug
+    - ReactNativeDependencies
+  - React-RuntimeApple (0.83.4):
+    - hermes-engine
+    - React-callinvoker
+    - React-Core-prebuilt
+    - React-Core/Default
+    - React-CoreModules
+    - React-cxxreact
+    - React-featureflags
+    - React-jserrorhandler
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsitooling
+    - React-Mapbuffer
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-RCTFBReactNativeSpec
+    - React-RuntimeCore
+    - React-runtimeexecutor
+    - React-RuntimeHermes
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+  - React-RuntimeCore (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-Fabric
+    - React-featureflags
+    - React-jserrorhandler
+    - React-jsi
+    - React-jsiexecutor
+    - React-jsinspector
+    - React-jsitooling
+    - React-performancetimeline
+    - React-runtimeexecutor
+    - React-runtimescheduler
+    - React-utils
+    - ReactNativeDependencies
+  - React-runtimeexecutor (0.83.4):
+    - React-Core-prebuilt
+    - React-debug
+    - React-featureflags
+    - React-jsi (= 0.83.4)
+    - React-utils
+    - ReactNativeDependencies
+  - React-RuntimeHermes (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-featureflags
+    - React-hermes
+    - React-jsi
+    - React-jsinspector
+    - React-jsinspectorcdp
+    - React-jsinspectortracing
+    - React-jsitooling
+    - React-jsitracing
+    - React-RuntimeCore
+    - React-runtimeexecutor
+    - React-utils
+    - ReactNativeDependencies
+  - React-runtimescheduler (0.83.4):
+    - hermes-engine
+    - React-callinvoker
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-debug
+    - React-featureflags
+    - React-jsi
+    - React-jsinspectortracing
+    - React-performancetimeline
+    - React-rendererconsistency
+    - React-rendererdebug
+    - React-runtimeexecutor
+    - React-timing
+    - React-utils
+    - ReactNativeDependencies
+  - React-timing (0.83.4):
+    - React-debug
+  - React-utils (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-debug
+    - React-jsi (= 0.83.4)
+    - ReactNativeDependencies
+  - React-webperformancenativemodule (0.83.4):
+    - hermes-engine
+    - React-Core-prebuilt
+    - React-cxxreact
+    - React-jsi
+    - React-jsiexecutor
+    - React-performancetimeline
+    - React-RCTFBReactNativeSpec
+    - React-runtimeexecutor
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - ReactAppDependencyProvider (0.83.4):
+    - ReactCodegen
+  - ReactCodegen (0.83.4):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-FabricImage
+    - React-featureflags
+    - React-graphics
+    - React-jsi
+    - React-jsiexecutor
+    - React-NativeModulesApple
+    - React-RCTAppDelegate
+    - React-rendererdebug
+    - React-utils
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+  - ReactCommon (0.83.4):
+    - React-Core-prebuilt
+    - ReactCommon/turbomodule (= 0.83.4)
+    - ReactNativeDependencies
+  - ReactCommon/turbomodule (0.83.4):
+    - hermes-engine
+    - React-callinvoker (= 0.83.4)
+    - React-Core-prebuilt
+    - React-cxxreact (= 0.83.4)
+    - React-jsi (= 0.83.4)
+    - React-logger (= 0.83.4)
+    - React-perflogger (= 0.83.4)
+    - ReactCommon/turbomodule/bridging (= 0.83.4)
+    - ReactCommon/turbomodule/core (= 0.83.4)
+    - ReactNativeDependencies
+  - ReactCommon/turbomodule/bridging (0.83.4):
+    - hermes-engine
+    - React-callinvoker (= 0.83.4)
+    - React-Core-prebuilt
+    - React-cxxreact (= 0.83.4)
+    - React-jsi (= 0.83.4)
+    - React-logger (= 0.83.4)
+    - React-perflogger (= 0.83.4)
+    - ReactNativeDependencies
+  - ReactCommon/turbomodule/core (0.83.4):
+    - hermes-engine
+    - React-callinvoker (= 0.83.4)
+    - React-Core-prebuilt
+    - React-cxxreact (= 0.83.4)
+    - React-debug (= 0.83.4)
+    - React-featureflags (= 0.83.4)
+    - React-jsi (= 0.83.4)
+    - React-logger (= 0.83.4)
+    - React-perflogger (= 0.83.4)
+    - React-utils (= 0.83.4)
+    - ReactNativeDependencies
+  - ReactNativeDependencies (0.83.4)
+  - RNFSTurbo (0.5.1):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - RNGestureHandler (2.30.1):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - RNReanimated (4.2.1):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-hermes
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - RNReanimated/reanimated (= 4.2.1)
+    - RNWorklets
+    - Yoga
+  - RNReanimated/reanimated (4.2.1):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-hermes
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - RNReanimated/reanimated/apple (= 4.2.1)
+    - RNWorklets
+    - Yoga
+  - RNReanimated/reanimated/apple (4.2.1):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-hermes
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - RNWorklets
+    - Yoga
+  - RNScreens (4.23.0):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-RCTImage
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - RNScreens/common (= 4.23.0)
+    - Yoga
+  - RNScreens/common (4.23.0):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-RCTImage
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - RNWorklets (0.7.2):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-hermes
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - RNWorklets/worklets (= 0.7.2)
+    - Yoga
+  - RNWorklets/worklets (0.7.2):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-hermes
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - RNWorklets/worklets/apple (= 0.7.2)
+    - Yoga
+  - RNWorklets/worklets/apple (0.7.2):
+    - hermes-engine
+    - RCTRequired
+    - RCTTypeSafety
+    - React-Core
+    - React-Core-prebuilt
+    - React-debug
+    - React-Fabric
+    - React-featureflags
+    - React-graphics
+    - React-hermes
+    - React-ImageManager
+    - React-jsi
+    - React-NativeModulesApple
+    - React-RCTFabric
+    - React-renderercss
+    - React-rendererdebug
+    - React-utils
+    - ReactCodegen
+    - ReactCommon/turbomodule/bridging
+    - ReactCommon/turbomodule/core
+    - ReactNativeDependencies
+    - Yoga
+  - SDWebImage (5.21.4):
+    - SDWebImage/Core (= 5.21.4)
+  - SDWebImage/Core (5.21.4)
+  - SDWebImageAVIFCoder (0.11.1):
+    - libavif/core (>= 0.11.0)
+    - SDWebImage (~> 5.10)
+  - SDWebImageSVGCoder (1.7.0):
+    - SDWebImage/Core (~> 5.6)
+  - SDWebImageWebPCoder (0.14.6):
+    - libwebp (~> 1.0)
+    - SDWebImage/Core (~> 5.17)
+  - Yoga (0.0.0)
+
+DEPENDENCIES:
+  - EXConstants (from `../node_modules/expo-constants/ios`)
+  - Expo (from `../node_modules/expo`)
+  - ExpoAsset (from `../node_modules/expo-asset/ios`)
+  - ExpoDevice (from `../node_modules/expo-device/ios`)
+  - "ExpoDomWebView (from `../node_modules/@expo/dom-webview/ios`)"
+  - ExpoFileSystem (from `../node_modules/expo-file-system/ios`)
+  - ExpoFont (from `../node_modules/expo-font/ios`)
+  - ExpoGlassEffect (from `../node_modules/expo-glass-effect/ios`)
+  - ExpoImage (from `../node_modules/expo-image/ios`)
+  - ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`)
+  - ExpoLinking (from `../node_modules/expo-linking/ios`)
+  - "ExpoLogBox (from `../node_modules/@expo/log-box`)"
+  - ExpoModulesCore (from `../node_modules/expo-modules-core`)
+  - ExpoModulesJSI (from `../node_modules/expo-modules-core`)
+  - ExpoRouter (from `../node_modules/expo-router/ios`)
+  - ExpoSplashScreen (from `../node_modules/expo-splash-screen/ios`)
+  - ExpoSymbols (from `../node_modules/expo-symbols/ios`)
+  - ExpoSystemUI (from `../node_modules/expo-system-ui/ios`)
+  - ExpoWebBrowser (from `../node_modules/expo-web-browser/ios`)
+  - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
+  - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
+  - NitroMmkv (from `../node_modules/react-native-mmkv`)
+  - NitroModules (from `../node_modules/react-native-nitro-modules`)
+  - RCTDeprecation (from `../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
+  - RCTRequired (from `../node_modules/react-native/Libraries/Required`)
+  - RCTSwiftUI (from `../node_modules/react-native/ReactApple/RCTSwiftUI`)
+  - RCTSwiftUIWrapper (from `../node_modules/react-native/ReactApple/RCTSwiftUIWrapper`)
+  - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
+  - React (from `../node_modules/react-native/`)
+  - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
+  - React-Core (from `../node_modules/react-native/`)
+  - React-Core-prebuilt (from `../node_modules/react-native/React-Core-prebuilt.podspec`)
+  - React-Core/RCTWebSocket (from `../node_modules/react-native/`)
+  - React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
+  - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
+  - React-debug (from `../node_modules/react-native/ReactCommon/react/debug`)
+  - React-defaultsnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/defaults`)
+  - React-domnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/dom`)
+  - React-Fabric (from `../node_modules/react-native/ReactCommon`)
+  - React-FabricComponents (from `../node_modules/react-native/ReactCommon`)
+  - React-FabricImage (from `../node_modules/react-native/ReactCommon`)
+  - React-featureflags (from `../node_modules/react-native/ReactCommon/react/featureflags`)
+  - React-featureflagsnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/featureflags`)
+  - React-graphics (from `../node_modules/react-native/ReactCommon/react/renderer/graphics`)
+  - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`)
+  - React-idlecallbacksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/idlecallbacks`)
+  - React-ImageManager (from `../node_modules/react-native/ReactCommon/react/renderer/imagemanager/platform/ios`)
+  - React-intersectionobservernativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/intersectionobserver`)
+  - React-jserrorhandler (from `../node_modules/react-native/ReactCommon/jserrorhandler`)
+  - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
+  - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
+  - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector-modern`)
+  - React-jsinspectorcdp (from `../node_modules/react-native/ReactCommon/jsinspector-modern/cdp`)
+  - React-jsinspectornetwork (from `../node_modules/react-native/ReactCommon/jsinspector-modern/network`)
+  - React-jsinspectortracing (from `../node_modules/react-native/ReactCommon/jsinspector-modern/tracing`)
+  - React-jsitooling (from `../node_modules/react-native/ReactCommon/jsitooling`)
+  - React-jsitracing (from `../node_modules/react-native/ReactCommon/hermes/executor/`)
+  - React-logger (from `../node_modules/react-native/ReactCommon/logger`)
+  - React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
+  - React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`)
+  - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
+  - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
+  - React-networking (from `../node_modules/react-native/ReactCommon/react/networking`)
+  - React-oscompat (from `../node_modules/react-native/ReactCommon/oscompat`)
+  - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
+  - React-performancecdpmetrics (from `../node_modules/react-native/ReactCommon/react/performance/cdpmetrics`)
+  - React-performancetimeline (from `../node_modules/react-native/ReactCommon/react/performance/timeline`)
+  - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
+  - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
+  - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`)
+  - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
+  - React-RCTFabric (from `../node_modules/react-native/React`)
+  - React-RCTFBReactNativeSpec (from `../node_modules/react-native/React`)
+  - React-RCTImage (from `../node_modules/react-native/Libraries/Image`)
+  - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`)
+  - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`)
+  - React-RCTRuntime (from `../node_modules/react-native/React/Runtime`)
+  - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
+  - React-RCTText (from `../node_modules/react-native/Libraries/Text`)
+  - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
+  - React-rendererconsistency (from `../node_modules/react-native/ReactCommon/react/renderer/consistency`)
+  - React-renderercss (from `../node_modules/react-native/ReactCommon/react/renderer/css`)
+  - React-rendererdebug (from `../node_modules/react-native/ReactCommon/react/renderer/debug`)
+  - React-RuntimeApple (from `../node_modules/react-native/ReactCommon/react/runtime/platform/ios`)
+  - React-RuntimeCore (from `../node_modules/react-native/ReactCommon/react/runtime`)
+  - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
+  - React-RuntimeHermes (from `../node_modules/react-native/ReactCommon/react/runtime`)
+  - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`)
+  - React-timing (from `../node_modules/react-native/ReactCommon/react/timing`)
+  - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
+  - React-webperformancenativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/webperformance`)
+  - ReactAppDependencyProvider (from `build/generated/ios/ReactAppDependencyProvider`)
+  - ReactCodegen (from `build/generated/ios/ReactCodegen`)
+  - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
+  - ReactNativeDependencies (from `../node_modules/react-native/third-party-podspecs/ReactNativeDependencies.podspec`)
+  - RNFSTurbo (from `../node_modules/react-native-fs-turbo`)
+  - RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
+  - RNReanimated (from `../node_modules/react-native-reanimated`)
+  - RNScreens (from `../node_modules/react-native-screens`)
+  - RNWorklets (from `../node_modules/react-native-worklets`)
+  - Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
+
+SPEC REPOS:
+  trunk:
+    - libavif
+    - libdav1d
+    - libwebp
+    - MMKVCore
+    - SDWebImage
+    - SDWebImageAVIFCoder
+    - SDWebImageSVGCoder
+    - SDWebImageWebPCoder
+
+EXTERNAL SOURCES:
+  EXConstants:
+    :path: "../node_modules/expo-constants/ios"
+  Expo:
+    :path: "../node_modules/expo"
+  ExpoAsset:
+    :path: "../node_modules/expo-asset/ios"
+  ExpoDevice:
+    :path: "../node_modules/expo-device/ios"
+  ExpoDomWebView:
+    :path: "../node_modules/@expo/dom-webview/ios"
+  ExpoFileSystem:
+    :path: "../node_modules/expo-file-system/ios"
+  ExpoFont:
+    :path: "../node_modules/expo-font/ios"
+  ExpoGlassEffect:
+    :path: "../node_modules/expo-glass-effect/ios"
+  ExpoImage:
+    :path: "../node_modules/expo-image/ios"
+  ExpoKeepAwake:
+    :path: "../node_modules/expo-keep-awake/ios"
+  ExpoLinking:
+    :path: "../node_modules/expo-linking/ios"
+  ExpoLogBox:
+    :path: "../node_modules/@expo/log-box"
+  ExpoModulesCore:
+    :path: "../node_modules/expo-modules-core"
+  ExpoModulesJSI:
+    :path: "../node_modules/expo-modules-core"
+  ExpoRouter:
+    :path: "../node_modules/expo-router/ios"
+  ExpoSplashScreen:
+    :path: "../node_modules/expo-splash-screen/ios"
+  ExpoSymbols:
+    :path: "../node_modules/expo-symbols/ios"
+  ExpoSystemUI:
+    :path: "../node_modules/expo-system-ui/ios"
+  ExpoWebBrowser:
+    :path: "../node_modules/expo-web-browser/ios"
+  FBLazyVector:
+    :path: "../node_modules/react-native/Libraries/FBLazyVector"
+  hermes-engine:
+    :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec"
+    :tag: hermes-v0.14.1
+  NitroMmkv:
+    :path: "../node_modules/react-native-mmkv"
+  NitroModules:
+    :path: "../node_modules/react-native-nitro-modules"
+  RCTDeprecation:
+    :path: "../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation"
+  RCTRequired:
+    :path: "../node_modules/react-native/Libraries/Required"
+  RCTSwiftUI:
+    :path: "../node_modules/react-native/ReactApple/RCTSwiftUI"
+  RCTSwiftUIWrapper:
+    :path: "../node_modules/react-native/ReactApple/RCTSwiftUIWrapper"
+  RCTTypeSafety:
+    :path: "../node_modules/react-native/Libraries/TypeSafety"
+  React:
+    :path: "../node_modules/react-native/"
+  React-callinvoker:
+    :path: "../node_modules/react-native/ReactCommon/callinvoker"
+  React-Core:
+    :path: "../node_modules/react-native/"
+  React-Core-prebuilt:
+    :podspec: "../node_modules/react-native/React-Core-prebuilt.podspec"
+  React-CoreModules:
+    :path: "../node_modules/react-native/React/CoreModules"
+  React-cxxreact:
+    :path: "../node_modules/react-native/ReactCommon/cxxreact"
+  React-debug:
+    :path: "../node_modules/react-native/ReactCommon/react/debug"
+  React-defaultsnativemodule:
+    :path: "../node_modules/react-native/ReactCommon/react/nativemodule/defaults"
+  React-domnativemodule:
+    :path: "../node_modules/react-native/ReactCommon/react/nativemodule/dom"
+  React-Fabric:
+    :path: "../node_modules/react-native/ReactCommon"
+  React-FabricComponents:
+    :path: "../node_modules/react-native/ReactCommon"
+  React-FabricImage:
+    :path: "../node_modules/react-native/ReactCommon"
+  React-featureflags:
+    :path: "../node_modules/react-native/ReactCommon/react/featureflags"
+  React-featureflagsnativemodule:
+    :path: "../node_modules/react-native/ReactCommon/react/nativemodule/featureflags"
+  React-graphics:
+    :path: "../node_modules/react-native/ReactCommon/react/renderer/graphics"
+  React-hermes:
+    :path: "../node_modules/react-native/ReactCommon/hermes"
+  React-idlecallbacksnativemodule:
+    :path: "../node_modules/react-native/ReactCommon/react/nativemodule/idlecallbacks"
+  React-ImageManager:
+    :path: "../node_modules/react-native/ReactCommon/react/renderer/imagemanager/platform/ios"
+  React-intersectionobservernativemodule:
+    :path: "../node_modules/react-native/ReactCommon/react/nativemodule/intersectionobserver"
+  React-jserrorhandler:
+    :path: "../node_modules/react-native/ReactCommon/jserrorhandler"
+  React-jsi:
+    :path: "../node_modules/react-native/ReactCommon/jsi"
+  React-jsiexecutor:
+    :path: "../node_modules/react-native/ReactCommon/jsiexecutor"
+  React-jsinspector:
+    :path: "../node_modules/react-native/ReactCommon/jsinspector-modern"
+  React-jsinspectorcdp:
+    :path: "../node_modules/react-native/ReactCommon/jsinspector-modern/cdp"
+  React-jsinspectornetwork:
+    :path: "../node_modules/react-native/ReactCommon/jsinspector-modern/network"
+  React-jsinspectortracing:
+    :path: "../node_modules/react-native/ReactCommon/jsinspector-modern/tracing"
+  React-jsitooling:
+    :path: "../node_modules/react-native/ReactCommon/jsitooling"
+  React-jsitracing:
+    :path: "../node_modules/react-native/ReactCommon/hermes/executor/"
+  React-logger:
+    :path: "../node_modules/react-native/ReactCommon/logger"
+  React-Mapbuffer:
+    :path: "../node_modules/react-native/ReactCommon"
+  React-microtasksnativemodule:
+    :path: "../node_modules/react-native/ReactCommon/react/nativemodule/microtasks"
+  react-native-safe-area-context:
+    :path: "../node_modules/react-native-safe-area-context"
+  React-NativeModulesApple:
+    :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios"
+  React-networking:
+    :path: "../node_modules/react-native/ReactCommon/react/networking"
+  React-oscompat:
+    :path: "../node_modules/react-native/ReactCommon/oscompat"
+  React-perflogger:
+    :path: "../node_modules/react-native/ReactCommon/reactperflogger"
+  React-performancecdpmetrics:
+    :path: "../node_modules/react-native/ReactCommon/react/performance/cdpmetrics"
+  React-performancetimeline:
+    :path: "../node_modules/react-native/ReactCommon/react/performance/timeline"
+  React-RCTActionSheet:
+    :path: "../node_modules/react-native/Libraries/ActionSheetIOS"
+  React-RCTAnimation:
+    :path: "../node_modules/react-native/Libraries/NativeAnimation"
+  React-RCTAppDelegate:
+    :path: "../node_modules/react-native/Libraries/AppDelegate"
+  React-RCTBlob:
+    :path: "../node_modules/react-native/Libraries/Blob"
+  React-RCTFabric:
+    :path: "../node_modules/react-native/React"
+  React-RCTFBReactNativeSpec:
+    :path: "../node_modules/react-native/React"
+  React-RCTImage:
+    :path: "../node_modules/react-native/Libraries/Image"
+  React-RCTLinking:
+    :path: "../node_modules/react-native/Libraries/LinkingIOS"
+  React-RCTNetwork:
+    :path: "../node_modules/react-native/Libraries/Network"
+  React-RCTRuntime:
+    :path: "../node_modules/react-native/React/Runtime"
+  React-RCTSettings:
+    :path: "../node_modules/react-native/Libraries/Settings"
+  React-RCTText:
+    :path: "../node_modules/react-native/Libraries/Text"
+  React-RCTVibration:
+    :path: "../node_modules/react-native/Libraries/Vibration"
+  React-rendererconsistency:
+    :path: "../node_modules/react-native/ReactCommon/react/renderer/consistency"
+  React-renderercss:
+    :path: "../node_modules/react-native/ReactCommon/react/renderer/css"
+  React-rendererdebug:
+    :path: "../node_modules/react-native/ReactCommon/react/renderer/debug"
+  React-RuntimeApple:
+    :path: "../node_modules/react-native/ReactCommon/react/runtime/platform/ios"
+  React-RuntimeCore:
+    :path: "../node_modules/react-native/ReactCommon/react/runtime"
+  React-runtimeexecutor:
+    :path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
+  React-RuntimeHermes:
+    :path: "../node_modules/react-native/ReactCommon/react/runtime"
+  React-runtimescheduler:
+    :path: "../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler"
+  React-timing:
+    :path: "../node_modules/react-native/ReactCommon/react/timing"
+  React-utils:
+    :path: "../node_modules/react-native/ReactCommon/react/utils"
+  React-webperformancenativemodule:
+    :path: "../node_modules/react-native/ReactCommon/react/nativemodule/webperformance"
+  ReactAppDependencyProvider:
+    :path: build/generated/ios/ReactAppDependencyProvider
+  ReactCodegen:
+    :path: build/generated/ios/ReactCodegen
+  ReactCommon:
+    :path: "../node_modules/react-native/ReactCommon"
+  ReactNativeDependencies:
+    :podspec: "../node_modules/react-native/third-party-podspecs/ReactNativeDependencies.podspec"
+  RNFSTurbo:
+    :path: "../node_modules/react-native-fs-turbo"
+  RNGestureHandler:
+    :path: "../node_modules/react-native-gesture-handler"
+  RNReanimated:
+    :path: "../node_modules/react-native-reanimated"
+  RNScreens:
+    :path: "../node_modules/react-native-screens"
+  RNWorklets:
+    :path: "../node_modules/react-native-worklets"
+  Yoga:
+    :path: "../node_modules/react-native/ReactCommon/yoga"
+
+SPEC CHECKSUMS:
+  EXConstants: 97e4a5b18e38331acce952f0e4a6817b0418408f
+  Expo: 04f5391a7affe866de03b928cf40d683ec4a3463
+  ExpoAsset: 3636e70a874487efd0a677f6c064dbc9fc8f174b
+  ExpoDevice: 221ea185adcd21845c5911d370b03af84a493413
+  ExpoDomWebView: 2b2fbd9a07de8790569257cbf9dfdaa31cf95c70
+  ExpoFileSystem: d40374bc7b6e990e2640e5dc3350fc83b1d74a40
+  ExpoFont: cdd7a1d574a376fa003c713eff49e0a4df8672c7
+  ExpoGlassEffect: 72bcb9dc634262c59897ff7c53c16e2ff03990d0
+  ExpoImage: ef931bba1fd3e907c2262216d17eb21095c9ac2b
+  ExpoKeepAwake: a1baf9810a2dee1905aa9bdd336852598f7220e9
+  ExpoLinking: b42fd76bdda8662ddf797b17cb4cc793adabfe98
+  ExpoLogBox: a3de999775d423ac9cb85d24bd47628e5392761f
+  ExpoModulesCore: 964f01116faf01b68467a6c8ea06e14d65fe7b3c
+  ExpoModulesJSI: 0dcd06b8d4b92826d30f52947a03a78f7590b604
+  ExpoRouter: a29e3a3479f33ceda0d08136bdd7931b3a7b040c
+  ExpoSplashScreen: 5d16d7a0ada0671b5c59080b1ce9126c987baee7
+  ExpoSymbols: 8b63e859ba013df1f2fc666f535fddb3d5270569
+  ExpoSystemUI: 8f1d5aac902dada8df8cc2944563c56e2179fcb9
+  ExpoWebBrowser: f81f8e35afd7f61ec809622ef354c579a3b580e2
+  FBLazyVector: 061f518bbd81677ed8a8317e2ae60b8779495808
+  hermes-engine: e4ecc5957f671df3fa4828a33b435bd6955c25a5
+  libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7
+  libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f
+  libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
+  MMKVCore: 3d16ce9f7d411e135020915fde98a056859a1efa
+  NitroMmkv: 7a7572934538ba6748e05dffc6ee8b06caad91cc
+  NitroModules: 00c15fcce98b504f21bd5b0c99276db161efcb39
+  RCTDeprecation: 5045f20b2cc1239bf422764004338c720684a22f
+  RCTRequired: b6b9724225dd780ac2989d2e575d5513c50fe04b
+  RCTSwiftUI: 395b65655229fa2006415207adcfcb6e35dc78ed
+  RCTSwiftUIWrapper: 91351441a592e07e09a2f94d2cbdf088fde7e2e1
+  RCTTypeSafety: dfd539968f0b82892da72bb32b7d8aa2f5789622
+  React: 3e14066ac707b3e369d09e2e923d8bee7f8c33ff
+  React-callinvoker: bd7959a24564feaf5e4c8c11789e64884da13482
+  React-Core: f060f4e14e9301685ce63ea65fbe903bf3397e45
+  React-Core-prebuilt: e958d0ca3f8828f37f35c4cff2594b6e080fd991
+  React-CoreModules: 89a1a544297be88ca4cdff317423f9e0d0c192a4
+  React-cxxreact: 81b1bfa305b1b759cc0fe18327644816216e5993
+  React-debug: 234fddb309822e13b9b442ef1bdca8d2b8c3cbf2
+  React-defaultsnativemodule: e465ef591eee34d967cd8542d3e2a4e3d46a354e
+  React-domnativemodule: e0df99aca200b98799d97323b7e8ceec67ed205b
+  React-Fabric: 78be00ef029f74f47ae75b8aac163c108b049c55
+  React-FabricComponents: 84a6c91260cbcc4382380c16eb68b41118d59a49
+  React-FabricImage: 52851292bb447ce2f77bfd1b053102fda5f47864
+  React-featureflags: 5868b47efa183acb7e50be2a0313f81101049ce4
+  React-featureflagsnativemodule: f2d8c27152f3e09c4448ab86012a0499785599d7
+  React-graphics: 96a2a086c46f9a3577b67ce3298c0c5935251104
+  React-hermes: 8a2af4efdf2c8bcb98ac60dc7fe9541bf1e7ce0d
+  React-idlecallbacksnativemodule: 010e6287d81d99f74a1922009ca50cd8228d5db0
+  React-ImageManager: d8404f1283093dbb0a43452a9558f055d9982658
+  React-intersectionobservernativemodule: 44cd7c0c5c21da8f5847ab59d65f65e3c4208c2c
+  React-jserrorhandler: d4c73c16ba639be63387971a2d52d478d6d1f8bd
+  React-jsi: e901e18fd04833b441de6803565903eb55336b24
+  React-jsiexecutor: bc6a2b2d53ce85c5f235f0cd3993c3ecc6fbd5e4
+  React-jsinspector: 603e56d09fdeccd36aef1d3515e0010680c46779
+  React-jsinspectorcdp: 7cddf91b091012c09d53d7ef1aef6774a99c33b8
+  React-jsinspectornetwork: c8c0bbdd96a056bd42aed980eff6991c935179e9
+  React-jsinspectortracing: 1fde11514a9d7b30884e29bb063d2b7c2a0b8479
+  React-jsitooling: 3b1d0a6df5ced5ca15566149d9a3dd46657d1cdd
+  React-jsitracing: dcc408e8d0f91e47cf5850814bfe0c2d2253f61f
+  React-logger: d0632d799fbd3507cdd5406f72489a83ed5f9163
+  React-Mapbuffer: 274cb203819492f7fb594bbb3a1f3f5061fa794d
+  React-microtasksnativemodule: 563b4dcc8b8570814d6de4fc1196f48d2944acd4
+  react-native-safe-area-context: 37e680fc4cace3c0030ee46e8987d24f5d3bdab2
+  React-NativeModulesApple: f3eb751b0ea23645a5283ed8c8bb8ebeeda32d15
+  React-networking: af5eba8ccda3334cd2f6246b599d3b55bb73eb2e
+  React-oscompat: 3774ed6bc0e9866ff7236b94adbc7ad33ceaecdd
+  React-perflogger: 9b2532c128b02a64ae9e5f73c11b5564f2547635
+  React-performancecdpmetrics: 7e2785e9bf6b2e6d4d773c591df0e1329678681b
+  React-performancetimeline: b94b69786a7226d6ab414d1b2e0bf1f60b4e6696
+  React-RCTActionSheet: f2148e4017876b944dc9c931f1c56ca7234c290a
+  React-RCTAnimation: 33e94951f811fb5571e7160165669344d2b22160
+  React-RCTAppDelegate: 1621957224c5256869a4deccc42b6741b178e08f
+  React-RCTBlob: 761bf4785bc035196b20778cca136b0823d32233
+  React-RCTFabric: 470928ef9074b7bb00a29ca6142fe34fb7ee81c9
+  React-RCTFBReactNativeSpec: 2904ab623b779afa0a2a450947159e0e28ffc894
+  React-RCTImage: 5560e503c96e247313b082c879a19cc211ee9f30
+  React-RCTLinking: 0ac9f185ea77603c5481a3ed482e7d907c37c3bf
+  React-RCTNetwork: 72785a503a1f4ef37d7ee874d2e1e5397440338e
+  React-RCTRuntime: a5a9cb0ab150d114b00d7bbf1893c1db4b157a50
+  React-RCTSettings: 89669a77d7eb5cc0ee9b5dac511107d385735c3b
+  React-RCTText: fd853dcbdcf3c46b08b53bf3fa2b8a817a4bd249
+  React-RCTVibration: 976f18168451ab9c2ed338ab8517b2ad560c9020
+  React-rendererconsistency: 0db1699629cdfb8110c2e12990e35aa01da2e197
+  React-renderercss: ed517df279318338a0b153f9bd378403e8fc7ca6
+  React-rendererdebug: d7f5a1c875e3278be110cbb340ad70940c64bf9a
+  React-RuntimeApple: 6f5f92a383b0d62661d81b060377c14bf4bef5c0
+  React-RuntimeCore: 5fa926643f76ec9b359edef2e93f7aa9bc1983c5
+  React-runtimeexecutor: f603dc903a3f4a30d319294ccdde90568baa5212
+  React-RuntimeHermes: f2316b8ae36214a9a264d4bff5f0d77f7eb78238
+  React-runtimescheduler: 22498bd949afb9c56280a23f507bf4767b06b96c
+  React-timing: ede821a42176a0b3c90a60ea9b85ced1f70b3612
+  React-utils: 6e94fb28c75cd15b4a6bacf93ee5a232f35db3ac
+  React-webperformancenativemodule: c5ea6876ea8eb9908c12cdeae9fa48b1b06cc7b3
+  ReactAppDependencyProvider: 2b19d66e5ddfe8dc7afb6338a4626156cbf2bab1
+  ReactCodegen: 43f0948182edee9407c7b977fb059455dfeb9361
+  ReactCommon: c6e81cc1ae185fa84863f3ea1d58caac4be741d7
+  ReactNativeDependencies: e3081feec6a8266d996ca8ce3d5707360258baf8
+  RNFSTurbo: 8d1d8640c0c78c11f65a1af028ac11b66642efcf
+  RNGestureHandler: 0ea8153746a92b3744d4eaadade647debedf646e
+  RNReanimated: 86e5991396f1aa514db90d6c79d4c3e37a37bb10
+  RNScreens: 02e62f995ceb94ea465864b3bf4d4767b87f0362
+  RNWorklets: 0e736f568c3c61cb3326cdcda767c4daee56a8a9
+  SDWebImage: d0184764be51240d49c761c37f53dd017e1ccaaf
+  SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57
+  SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c
+  SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
+  Yoga: acd565934addf7423687593ec490bd4491b2a802
+
+PODFILE CHECKSUM: f8484271daa2d3a412f55807eb9cc72bafb26b9f
+
+COCOAPODS: 1.16.2

+ 4 - 0
ios/Podfile.properties.json

@@ -0,0 +1,4 @@
+{
+  "expo.jsEngine": "hermes",
+  "EX_DEV_CLIENT_NETWORK_INSPECTOR": "true"
+}

+ 8 - 1
metro.config.js

@@ -2,5 +2,12 @@ const { getDefaultConfig } = require("expo/metro-config");
 const { withNativeWind } = require('nativewind/metro');
  
 const config = getDefaultConfig(__dirname)
- 
+
+config.transformer.minifierConfig = {
+  compress: {
+    // The option below removes all console logs statements in production.
+    drop_console: true,
+  },
+};
+
 module.exports = withNativeWind(config, { input: './src/global.css' })

+ 11 - 1
package.json

@@ -8,9 +8,16 @@
     "android": "expo run:android",
     "ios": "expo run:ios",
     "web": "expo start --web",
+    "build:web": "expo export --platform web",
+    "build:ios": "",
+    "build:apk": "cd android && ./gradlew app:bundleRelease",
+    "build:ios-patch": "expo export --platform ios --output-dir dist/ios-patch",
+    "build:android-patch": "expo export --platform android --output-dir dist/android-patch",
     "lint": "expo lint"
   },
   "dependencies": {
+    "@ant-design/icons-react-native": "^2.3.2",
+    "@ant-design/react-native": "^5.4.3",
     "@react-navigation/bottom-tabs": "^7.15.5",
     "@react-navigation/elements": "^2.9.10",
     "@react-navigation/native": "^7.1.33",
@@ -33,7 +40,7 @@
     "react-dom": "19.2.0",
     "react-native": "0.83.4",
     "react-native-fs-turbo": "^0.5.1",
-    "react-native-gesture-handler": "~2.30.0",
+    "react-native-gesture-handler": "~2.30.1",
     "react-native-mmkv": "^4.3.1",
     "react-native-nitro-modules": "^0.35.3",
     "react-native-reanimated": "4.2.1",
@@ -44,6 +51,9 @@
   },
   "devDependencies": {
     "@types/react": "~19.2.2",
+    "babel-plugin-import": "^1.13.8",
+    "eslint": "^9.39.4",
+    "eslint-config-expo": "~55.0.0",
     "typescript": "~5.9.2"
   },
   "private": true

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 666 - 7
pnpm-lock.yaml


+ 8 - 64
src/app/(tabs)/_layout.tsx

@@ -1,76 +1,20 @@
-import { Colors } from '@/constants/theme';
+import AppTabs from '@/components/app-tabs';
 import { useAuth } from '@/utils/auth';
 import { router } from 'expo-router';
-import { NativeTabs } from 'expo-router/unstable-native-tabs';
 import React, { useEffect } from 'react';
-import { useColorScheme } from 'react-native';
 
-/**
- * Tab 导航布局 — 5 个 Tab 对应设计稿底部导航栏
- * 首页 / 客户 / 分析 / 报表 / 我的
- *
- * 使用 NativeTabs 获得原生 iOS/Android Tab Bar 体验
- * 图标:复用已有 PNG 资源,TODO: 补充 analytics / reports / profile 专属图标
- */
 export default function TabLayout() {
-  const scheme = useColorScheme();
-  const colors = Colors[scheme === 'unspecified' ? 'light' : scheme];
   const { isAuthenticated } = useAuth();
-  useEffect(() => { 
+
+  useEffect(() => {
     if (!isAuthenticated) {
-      router.push('/sign-in');
+      router.replace('/sign-in');
     }
   }, [isAuthenticated]);
-  return (
-    <NativeTabs
-      backgroundColor={colors.background}
-      indicatorColor={colors.backgroundElement}
-      labelStyle={{ selected: { color: colors.text } }}
-    >
-      <NativeTabs.Trigger name="index">
-        <NativeTabs.Trigger.Label>首页</NativeTabs.Trigger.Label>
-        <NativeTabs.Trigger.Icon
-          src={require('@/assets/images/tabIcons/home.png')}
-          renderingMode="template"
-        />
-      </NativeTabs.Trigger>
-
-      <NativeTabs.Trigger name="customer">
-        <NativeTabs.Trigger.Label>客户</NativeTabs.Trigger.Label>
-        <NativeTabs.Trigger.Icon
-          src={require('@/assets/images/tabIcons/explore.png')}
-          renderingMode="template"
-        />
-      </NativeTabs.Trigger>
-
-      <NativeTabs.Trigger name="analytics">
-        <NativeTabs.Trigger.Label>分析</NativeTabs.Trigger.Label>
-        {/* TODO: 替换为 analytics 专属图标 */}
-        <NativeTabs.Trigger.Icon
-          src={require('@/assets/images/tabIcons/explore.png')}
-          renderingMode="template"
-        />
-      </NativeTabs.Trigger>
 
-      <NativeTabs.Trigger name="reports">
-        <NativeTabs.Trigger.Label>报表</NativeTabs.Trigger.Label>
-        {/* TODO: 替换为 reports 专属图标 */}
-        <NativeTabs.Trigger.Icon
-          src={require('@/assets/images/tabIcons/explore.png')}
-          renderingMode="template"
-        />
-      </NativeTabs.Trigger>
+  if (!isAuthenticated) {
+    return null;
+  }
 
-      <NativeTabs.Trigger name="profile">
-        <NativeTabs.Trigger.Label>我的</NativeTabs.Trigger.Label>
-        {/* TODO: 替换为 person 专属图标 */}
-        <NativeTabs.Trigger.Icon
-          src={require('@/assets/images/tabIcons/home.png')}
-          renderingMode="template"
-        />
-      </NativeTabs.Trigger>
-    </NativeTabs>
-  );
+  return <AppTabs />;
 }
-
-

+ 118 - 122
src/app/(tabs)/analytics.tsx

@@ -1,165 +1,163 @@
-import { PrimaryButton } from '@/components/ui/primary-button';
 import { SectionHeader } from '@/components/ui/section-header';
+import { Toast } from '@ant-design/react-native';
 import { Ionicons } from '@expo/vector-icons';
 import React, { useState } from 'react';
 import { Pressable, ScrollView, Text, View } from 'react-native';
 import { SafeAreaView } from 'react-native-safe-area-context';
 
-/**
- * 征信分析页 — 对应设计稿 #upload + #processing 屏幕
- *
- * 布局结构:
- * 1. 标题 + 简介
- * 2. 选择客户(下拉/输入)
- * 3. 上传区域(点击选择文件,虚线卡片)
- * 4. 解析设置(快速 / 深度)
- * 5. 开始解析按钮
- * 6. 历史解析记录
- */
+type AnalysisMode = 'fast' | 'deep';
 
-interface AnalysisRecord {
+type AnalysisRecord = {
   id: string;
   customerName: string;
   time: string;
   status: '解析中' | '已完成' | '解析失败';
   progress?: number;
   score?: string;
-}
+};
 
-const MOCK_RECORDS: AnalysisRecord[] = [
+const ANALYSIS_RECORDS: AnalysisRecord[] = [
   { id: '1', customerName: '张德发', time: '今天 10:42', status: '已完成', score: 'B+' },
-  { id: '2', customerName: '王五', time: '今天 09:16', status: '解析中', progress: 72 },
+  { id: '2', customerName: '钱进', time: '今天 10:05', status: '解析中', progress: 72 },
   { id: '3', customerName: '李美华', time: '昨天 15:20', status: '已完成', score: 'A' },
   { id: '4', customerName: '赵丽', time: '3天前', status: '解析失败' },
 ];
 
 export default function AnalyticsScreen() {
-  const [analysisMode, setAnalysisMode] = useState<'fast' | 'deep'>('fast');
+  const [analysisMode, setAnalysisMode] = useState<AnalysisMode>('fast');
 
   return (
     <SafeAreaView className="flex-1 bg-surface" edges={['top']}>
       <ScrollView
         className="flex-1"
-        contentContainerClassName="px-6 pt-4 pb-24"
+        contentContainerClassName="px-6 pt-4 pb-28"
         showsVerticalScrollIndicator={false}
       >
-        {/* ── 标题 ── */}
-        <Text className="text-3xl font-extrabold tracking-tight text-on-surface mb-2">
+        <Text className="mb-2 text-4xl font-extrabold tracking-tight text-on-surface">
           征信分析
         </Text>
-        <Text className="text-on-surface-variant text-sm mb-8">
-          上传征信报告,AI 自动解析评估信用状况
+        <Text className="mb-8 text-base leading-7 text-on-surface-variant">
+          先选择客户,再上传征信文件,系统会自动生成评分和建议动作
         </Text>
 
-        {/* ── 选择客户 ── */}
-        <View className="bg-surface-container-lowest rounded-xl p-5 shadow-sm mb-4">
-          <Text className="text-xs font-bold tracking-wider text-outline uppercase mb-3 ml-1">
+        <View className="mb-4 rounded-2xl bg-surface-container-lowest p-5 shadow-sm">
+          <Text className="mb-3 text-xs font-bold uppercase tracking-widest text-outline">
             选择客户
           </Text>
-          <Pressable className="flex-row items-center bg-surface-container-low rounded-lg px-4 py-3.5">
+          <Pressable
+            className="flex-row items-center rounded-2xl bg-surface-container-low px-4 py-4"
+            style={({ pressed }) => ({
+              opacity: pressed ? 0.9 : 1,
+            })}
+          >
             <Ionicons name="person-outline" size={18} color="#737686" />
-            <Text className="flex-1 ml-3 text-on-surface font-medium">
+            <Text className="ml-3 flex-1 text-base font-medium text-on-surface">
               张德发(138****8888)
             </Text>
             <Ionicons name="chevron-down" size={18} color="#c3c6d7" />
           </Pressable>
         </View>
 
-        {/* ── 上传区域 ── */}
-        <View className="bg-surface-container-lowest rounded-xl p-5 shadow-sm mb-4">
-          <Text className="text-xs font-bold tracking-wider text-outline uppercase mb-3 ml-1">
+        <View className="mb-4 rounded-2xl bg-surface-container-lowest p-5 shadow-sm">
+          <Text className="mb-3 text-xs font-bold uppercase tracking-widest text-outline">
             上传征信文件
           </Text>
-          <Pressable className="items-center justify-center py-10 rounded-xl border-2 border-dashed border-outline-variant/40 bg-surface-container-low/50">
-            <View className="w-16 h-16 rounded-full bg-primary-fixed items-center justify-center mb-4">
-              <Ionicons name="cloud-upload-outline" size={32} color="#004ac6" />
+          <Pressable
+            onPress={() => Toast.info('演示页暂未接入真实上传能力')}
+            className="items-center rounded-2xl border-2 border-dashed border-outline-variant/40 bg-surface-container-low/50 px-6 py-10"
+            style={({ pressed }) => ({
+              opacity: pressed ? 0.92 : 1,
+            })}
+          >
+            <View className="mb-4 h-16 w-16 items-center justify-center rounded-full bg-primary-fixed">
+              <Ionicons name="cloud-upload-outline" size={30} color="#004ac6" />
             </View>
-            <Text className="text-on-surface font-semibold mb-1">点击上传征信报告</Text>
-            <Text className="text-on-surface-variant text-xs">
+            <Text className="mb-1 text-lg font-bold text-on-surface">点击上传征信报告</Text>
+            <Text className="text-sm leading-6 text-on-surface-variant">
               支持 PDF、图片格式,最大 20MB
             </Text>
           </Pressable>
         </View>
 
-        {/* ── 解析模式 ── */}
-        <View className="bg-surface-container-lowest rounded-xl p-5 shadow-sm mb-6">
-          <Text className="text-xs font-bold tracking-wider text-outline uppercase mb-3 ml-1">
+        <View className="mb-6 rounded-2xl bg-surface-container-lowest p-5 shadow-sm">
+          <Text className="mb-3 text-xs font-bold uppercase tracking-widest text-outline">
             解析模式
           </Text>
           <View className="flex-row gap-3">
-            <Pressable
-              onPress={() => setAnalysisMode('fast')}
-              className={`flex-1 p-4 rounded-xl items-center ${
-                analysisMode === 'fast'
-                  ? 'bg-primary-container'
-                  : 'bg-surface-container-low'
-              }`}
-            >
-              <Ionicons
-                name="flash-outline"
-                size={24}
-                color={analysisMode === 'fast' ? '#ffffff' : '#737686'}
-              />
-              <Text
-                className={`text-sm font-bold mt-2 ${
-                  analysisMode === 'fast' ? 'text-on-primary' : 'text-on-surface'
-                }`}
-              >
-                快速解析
-              </Text>
-              <Text
-                className={`text-[10px] mt-1 ${
-                  analysisMode === 'fast' ? 'text-on-primary/70' : 'text-on-surface-variant'
-                }`}
-              >
-                约30秒,关键指标
-              </Text>
-            </Pressable>
-            <Pressable
-              onPress={() => setAnalysisMode('deep')}
-              className={`flex-1 p-4 rounded-xl items-center ${
-                analysisMode === 'deep'
-                  ? 'bg-primary-container'
-                  : 'bg-surface-container-low'
-              }`}
-            >
-              <Ionicons
-                name="layers-outline"
-                size={24}
-                color={analysisMode === 'deep' ? '#ffffff' : '#737686'}
-              />
-              <Text
-                className={`text-sm font-bold mt-2 ${
-                  analysisMode === 'deep' ? 'text-on-primary' : 'text-on-surface'
-                }`}
-              >
-                深度分析
-              </Text>
-              <Text
-                className={`text-[10px] mt-1 ${
-                  analysisMode === 'deep' ? 'text-on-primary/70' : 'text-on-surface-variant'
-                }`}
-              >
-                约90秒,全面报告
-              </Text>
-            </Pressable>
+            {[
+              {
+                key: 'fast' as const,
+                title: '快速解析',
+                description: '约 30 秒,先看核心指标',
+                icon: 'flash-outline' as const,
+              },
+              {
+                key: 'deep' as const,
+                title: '深度分析',
+                description: '约 90 秒,生成完整建议',
+                icon: 'layers-outline' as const,
+              },
+            ].map((item) => {
+              const active = analysisMode === item.key;
+              return (
+                <Pressable
+                  key={item.key}
+                  onPress={() => setAnalysisMode(item.key)}
+                  className={`flex-1 rounded-2xl px-4 py-5 ${
+                    active ? 'bg-primary-container' : 'bg-surface-container-low'
+                  }`}
+                  style={({ pressed }) => ({
+                    opacity: pressed ? 0.9 : 1,
+                  })}
+                >
+                  <Ionicons
+                    name={item.icon}
+                    size={24}
+                    color={active ? '#ffffff' : '#737686'}
+                  />
+                  <Text
+                    className={`mt-4 text-lg font-bold ${
+                      active ? 'text-on-primary' : 'text-on-surface'
+                    }`}
+                  >
+                    {item.title}
+                  </Text>
+                  <Text
+                    className={`mt-2 text-sm leading-6 ${
+                      active ? 'text-on-primary/80' : 'text-on-surface-variant'
+                    }`}
+                  >
+                    {item.description}
+                  </Text>
+                </Pressable>
+              );
+            })}
           </View>
         </View>
 
-        {/* ── 开始解析按钮 ── */}
-        <PrimaryButton title="开始解析" className="mb-10" />
+        <Pressable
+          onPress={() => Toast.success('解析任务已加入队列')}
+          className="mb-10 items-center rounded-2xl bg-primary-container py-4 shadow-lg"
+          style={({ pressed }) => ({
+            opacity: pressed ? 0.88 : 1,
+            transform: [{ scale: pressed ? 0.985 : 1 }],
+          })}
+        >
+          <Text className="text-lg font-bold text-on-primary">开始解析</Text>
+        </Pressable>
 
-        {/* ── 历史解析记录 ── */}
         <SectionHeader title="解析记录" actionText="查看全部" />
-        <View className="gap-3">
-          {MOCK_RECORDS.map((record) => (
+        <View className="gap-4">
+          {ANALYSIS_RECORDS.map((record) => (
             <Pressable
               key={record.id}
-              className="bg-surface-container-lowest p-4 rounded-xl shadow-sm flex-row items-center active:bg-surface-container-low"
+              className="flex-row items-center rounded-2xl bg-surface-container-lowest px-4 py-4 shadow-sm"
+              style={({ pressed }) => ({
+                opacity: pressed ? 0.93 : 1,
+              })}
             >
-              {/* 左侧图标 */}
               <View
-                className={`w-10 h-10 rounded-full items-center justify-center mr-4 ${
+                className={`mr-4 h-12 w-12 items-center justify-center rounded-full ${
                   record.status === '已完成'
                     ? 'bg-green-50'
                     : record.status === '解析中'
@@ -186,44 +184,42 @@ export default function AnalyticsScreen() {
                 />
               </View>
 
-              {/* 中间内容 */}
               <View className="flex-1">
-                <View className="flex-row items-center justify-between mb-1">
-                  <Text className="font-bold text-on-surface">{record.customerName}</Text>
-                  <Text className="text-[10px] text-on-surface-variant">{record.time}</Text>
+                <View className="mb-1 flex-row items-center justify-between gap-3">
+                  <Text className="text-lg font-bold text-on-surface">
+                    {record.customerName}
+                  </Text>
+                  <Text className="text-xs text-on-surface-variant">{record.time}</Text>
                 </View>
+
                 {record.status === '解析中' && record.progress != null ? (
                   <View>
-                    <View className="flex-row items-center justify-between mb-1">
-                      <Text className="text-xs text-on-surface-variant">解析中...</Text>
-                      <Text className="text-xs text-primary font-bold">{record.progress}%</Text>
+                    <View className="mb-2 flex-row items-center justify-between">
+                      <Text className="text-sm text-on-surface-variant">正在解析征信数据...</Text>
+                      <Text className="text-sm font-bold text-primary">
+                        {record.progress}%
+                      </Text>
                     </View>
-                    <View className="h-1.5 w-full bg-surface-container rounded-full overflow-hidden">
+                    <View className="h-1.5 rounded-full bg-surface-container">
                       <View
-                        className="h-full bg-primary-container rounded-full"
+                        className="h-full rounded-full bg-primary-container"
                         style={{ width: `${record.progress}%` }}
                       />
                     </View>
                   </View>
                 ) : record.status === '已完成' ? (
                   <View className="flex-row items-center gap-2">
-                    <Text className="text-xs text-on-surface-variant">征信评分</Text>
-                    <View className="bg-primary-fixed px-2 py-0.5 rounded-full">
-                      <Text className="text-[10px] font-bold text-primary">{record.score}</Text>
+                    <Text className="text-sm text-on-surface-variant">征信评分</Text>
+                    <View className="rounded-full bg-primary-fixed px-2.5 py-1">
+                      <Text className="text-xs font-bold text-primary">{record.score}</Text>
                     </View>
                   </View>
                 ) : (
-                  <Text className="text-xs text-error">解析失败,请重试</Text>
+                  <Text className="text-sm text-error">解析失败,请重新上传文件后重试</Text>
                 )}
               </View>
 
-              {/* 右侧箭头 */}
-              <Ionicons
-                name="chevron-forward"
-                size={18}
-                color="#c3c6d7"
-                style={{ marginLeft: 8 }}
-              />
+              <Ionicons name="chevron-forward" size={18} color="#c3c6d7" />
             </Pressable>
           ))}
         </View>

+ 166 - 131
src/app/(tabs)/customer.tsx

@@ -1,32 +1,25 @@
 import { StatusBadge } from '@/components/ui/status-badge';
 import { Ionicons } from '@expo/vector-icons';
 import React, { useState } from 'react';
-import { FlatList, Pressable, ScrollView, Text, TextInput, View } from 'react-native';
+import { Pressable, ScrollView, Text, TextInput, View } from 'react-native';
 import { SafeAreaView } from 'react-native-safe-area-context';
 
-/**
- * 客户管理页 — 对应设计稿 #customers 屏幕
- *
- * 布局结构:
- * 1. 顶部搜索栏(filled 风格输入框)
- * 2. 状态筛选 Tag 行(横向滚动)
- * 3. 客户卡片列表(name / phone / status / 操作按钮)
- * 4. 底部新增客户 FAB
- */
+type CustomerStatus = '全部' | '待上传' | '解析中' | '已分析' | '已匹配' | '审核中';
 
-type CustomerStatus = '全部' | '待上传' | '已分析' | '已匹配' | '审核中';
-
-interface Customer {
+type Customer = {
   id: string;
   name: string;
   phone: string;
   loanType: string;
-  status: CustomerStatus;
+  status: Exclude<CustomerStatus, '全部'>;
   score?: string;
-  lastUpdate: string;
-}
+  note: string;
+  updatedAt: string;
+};
 
-const MOCK_CUSTOMERS: Customer[] = [
+const FILTERS: CustomerStatus[] = ['全部', '待上传', '解析中', '已分析', '已匹配', '审核中'];
+
+const CUSTOMERS: Customer[] = [
   {
     id: '1',
     name: '张德发',
@@ -34,7 +27,8 @@ const MOCK_CUSTOMERS: Customer[] = [
     loanType: '经营贷',
     status: '审核中',
     score: 'B+',
-    lastUpdate: '今天 10:42',
+    note: '申请材料已补齐,等待风控初审',
+    updatedAt: '今天 10:42',
   },
   {
     id: '2',
@@ -43,7 +37,8 @@ const MOCK_CUSTOMERS: Customer[] = [
     loanType: '消费贷',
     status: '已匹配',
     score: 'A',
-    lastUpdate: '昨天 15:20',
+    note: '已匹配 3 个可推荐产品,待沟通方案',
+    updatedAt: '今天 09:18',
   },
   {
     id: '3',
@@ -52,7 +47,8 @@ const MOCK_CUSTOMERS: Customer[] = [
     loanType: '房抵贷',
     status: '已分析',
     score: 'B',
-    lastUpdate: '3天前',
+    note: '征信报告已生成,建议先推进抵押类产品',
+    updatedAt: '昨天 16:20',
   },
   {
     id: '4',
@@ -60,169 +56,208 @@ const MOCK_CUSTOMERS: Customer[] = [
     phone: '136****1111',
     loanType: '消费贷',
     status: '待上传',
-    lastUpdate: '5天前',
+    note: '客户资料已建档,待上传征信文件',
+    updatedAt: '2天前',
   },
   {
     id: '5',
     name: '钱进',
     phone: '135****9999',
     loanType: '经营贷',
-    status: '已匹配',
-    score: 'A-',
-    lastUpdate: '1周前',
+    status: '解析中',
+    note: '系统正在解析征信数据,预计 30-90 秒完成',
+    updatedAt: '刚刚',
   },
 ];
 
-const FILTERS: CustomerStatus[] = ['全部', '待上传', '已分析', '已匹配', '审核中'];
-
-const statusBadgeVariant = (s: CustomerStatus) => {
-  switch (s) {
+function getBadgeVariant(status: Customer['status']) {
+  switch (status) {
     case '待上传':
-      return 'error';
+      return 'error' as const;
+    case '解析中':
+    case '审核中':
+      return 'secondary' as const;
     case '已分析':
-      return 'primary';
+      return 'primary' as const;
     case '已匹配':
-      return 'success';
-    case '审核中':
-      return 'secondary';
+      return 'tertiary' as const;
     default:
-      return 'secondary';
+      return 'secondary' as const;
   }
-};
+}
+
+function getPrimaryAction(status: Customer['status']) {
+  switch (status) {
+    case '待上传':
+      return '上传征信';
+    case '解析中':
+      return '查看进度';
+    default:
+      return '查看报告';
+  }
+}
 
 export default function CustomerScreen() {
   const [search, setSearch] = useState('');
   const [activeFilter, setActiveFilter] = useState<CustomerStatus>('全部');
 
-  const filtered = MOCK_CUSTOMERS.filter((c) => {
+  const filteredCustomers = CUSTOMERS.filter((item) => {
     const matchSearch =
-      !search || c.name.includes(search) || c.phone.includes(search);
-    const matchFilter = activeFilter === '全部' || c.status === activeFilter;
+      search.trim().length === 0 ||
+      item.name.includes(search) ||
+      item.phone.includes(search);
+    const matchFilter = activeFilter === '全部' || item.status === activeFilter;
     return matchSearch && matchFilter;
   });
 
   return (
     <SafeAreaView className="flex-1 bg-surface" edges={['top']}>
-      {/* ── 顶部标题 ── */}
-      <View className="px-6 pt-4 pb-2">
-        <Text className="text-3xl font-extrabold tracking-tight text-on-surface mb-4">
+      <ScrollView
+        className="flex-1"
+        contentContainerClassName="px-6 pt-4 pb-28"
+        keyboardShouldPersistTaps="handled"
+        showsVerticalScrollIndicator={false}
+      >
+        <Text className="mb-2 text-4xl font-extrabold tracking-tight text-on-surface">
           客户
         </Text>
+        <Text className="mb-6 text-base leading-7 text-on-surface-variant">
+          统一跟进客户资料、征信进度和产品匹配状态
+        </Text>
 
-        {/* 搜索栏 — filled 风格 */}
-        <View className="flex-row items-center bg-surface-container-low rounded-lg px-4 py-3 mb-4">
-          <Ionicons name="search-outline" size={18} color="#737686" />
+        <View className="mb-4 flex-row items-center rounded-2xl bg-surface-container-low px-4 py-3.5">
+          <Ionicons name="search-outline" size={20} color="#737686" />
           <TextInput
-            className="flex-1 ml-3 text-on-surface text-sm font-medium p-0"
-            placeholder="搜索客户姓名 / 手机号"
-            placeholderTextColor="#737686"
             value={search}
             onChangeText={setSearch}
+            placeholder="搜索客户姓名 / 手机号"
+            placeholderTextColor="#9ca3af"
+            className="ml-3 flex-1 p-0 text-base text-on-surface"
           />
-          {search.length > 0 && (
-            <Pressable onPress={() => setSearch('')} hitSlop={8}>
-              <Ionicons name="close-circle" size={18} color="#c3c6d7" />
+          {search.length > 0 ? (
+            <Pressable hitSlop={8} onPress={() => setSearch('')}>
+              <Ionicons name="close-circle" size={20} color="#c3c6d7" />
             </Pressable>
-          )}
+          ) : null}
         </View>
 
-        {/* 筛选 Tag 行 */}
         <ScrollView
           horizontal
           showsHorizontalScrollIndicator={false}
           contentContainerClassName="gap-2 pb-2"
+          className="mb-6"
         >
-          {FILTERS.map((f) => (
-            <Pressable
-              key={f}
-              onPress={() => setActiveFilter(f)}
-              className={`px-4 py-2 rounded-full ${
-                activeFilter === f
-                  ? 'bg-primary-container'
-                  : 'bg-surface-container-lowest'
-              }`}
-            >
-              <Text
-                className={`text-xs font-bold ${
-                  activeFilter === f ? 'text-on-primary' : 'text-on-surface-variant'
+          {FILTERS.map((filter) => {
+            const active = activeFilter === filter;
+            return (
+              <Pressable
+                key={filter}
+                onPress={() => setActiveFilter(filter)}
+                className={`rounded-full px-4 py-2.5 ${
+                  active ? 'bg-primary-container' : 'bg-surface-container-lowest'
                 }`}
+                style={({ pressed }) => ({
+                  opacity: pressed ? 0.84 : 1,
+                })}
               >
-                {f}
-              </Text>
-            </Pressable>
-          ))}
+                <Text
+                  className={`text-sm font-bold ${
+                    active ? 'text-on-primary' : 'text-on-surface-variant'
+                  }`}
+                >
+                  {filter}
+                </Text>
+              </Pressable>
+            );
+          })}
         </ScrollView>
-      </View>
 
-      {/* ── 客户列表 ── */}
-      <FlatList
-        data={filtered}
-        keyExtractor={(item) => item.id}
-        contentContainerClassName="px-6 pt-2 pb-24 gap-3"
-        showsVerticalScrollIndicator={false}
-        ListEmptyComponent={
-          <View className="items-center pt-20">
-            <Ionicons name="people-outline" size={48} color="#c3c6d7" />
-            <Text className="text-on-surface-variant text-sm mt-4">暂无匹配客户</Text>
-          </View>
-        }
-        renderItem={({ item }) => (
-          <Pressable className="bg-surface-container-lowest p-5 rounded-xl shadow-sm active:bg-surface-container-low">
-            {/* 第一行:姓名 + 手机 */}
-            <View className="flex-row justify-between items-start mb-2">
-              <View className="flex-row items-center gap-3">
-                <View className="w-10 h-10 rounded-full bg-primary-fixed items-center justify-center">
-                  <Text className="text-primary font-bold">{item.name[0]}</Text>
-                </View>
-                <View>
-                  <Text className="font-bold text-on-surface text-base">{item.name}</Text>
-                  <Text className="text-xs text-on-surface-variant">{item.phone}</Text>
-                </View>
-              </View>
-              <StatusBadge text={item.status} variant={statusBadgeVariant(item.status)} />
+        <View className="gap-4">
+          {filteredCustomers.length === 0 ? (
+            <View className="items-center rounded-2xl bg-surface-container-lowest px-6 py-16 shadow-sm">
+              <Ionicons name="people-outline" size={44} color="#c3c6d7" />
+              <Text className="mt-4 text-base text-on-surface-variant">暂无匹配客户</Text>
             </View>
+          ) : (
+            filteredCustomers.map((item) => (
+              <Pressable
+                key={item.id}
+                className="rounded-2xl bg-surface-container-lowest px-5 py-5 shadow-sm"
+                style={({ pressed }) => ({
+                  opacity: pressed ? 0.93 : 1,
+                  transform: [{ scale: pressed ? 0.995 : 1 }],
+                })}
+              >
+                <View className="mb-4 flex-row items-start justify-between gap-3">
+                  <View className="flex-1 flex-row items-center gap-3">
+                    <View className="h-12 w-12 items-center justify-center rounded-full bg-primary-fixed">
+                      <Text className="text-lg font-bold text-primary">{item.name[0]}</Text>
+                    </View>
+                    <View className="flex-1">
+                      <Text className="text-xl font-bold text-on-surface">{item.name}</Text>
+                      <Text className="mt-1 text-sm text-on-surface-variant">
+                        {item.phone}
+                      </Text>
+                    </View>
+                  </View>
+                  <StatusBadge
+                    text={item.status}
+                    variant={getBadgeVariant(item.status)}
+                  />
+                </View>
 
-            {/* 第二行:贷款类型 + 评分 + 更新时间 */}
-            <View className="flex-row items-center gap-4 mt-2 ml-13">
-              <View className="flex-row items-center gap-1">
-                <Ionicons name="document-text-outline" size={14} color="#737686" />
-                <Text className="text-xs text-on-surface-variant">{item.loanType}</Text>
-              </View>
-              {item.score && (
-                <View className="flex-row items-center gap-1">
-                  <Ionicons name="analytics-outline" size={14} color="#737686" />
-                  <Text className="text-xs text-on-surface-variant">评分 {item.score}</Text>
+                <Text className="mb-3 text-sm leading-6 text-on-surface-variant">
+                  {item.note}
+                </Text>
+
+                <View className="mb-4 flex-row flex-wrap items-center gap-3">
+                  <View className="flex-row items-center gap-1">
+                    <Ionicons name="document-text-outline" size={14} color="#737686" />
+                    <Text className="text-xs text-on-surface-variant">{item.loanType}</Text>
+                  </View>
+                  {item.score ? (
+                    <View className="flex-row items-center gap-1">
+                      <Ionicons name="analytics-outline" size={14} color="#737686" />
+                      <Text className="text-xs text-on-surface-variant">
+                        评分 {item.score}
+                      </Text>
+                    </View>
+                  ) : null}
+                  <Text className="ml-auto text-xs text-outline">{item.updatedAt}</Text>
                 </View>
-              )}
-              <Text className="text-[10px] text-outline ml-auto">{item.lastUpdate}</Text>
-            </View>
 
-            {/* 第三行:操作按钮 */}
-            <View className="flex-row gap-3 mt-4">
-              {item.status === '待上传' ? (
-                <Pressable className="flex-1 py-2.5 bg-primary-container rounded-lg items-center">
-                  <Text className="text-on-primary text-xs font-bold">上传征信</Text>
-                </Pressable>
-              ) : (
-                <Pressable className="flex-1 py-2.5 bg-primary-container rounded-lg items-center">
-                  <Text className="text-on-primary text-xs font-bold">查看报告</Text>
-                </Pressable>
-              )}
-              <Pressable className="flex-1 py-2.5 bg-surface-container-high rounded-lg items-center">
-                <Text className="text-on-surface text-xs font-semibold">编辑资料</Text>
+                <View className="flex-row gap-3">
+                  <Pressable
+                    className="flex-1 items-center rounded-xl bg-primary-container py-3"
+                    style={({ pressed }) => ({
+                      opacity: pressed ? 0.88 : 1,
+                    })}
+                  >
+                    <Text className="text-sm font-bold text-on-primary">
+                      {getPrimaryAction(item.status)}
+                    </Text>
+                  </Pressable>
+                  <Pressable
+                    className="flex-1 items-center rounded-xl bg-surface-container-high py-3"
+                    style={({ pressed }) => ({
+                      opacity: pressed ? 0.88 : 1,
+                    })}
+                  >
+                    <Text className="text-sm font-semibold text-on-surface">编辑资料</Text>
+                  </Pressable>
+                </View>
               </Pressable>
-            </View>
-          </Pressable>
-        )}
-      />
+            ))
+          )}
+        </View>
+      </ScrollView>
 
-      {/* ── FAB 新增客户 ── */}
-      <View className="absolute bottom-6 right-6">
+      <View className="absolute bottom-8 right-6">
         <Pressable
-          className="w-14 h-14 rounded-full bg-primary-container items-center justify-center shadow-xl"
+          className="h-16 w-16 items-center justify-center rounded-full bg-primary-container shadow-xl"
           style={({ pressed }) => ({
-            opacity: pressed ? 0.8 : 1,
-            transform: [{ scale: pressed ? 0.9 : 1 }],
+            opacity: pressed ? 0.88 : 1,
+            transform: [{ scale: pressed ? 0.94 : 1 }],
           })}
         >
           <Ionicons name="person-add" size={24} color="#ffffff" />

+ 212 - 93
src/app/(tabs)/index.tsx

@@ -1,150 +1,269 @@
-import { ActionIconButton } from '@/components/ui/action-icon-button';
-import { ActivityCard } from '@/components/ui/activity-card';
 import { SectionHeader } from '@/components/ui/section-header';
+import { StatusBadge } from '@/components/ui/status-badge';
 import { Ionicons } from '@expo/vector-icons';
 import React from 'react';
 import { Pressable, ScrollView, Text, View } from 'react-native';
 import { SafeAreaView } from 'react-native-safe-area-context';
 
-/**
- * 首页 — 还原设计稿 home/code.html
- *
- * 布局结构(自上而下):
- * 1. 顶部导航栏(头像 + 标题 + 通知铃铛)
- * 2. 问候语 + 日期
- * 3. Bento 式统计卡片(待处理·大卡 + 进行中/成功撮合·双小卡)
- * 4. 快捷操作四宫格
- * 5. 最近动态列表
- * 6. 行业洞察 Banner
- * 7. FAB 悬浮按钮
- */
+type QuickAction = {
+  icon: keyof typeof Ionicons.glyphMap;
+  label: string;
+};
+
+type ActivityItem = {
+  id: string;
+  name: string;
+  loanType: string;
+  time: string;
+  description: string;
+  badgeText: string;
+  badgeVariant: 'primary' | 'secondary' | 'tertiary';
+  avatarBackground: string;
+  avatarColor: string;
+};
+
+const QUICK_ACTIONS: QuickAction[] = [
+  { icon: 'person-add-outline', label: '新增客户' },
+  { icon: 'cloud-upload-outline', label: '上传征信' },
+  { icon: 'calculator-outline', label: '额度测算' },
+  { icon: 'document-text-outline', label: '面谈记录' },
+];
+
+const RECENT_ACTIVITIES: ActivityItem[] = [
+  {
+    id: '1',
+    name: '张德发',
+    loanType: '经营贷',
+    time: '10分钟前',
+    description: '申请材料已上传,等待风控初审',
+    badgeText: '审核中',
+    badgeVariant: 'secondary',
+    avatarBackground: '#0f172a',
+    avatarColor: '#ffffff',
+  },
+  {
+    id: '2',
+    name: '李美华',
+    loanType: '消费贷',
+    time: '2小时前',
+    description: '系统匹配到 3 个符合条件的银行产品',
+    badgeText: '已匹配',
+    badgeVariant: 'tertiary',
+    avatarBackground: '#ccfbf1',
+    avatarColor: '#0f172a',
+  },
+  {
+    id: '3',
+    name: '王大锤',
+    loanType: '房抵贷',
+    time: '1天前',
+    description: '银行面谈已完成,正在落实抵押登记',
+    badgeText: '待抵押',
+    badgeVariant: 'primary',
+    avatarBackground: '#dcfce7',
+    avatarColor: '#0f172a',
+  },
+];
+
+const CHART_BARS = [22, 36, 44, 58, 34, 64, 48, 72, 52, 40];
+
+function formatToday() {
+  const date = new Date();
+  const weekdays = [
+    '星期日',
+    '星期一',
+    '星期二',
+    '星期三',
+    '星期四',
+    '星期五',
+    '星期六',
+  ];
+
+  return `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日 ${weekdays[date.getDay()]}`;
+}
+
+function getGreeting() {
+  const hour = new Date().getHours();
+  if (hour < 12) {
+    return '早上好';
+  }
+  if (hour < 18) {
+    return '下午好';
+  }
+  return '晚上好';
+}
+
 export default function HomeScreen() {
   return (
     <SafeAreaView className="flex-1 bg-surface" edges={['top']}>
-      {/* ── 顶部导航 ── */}
-      <View className="flex-row items-center justify-between px-6 h-14">
+      <View className="h-16 flex-row items-center justify-between border-b border-outline-variant/20 bg-surface-container-lowest px-7">
         <View className="flex-row items-center gap-3">
-          <View className="w-10 h-10 rounded-full bg-primary-fixed items-center justify-center overflow-hidden">
-            <Ionicons name="person" size={20} color="#004ac6" />
+          <View className="h-10 w-10 items-center justify-center rounded-full bg-slate-900">
+            <Ionicons name="person" size={18} color="#ffffff" />
           </View>
-          <Text className="text-lg font-bold text-on-surface tracking-tight">贷款助手</Text>
+          <Text className="text-2xl font-extrabold tracking-tight text-on-surface">
+            贷款助手
+          </Text>
         </View>
         <Pressable hitSlop={8}>
-          <Ionicons name="notifications-outline" size={24} color="#737686" />
+          <Ionicons name="notifications-outline" size={24} color="#94a3b8" />
         </Pressable>
       </View>
 
       <ScrollView
         className="flex-1"
-        contentContainerClassName="px-6 pt-4 pb-24"
+        contentContainerClassName="px-7 pt-6 pb-28"
         showsVerticalScrollIndicator={false}
       >
-        {/* ── 问候语 ── */}
         <View className="mb-8">
-          <Text className="text-on-surface-variant text-sm tracking-wider uppercase mb-1">
-            2024年5月22日 星期三
+          <Text className="mb-2 text-base tracking-wide text-on-surface-variant">
+            {formatToday()}
           </Text>
-          <Text className="text-3xl font-extrabold tracking-tight text-on-surface">
-            早上好,王经理
+          <Text className="text-4xl font-extrabold tracking-tight text-on-surface">
+            {getGreeting()},王经理
           </Text>
         </View>
 
-        {/* ── Bento 统计卡片 ── */}
-        <View className="gap-4 mb-8">
-          {/* 大卡:待处理申请 */}
-          <View className="bg-primary-container p-6 rounded-xl shadow-lg">
-            <View className="flex-row justify-between items-start mb-4">
-              <View className="bg-white/20 p-2 rounded-lg">
-                <Ionicons name="time-outline" size={24} color="#ffffff" />
+        <View className="mb-10 gap-4">
+          <View className="rounded-2xl bg-primary-container px-6 py-6 shadow-lg">
+            <View className="mb-6 flex-row items-start justify-between">
+              <View className="h-12 w-12 items-center justify-center rounded-2xl bg-white/20">
+                <Ionicons name="briefcase-outline" size={22} color="#ffffff" />
               </View>
-              <View className="bg-white/20 px-2 py-1 rounded-full">
-                <Text className="text-xs text-on-primary font-bold">+12%</Text>
+              <View className="rounded-full bg-white/20 px-3 py-1">
+                <Text className="text-sm font-bold text-on-primary">+12%</Text>
               </View>
             </View>
-            <Text className="text-on-primary/80 text-sm mb-1">待处理申请</Text>
-            <Text className="text-4xl font-extrabold text-on-primary">24</Text>
+            <Text className="mb-2 text-base text-on-primary/80">待处理申请</Text>
+            <Text className="text-6xl font-extrabold text-on-primary">24</Text>
           </View>
 
-          {/* 双小卡行 */}
           <View className="flex-row gap-4">
-            <View className="flex-1 bg-surface-container-lowest p-6 rounded-xl shadow-sm">
-              <Text className="text-on-surface-variant text-sm mb-1">进行中</Text>
-              <Text className="text-2xl font-bold text-on-surface">156</Text>
-              <View className="mt-4 h-1 w-full bg-surface-container rounded-full overflow-hidden">
-                <View className="h-full bg-secondary w-[65%] rounded-full" />
+            <View className="flex-1 rounded-2xl bg-surface-container-lowest px-5 py-6 shadow-sm">
+              <Text className="mb-2 text-base text-on-surface-variant">进行中</Text>
+              <Text className="text-5xl font-bold text-on-surface">156</Text>
+              <View className="mt-5 h-1.5 rounded-full bg-surface-container">
+                <View
+                  className="h-full rounded-full bg-secondary"
+                  style={{ width: '65%' }}
+                />
               </View>
             </View>
-            <View className="flex-1 bg-surface-container-lowest p-6 rounded-xl shadow-sm">
-              <Text className="text-on-surface-variant text-sm mb-1">成功撮合</Text>
-              <Text className="text-2xl font-bold text-on-surface">1,280</Text>
-              <View className="mt-4 h-1 w-full bg-surface-container rounded-full overflow-hidden">
-                <View className="h-full bg-tertiary-fixed-dim w-[88%] rounded-full" />
+            <View className="flex-1 rounded-2xl bg-surface-container-lowest px-5 py-6 shadow-sm">
+              <Text className="mb-2 text-base text-on-surface-variant">成功撮合</Text>
+              <Text className="text-5xl font-bold text-on-surface">1,280</Text>
+              <View className="mt-5 h-1.5 rounded-full bg-surface-container">
+                <View
+                  className="h-full rounded-full bg-tertiary-container"
+                  style={{ width: '88%' }}
+                />
               </View>
             </View>
           </View>
         </View>
 
-        {/* ── 快捷操作 ── */}
         <View className="mb-10">
           <SectionHeader title="快捷操作" />
-          <View className="flex-row justify-between">
-            <ActionIconButton icon="person-add-outline" label="新增客户" />
-            <ActionIconButton icon="cloud-upload-outline" label="上传征信" />
-            <ActionIconButton icon="calculator-outline" label="额度测算" />
-            <ActionIconButton icon="document-text-outline" label="面谈记录" />
+          <View className="flex-row items-start justify-between">
+            {QUICK_ACTIONS.map((action) => (
+              <Pressable
+                key={action.label}
+                className="items-center"
+                style={({ pressed }) => ({
+                  opacity: pressed ? 0.84 : 1,
+                  transform: [{ scale: pressed ? 0.96 : 1 }],
+                })}
+              >
+                <View className="mb-3 h-16 w-16 items-center justify-center rounded-2xl bg-surface-container-high">
+                  <Ionicons name={action.icon} size={26} color="#004ac6" />
+                </View>
+                <Text className="text-sm font-medium text-on-surface-variant">
+                  {action.label}
+                </Text>
+              </Pressable>
+            ))}
           </View>
         </View>
 
-        {/* ── 最近动态 ── */}
-        <View className="mb-8">
+        <View className="mb-10">
           <SectionHeader title="最近动态" actionText="查看全部" />
-          <View className="gap-3">
-            <ActivityCard
-              name="张德发"
-              loanType="经营贷"
-              time="10分钟前"
-              description="申请材料已上传,等待风控初审"
-              badgeText="审核中"
-              badgeVariant="secondary"
-            />
-            <ActivityCard
-              name="李美华"
-              loanType="消费贷"
-              time="2小时前"
-              description="系统匹配到 3 个符合条件的银行产品"
-              badgeText="已匹配"
-              badgeVariant="tertiary"
-            />
-            <ActivityCard
-              name="王大锤"
-              loanType="房抵贷"
-              time="1天前"
-              description="银行面谈已完成,正在落实抵押登记"
-              badgeText="待抵押"
-              badgeVariant="primary"
-            />
+          <View className="gap-4">
+            {RECENT_ACTIVITIES.map((item) => (
+              <Pressable
+                key={item.id}
+                className="flex-row items-center gap-4 rounded-2xl bg-surface-container-lowest px-4 py-4 shadow-sm"
+                style={({ pressed }) => ({
+                  opacity: pressed ? 0.92 : 1,
+                  transform: [{ scale: pressed ? 0.99 : 1 }],
+                })}
+              >
+                <View
+                  className="h-14 w-14 items-center justify-center rounded-full"
+                  style={{ backgroundColor: item.avatarBackground }}
+                >
+                  <Ionicons name="person" size={20} color={item.avatarColor} />
+                </View>
+                <View className="flex-1">
+                  <View className="mb-1 flex-row items-start justify-between gap-3">
+                    <Text className="flex-1 text-2xl font-bold text-on-surface">
+                      {item.name} - {item.loanType}
+                    </Text>
+                    <Text className="text-xs text-on-surface-variant">{item.time}</Text>
+                  </View>
+                  <Text
+                    className="text-sm leading-6 text-on-surface-variant"
+                    numberOfLines={1}
+                  >
+                    {item.description}
+                  </Text>
+                </View>
+                <StatusBadge text={item.badgeText} variant={item.badgeVariant} />
+              </Pressable>
+            ))}
           </View>
         </View>
 
-        {/* ── 行业洞察 Banner ── */}
-        <View className="rounded-xl overflow-hidden bg-inverse-surface h-40 mb-6">
-          <View className="flex-1 p-8 justify-end z-10">
-            <Text className="text-on-primary text-xl font-bold mb-2">行业洞察</Text>
-            <Text className="text-inverse-on-surface/70 text-sm mb-4">
-              本周 LPR 利率下调,建议优先推荐...
+        <View className="mb-4 h-48 overflow-hidden rounded-2xl bg-slate-950">
+          <View className="absolute inset-0 bg-primary/10" />
+          <View className="absolute bottom-0 right-0 h-full w-44 flex-row items-end gap-1 px-6 pb-6">
+            {CHART_BARS.map((height, index) => (
+              <View
+                key={`${height}-${index}`}
+                className="w-2 rounded-full bg-primary-container/40"
+                style={{ height }}
+              />
+            ))}
+          </View>
+          <View className="absolute inset-y-0 right-0 w-1/2 bg-primary/5" />
+          <View className="relative flex-1 justify-end px-7 py-7">
+            <Text className="mb-3 text-4xl font-extrabold text-on-primary">
+              行业洞察
+            </Text>
+            <Text
+              className="text-base leading-7 text-white/75"
+              style={{ maxWidth: 190 }}
+            >
+              本周 LPR 利率下调,建议优先推荐对流水稳定要求更高的产品。
             </Text>
-            <Pressable className="bg-surface-container-lowest px-4 py-2 rounded-lg self-start">
-              <Text className="text-inverse-surface text-xs font-bold">立即了解</Text>
+            <Pressable
+              className="mt-5 self-start rounded-full bg-surface-container-lowest px-5 py-3"
+              style={({ pressed }) => ({
+                opacity: pressed ? 0.86 : 1,
+              })}
+            >
+              <Text className="text-sm font-bold text-inverse-surface">立即了解</Text>
             </Pressable>
           </View>
         </View>
       </ScrollView>
 
-      {/* ── FAB 悬浮按钮 ── */}
-      <View className="absolute bottom-6 right-6">
+      <View className="absolute bottom-8 right-7">
         <Pressable
-          className="w-14 h-14 rounded-full bg-primary-container items-center justify-center shadow-xl"
-          style={({ pressed }) => ({ opacity: pressed ? 0.8 : 1, transform: [{ scale: pressed ? 0.9 : 1 }] })}
+          className="h-16 w-16 items-center justify-center rounded-full bg-primary-container shadow-xl"
+          style={({ pressed }) => ({
+            opacity: pressed ? 0.86 : 1,
+            transform: [{ scale: pressed ? 0.94 : 1 }],
+          })}
         >
           <Ionicons name="add" size={28} color="#ffffff" />
         </Pressable>

+ 55 - 55
src/app/(tabs)/profile.tsx

@@ -1,86 +1,84 @@
 import { MenuRow } from '@/components/ui/menu-row';
+import { useAuthContext } from '@/utils/auth';
 import { Ionicons } from '@expo/vector-icons';
+import { router } from 'expo-router';
 import React from 'react';
-import { Pressable, ScrollView, Text, View } from 'react-native';
+import { Alert, Pressable, ScrollView, Text, View } from 'react-native';
 import { SafeAreaView } from 'react-native-safe-area-context';
 
-/**
- * 个人中心 — 还原设计稿 profile/code.html
- *
- * 布局结构:
- * 1. 顶部导航栏
- * 2. 头像 + 姓名 + 职位
- * 3. 三栏统计(已完成 / 成功率 / 本月收入)
- * 4. 菜单分组(业务 / 系统 / 退出登录)
- */
 export default function ProfileScreen() {
+  const { setToken } = useAuthContext();
+
+  const handleLogout = () => {
+    Alert.alert('退出登录', '确定要退出当前账号吗?', [
+      { text: '取消', style: 'cancel' },
+      {
+        text: '退出',
+        style: 'destructive',
+        onPress: () => {
+          setToken(null);
+          router.replace('/sign-in');
+        },
+      },
+    ]);
+  };
+
   return (
     <SafeAreaView className="flex-1 bg-surface" edges={['top']}>
-      {/* ── 顶部导航 ── */}
-      <View className="flex-row items-center justify-between px-6 h-14">
+      <View className="h-16 flex-row items-center justify-between border-b border-outline-variant/20 bg-surface-container-lowest px-7">
         <View className="flex-row items-center gap-3">
-          <View className="w-8 h-8 rounded-full bg-primary-fixed items-center justify-center overflow-hidden">
-            <Ionicons name="person" size={16} color="#004ac6" />
+          <View className="h-10 w-10 items-center justify-center rounded-full bg-slate-900">
+            <Ionicons name="person" size={18} color="#ffffff" />
           </View>
-          <Text className="text-lg font-bold text-on-surface tracking-tight">贷款助手</Text>
+          <Text className="text-2xl font-extrabold tracking-tight text-on-surface">
+            贷款助手
+          </Text>
         </View>
         <Pressable hitSlop={8}>
-          <Ionicons name="notifications-outline" size={24} color="#737686" />
+          <Ionicons name="notifications-outline" size={24} color="#94a3b8" />
         </Pressable>
       </View>
 
       <ScrollView
         className="flex-1"
-        contentContainerClassName="px-6 pt-4 pb-32"
+        contentContainerClassName="px-6 pt-6 pb-28"
         showsVerticalScrollIndicator={false}
       >
-        {/* ── 头像区域 ── */}
-        <View className="items-center mb-10">
-          <View className="relative mb-4">
-            {/* 渐变圆环 — 用 primary-container 模拟 */}
-            <View className="w-28 h-28 rounded-full bg-primary-container p-1">
-              <View className="w-full h-full rounded-full overflow-hidden border-4 border-surface-container-lowest bg-surface-container items-center justify-center">
-                {/* 占位头像:实际项目替换为用户真实头像 */}
-                <Ionicons name="person" size={40} color="#495c95" />
+        <View className="mb-10 items-center">
+          <View className="relative mb-5">
+            <View className="h-32 w-32 rounded-full bg-primary-container p-1.5">
+              <View className="h-full w-full items-center justify-center rounded-full border-4 border-surface-container-lowest bg-slate-900">
+                <Ionicons name="person" size={48} color="#ffffff" />
               </View>
             </View>
-            {/* 认证徽章 */}
-            <View className="absolute bottom-1 right-1 bg-primary w-8 h-8 rounded-full items-center justify-center border-4 border-surface-container-lowest shadow-lg">
-              <Ionicons name="checkmark" size={14} color="#ffffff" />
+            <View className="absolute bottom-1 right-1 h-9 w-9 items-center justify-center rounded-full border-4 border-surface-container-lowest bg-primary shadow-lg">
+              <Ionicons name="checkmark" size={15} color="#ffffff" />
             </View>
           </View>
-          <Text className="text-2xl font-extrabold tracking-tight text-on-surface mb-1">
+          <Text className="mb-2 text-4xl font-extrabold tracking-tight text-on-surface">
             张建华
           </Text>
-          <Text className="text-on-surface-variant text-sm font-medium tracking-wide">
+          <Text className="text-base font-medium text-on-surface-variant">
             高级信贷经理 · 智融金融
           </Text>
         </View>
 
-        {/* ── 三栏统计 ── */}
-        <View className="flex-row gap-4 mb-10">
-          <View className="flex-1 bg-surface-container-lowest rounded-xl p-4 items-center shadow-sm">
-            <Text className="text-primary text-xl font-extrabold mb-1">128</Text>
-            <Text className="text-[10px] uppercase tracking-widest text-outline font-bold">
-              已完成
-            </Text>
+        <View className="mb-10 flex-row gap-4">
+          <View className="flex-1 items-center rounded-2xl bg-surface-container-lowest px-4 py-5 shadow-sm">
+            <Text className="text-4xl font-extrabold text-primary">128</Text>
+            <Text className="mt-2 text-sm font-bold text-outline">已完成</Text>
           </View>
-          <View className="flex-1 bg-surface-container-lowest rounded-xl p-4 items-center shadow-sm">
-            <Text className="text-primary text-xl font-extrabold mb-1">94%</Text>
-            <Text className="text-[10px] uppercase tracking-widest text-outline font-bold">
-              成功率
-            </Text>
+          <View className="flex-1 items-center rounded-2xl bg-surface-container-lowest px-4 py-5 shadow-sm">
+            <Text className="text-4xl font-extrabold text-primary">94%</Text>
+            <Text className="mt-2 text-sm font-bold text-outline">成功率</Text>
           </View>
-          <View className="flex-1 bg-surface-container-lowest rounded-xl p-4 items-center shadow-sm">
-            <Text className="text-primary text-xl font-extrabold mb-1">¥42k</Text>
-            <Text className="text-[10px] uppercase tracking-widest text-outline font-bold">
-              本月收入
-            </Text>
+          <View className="flex-1 items-center rounded-2xl bg-surface-container-lowest px-4 py-5 shadow-sm">
+            <Text className="text-4xl font-extrabold text-primary">¥42k</Text>
+            <Text className="mt-2 text-sm font-bold text-outline">本月收入</Text>
           </View>
         </View>
 
-        {/* ── 菜单分组 1:业务 ── */}
-        <View className="bg-surface-container-lowest rounded-xl overflow-hidden shadow-sm mb-6">
+        <View className="mb-6 overflow-hidden rounded-2xl bg-surface-container-lowest shadow-sm">
           <MenuRow icon="people-outline" label="我的客户" iconBgClass="bg-blue-50" />
           <MenuRow
             icon="business-outline"
@@ -90,8 +88,7 @@ export default function ProfileScreen() {
           />
         </View>
 
-        {/* ── 菜单分组 2:系统 ── */}
-        <View className="bg-surface-container-lowest rounded-xl overflow-hidden shadow-sm mb-6">
+        <View className="mb-6 overflow-hidden rounded-2xl bg-surface-container-lowest shadow-sm">
           <MenuRow
             icon="shield-outline"
             label="安全设置"
@@ -112,13 +109,16 @@ export default function ProfileScreen() {
           />
         </View>
 
-        {/* ── 退出登录 ── */}
         <Pressable
-          className="mt-4 bg-surface-container-low py-4 rounded-xl flex-row items-center justify-center gap-2"
-          style={({ pressed }) => ({ opacity: pressed ? 0.7 : 1, transform: [{ scale: pressed ? 0.98 : 1 }] })}
+          onPress={handleLogout}
+          className="mt-3 flex-row items-center justify-center gap-2 rounded-2xl bg-surface-container-low py-4"
+          style={({ pressed }) => ({
+            opacity: pressed ? 0.86 : 1,
+            transform: [{ scale: pressed ? 0.985 : 1 }],
+          })}
         >
           <Ionicons name="log-out-outline" size={20} color="#ba1a1a" />
-          <Text className="text-error font-bold">退出登录</Text>
+          <Text className="text-lg font-bold text-error">退出登录</Text>
         </Pressable>
       </ScrollView>
     </SafeAreaView>

+ 189 - 181
src/app/(tabs)/reports.tsx

@@ -4,19 +4,14 @@ import React, { useState } from 'react';
 import { Pressable, ScrollView, Text, View } from 'react-native';
 import { SafeAreaView } from 'react-native-safe-area-context';
 
-/**
- * 报表页 — 对应设计稿 #reports / #report / #match 屏幕
- *
- * 布局结构:
- * 1. 标题
- * 2. 概览统计卡片(征信分析总量 / 匹配成功率 / 平均额度)
- * 3. 筛选 Tab(全部 / 征信报告 / 匹配结果)
- * 4. 报告卡片列表
- */
-
 type ReportTab = '全部' | '征信报告' | '匹配结果';
 
-interface Report {
+type ReportTag = {
+  text: string;
+  variant: 'primary' | 'secondary' | 'tertiary' | 'error';
+};
+
+type Report = {
   id: string;
   customerName: string;
   type: '征信报告' | '匹配结果';
@@ -25,11 +20,12 @@ interface Report {
   score?: string;
   matchCount?: number;
   matchRate?: string;
-  /** 关键标签 */
-  tags?: { text: string; variant: 'primary' | 'secondary' | 'tertiary' | 'error' }[];
-}
+  tags?: ReportTag[];
+};
 
-const MOCK_REPORTS: Report[] = [
+const TABS: ReportTab[] = ['全部', '征信报告', '匹配结果'];
+
+const REPORTS: Report[] = [
   {
     id: '1',
     customerName: '张德发',
@@ -66,22 +62,13 @@ const MOCK_REPORTS: Report[] = [
   },
   {
     id: '4',
-    customerName: '王大锤',
-    type: '征信报告',
-    time: '3天前',
-    status: '已完成',
-    score: 'B',
-    tags: [{ text: '收入稳定', variant: 'primary' }],
-  },
-  {
-    id: '5',
     customerName: '王五',
     type: '征信报告',
     time: '今天 09:16',
     status: '解析中',
   },
   {
-    id: '6',
+    id: '5',
     customerName: '赵丽',
     type: '匹配结果',
     time: '5天前',
@@ -89,205 +76,226 @@ const MOCK_REPORTS: Report[] = [
   },
 ];
 
-const TABS: ReportTab[] = ['全部', '征信报告', '匹配结果'];
+function getStatusVariant(status: Report['status']) {
+  switch (status) {
+    case '已完成':
+      return 'success' as const;
+    case '解析中':
+      return 'secondary' as const;
+    case '待匹配':
+      return 'error' as const;
+    default:
+      return 'secondary' as const;
+  }
+}
 
 export default function ReportsScreen() {
   const [activeTab, setActiveTab] = useState<ReportTab>('全部');
 
-  const filtered = MOCK_REPORTS.filter(
-    (r) => activeTab === '全部' || r.type === activeTab
+  const filteredReports = REPORTS.filter(
+    (item) => activeTab === '全部' || item.type === activeTab
   );
 
-  const completedCount = MOCK_REPORTS.filter((r) => r.status === '已完成').length;
+  const completedCount = REPORTS.filter((item) => item.status === '已完成').length;
 
   return (
     <SafeAreaView className="flex-1 bg-surface" edges={['top']}>
       <ScrollView
         className="flex-1"
-        contentContainerClassName="pb-24"
+        contentContainerClassName="px-6 pt-4 pb-28"
         showsVerticalScrollIndicator={false}
-        stickyHeaderIndices={[2]}
       >
-        {/* ── 标题 ── */}
-        <View className="px-6 pt-4 mb-6">
-          <Text className="text-3xl font-extrabold tracking-tight text-on-surface mb-2">
-            报表
-          </Text>
-          <Text className="text-on-surface-variant text-sm">
-            征信分析报告与智能匹配结果汇总
-          </Text>
-        </View>
+        <Text className="mb-2 text-4xl font-extrabold tracking-tight text-on-surface">
+          报表
+        </Text>
+        <Text className="mb-6 text-base leading-7 text-on-surface-variant">
+          汇总查看征信分析结果、匹配建议和当前处理进度
+        </Text>
 
-        {/* ── 概览统计 ── */}
-        <View className="flex-row gap-3 px-6 mb-6">
-          <View className="flex-1 bg-surface-container-lowest p-4 rounded-xl shadow-sm items-center">
-            <Text className="text-2xl font-extrabold text-primary mb-1">
-              {MOCK_REPORTS.length}
-            </Text>
-            <Text className="text-[10px] uppercase tracking-widest text-outline font-bold">
+        <View className="mb-6 flex-row gap-3">
+          <View className="flex-1 items-center rounded-2xl bg-surface-container-lowest px-3 py-4 shadow-sm">
+            <Text className="text-3xl font-extrabold text-primary">{REPORTS.length}</Text>
+            <Text className="mt-2 text-xs font-bold uppercase tracking-widest text-outline">
               总报告数
             </Text>
           </View>
-          <View className="flex-1 bg-surface-container-lowest p-4 rounded-xl shadow-sm items-center">
-            <Text className="text-2xl font-extrabold text-primary mb-1">
-              {completedCount}
-            </Text>
-            <Text className="text-[10px] uppercase tracking-widest text-outline font-bold">
+          <View className="flex-1 items-center rounded-2xl bg-surface-container-lowest px-3 py-4 shadow-sm">
+            <Text className="text-3xl font-extrabold text-primary">{completedCount}</Text>
+            <Text className="mt-2 text-xs font-bold uppercase tracking-widest text-outline">
               已完成
             </Text>
           </View>
-          <View className="flex-1 bg-surface-container-lowest p-4 rounded-xl shadow-sm items-center">
-            <Text className="text-2xl font-extrabold text-primary mb-1">92%</Text>
-            <Text className="text-[10px] uppercase tracking-widest text-outline font-bold">
+          <View className="flex-1 items-center rounded-2xl bg-surface-container-lowest px-3 py-4 shadow-sm">
+            <Text className="text-3xl font-extrabold text-primary">92%</Text>
+            <Text className="mt-2 text-xs font-bold uppercase tracking-widest text-outline">
               最高匹配
             </Text>
           </View>
         </View>
 
-        {/* ── 筛选 Tab ── */}
-        <View className="bg-surface px-6 pb-3 pt-1">
-          <View className="flex-row bg-surface-container-low rounded-lg p-1">
-            {TABS.map((tab) => (
-              <Pressable
-                key={tab}
-                onPress={() => setActiveTab(tab)}
-                className={`flex-1 py-2.5 rounded-md items-center ${
-                  activeTab === tab ? 'bg-surface-container-lowest shadow-sm' : ''
-                }`}
-              >
-                <Text
-                  className={`text-xs font-bold ${
-                    activeTab === tab ? 'text-primary' : 'text-on-surface-variant'
+        <View className="mb-6 rounded-2xl bg-surface-container-low p-1">
+          <View className="flex-row">
+            {TABS.map((tab) => {
+              const active = activeTab === tab;
+              return (
+                <Pressable
+                  key={tab}
+                  onPress={() => setActiveTab(tab)}
+                  className={`flex-1 rounded-xl py-3 ${
+                    active ? 'bg-surface-container-lowest' : ''
                   }`}
+                  style={({ pressed }) => ({
+                    opacity: pressed ? 0.88 : 1,
+                  })}
                 >
-                  {tab}
-                </Text>
-              </Pressable>
-            ))}
+                  <Text
+                    className={`text-center text-sm font-bold ${
+                      active ? 'text-primary' : 'text-on-surface-variant'
+                    }`}
+                  >
+                    {tab}
+                  </Text>
+                </Pressable>
+              );
+            })}
           </View>
         </View>
 
-        {/* ── 报告列表 ── */}
-        <View className="px-6 pt-2 gap-3">
-          {filtered.length === 0 ? (
-            <View className="items-center pt-20">
-              <Ionicons name="document-text-outline" size={48} color="#c3c6d7" />
-              <Text className="text-on-surface-variant text-sm mt-4">暂无报告</Text>
-            </View>
-          ) : (
-            filtered.map((report) => (
-              <Pressable
-                key={report.id}
-                className="bg-surface-container-lowest p-5 rounded-xl shadow-sm active:bg-surface-container-low"
-              >
-                {/* 头部:类型 + 客户名 + 时间 */}
-                <View className="flex-row items-start justify-between mb-3">
-                  <View className="flex-row items-center gap-3">
-                    <View
-                      className={`w-10 h-10 rounded-xl items-center justify-center ${
-                        report.type === '征信报告' ? 'bg-blue-50' : 'bg-green-50'
-                      }`}
-                    >
-                      <Ionicons
-                        name={
-                          report.type === '征信报告'
-                            ? 'document-text-outline'
-                            : 'git-compare-outline'
-                        }
-                        size={20}
-                        color={report.type === '征信报告' ? '#2563eb' : '#16a34a'}
-                      />
-                    </View>
-                    <View>
-                      <Text className="font-bold text-on-surface">{report.customerName}</Text>
-                      <Text className="text-[10px] text-on-surface-variant">{report.type}</Text>
-                    </View>
-                  </View>
-                  <View className="items-end">
-                    <Text className="text-[10px] text-on-surface-variant mb-1">
-                      {report.time}
-                    </Text>
-                    <StatusBadge
-                      text={report.status}
-                      variant={
-                        report.status === '已完成'
-                          ? 'success'
-                          : report.status === '解析中'
-                            ? 'secondary'
-                            : 'error'
+        <View className="gap-4">
+          {filteredReports.map((report) => (
+            <Pressable
+              key={report.id}
+              className="rounded-2xl bg-surface-container-lowest px-5 py-5 shadow-sm"
+              style={({ pressed }) => ({
+                opacity: pressed ? 0.93 : 1,
+              })}
+            >
+              <View className="mb-4 flex-row items-start justify-between gap-3">
+                <View className="flex-1 flex-row items-center gap-3">
+                  <View
+                    className={`h-12 w-12 items-center justify-center rounded-2xl ${
+                      report.type === '征信报告' ? 'bg-blue-50' : 'bg-green-50'
+                    }`}
+                  >
+                    <Ionicons
+                      name={
+                        report.type === '征信报告'
+                          ? 'document-text-outline'
+                          : 'git-compare-outline'
                       }
+                      size={20}
+                      color={report.type === '征信报告' ? '#2563eb' : '#16a34a'}
                     />
                   </View>
-                </View>
-
-                {/* 征信报告:评分 + 标签 */}
-                {report.type === '征信报告' && report.status === '已完成' && (
-                  <View>
-                    <View className="flex-row items-center gap-3 mb-3">
-                      <View className="w-14 h-14 rounded-full border-4 border-primary-fixed items-center justify-center bg-surface-container-lowest">
-                        <Text className="text-primary font-extrabold text-lg">
-                          {report.score}
-                        </Text>
-                      </View>
-                      <View className="flex-1">
-                        <Text className="text-xs text-on-surface-variant mb-2">关键标签</Text>
-                        <View className="flex-row flex-wrap gap-1.5">
-                          {report.tags?.map((tag, i) => (
-                            <StatusBadge key={i} text={tag.text} variant={tag.variant} />
-                          ))}
-                        </View>
-                      </View>
-                    </View>
+                  <View className="flex-1">
+                    <Text className="text-xl font-bold text-on-surface">
+                      {report.customerName}
+                    </Text>
+                    <Text className="mt-1 text-sm text-on-surface-variant">
+                      {report.type}
+                    </Text>
                   </View>
-                )}
+                </View>
+                <View className="items-end">
+                  <Text className="mb-2 text-xs text-on-surface-variant">{report.time}</Text>
+                  <StatusBadge
+                    text={report.status}
+                    variant={getStatusVariant(report.status)}
+                  />
+                </View>
+              </View>
 
-                {/* 匹配结果:匹配数量 + 最高匹配率 */}
-                {report.type === '匹配结果' && report.status === '已完成' && (
-                  <View className="flex-row gap-4 mt-1">
-                    <View className="flex-1 bg-surface-container-low p-3 rounded-lg items-center">
-                      <Text className="text-lg font-bold text-on-surface">
-                        {report.matchCount}
+              {report.type === '征信报告' && report.status === '已完成' ? (
+                <View>
+                  <View className="mb-4 flex-row items-center gap-4">
+                    <View className="h-16 w-16 items-center justify-center rounded-full border-4 border-primary-fixed bg-surface-container-lowest">
+                      <Text className="text-xl font-extrabold text-primary">
+                        {report.score}
                       </Text>
-                      <Text className="text-[10px] text-on-surface-variant">匹配产品数</Text>
                     </View>
-                    <View className="flex-1 bg-surface-container-low p-3 rounded-lg items-center">
-                      <Text className="text-lg font-bold text-primary">{report.matchRate}</Text>
-                      <Text className="text-[10px] text-on-surface-variant">最高匹配度</Text>
+                    <View className="flex-1">
+                      <Text className="mb-2 text-sm text-on-surface-variant">关键标签</Text>
+                      <View className="flex-row flex-wrap gap-2">
+                        {report.tags?.map((tag) => (
+                          <StatusBadge
+                            key={`${report.id}-${tag.text}`}
+                            text={tag.text}
+                            variant={tag.variant}
+                          />
+                        ))}
+                      </View>
                     </View>
                   </View>
-                )}
+                  <Text className="text-sm leading-6 text-on-surface-variant">
+                    建议可申请额度:20万-35万,优先推荐更看重流水稳定性的产品。
+                  </Text>
+                </View>
+              ) : null}
 
-                {/* 解析中:进度条 */}
-                {report.status === '解析中' && (
-                  <View className="mt-1">
-                    <View className="flex-row items-center justify-between mb-1">
-                      <Text className="text-xs text-on-surface-variant">正在解析...</Text>
-                      <Text className="text-xs text-primary font-bold">72%</Text>
-                    </View>
-                    <View className="h-1.5 w-full bg-surface-container rounded-full overflow-hidden">
-                      <View className="h-full bg-primary-container rounded-full w-[72%]" />
-                    </View>
+              {report.type === '匹配结果' && report.status === '已完成' ? (
+                <View className="flex-row gap-3">
+                  <View className="flex-1 rounded-xl bg-surface-container-low px-4 py-4">
+                    <Text className="text-3xl font-bold text-on-surface">
+                      {report.matchCount}
+                    </Text>
+                    <Text className="mt-1 text-xs text-on-surface-variant">匹配产品数</Text>
                   </View>
-                )}
+                  <View className="flex-1 rounded-xl bg-surface-container-low px-4 py-4">
+                    <Text className="text-3xl font-bold text-primary">
+                      {report.matchRate}
+                    </Text>
+                    <Text className="mt-1 text-xs text-on-surface-variant">最高匹配度</Text>
+                  </View>
+                </View>
+              ) : null}
 
-                {/* 底部操作 */}
-                {report.status === '已完成' && (
-                  <View className="flex-row gap-3 mt-4">
-                    <Pressable className="flex-1 py-2.5 bg-primary-container rounded-lg items-center">
-                      <Text className="text-on-primary text-xs font-bold">
-                        {report.type === '征信报告' ? '查看详情' : '查看匹配'}
-                      </Text>
-                    </Pressable>
-                    <Pressable className="flex-1 py-2.5 bg-surface-container-high rounded-lg items-center">
-                      <Text className="text-on-surface text-xs font-semibold">
-                        {report.type === '征信报告' ? '智能匹配' : '重新匹配'}
-                      </Text>
-                    </Pressable>
+              {report.status === '解析中' ? (
+                <View className="mt-1">
+                  <View className="mb-2 flex-row items-center justify-between">
+                    <Text className="text-sm text-on-surface-variant">正在生成报告...</Text>
+                    <Text className="text-sm font-bold text-primary">72%</Text>
+                  </View>
+                  <View className="h-1.5 rounded-full bg-surface-container">
+                    <View
+                      className="h-full rounded-full bg-primary-container"
+                      style={{ width: '72%' }}
+                    />
                   </View>
-                )}
-              </Pressable>
-            ))
-          )}
+                </View>
+              ) : null}
+
+              {report.status === '待匹配' ? (
+                <Text className="text-sm leading-6 text-on-surface-variant">
+                  当前客户信息已同步,待进入智能匹配流程生成推荐结果。
+                </Text>
+              ) : null}
+
+              {report.status === '已完成' ? (
+                <View className="mt-4 flex-row gap-3">
+                  <Pressable
+                    className="flex-1 items-center rounded-xl bg-primary-container py-3"
+                    style={({ pressed }) => ({
+                      opacity: pressed ? 0.88 : 1,
+                    })}
+                  >
+                    <Text className="text-sm font-bold text-on-primary">
+                      {report.type === '征信报告' ? '查看详情' : '查看匹配'}
+                    </Text>
+                  </Pressable>
+                  <Pressable
+                    className="flex-1 items-center rounded-xl bg-surface-container-high py-3"
+                    style={({ pressed }) => ({
+                      opacity: pressed ? 0.88 : 1,
+                    })}
+                  >
+                    <Text className="text-sm font-semibold text-on-surface">
+                      {report.type === '征信报告' ? '智能匹配' : '重新匹配'}
+                    </Text>
+                  </Pressable>
+                </View>
+              ) : null}
+            </Pressable>
+          ))}
         </View>
       </ScrollView>
     </SafeAreaView>

+ 79 - 0
src/app/+html.tsx

@@ -0,0 +1,79 @@
+import { ScrollViewStyleReset } from 'expo-router/html';
+import { type PropsWithChildren } from 'react';
+
+// This file is web-only and used to configure the root HTML for every
+// web page during static rendering.
+// The contents of this function only run in Node.js environments and
+// do not have access to the DOM or browser APIs.
+export default function Root({ children }: PropsWithChildren) {
+  return (
+    <html lang="en">
+      <head>
+        <meta charSet="utf-8" />
+        <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
+        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
+
+        {/*
+          Disable body scrolling on web. This makes ScrollView components work closer to how they do on native.
+          However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line.
+        */}
+        <ScrollViewStyleReset />
+          
+        {/* Add any additional <head> elements that you want globally available on web... */}
+        </head>
+      <body>
+        <style
+          dangerouslySetInnerHTML={{
+            __html:`
+            html,
+body {
+  min-height: 100%;
+  margin: 0;
+}
+
+* {
+  scrollbar-width: none;
+  -ms-overflow-style: none;
+}
+  ::-webkit-scrollbar {
+    display: none;
+    width: 0;
+    height: 0;
+  }
+
+  body {
+    min-height: 100vh;
+    background:
+      radial-gradient(circle at top, rgba(96, 165, 250, 0.18), transparent 32%),
+      linear-gradient(180deg, #172554 0%, #0f172a 55%, #020617 100%);
+  }
+
+  #root {
+    max-width: 448px;
+    margin: 0 auto;
+    background: #ffffff;
+  }
+
+  @media (min-width: 448px) {
+
+    #root {
+      min-height: 100vh;
+      overflow: hidden;
+      border-radius: 24px;
+      border: 1px solid rgba(255, 255, 255, 0.08);
+      box-shadow:
+        0 36px 90px rgba(2, 6, 23, 0.46),
+        0 18px 34px rgba(15, 23, 42, 0.28),
+        inset 0 1px 0 rgba(255, 255, 255, 0.9),
+        inset 0 -1px 0 rgba(15, 23, 42, 0.06);
+    }
+  }`
+          }}
+        />
+        <div id="root">
+          {children}
+        </div>
+      </body>
+    </html>
+  );
+}

+ 43 - 14
src/app/_layout.tsx

@@ -1,31 +1,60 @@
 import '@/global.css';
 
-import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
-import { Stack } from 'expo-router';
-import React from 'react';
-import { useColorScheme } from 'react-native';
+import {
+  DefaultTheme as ReactNavigationDefaultTheme,
+  Theme,
+  ThemeProvider,
+} from '@react-navigation/native';
 
 import { AnimatedSplashOverlay } from '@/components/animated-icon';
-import { HUDProvider } from '@/components/ui/hud';
 import { AuthProvider } from '@/utils/auth';
+import { Provider } from '@ant-design/react-native';
+import antdDefaultTheme from '@ant-design/react-native/lib/style/themes/default';
+import { useFonts } from 'expo-font';
+import { Stack } from 'expo-router';
+
+const antdTheme = antdDefaultTheme;
+
+export const DefaultTheme: Theme = {
+  ...ReactNavigationDefaultTheme,
+  colors: {
+    ...ReactNavigationDefaultTheme.colors,
+    primary: antdTheme.brand_primary,
+    background: antdTheme.fill_body,
+    card: antdTheme.fill_base,
+    text: antdTheme.color_text_base,
+    border: antdTheme.border_color_base,
+    notification: antdTheme.brand_error,
+  },
+};
 
-/**
- * 根布局 — Stack 导航器
- * (tabs) 为主 Tab 页面组,sign-in 为全屏模态登录页
- */
 export default function RootLayout() {
-  const colorScheme = useColorScheme();
+  // const colorScheme = useColorScheme();
+  const [fontsLoaded] = useFonts({
+    antoutline: require('@ant-design/icons-react-native/fonts/antoutline.ttf'),
+  });
+
+  // useEffect(() => {
+  //   if (!fontsLoaded) {
+  //     console.warn('Ant Design icons font failed to load');
+  //   }
+  // }, [fontsLoaded]);
+
+  if (!fontsLoaded) {
+    return null; // 或者返回一个加载中的组件
+  }
+
   return (
-    <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
-      <HUDProvider>
+    <ThemeProvider value={DefaultTheme}>
+      <Provider theme={antdTheme}>
         <AuthProvider>
           <AnimatedSplashOverlay />
           <Stack screenOptions={{ headerShown: false }}>
             <Stack.Screen name="(tabs)" />
-            <Stack.Screen name="sign-in" options={{ presentation: 'fullScreenModal' }} />
+            <Stack.Screen name="sign-in" />
           </Stack>
         </AuthProvider>
-      </HUDProvider>
+      </Provider>
     </ThemeProvider>
   );
 }

+ 271 - 172
src/app/sign-in.tsx

@@ -1,50 +1,98 @@
-import useHUD from '@/components/ui/hud';
-import { InputField } from '@/components/ui/input-field';
-import { PrimaryButton } from '@/components/ui/primary-button';
 import { signIn, useAuthContext } from '@/utils/auth';
+import { Toast } from '@ant-design/react-native';
 import { Ionicons } from '@expo/vector-icons';
-import { useRoute } from '@react-navigation/native';
+import { router, useLocalSearchParams } from 'expo-router';
 import React, { useState } from 'react';
-import { KeyboardAvoidingView, Platform, Pressable, ScrollView, Text, View } from 'react-native';
+import {
+  KeyboardAvoidingView,
+  Platform,
+  Pressable,
+  ScrollView,
+  StyleSheet,
+  Text,
+  TextInput,
+  View,
+} from 'react-native';
 import { SafeAreaView } from 'react-native-safe-area-context';
 
-/**
- * 登录页 — 还原设计稿 sign/code.html 布局
- *
- * 布局层次:
- * 1. 背景装饰层(渐变色块 + 虚化圆形)
- * 2. 主内容区域(logo → 标题 → 登录卡片 → 操作按钮 → 社交登录 → 协议)
- */
-export default function SignInScreen({callback}: {callback?: (signin: boolean) => void}) {
+function FieldLabel({ children }: { children: React.ReactNode }) {
+  return (
+    <Text className="mb-2 ml-1 text-xs font-bold uppercase tracking-widest text-outline">
+      {children}
+    </Text>
+  );
+}
+
+export default function SignInScreen({
+  callback,
+}: {
+  callback?: (signin: boolean) => void;
+}) {
   const [authMode, setAuthMode] = useState<'sms' | 'password'>('sms');
   const [agreed, setAgreed] = useState(false);
   const [loading, setLoading] = useState(false);
-  const [setToken] = useAuthContext();
-  // get rout args
+  const [phone, setPhone] = useState('');
+  const [code, setCode] = useState('');
+  const [password, setPassword] = useState('');
+
+  const { redirectTo } = useLocalSearchParams<{ redirectTo?: string }>();
+  const { setToken } = useAuthContext();
+
+  const handleSendCode = () => {
+    if (phone.trim().length !== 11) {
+      Toast.fail('请先输入 11 位手机号');
+      return;
+    }
+    Toast.success('验证码已发送');
+  };
 
-  const hud = useHUD();
-  const {redirectTo} = useRoute().params as { redirectTo?: string };
   const handleLogin = async () => {
-    // setLoading(true);
-    const l = hud.loading("登录中...");
-    // TODO: 接入登录接口
+    if (!agreed) {
+      Toast.fail('请先阅读并同意协议');
+      callback?.(false);
+      return;
+    }
+
+    if (phone.trim().length !== 11) {
+      Toast.fail('请输入正确的手机号');
+      callback?.(false);
+      return;
+    }
+
+    if (authMode === 'sms' && code.trim().length !== 6) {
+      Toast.fail('请输入 6 位验证码');
+      callback?.(false);
+      return;
+    }
+
+    if (authMode === 'password' && password.trim().length < 6) {
+      Toast.fail('请输入不少于 6 位的密码');
+      callback?.(false);
+      return;
+    }
+
+    setLoading(true);
+    const toastKey = Toast.loading('正在登录...');
+
     try {
       const token = await signIn(1);
-      if (token) {
-        setToken(token);
-      } else {
-        throw new Error('登录失败,未获取到 token');
-      }
+      setToken(token);
+      Toast.success('登录成功');
+      callback?.(true);
+
+      const nextRoute =
+        typeof redirectTo === 'string' && redirectTo.startsWith('/')
+          ? redirectTo
+          : '/';
+      router.replace(nextRoute as never);
     } catch (error) {
       console.error('登录失败:', error);
+      Toast.fail('登录失败,请稍后重试');
       callback?.(false);
-      return;
+    } finally {
+      setLoading(false);
+      Toast.remove(toastKey);
     }
-    finally {
-      // setLoading(false);
-      // l.close();
-    } 
-    return;
   };
 
   return (
@@ -55,160 +103,211 @@ export default function SignInScreen({callback}: {callback?: (signin: boolean) =
       >
         <ScrollView
           className="flex-1"
-          contentContainerClassName="px-8 pt-12 pb-12"
+          contentContainerClassName="px-8 pt-12 pb-10"
+          contentContainerStyle={{ flexGrow: 1 }}
           keyboardShouldPersistTaps="handled"
           showsVerticalScrollIndicator={false}
         >
-          {/* ── 背景装饰(绝对定位) ── */}
-          <View className="absolute -top-24 -right-24 w-96 h-96 bg-primary-container/5 rounded-full" />
-          <View className="absolute top-32 -left-20 w-64 h-64 bg-secondary-container/10 rounded-full" />
-
-          {/* ── Header:Logo + 标题 ── */}
-          <View className="mb-12">
-            <View className="w-16 h-16 bg-primary-container rounded-xl items-center justify-center shadow-lg mb-6">
-              <Ionicons name="business-outline" size={32} color="#ffffff" />
-            </View>
-            <Text className="text-3xl font-bold tracking-tight text-on-surface mb-2">
-              欢迎回来
-            </Text>
-            <Text className="text-on-surface-variant font-medium">
-              登录贷款助手,开启您的财务管理之旅
-            </Text>
-          </View>
+          <View className="absolute -top-24 -right-24 h-96 w-96 rounded-full bg-primary-container/10" />
+          <View className="absolute top-32 -left-20 h-64 w-64 rounded-full bg-secondary-container/20" />
+          <View className="absolute -bottom-16 right-0 h-48 w-48 rounded-full bg-primary-fixed/50" />
 
-          {/* ── 登录卡片 ── */}
-          <View className="bg-surface-container-lowest rounded-xl p-1 shadow-sm mb-8">
-            {/* Tab 切换 */}
-            <View className="flex-row p-1 gap-1 mb-4">
-              <Pressable
-              disabled={loading}
-                onPress={() => setAuthMode('sms')}
-                className={`flex-1 py-3 rounded-lg items-center ${
-                  authMode === 'sms'
-                    ? 'bg-surface-container-lowest shadow-sm'
-                    : ''
-                }`}
-              >
-                <Text
-                  className={`text-sm font-semibold ${
-                    authMode === 'sms' ? 'text-primary' : 'text-on-surface-variant'
-                  }`}
-                >
-                  验证码登录
+          <View className="flex-1 justify-between">
+            <View>
+              <View className="mb-12">
+                <View className="mb-6 h-16 w-16 items-center justify-center rounded-2xl bg-primary-container shadow-lg">
+                  <Ionicons name="business" size={30} color="#ffffff" />
+                </View>
+                <Text className="mb-2 text-4xl font-extrabold tracking-tight text-on-surface">
+                  欢迎回来
                 </Text>
-              </Pressable>
-              <Pressable
-                disabled={loading}
-
-                // onPress={() => setAuthMode('password')}
-                className={`flex-1 py-3 rounded-lg items-center ${
-                  authMode === 'password'
-                    ? 'bg-surface-container-lowest shadow-sm'
-                    : ''
-                }`}
-              >
-                <Text
-                  className={`text-sm font-semibold ${
-                    authMode === 'password' ? 'text-primary' : 'text-on-surface-variant'
-                  }`}
-                >
-                  密码登录
+                <Text className="text-base font-medium leading-7 text-on-surface-variant">
+                  登录贷款助手,开启您的财务管理之旅
                 </Text>
-              </Pressable>
-            </View>
+              </View>
 
-            {/* 表单区域 */}
-            <View className="px-3 pb-4">
-              {/* 手机号 */}
-              <InputField
-              readOnly={loading}
-                label="手机号码"
-                prefix="+86"
-                placeholder="请输入手机号"
-                keyboardType="phone-pad"
-                maxLength={11}
-                suffix={
-                  <Ionicons name="phone-portrait-outline" size={18} color="#c3c6d7" />
-                }
-              />
-
-              {/* 验证码 / 密码 */}
-              {authMode === 'sms' ? (
-                <InputField
-                readOnly={loading}  
-                  label="验证码"
-                  placeholder="请输入6位验证码"
-                  keyboardType="number-pad"
-                  maxLength={6}
-                  suffix={
-                    <Pressable hitSlop={8}>
-                      <Text className="text-sm font-bold text-primary">获取验证码</Text>
-                    </Pressable>
-                  }
-                />
-              ) : (
-                <InputField
-                    readOnly={loading}
-                  label="密码"
-                  placeholder="请输入密码"
-                  secureTextEntry
-                  suffix={
-                    <Ionicons name="eye-off-outline" size={18} color="#c3c6d7" />
-                  }
-                />
-              )}
-            </View>
-          </View>
+              <View className="mb-8 rounded-2xl bg-surface-container-lowest p-3 shadow-sm">
+                <View className="mb-6 flex-row rounded-2xl bg-surface-container-low p-1">
+                  {[
+                    ['sms', '验证码登录'],
+                    ['password', '密码登录'],
+                  ].map(([mode, label]) => {
+                    const active = authMode === mode;
+                    return (
+                      <Pressable
+                        key={mode}
+                        disabled={loading}
+                        onPress={() => setAuthMode(mode as 'sms' | 'password')}
+                        className={`flex-1 rounded-xl px-4 py-3 ${
+                          active ? 'bg-surface-container-lowest' : ''
+                        }`}
+                        style={({ pressed }) => ({
+                          opacity: loading ? 0.5 : pressed ? 0.86 : 1,
+                          transform: [{ scale: pressed ? 0.99 : 1 }],
+                        })}
+                      >
+                        <Text
+                          className={`text-center text-base font-bold ${
+                            active ? 'text-primary' : 'text-on-surface-variant'
+                          }`}
+                        >
+                          {label}
+                        </Text>
+                      </Pressable>
+                    );
+                  })}
+                </View>
+
+                <View className="px-2 pb-2">
+                  <FieldLabel>手机号码</FieldLabel>
+                  <View className="mb-5 flex-row items-center rounded-2xl bg-surface-container-low px-5 py-4">
+                    <Text className="text-2xl font-bold text-on-surface">+86</Text>
+                    <View
+                      className="mx-4 h-5 bg-outline-variant/40"
+                      style={{ width: StyleSheet.hairlineWidth }}
+                    />
+                    <TextInput
+                      value={phone}
+                      onChangeText={setPhone}
+                      editable={!loading}
+                      keyboardType="phone-pad"
+                      maxLength={11}
+                      placeholder="请输入手机号"
+                      placeholderTextColor="#9ca3af"
+                      className="flex-1 p-0 text-xl font-medium text-on-surface"
+                    />
+                    <Ionicons
+                      name="phone-portrait-outline"
+                      size={22}
+                      color="#c3c6d7"
+                    />
+                  </View>
+
+                  <FieldLabel>{authMode === 'sms' ? '验证码' : '密码'}</FieldLabel>
+                  <View className="flex-row items-center rounded-2xl bg-surface-container-low px-5 py-4">
+                    <TextInput
+                      value={authMode === 'sms' ? code : password}
+                      onChangeText={authMode === 'sms' ? setCode : setPassword}
+                      editable={!loading}
+                      keyboardType={authMode === 'sms' ? 'number-pad' : 'default'}
+                      maxLength={authMode === 'sms' ? 6 : 20}
+                      secureTextEntry={authMode === 'password'}
+                      placeholder={
+                        authMode === 'sms'
+                          ? '请输入 6 位验证码'
+                          : '请输入登录密码'
+                      }
+                      placeholderTextColor="#9ca3af"
+                      className="flex-1 p-0 text-xl font-medium text-on-surface"
+                    />
+                    {authMode === 'sms' ? (
+                      <Pressable
+                        disabled={loading}
+                        hitSlop={8}
+                        onPress={handleSendCode}
+                        style={({ pressed }) => ({
+                          opacity: loading ? 0.5 : pressed ? 0.72 : 1,
+                        })}
+                      >
+                        <Text className="text-lg font-bold leading-6 text-primary">
+                          获取验证码
+                        </Text>
+                      </Pressable>
+                    ) : (
+                      <Ionicons name="lock-closed-outline" size={22} color="#c3c6d7" />
+                    )}
+                  </View>
+                </View>
+              </View>
 
-          {/* ── 操作按钮 ── */}
-          <View className="gap-4 mb-8">
-            <PrimaryButton title="立即登录" onPress={handleLogin} />
-            <View className="flex-row items-center justify-between px-2">
-              <Pressable hitSlop={8}>
-                <Text className="text-sm font-medium text-on-surface-variant">注册账号</Text>
-              </Pressable>
-              <Pressable hitSlop={8}>
-                <Text className="text-sm font-medium text-on-surface-variant">遇到问题?</Text>
-              </Pressable>
+              <View className="mb-8 gap-4">
+                <Pressable
+                  disabled={loading}
+                  onPress={handleLogin}
+                  className="items-center justify-center rounded-2xl bg-primary-container py-5 shadow-lg"
+                  style={({ pressed }) => ({
+                    opacity: loading ? 0.6 : pressed ? 0.88 : 1,
+                    transform: [{ scale: pressed ? 0.985 : 1 }],
+                  })}
+                >
+                  <Text className="text-2xl font-extrabold text-on-primary">
+                    {loading ? '登录中...' : '立即登录'}
+                  </Text>
+                </Pressable>
+
+                <View className="flex-row items-center justify-between px-3">
+                  <Pressable hitSlop={8}>
+                    <Text className="text-lg font-medium text-on-surface-variant">
+                      注册账号
+                    </Text>
+                  </Pressable>
+                  <Pressable hitSlop={8}>
+                    <Text className="text-lg font-medium text-on-surface-variant">
+                      遇到问题?
+                    </Text>
+                  </Pressable>
+                </View>
+              </View>
             </View>
-          </View>
 
-          {/* ── 社交登录分割线 ── */}
-          <View className="flex-row items-center gap-4 mb-8">
-            <View className="h-px flex-1 bg-surface-container-highest" />
-            <Text className="text-xs font-bold text-outline tracking-widest uppercase">
-              其他方式登录
-            </Text>
-            <View className="h-px flex-1 bg-surface-container-highest" />
-          </View>
+            <View className="pt-4">
+              <View className="mb-8 flex-row items-center gap-4">
+                <View className="h-px flex-1 bg-surface-container-highest" />
+                <Text className="text-sm font-bold tracking-widest text-outline">
+                  其他方式登录
+                </Text>
+                <View className="h-px flex-1 bg-surface-container-highest" />
+              </View>
 
-          {/* 第三方图标 */}
-          <View className="flex-row justify-center gap-8 mb-10">
-            <Pressable className="w-12 h-12 rounded-full bg-surface-container-low items-center justify-center">
-              <Ionicons name="chatbubble-ellipses-outline" size={24} color="#737686" />
-            </Pressable>
-            <Pressable className="w-12 h-12 rounded-full bg-surface-container-low items-center justify-center">
-              <Ionicons name="logo-apple" size={24} color="#737686" />
-            </Pressable>
-          </View>
+              <View className="mb-10 flex-row justify-center gap-10">
+                {[
+                  ['chatbubble-ellipses-outline', '#6b7280'],
+                  ['logo-apple', '#6b7280'],
+                ].map(([icon, color]) => (
+                  <Pressable
+                    key={icon}
+                    className="h-14 w-14 items-center justify-center rounded-full bg-surface-container-low"
+                    style={({ pressed }) => ({
+                      opacity: pressed ? 0.8 : 1,
+                      transform: [{ scale: pressed ? 0.94 : 1 }],
+                    })}
+                  >
+                    <Ionicons
+                      name={icon as keyof typeof Ionicons.glyphMap}
+                      size={24}
+                      color={color}
+                    />
+                  </Pressable>
+                ))}
+              </View>
 
-          {/* ── 用户协议 ── */}
-          <View className="flex-row items-start gap-3 px-2">
-            <Pressable onPress={() => setAgreed(!agreed)} className="pt-0.5">
-              <View
-                className={`w-5 h-5 rounded-full border-2 items-center justify-center ${
-                  agreed ? 'bg-primary border-primary' : 'border-outline-variant bg-surface-container-low'
-                }`}
-              >
-                {agreed && <Ionicons name="checkmark" size={12} color="#fff" />}
+              <View className="flex-row items-start gap-3 px-2">
+                <Pressable
+                  onPress={() => setAgreed((value) => !value)}
+                  hitSlop={8}
+                  className="pt-1"
+                >
+                  <View
+                    className={`h-6 w-6 items-center justify-center rounded-full border ${
+                      agreed
+                        ? 'border-primary bg-primary'
+                        : 'border-outline-variant bg-surface-container-low'
+                    }`}
+                  >
+                    {agreed ? (
+                      <Ionicons name="checkmark" size={14} color="#ffffff" />
+                    ) : null}
+                  </View>
+                </Pressable>
+                <Text className="flex-1 text-sm leading-7 text-on-surface-variant">
+                  登录即代表您已阅读并同意
+                  <Text className="font-semibold text-primary">《用户服务协议》</Text>
+                  、
+                  <Text className="font-semibold text-primary">《隐私政策》</Text>
+                  ,以及授权该应用获取您的公开信息。
+                </Text>
               </View>
-            </Pressable>
-            <Text className="text-xs leading-relaxed text-on-surface-variant flex-1">
-              登录即代表您已阅读并同意
-              <Text className="text-primary font-semibold">《用户服务协议》</Text>、
-              <Text className="text-primary font-semibold">《隐私政策》</Text>
-              以及授权该应用获取您的公开信息。
-            </Text>
+            </View>
           </View>
         </ScrollView>
       </KeyboardAvoidingView>

+ 24 - 0
src/components/app-tabs.tsx

@@ -28,6 +28,30 @@ export default function AppTabs() {
           renderingMode="template"
         />
       </NativeTabs.Trigger>
+
+      <NativeTabs.Trigger name="analytics">
+        <NativeTabs.Trigger.Label>分析</NativeTabs.Trigger.Label>
+        <NativeTabs.Trigger.Icon
+          src={require('@/assets/images/tabIcons/explore.png')}
+          renderingMode="template"
+        />
+      </NativeTabs.Trigger>
+
+      <NativeTabs.Trigger name="reports">
+        <NativeTabs.Trigger.Label>报表</NativeTabs.Trigger.Label>
+        <NativeTabs.Trigger.Icon
+          src={require('@/assets/images/tabIcons/explore.png')}
+          renderingMode="template"
+        />
+      </NativeTabs.Trigger>
+
+      <NativeTabs.Trigger name="profile">
+        <NativeTabs.Trigger.Label>我的</NativeTabs.Trigger.Label>
+        <NativeTabs.Trigger.Icon
+          src={require('@/assets/images/tabIcons/home.png')}
+          renderingMode="template"
+        />
+      </NativeTabs.Trigger>
     </NativeTabs>
   );
 }

+ 35 - 29
src/components/app-tabs.web.tsx

@@ -1,32 +1,43 @@
 import {
-  Tabs,
   TabList,
-  TabTrigger,
+  TabListProps,
+  Tabs,
   TabSlot,
+  TabTrigger,
   TabTriggerSlotProps,
-  TabListProps,
 } from 'expo-router/ui';
-import { SymbolView } from 'expo-symbols';
 import React from 'react';
-import { Pressable, useColorScheme, View, StyleSheet } from 'react-native';
+import { Pressable, StyleSheet, View } from 'react-native';
 
-import { ExternalLink } from './external-link';
 import { ThemedText } from './themed-text';
 import { ThemedView } from './themed-view';
 
 import { Colors, MaxContentWidth, Spacing } from '@/constants/theme';
+import { Image, ImageSource } from 'expo-image';
+
+import antdDefaultTheme from '@ant-design/react-native/lib/style/themes/default';
+
 
 export default function AppTabs() {
   return (
     <Tabs>
-      <TabSlot style={{ height: '100%' }} />
+      <TabSlot style={{ height: '100%', paddingBottom: 44 }} />
       <TabList asChild>
         <CustomTabList>
           <TabTrigger name="home" href="/" asChild>
-            <TabButton>Home</TabButton>
+            <TabButton icon={require("@/assets/images/tabIcons/home.png")}>首页</TabButton>
+          </TabTrigger>
+          <TabTrigger name="customer" href="/customer" asChild>
+            <TabButton  icon={require("@/assets/images/tabIcons/explore.png")}>客户</TabButton>
           </TabTrigger>
-          <TabTrigger name="explore" href="/explore" asChild>
-            <TabButton>Explore</TabButton>
+          <TabTrigger name="analytics" href="/analytics" asChild>
+            <TabButton icon={require("@/assets/images/tabIcons/explore.png")}>统计</TabButton>
+          </TabTrigger>
+          <TabTrigger name="reports" href="/reports" asChild>
+            <TabButton icon={require("@/assets/images/tabIcons/explore.png")}>分析</TabButton>
+          </TabTrigger>
+          <TabTrigger name="profile" href="/profile" asChild>
+            <TabButton icon={require("@/assets/images/tabIcons/home.png")}>我的</TabButton>
           </TabTrigger>
         </CustomTabList>
       </TabList>
@@ -34,13 +45,14 @@ export default function AppTabs() {
   );
 }
 
-export function TabButton({ children, isFocused, ...props }: TabTriggerSlotProps) {
+export function TabButton({ children, isFocused, icon, ...props }: TabTriggerSlotProps & {icon: ImageSource}) {
   return (
     <Pressable {...props} style={({ pressed }) => pressed && styles.pressed}>
       <ThemedView
-        type={isFocused ? 'backgroundSelected' : 'backgroundElement'}
+        type={'backgroundElement'}
         style={styles.tabButtonView}>
-        <ThemedText type="small" themeColor={isFocused ? 'text' : 'textSecondary'}>
+          <Image tintColor={isFocused ? antdDefaultTheme.brand_primary : undefined} className="w-6 h-6 mb-1 self-center " source={icon} />
+        <ThemedText type="small" style={{color: isFocused ? antdDefaultTheme.brand_primary : undefined}}>
           {children}
         </ThemedText>
       </ThemedView>
@@ -49,28 +61,17 @@ export function TabButton({ children, isFocused, ...props }: TabTriggerSlotProps
 }
 
 export function CustomTabList(props: TabListProps) {
-  const scheme = useColorScheme();
-  const colors = Colors[scheme === 'unspecified' ? 'light' : scheme];
+  // const scheme = "light"
+  const colors = Colors['light'];
 
   return (
     <View {...props} style={styles.tabListContainer}>
       <ThemedView type="backgroundElement" style={styles.innerContainer}>
-        <ThemedText type="smallBold" style={styles.brandText}>
-          Expo Starter
-        </ThemedText>
+        
 
         {props.children}
 
-        <ExternalLink href="https://docs.expo.dev" asChild>
-          <Pressable style={styles.externalPressable}>
-            <ThemedText type="link">Docs</ThemedText>
-            <SymbolView
-              tintColor={colors.text}
-              name={{ ios: 'arrow.up.right.square', web: 'link' }}
-              size={12}
-            />
-          </Pressable>
-        </ExternalLink>
+        
       </ThemedView>
     </View>
   );
@@ -84,6 +85,7 @@ const styles = StyleSheet.create({
     justifyContent: 'center',
     alignItems: 'center',
     flexDirection: 'row',
+    bottom: 0,
   },
   innerContainer: {
     paddingVertical: Spacing.two,
@@ -104,7 +106,11 @@ const styles = StyleSheet.create({
   tabButtonView: {
     paddingVertical: Spacing.one,
     paddingHorizontal: Spacing.three,
-    borderRadius: Spacing.three,
+    borderRadius: Spacing.half,
+    display: 'flex',
+    flexDirection: "column",
+    justifyContent: "center",
+    alignContent: "center",
   },
   externalPressable: {
     flexDirection: 'row',

+ 0 - 266
src/components/ui/hud.tsx

@@ -1,266 +0,0 @@
-import { useTimeout } from "@/hooks/hooks";
-import { Ionicons } from "@expo/vector-icons";
-import {
-  createContext,
-  memo,
-  useCallback,
-  useContext,
-  useMemo,
-  useRef,
-  useState,
-} from "react";
-import { ActivityIndicator, StyleSheet, Text, View } from "react-native";
-
-// ---- Types ----
-
-type HUDType = "loading" | "error" | "success" | "progress";
-
-interface HUDProps {
-  type?: HUDType;
-  /** 0-1 的数字,表示进度 */
-  progress?: number;
-  msg?: string;
-  mask?: boolean;
-  autoHide?: boolean;
-  duration?: number;
-  onHide?: () => void;
-}
-
-export type HUDOptions = HUDProps;
-
-interface HUDHandle {
-  close: () => void;
-  update: (optionsOrMsg: Partial<HUDProps> | string) => void;
-}
-
-interface ProgressHandle {
-  close: () => void;
-  update: (progress?: number, msg?: string) => void;
-}
-
-// ---- Context ----
-
-interface HUDContextValue {
-  remove: (key: string) => void;
-  add: (props: HUDProps) => string;
-  edit: (key: string, newProps: Partial<HUDProps>) => void;
-  getList: () => Record<string, HUDProps>;
-}
-
-const HUDContext = createContext<HUDContextValue | null>(null);
-
-// ---- Internal Component ----
-
-interface HUDInnerProps extends HUDProps {
-  hudKey: string;
-  close: (key: string) => void;
-}
-
-const HUDInner = memo(function HUDInner({
-  type,
-  msg,
-  progress = 0,
-  autoHide = true,
-  duration = 200,
-  hudKey,
-  onHide,
-  close,
-  mask = false,
-}: HUDInnerProps) {
-  useTimeout(() => {
-    close(hudKey);
-    onHide?.();
-  }, autoHide ? (duration ?? 2000) : null);
-  return (
-    <View
-      // entering={FadeIn}
-      // exiting={FadeOut}
-      style={[styles.overlay, { backgroundColor: 1 ? "rgba(0,0,0,0.2)" : "transparent" }]}
-      // pointerEvents={mask ? "auto" : "box-none"}
-    >
-      <View className="flex items-center justify-center bg-gray-800 rounded-lg px-5 py-4 max-w-1/2 h-auto">
-        {type === "loading" && (
-          <ActivityIndicator size="large" color="#fff" />
-        )}
-        {type === "error" && (
-          <Ionicons name="close-circle" size={48} color="red" />
-        )}
-        {type === "success" && (
-          <Ionicons name="checkmark-circle" size={48} color="green" />
-        )}
-        {type === "progress" && (
-          <View className="w-16 h-16 rounded-full border-4 border-gray-300 items-center justify-center">
-            <View
-              className="absolute w-16 h-16 rounded-full border-4 border-primary"
-              style={{
-                transform: [{ rotate: `${(progress ?? 0) * 360}deg` }],
-              }}
-            />
-          </View>
-        )}
-        {msg != null && (
-          <Text className={type ? "mt-2 text-white" : "text-white"}>
-            {msg}
-          </Text>
-        )}
-      </View>
-    </View>
-  );
-});
-
-// ---- Key Generator ----
-
-let nextKey = 0;
-
-// ---- Provider ----
-
-export function HUDProvider({ children }: { children: React.ReactNode }) {
-  const [list, setList] = useState<Record<string, HUDProps>>({});
-  const listRef = useRef(list);
-  listRef.current = list;
-
-  const remove = useCallback((key: string) => {
-    setList((prev) => {
-      if (!prev[key]) return prev;
-      const { [key]: _, ...rest } = prev;
-      return rest;
-    });
-  }, []);
-
-  const add = useCallback((props: HUDProps) => {
-    const key = `hud_${nextKey++}`;
-    setList((prev) => ({ ...prev, [key]: props }));
-    return key;
-  }, []);
-
-  const edit = useCallback((key: string, newProps: Partial<HUDProps>) => {
-    setList((prev) => {
-      if (!prev[key]) return prev;
-      return { ...prev, [key]: { ...prev[key], ...newProps } };
-    });
-  }, [setList]);
-
-  const getList = useCallback(() => listRef.current, []);
-
-  // contextValue 引用稳定,不会因 list 变化触发 consumer 重渲染
-  const contextValue = useMemo<HUDContextValue>(
-    () => ({ remove, add, edit, getList }),
-    [remove, add, edit, getList],
-  );
-
-  return (
-    <HUDContext.Provider value={contextValue}>
-      {children}
-      {Object.entries(list).map(([key, props]) => (
-        <HUDInner key={key} hudKey={key} {...props} close={remove} />
-      ))}
-    </HUDContext.Provider>
-  );
-}
-
-// ---- Hook helpers ----
-
-function createHandle(
-  key: string,
-  remove: HUDContextValue["remove"],
-  edit: HUDContextValue["edit"],
-): HUDHandle {
-  return {
-    close: () => remove(key),
-    update: (optionsOrMsg) => {
-      edit(
-        key,
-        typeof optionsOrMsg === "string" ? { msg: optionsOrMsg } : optionsOrMsg,
-      );
-    },
-  };
-}
-
-// ---- Hook ----
-
-export default function useHUD() {
-  const ctx = useContext(HUDContext);
-  if (!ctx) throw new Error("useHUD must be used within HUDProvider");
-  const { add, edit, remove, getList } = ctx;
-
-  return useMemo(() => ({
-    hideAll: () => {
-      Object.keys(getList()).forEach(remove);
-    },
-    hideAllLoading: () => {
-      Object.entries(getList()).forEach(([key, props]) => {
-        if (props.type === "loading") remove(key);
-      });
-    },
-    show: (options: HUDOptions | string): HUDHandle => {
-      const opts: HUDProps =
-        typeof options === "string"
-          ? { msg: options, type: "loading", autoHide: true }
-          : { autoHide: true, ...options };
-      return createHandle(add(opts), remove, edit);
-    },
-    tips: (msg: string, duration?: number): HUDHandle => {
-      return createHandle(add({ msg, autoHide: true, duration }), remove, edit);
-    },
-    success: (
-      msg?: string,
-      options?: Omit<HUDProps, "progress" | "type">,
-    ): HUDHandle => {
-      return createHandle(
-        add({ type: "success", msg, autoHide: true, ...options }),
-        remove,
-        edit,
-      );
-    },
-    error: (
-      msg?: string,
-      options?: Omit<HUDProps, "progress" | "type">,
-    ): HUDHandle => {
-      return createHandle(
-        add({ type: "error", msg, autoHide: true, ...options }),
-        remove,
-        edit,
-      );
-    },
-    loading: (msg?: string, options?: Omit<HUDProps, "type">): HUDHandle => {
-      return createHandle(
-        add({ autoHide: false, mask: true, ...options, type: "loading", msg }),
-        remove,
-        edit,
-      );
-    },
-    progress: (
-      options?: Omit<HUDProps, "type" | "progress">,
-    ): ProgressHandle => {
-      const key = add({
-        mask: true,
-        ...options,
-        type: "progress",
-        progress: 0,
-        autoHide: false,
-      });
-      return {
-        close: () => remove(key),
-        update: (progress?: number, msg?: string) => {
-          edit(key, { progress, msg });
-        },
-      };
-    },
-  }), [add, edit, remove, getList]);
-}
-
-export type { HUDHandle, HUDProps, ProgressHandle };
-
-const styles = StyleSheet.create({
-  overlay: {
-    position: "absolute",
-    left: 0,
-    top: 0,
-    width: "100%",
-    height: "100%",
-    paddingBottom: '15%',
-    zIndex: 50,
-    alignItems: "center",
-    justifyContent: "center",
-  },
-});

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů