From 3f8368fb722623810117ae9ff3f2a55000982147 Mon Sep 17 00:00:00 2001 From: Charles Dudley Date: Thu, 13 Jun 2024 14:13:59 -0700 Subject: [PATCH] Update RN Share.share()'s argument types to be more explicit (#44887) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/44887 The previous inexact object types and documentation for Share.share()'s arguments have led to confusion in how this library should be used. This diff updates the argument types to be more explicit, and rewrites some of the documentation for clarity. Changelog: [General][Breaking] Update `Share.share()`'s argument types to be more explicit. Reviewed By: NickGerleman Differential Revision: D58224906 --- .../react-native/Libraries/Share/Share.d.ts | 26 ++++++++++------- .../react-native/Libraries/Share/Share.js | 29 +++++++++---------- .../__snapshots__/public-api-test.js.snap | 17 +++++------ 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/packages/react-native/Libraries/Share/Share.d.ts b/packages/react-native/Libraries/Share/Share.d.ts index 789251a2c7bcfe..a9cf70f1485e78 100644 --- a/packages/react-native/Libraries/Share/Share.d.ts +++ b/packages/react-native/Libraries/Share/Share.d.ts @@ -12,11 +12,13 @@ import {ColorValue} from '../StyleSheet/StyleSheet'; export type ShareContent = | { title?: string | undefined; - message: string; + url: string; + message?: string | undefined; } | { title?: string | undefined; - url: string; + url?: string | undefined; + message: string; }; export type ShareOptions = { @@ -40,29 +42,33 @@ export interface ShareStatic { * If the user dismissed the dialog, the Promise will still be resolved with action being `Share.dismissedAction` * and all the other keys being undefined. * - * In Android, Returns a Promise which always be resolved with action being `Share.sharedAction`. + * In Android, Returns a Promise which always resolves with action being `Share.sharedAction`. * * ### Content * + * #### iOS + * + * - `url` - a URL to share * - `message` - a message to share - * - `title` - title of the message * - * #### iOS + * At least one of `URL` or `message` is required. * - * - `url` - an URL to share + * #### Android * - * At least one of URL and message is required. + * - `title` - title of the message (optional) + * - `message` - a message to share (often will include a URL). * * ### Options * * #### iOS * - * - `excludedActivityTypes` - * - `tintColor` + * - `subject` - a subject to share via email + * - `excludedActivityTypes` + * - `tintColor` * * #### Android * - * - `dialogTitle` + * - `dialogTitle` * */ share(content: ShareContent, options?: ShareOptions): Promise; diff --git a/packages/react-native/Libraries/Share/Share.js b/packages/react-native/Libraries/Share/Share.js index 59ffde5133629e..0a21bbac142bf6 100644 --- a/packages/react-native/Libraries/Share/Share.js +++ b/packages/react-native/Libraries/Share/Share.js @@ -15,24 +15,23 @@ const processColor = require('../StyleSheet/processColor').default; const Platform = require('../Utilities/Platform'); const invariant = require('invariant'); -type Content = +export type ShareContent = | { title?: string, - message: string, - ... + url: string, + message?: string, } | { title?: string, - url: string, - ... + url?: string, + message: string, }; -type Options = { +export type ShareOptions = { dialogTitle?: string, excludedActivityTypes?: Array, tintColor?: string, subject?: string, anchor?: number, - ... }; class Share { @@ -43,21 +42,21 @@ class Share { * If the user dismissed the dialog, the Promise will still be resolved with action being `Share.dismissedAction` * and all the other keys being undefined. * - * In Android, Returns a Promise which always be resolved with action being `Share.sharedAction`. + * In Android, Returns a Promise which always resolves with action being `Share.sharedAction`. * * ### Content * - * - `message` - a message to share - * * #### iOS * * - `url` - a URL to share + * - `message` - a message to share * - * At least one of URL and message is required. + * At least one of `URL` or `message` is required. * * #### Android * - * - `title` - title of the message + * - `title` - title of the message (optional) + * - `message` - a message to share (often will include a URL). * * ### Options * @@ -73,8 +72,8 @@ class Share { * */ static share( - content: Content, - options: Options = {}, + content: ShareContent, + options: ShareOptions = {}, ): Promise<{action: string, activityType: ?string}> { invariant( typeof content === 'object' && content !== null, @@ -82,7 +81,7 @@ class Share { ); invariant( typeof content.url === 'string' || typeof content.message === 'string', - 'At least one of URL and message is required', + 'At least one of URL or message is required', ); invariant( typeof options === 'object' && options !== null, diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 5846450e770873..9e2246121538a1 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -7340,29 +7340,28 @@ declare export default typeof NativeShareModule; `; exports[`public API should not change unintentionally Libraries/Share/Share.js 1`] = ` -"type Content = +"export type ShareContent = | { title?: string, - message: string, - ... + url: string, + message?: string, } | { title?: string, - url: string, - ... + url?: string, + message: string, }; -type Options = { +export type ShareOptions = { dialogTitle?: string, excludedActivityTypes?: Array, tintColor?: string, subject?: string, anchor?: number, - ... }; declare class Share { static share( - content: Content, - options: Options + content: ShareContent, + options: ShareOptions ): Promise<{ action: string, activityType: ?string }>; static sharedAction: \\"sharedAction\\"; static dismissedAction: \\"dismissedAction\\";