diff --git a/cndocs/accessibilityinfo.md b/cndocs/accessibilityinfo.md index 34226d56f01..5798bdc3254 100644 --- a/cndocs/accessibilityinfo.md +++ b/cndocs/accessibilityinfo.md @@ -257,7 +257,7 @@ static prefersCrossFadeTransitions(): Promise; ### 🗑️ `setAccessibilityFocus()` -:::warning Deprecated +:::warning[Deprecated] 建议改用 `sendAccessibilityEvent`,并将 `eventType` 设为 `focus`。 ::: diff --git a/cndocs/backhandler.md b/cndocs/backhandler.md index d90ac7dc341..5bd6cf21b98 100644 --- a/cndocs/backhandler.md +++ b/cndocs/backhandler.md @@ -10,7 +10,7 @@ Backhandler API 检测用于后退导航的硬件按钮按下情况,允许您 - **如果一个订阅返回true,**那么之前注册的订阅将不会被调用。 - **如果没有订阅返回 true 或没有注册,** 它会以编程方式调用默认后退按钮功能以退出应用程序。 -:::warning 对模式用户的警告 +:::warning[对模式用户的警告] 如果您的应用程序显示打开的“Modal”,则“BackHandler”将不会发布任何事件([请参阅“Modal”文档](modal#onrequestclose))。 ::: diff --git a/cndocs/building-for-tv.md b/cndocs/building-for-tv.md index 147dcafd448..2b8bebb5308 100644 --- a/cndocs/building-for-tv.md +++ b/cndocs/building-for-tv.md @@ -6,6 +6,6 @@ hide_table_of_contents: true 实现电视设备支持的目的是使现有的 React Native 应用程序可以在 Apple TV 和 Android TV 上运行,而应用程序的 JavaScript 代码只需很少或无需更改。 -:::警告 已弃用 +:::warning[已弃用] 电视支持已移至 [React Native for TV](https://github.com/react-native-tvos/react-native-tvos#readme) 存储库。请参阅此处的**自述文件**,了解有关 Apple TV 或 Android TV 项目的信息。 ::: diff --git a/cndocs/global-PerformanceEventTiming.md b/cndocs/global-PerformanceEventTiming.md index 3439e405deb..e2050b1b787 100644 --- a/cndocs/global-PerformanceEventTiming.md +++ b/cndocs/global-PerformanceEventTiming.md @@ -3,7 +3,7 @@ id: global-PerformanceEventTiming title: PerformanceEventTiming --- -:::warning +:::warning[部分支持] 🚧 本页面仍在完善中,请参考 [MDN 文档](https://developer.mozilla.org/zh-CN/docs/Web/API/PerformanceEventTiming) 获取更多信息。 ::: diff --git a/cndocs/global-PerformanceLongTaskTiming.md b/cndocs/global-PerformanceLongTaskTiming.md index 891c4aa4955..ac7a7fcd5e3 100644 --- a/cndocs/global-PerformanceLongTaskTiming.md +++ b/cndocs/global-PerformanceLongTaskTiming.md @@ -3,7 +3,7 @@ id: global-PerformanceLongTaskTiming title: PerformanceLongTaskTiming --- -:::warning +:::warning[部分支持] 🚧 本页面仍在完善中,请参考 [MDN 文档](https://developer.mozilla.org/zh-CN/docs/Web/API/PerformanceLongTaskTiming) 获取更多信息。 ::: diff --git a/cndocs/global-PerformanceResourceTiming.md b/cndocs/global-PerformanceResourceTiming.md index 33c49e38f0d..c7470a287be 100644 --- a/cndocs/global-PerformanceResourceTiming.md +++ b/cndocs/global-PerformanceResourceTiming.md @@ -5,7 +5,7 @@ title: PerformanceResourceTiming 全局 [`PerformanceResourceTiming`](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming) 类,遵循 Web 规范定义。 -:::warning 部分支持 +:::warning[部分支持] React Native 仅实现了以下 `PerformanceResourceTiming` 属性: diff --git a/cndocs/global-intersectionobserver.md b/cndocs/global-intersectionobserver.md index 36de82da7e1..c54e5c774ac 100644 --- a/cndocs/global-intersectionobserver.md +++ b/cndocs/global-intersectionobserver.md @@ -38,12 +38,12 @@ new IntersectionObserver(callback, options?) 一个可选对象,包含以下属性: -| 名称 | 类型 | 说明 | -| -------------------- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `root` | [Element](element-nodes) \| null | 目标的祖先元素,其边界矩形将被视为视口。如果未指定或为 `null`,则默认为根视口。 | -| `rootMargin` | string | 计算交叉时添加到根边界框的偏移量字符串。默认为 `"0px 0px 0px 0px"`。 | -| `threshold` | number \| number[] | 一个数值或数值数组(范围 0.0 到 1.0),指定目标元素交叉面积与总边界框面积的比值。如果未设置 `rnRootThreshold`,则默认为 `[0]`。 | -| `rnRootThreshold` ⚠️ | number \| number[] | **React Native 特有。** 一个数值或数值数组(范围 0.0 到 1.0),指定交叉面积与根元素总面积的比值。 | +| 名称 | 类型 | 说明 | +| -------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| `root` | [Element](element-nodes) \| null | 目标的祖先元素,其边界矩形将被视为视口。如果未指定或为 `null`,则默认为根视口。 | +| `rootMargin` | string | 计算交叉时添加到根边界框的偏移量字符串。默认为 `"0px 0px 0px 0px"`。 | +| `threshold` | number \| number[] | 一个数值或数值数组(范围 0.0 到 1.0),指定目标元素交叉面积与总边界框面积的比值。如果未设置 `rnRootThreshold`,则默认为 `[0]`。 | +| `rnRootThreshold` ⚠️ | number \| number[] | **React Native 特有。** 一个数值或数值数组(范围 0.0 到 1.0),指定交叉面积与根元素总面积的比值。 | ## 实例属性 @@ -61,7 +61,7 @@ new IntersectionObserver(callback, options?) ### `rnRootThresholds` ⚠️ -:::warning 非标准 +:::warning[非标准] 这是 React Native 特有的扩展。 ::: diff --git a/cndocs/global-intersectionobserverentry.md b/cndocs/global-intersectionobserverentry.md index fca9f179f69..83d014f06b7 100644 --- a/cndocs/global-intersectionobserverentry.md +++ b/cndocs/global-intersectionobserverentry.md @@ -43,7 +43,7 @@ import CanaryAPIWarning from './\_canary-channel-api-warning.mdx'; ### `rnRootIntersectionRatio` ⚠️ -:::warning 非标准 +:::warning[非标准] 这是 React Native 特有的扩展。 ::: diff --git a/cndocs/global-performance.md b/cndocs/global-performance.md index b8376a9f9a1..49352d69f85 100644 --- a/cndocs/global-performance.md +++ b/cndocs/global-performance.md @@ -21,7 +21,7 @@ title: performance ### `rnStartupTiming` ⚠️ -:::warning 非标准 +:::warning[非标准] 这是 React Native 特有的扩展。 ::: @@ -33,15 +33,15 @@ get rnStartupTiming(): ReactNativeStartupTiming; `ReactNativeStartupTiming` 接口提供以下字段: -| 名称 | 类型 | 描述 | -| ---------------------------------------- | -------------- | ---------------------------------------------- | -| `startTime` | number \| void | React Native 运行时初始化开始的时间。 | -| `executeJavaScriptBundleEntryPointStart` | number \| void | 应用 bundle 开始执行的时间。 | -| `endTime` | number \| void | React Native 运行时完全初始化完成的时间。 | +| 名称 | 类型 | 描述 | +| ---------------------------------------- | -------------- | ----------------------------------------- | +| `startTime` | number \| void | React Native 运行时初始化开始的时间。 | +| `executeJavaScriptBundleEntryPointStart` | number \| void | 应用 bundle 开始执行的时间。 | +| `endTime` | number \| void | React Native 运行时完全初始化完成的时间。 | ### `timeOrigin` -:::warning 部分支持 +:::warning[部分支持] 提供的是从 UNIX 纪元到系统启动的毫秒数,而非从 UNIX 纪元到应用启动的毫秒数。 ::: @@ -79,7 +79,7 @@ get rnStartupTiming(): ReactNativeStartupTiming; ### `now()` -:::warning 部分支持 +:::warning[部分支持] 提供的是从系统启动开始的毫秒数,而非从应用启动开始的毫秒数。 ::: diff --git a/cndocs/integration-with-android-fragment.md b/cndocs/integration-with-android-fragment.md index 31f7cd28096..491bfc800b7 100644 --- a/cndocs/integration-with-android-fragment.md +++ b/cndocs/integration-with-android-fragment.md @@ -32,7 +32,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con 进入你的宿主 Activity,确保它实现了 `DefaultHardwareBackBtnHandler` 接口: -:::warning 已弃用 +:::warning[已弃用] 自 API 级别 33 起,`Activity.onBackPressed()` 已被[弃用]()。面向 API 级别 36 的 Android 16 设备将[不再调用此方法](https://developer.android.com/about/versions/16/behavior-changes-16#predictive-back),应改用 [OnBackPressedDispatcher](https://developer.android.com/reference/androidx/activity/OnBackPressedDispatcher)。 ::: diff --git a/cndocs/interactionmanager.md b/cndocs/interactionmanager.md index 04c19bc067c..ba6af655187 100644 --- a/cndocs/interactionmanager.md +++ b/cndocs/interactionmanager.md @@ -5,7 +5,7 @@ title: 🗑️ InteractionManager import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; -:::warning 已废弃 +:::warning[已废弃] 避免长时间运行的工作,改用 [`requestIdleCallback`](global-requestIdleCallback)。 ::: diff --git a/cndocs/modal.md b/cndocs/modal.md index 5fcd9214620..e26a47198fd 100644 --- a/cndocs/modal.md +++ b/cndocs/modal.md @@ -106,7 +106,7 @@ export default App; ### 🗑️ `animated` -:::warning 已弃用 +:::warning[已弃用] 请改用 [`animationType`](modal.md#animationtype) 属性。 ::: diff --git a/cndocs/network.md b/cndocs/network.md index 0441208ba05..447011d6722 100644 --- a/cndocs/network.md +++ b/cndocs/network.md @@ -231,7 +231,7 @@ request.open('GET', 'https://mywebsite.com/endpoint/'); request.send(); ``` -:::warning 注意 +:::warning[注意] XMLHttpRequest 的安全模型与网页不同,因为在原生应用中没有[跨域](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing)的概念。 ::: diff --git a/cndocs/other-debugging-methods.md b/cndocs/other-debugging-methods.md index e8f187c5b58..c49e506699b 100644 --- a/cndocs/other-debugging-methods.md +++ b/cndocs/other-debugging-methods.md @@ -27,7 +27,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con ## 远程 JavaScript 调试(已移除) -:::warning 重要 +:::warning[重要] 远程 JavaScript 调试功能已在 React Native 0.79 版本中移除。请查看原始的[弃用公告](https://github.com/react-native-community/discussions-and-proposals/discussions/734)。 如果你使用的是较旧版本的 React Native,请查阅[对应版本的文档](/versions)。 diff --git a/cndocs/progressbarandroid.md b/cndocs/progressbarandroid.md index 0b0d80a1aeb..6cb300d80a5 100644 --- a/cndocs/progressbarandroid.md +++ b/cndocs/progressbarandroid.md @@ -3,7 +3,7 @@ id: progressbarandroid title: '🗑️ ProgressBarAndroid' --- -:::warning Deprecated +:::warning[Deprecated] Use one of the [community packages](https://reactnative.directory/?search=progressbar) instead. ::: diff --git a/cndocs/pushnotificationios.md b/cndocs/pushnotificationios.md index 35b7543c47e..daddbb7acaa 100644 --- a/cndocs/pushnotificationios.md +++ b/cndocs/pushnotificationios.md @@ -3,7 +3,7 @@ id: pushnotificationios title: '🗑️ PushNotificationIOS' --- -:::warning 已弃用 +:::warning[已弃用] 请改用[社区提供的替代方案](https://reactnative.directory/?search=notification)。 ::: @@ -201,9 +201,9 @@ static getDeliveredNotifications(callback: (notifications: Object[]) => void); **参数:** -| 名称 | 类型 | 必需 | 说明 | -| -------- | -------- | ---- | ------------------------------------ | -| callback | function | 是 | 接收已送达通知数组的函数。 | +| 名称 | 类型 | 必需 | 说明 | +| -------- | -------- | ---- | -------------------------- | +| callback | function | 是 | 接收已送达通知数组的函数。 | 一个已送达的通知是包含以下字段的对象: @@ -226,9 +226,9 @@ static removeDeliveredNotifications(identifiers: string[]); **参数:** -| 名称 | 类型 | 必需 | 说明 | -| ----------- | ----- | ---- | -------------------- | -| identifiers | array | 是 | 通知标识符数组。 | +| 名称 | 类型 | 必需 | 说明 | +| ----------- | ----- | ---- | ---------------- | +| identifiers | array | 是 | 通知标识符数组。 | --- @@ -258,9 +258,9 @@ static getApplicationIconBadgeNumber(callback: (num: number) => void); **参数:** -| 名称 | 类型 | 必需 | 说明 | -| -------- | -------- | ---- | ------------------------------ | -| callback | function | 是 | 处理当前角标数字的函数。 | +| 名称 | 类型 | 必需 | 说明 | +| -------- | -------- | ---- | ------------------------ | +| callback | function | 是 | 处理当前角标数字的函数。 | --- @@ -292,9 +292,9 @@ static getScheduledLocalNotifications( **参数:** -| 名称 | 类型 | 必需 | 说明 | -| -------- | -------- | ---- | -------------------------------------- | -| callback | function | 是 | 处理描述本地通知的对象数组的函数。 | +| 名称 | 类型 | 必需 | 说明 | +| -------- | -------- | ---- | ---------------------------------- | +| callback | function | 是 | 处理描述本地通知的对象数组的函数。 | --- @@ -340,9 +340,9 @@ static removeEventListener( **参数:** -| 名称 | 类型 | 必需 | 说明 | -| ---- | ------ | ---- | ----------------------------------------------- | -| type | string | 是 | 事件类型。可选值参见 `addEventListener()`。 | +| 名称 | 类型 | 必需 | 说明 | +| ---- | ------ | ---- | ------------------------------------------- | +| type | string | 是 | 事件类型。可选值参见 `addEventListener()`。 | --- @@ -364,9 +364,9 @@ static requestPermissions(permissions?: PushNotificationPermissions[]); **参数:** -| 名称 | 类型 | 必需 | 说明 | -| ----------- | ----- | ---- | ---------------------- | -| permissions | array | 否 | alert、badge 或 sound | +| 名称 | 类型 | 必需 | 说明 | +| ----------- | ----- | ---- | --------------------- | +| permissions | array | 否 | alert、badge 或 sound | --- @@ -447,7 +447,7 @@ finish(result: string); 在 JS 端完成通知处理后,调用 `finish()` 来执行原生完成处理器。调用此方法时,传入最能描述操作结果的获取结果值。可能的值列表请参见 `PushNotificationIOS.FetchResult`。 -如果你使用了 `application:didReceiveRemoteNotification:fetchCompletionHandler:`,你_必须_调用此处理器,并且应尽快调用。更多详情请参阅[官方文档](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application?language=objc)。 +如果你使用了 `application:didReceiveRemoteNotification:fetchCompletionHandler:`,你*必须*调用此处理器,并且应尽快调用。更多详情请参阅[官方文档](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application?language=objc)。 --- diff --git a/cndocs/safeareaview.md b/cndocs/safeareaview.md index 9aa0ead959c..d417246625e 100644 --- a/cndocs/safeareaview.md +++ b/cndocs/safeareaview.md @@ -3,7 +3,7 @@ id: safeareaview title: '🗑️ SafeAreaView' --- -:::warning 已弃用 +:::warning[已弃用] 请改用 [react-native-safe-area-context](https://github.com/AppAndFlow/react-native-safe-area-context)。 ::: diff --git a/cndocs/security.md b/cndocs/security.md index d7c70b8115d..b53bac2a533 100644 --- a/cndocs/security.md +++ b/cndocs/security.md @@ -27,11 +27,11 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con [Async Storage](https://github.com/react-native-async-storage/async-storage) 是一个由社区维护的 React Native 模块,它提供了一个异步、未加密的键值对存储。异步存储不是在应用之间共享的:每个应用都有自己的沙盒环境,并且无法访问其他应用的数据。 -| **使用Async Storage的情况** | **不推荐使用Async Storage的情况** | -| ---------------------- | -------------------------- | -| 在应用运行间持久保存非敏感数据 | 令牌存储 | -| 持久保存 Redux 状态 | 密钥 | -| 持久保存 GraphQL 状态 | | +| **使用Async Storage的情况** | **不推荐使用Async Storage的情况** | +| ------------------------------ | --------------------------------- | +| 在应用运行间持久保存非敏感数据 | 令牌存储 | +| 持久保存 Redux 状态 | 密钥 | +| 持久保存 GraphQL 状态 | | :::note Async Storage 是 React Native 中与 Web 的 Local Storage 类似的功能 @@ -58,11 +58,10 @@ React Native 本身没有提供任何用于安全地储存敏感数据的方式 - [expo-secure-store](https://docs.expo.dev/versions/latest/sdk/securestore/) - [react-native-keychain](https://github.com/oblador/react-native-keychain) -:::warning Caution +:::warning[Caution] **请注意不要无意中存储或暴露敏感信息。**这可能会意外发生,例如在redux状态中保存敏感表单数据并持久化整个状态树到Async Storage。或者将用户令牌和个人信息发送到应用程序监控服务如Sentry或Crashlytics。 ::: - ## 认证和深度链接(Deep Linking)  @@ -86,14 +85,14 @@ OAuth2 认证协议现在非常流行,被誉为最完整和安全的协议之 [PKCE](https://oauth.net/2/pkce/)发音为“Pixy”代表Proof of Key Code Exchange,是对OAuth 2规范的一个扩展。这涉及到增加了一层安全措施,用来验证身份验证和令牌交换请求来自同一个客户端。PKCE使用了SHA256加密哈希算法。SHA256 为任意大小的文字或者文件创建了一个独特的“签名”,但它: -* 不管输入文件的大小总是保持一致的长度 -* 对同样的输入始终产生一样的结果 -* 是单向的(也就是说你不可以通过它反向工程出原始输入) - +- 不管输入文件的大小总是保持一致的长度 +- 对同样的输入始终产生一样的结果 +- 是单向的(也就是说你不可以通过它反向工程出原始输入) + 现在你有这两个值: -* **code_verifier** -由客户端生成的大随机字符串 -* **code_challenge** - code_verifier 的 SHA256 +- **code_verifier** -由客户端生成的大随机字符串 +- **code_challenge** - code_verifier 的 SHA256 在初始的 `/authorize` 请求期间,客户端还会发送它保存在内存中的 `code_verifier` 对应的 `code_challenge`。授权请求正确返回后,客户端还会发送用于生成 `code_challenge` 的 `code_verifier`。身份提供商(IDP)随后会计算 `code_challenge`,检查它是否与最初的 `/authorize` 请求中设置的值匹配,并仅在值匹配时才发送访问令牌。 @@ -117,7 +116,7 @@ React-native-app-auth 只有在您的身份提供商支持 PKCE 时才能支持 **SSL固定**是一种可以在客户端使用的技巧来避免这种攻击。它的工作原理是在开发期间将受信任的证书列表嵌入(或固定)到客户端中,以便只接受用其中一个受信任的证书签名的请求,并拒绝任何自签名的证书。 -:::warning Caution +:::warning[Caution] 使用SSL固定时,您应该注意到期日期的问题。每1-2年就需要更新一次数字认证书,在数字认证书过期之后需要同时更新应用程序和服务器上的版本信息。一旦服务器上的数字认证书得到更新,则那些内嵌有旧版数字认证书的应用将无法正常工作了。 ::: diff --git a/cndocs/statusbar.md b/cndocs/statusbar.md index 6c657b58cfa..52e190a5ec8 100644 --- a/cndocs/statusbar.md +++ b/cndocs/statusbar.md @@ -440,7 +440,7 @@ static setHidden(hidden: boolean, animation?: StatusBarAnimation); ### 🗑️ `setNetworkActivityIndicatorVisible()`
iOS
-:::warning 已弃用 +:::warning[已弃用] iOS 13 及更高版本不再支持状态栏网络活动指示器。此方法将在未来版本中移除。 ::: diff --git a/cndocs/stylesheet.md b/cndocs/stylesheet.md index dedd1f08334..f0b90833b5e 100644 --- a/cndocs/stylesheet.md +++ b/cndocs/stylesheet.md @@ -171,7 +171,7 @@ export default App; ### `setStyleAttributePreprocessor()` -:::warning 实验性功能 +:::warning[实验性功能] 可能会频繁发生破坏性变更,且不一定会提前通知。整个功能都可能被删除。使用需自担风险。 ::: diff --git a/cndocs/textinput.md b/cndocs/textinput.md index 439b9f55670..f96054823df 100644 --- a/cndocs/textinput.md +++ b/cndocs/textinput.md @@ -235,7 +235,7 @@ The following values work across platforms: ### 🗑️ `blurOnSubmit` -:::warning Deprecated +:::warning[Deprecated] `submitBehavior` 现在取代了 `blurOnSubmit`,并会覆盖由 `blurOnSubmit` 定义的行为。详见 [submitBehavior](textinput#submitbehavior)。 ::: diff --git a/cndocs/timers.md b/cndocs/timers.md index 3e0abf52c78..92c49151550 100644 --- a/cndocs/timers.md +++ b/cndocs/timers.md @@ -25,7 +25,7 @@ title: 定时器 ## InteractionManager -:::warning 已弃用 +:::warning[已弃用] `InteractionManager` 的行为已更改为与 `setImmediate` 相同,应该改用 `setImmediate`。 ::: diff --git a/cndocs/transforms.md b/cndocs/transforms.md index ecaee8b9ac3..8d0fe6aa20f 100644 --- a/cndocs/transforms.md +++ b/cndocs/transforms.md @@ -267,7 +267,7 @@ export default App; ### 🗑️ `decomposedMatrix`, `rotation`, `scaleX`, `scaleY`, `transformMatrix`, `translateX`, `translateY` -:::warning 已弃用 +:::warning[已弃用] 请使用 [`transform`](transforms#transform) 属性代替。 ::: diff --git a/cndocs/virtualizedlist.md b/cndocs/virtualizedlist.md index 76db5a68269..10deb7a4f05 100644 --- a/cndocs/virtualizedlist.md +++ b/cndocs/virtualizedlist.md @@ -557,7 +557,9 @@ CellRendererComponent 允许自定义由 `renderItem`/`ListItemComponent` 渲染 ### 🗑️ `disableVirtualization` -**已过时** : Virtualization 提供了显著的性能和内存优化,并且完全卸载了位于可视区之外的 react 实例。当且仅当为了调试,你才可以关闭这个特性。 +:::warning[已弃用] +Virtualization 能显著优化性能和内存使用,但会完全卸载渲染窗口之外的 React 实例。你应该只在调试时才需要禁用它。 +::: | 类型 | 必需 | | ---- | ---- | diff --git a/cnwebsite/docusaurus.config.ts b/cnwebsite/docusaurus.config.ts index 0382d689117..c133d456fb3 100644 --- a/cnwebsite/docusaurus.config.ts +++ b/cnwebsite/docusaurus.config.ts @@ -5,7 +5,7 @@ import path from 'path'; import prismThemeDark from './core/PrismThemeDark'; import prismThemeLight from './core/PrismThemeLight'; -// const users = require('./showcase.json'); +import users from './showcase.json'; const versions = require('./versions.json'); const lastVersion = versions[0]; const cdnUrl = ''; @@ -63,6 +63,9 @@ const config: Config = { ], favicon: cdnUrl + 'img/favicon.ico', titleDelimiter: '·', + customFields: { + users, + }, onBrokenLinks: 'ignore', onBrokenAnchors: 'ignore', presets: [ diff --git a/cnwebsite/src/components/Home/Community/PartnersShowcase.tsx b/cnwebsite/src/components/Home/Community/PartnersShowcase.tsx new file mode 100644 index 00000000000..9357613c7de --- /dev/null +++ b/cnwebsite/src/components/Home/Community/PartnersShowcase.tsx @@ -0,0 +1,68 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {useEffect, useState} from 'react'; + +import CallstackWordmark from '@site/static/img/showcase/callstack_wordmark.svg'; +import ExpoWordmark from '@site/static/img/showcase/expo-wordmark.svg'; +import InfiniteRedWordmark from '@site/static/img/showcase/infinite-red-wordmark.svg'; +import MicrosoftWordmark from '@site/static/img/showcase/microsoft-wordmark.svg'; +import SWMWordmark from '@site/static/img/showcase/swm-wordmark.svg'; +import {PartnerLink} from '@site/src/types'; + +import styles from './styles.module.css'; + +const PARTNERS = [ + { + href: 'https://callstack.com/', + logo: , + }, + { + href: 'https://expo.dev/', + className: styles.expo, + logo: , + }, + { + href: 'https://infinite.red/', + logo: , + }, + { + href: 'https://www.microsoft.com/', + logo: , + }, + { + href: 'https://swmansion.com/', + logo: , + }, +]; + +export default function PartnersShowcase() { + const [partners, setPartners] = useState(PARTNERS); + + useEffect(() => { + setPartners(currentCompanies => shuffleItems(currentCompanies)); + }, []); + + return ( +
+ {partners.map(({href, className, logo}) => ( + + {logo} + + ))} +
+ ); +} + +function shuffleItems(apps: PartnerLink[]) { + return [...apps].sort(() => 0.5 - Math.random()); +} diff --git a/cnwebsite/src/components/Home/Community/index.tsx b/cnwebsite/src/components/Home/Community/index.tsx index 05e5db13dec..c7b72860045 100644 --- a/cnwebsite/src/components/Home/Community/index.tsx +++ b/cnwebsite/src/components/Home/Community/index.tsx @@ -5,11 +5,11 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; - import useBaseUrl from '@docusaurus/useBaseUrl'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import {ShowcaseData} from '@site/src/types'; +import PartnersShowcase from './PartnersShowcase'; import Section from '../Section'; import SectionTitle from '../SectionTitle'; @@ -17,85 +17,87 @@ import styles from './styles.module.css'; function Community() { const {siteConfig} = useDocusaurusContext(); - const apps = Object.values(siteConfig.customFields.users) + const apps = Object.values(siteConfig.customFields?.users as ShowcaseData) .flat() - .filter(app => app.pinned); + .filter(app => Boolean(app.pinned)); return (
- + + React Native 正被用于成千上万款应用, +
+ 你很可能已经用过其中之一。 + + } + />
-
-

- Meta released React Native in 2015 and has been maintaining it ever - since. -

-

- In 2018, React Native had the{' '} - - 2nd highest - {' '} - number of contributors for any repository in GitHub. Today, React - Native is supported by contributions from individuals and companies - around the world including{' '} - - Callstack - - ,{' '} - - Expo - - , Infinite Red,{' '} - Microsoft and{' '} - Software Mansion. -

-

- Our community is always shipping exciting new projects and exploring - platforms beyond Android and iOS with repos like{' '} - - - React Native Windows - - - ,{' '} - - React Native macOS - {' '} - and{' '} - - React Native Web - - . -

-
-
-

- React Native is being used in thousands of apps, but it's likely - you've already used it in one of these apps: -

-
    - {apps.map((app, i) => { - const imgSource = !app.icon.startsWith('http') - ? useBaseUrl('img/showcase/' + app.icon) - : app.icon; - return ( -
  • - {app.infoLink ? ( - - {app.name} - - ) : ( +
      + {apps.map((app, i) => { + const imgSource = !app.icon.startsWith('http') + ? useBaseUrl('img/showcase/' + app.icon) + : app.icon; + return ( +
    • + {app.infoLink ? ( + {app.name} - )} -
    • - ); - })} -
    -

    - and many more. -

    -
+ + ) : ( + {app.name} + )} + + ); + })} + +
+ + 查看全部精选应用 + +
+

+ Meta 在 2015 年发布了 React Native,并一直维护至今。 +
+ 如今,React Native 也由来自世界各地的个人和公司共同贡献支持,包括: +

+ +

+ 此外,我们的社区也在不断推出令人兴奋的新项目,并通过{' '} + + React Native Windows + + 、{' '} + + React Native macOS + {' '} + 和{' '} + + React Native Web + {' '} + 等项目持续拓展 Android 与 iOS 之外的平台。 +

+ + 进一步了解生态系统 +
); } diff --git a/cnwebsite/src/components/Home/Community/styles.module.css b/cnwebsite/src/components/Home/Community/styles.module.css index 10cf5dd032d..5c9f6d52b81 100644 --- a/cnwebsite/src/components/Home/Community/styles.module.css +++ b/cnwebsite/src/components/Home/Community/styles.module.css @@ -6,26 +6,134 @@ */ .featureContainer { + margin: 32px auto 16px; +} + +.appList { display: flex; - justify-content: space-between; - gap: 2rem; - margin: 1rem auto; + flex-wrap: wrap; + justify-content: center; + gap: 16px; + padding: 0; + + li { + list-style: none; + width: calc((100% - 9 * 16px) / 10); + + a { + border-bottom: 0 !important; + + &:hover { + img { + transform: scale(1.05); + } + } + } + + img { + display: block; + width: 100%; + border-radius: 16px; + overflow: hidden; + box-shadow: 0 6px 14px rgb(20 20 20 / 0.08); + transition: transform 0.2s ease-in-out; + } + } } -.featureContainer > :first-child { - border-right: 1px solid var(--home-border); - padding-right: 2rem; +@media only screen and (max-width: 800px) { + .appList li { + width: calc((100% - 6 * 16px) / 7); + } } -@media only screen and (max-width: 900px) { - .featureContainer { - flex-direction: column; - gap: 0rem; - max-width: 600px; +@media only screen and (max-width: 450px) { + .appList li { + width: calc((100% - 3 * 16px) / 4); } +} + +.partnersContainer { + display: grid; + grid-template-columns: 1fr 1fr 1fr 1fr 1fr; + align-items: center; + justify-content: center; + gap: 16px; + padding: 20px 0 40px; + + a { + display: flex; + justify-content: center; + color: var(--ifm-heading-color); + + &, + &:hover { + border-bottom: 0 !important; + } + + &.expo svg { + max-width: 130px; + } + } + + svg { + max-width: 142px; + max-height: 56px; + } +} - .featureContainer > :first-child { - border-right: none; - padding-right: 0; +html[data-theme="dark"] { + .partnersContainer a { + color: var(--ifm-heading-color) !important; } } + +@media only screen and (max-width: 800px) { + .partnersContainer { + grid-template-columns: 1fr 1fr 1fr; + gap: 20px 24px; + } +} + +@media only screen and (max-width: 450px) { + .partnersContainer { + grid-template-columns: 1fr 1fr; + column-gap: 32px; + } +} + +.communityNote { + margin-top: 52px; + margin-bottom: 8px; + text-align: center; + color: var(--home-secondary-text); + padding: 0 12px; + font-size: 0.9rem; +} + +.secondaryButton { + padding: 10px 24px; + border-radius: 99rem; + font-weight: bold; + font-size: 1rem; + display: flex; + align-items: center; + justify-content: center; + gap: 0.35rem; + color: var(--home-button-secondary-text); + border: 1px solid var(--home-button-secondary-border); + background-color: var(--home-button-secondary); + transition: background-color 200ms ease-in-out; + + &:hover { + background-color: var(--home-button-secondary-hover); + color: var(--home-button-secondary-text); + } +} + +.buttonGroup { + display: flex; + justify-content: center; + gap: 16px; + margin-top: 16px; +} diff --git a/cnwebsite/src/types/index.d.ts b/cnwebsite/src/types/index.d.ts new file mode 100644 index 00000000000..611ef258d88 --- /dev/null +++ b/cnwebsite/src/types/index.d.ts @@ -0,0 +1,13 @@ +import {ReactNode} from 'react'; + +import users from '../../showcase.json'; + +export type ShowcaseApp = (typeof users)[keyof typeof users][number]; + +export type ShowcaseData = Record; + +export type PartnerLink = { + href: string; + className?: string; + logo: ReactNode; +}; diff --git a/cnwebsite/static/img/showcase/callstack_wordmark.svg b/cnwebsite/static/img/showcase/callstack_wordmark.svg new file mode 100644 index 00000000000..b94c7f3e6e6 --- /dev/null +++ b/cnwebsite/static/img/showcase/callstack_wordmark.svg @@ -0,0 +1,3 @@ + + + diff --git a/cnwebsite/static/img/showcase/expo-wordmark.svg b/cnwebsite/static/img/showcase/expo-wordmark.svg new file mode 100644 index 00000000000..62fe56891b1 --- /dev/null +++ b/cnwebsite/static/img/showcase/expo-wordmark.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cnwebsite/static/img/showcase/infinite-red-wordmark.svg b/cnwebsite/static/img/showcase/infinite-red-wordmark.svg new file mode 100644 index 00000000000..01b71f28dd0 --- /dev/null +++ b/cnwebsite/static/img/showcase/infinite-red-wordmark.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cnwebsite/static/img/showcase/microsoft-wordmark.svg b/cnwebsite/static/img/showcase/microsoft-wordmark.svg new file mode 100644 index 00000000000..e8c71b399e8 --- /dev/null +++ b/cnwebsite/static/img/showcase/microsoft-wordmark.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/cnwebsite/static/img/showcase/swm-wordmark.svg b/cnwebsite/static/img/showcase/swm-wordmark.svg new file mode 100644 index 00000000000..c745750fac1 --- /dev/null +++ b/cnwebsite/static/img/showcase/swm-wordmark.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file