Skip to content

Commit

Permalink
Add possibility to disable buttons in action sheet ios (#28792)
Browse files Browse the repository at this point in the history
Summary:
I've noticed that currently there is no option to disable button within the `ActionSheetIOS`. It can be really useful and decided to extend the API to support that functionality.

I added a new option called `disabledButtonsIndices` to `ActionSheetIOS` which is an array of button indices which should be disabled.

`ActionSheetIOS` documentation - PR facebook/react-native-website#1898

## Changelog

[iOS] [Added] - Add disableButtonsIndices option to ActionSheetIOS component
Pull Request resolved: #28792

Test Plan:
1. Run the `RNTester`
2. Choose `ActionSheetIOS`
3. Check the fourth example `Show Action Sheet with disabled buttons`
4. `Option 1` and `Option 2` should be disabled

screenshot | gif
 --- | ---
<img width="493" alt="Screenshot 2020-04-30 at 15 16 22" src="https://user-images.githubusercontent.com/22746080/80739025-1ec52780-8b16-11ea-8b1c-30bb40ad8c99.png"> | ![action_sheet_disabled](https://user-images.githubusercontent.com/22746080/80739043-24227200-8b16-11ea-8bcb-af25eb57baac.gif)

Differential Revision: D21396409

Pulled By: shergin

fbshipit-source-id: b3c3e442965160e0c5e52854352f0540575c4d4c
  • Loading branch information
lukewalczak authored and facebook-github-bot committed May 19, 2020
1 parent 4aaf629 commit f0bf4b0
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Libraries/ActionSheetIOS/ActionSheetIOS.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const ActionSheetIOS = {
* - `destructiveButtonIndex` (int or array of ints) - index or indices of destructive buttons in `options`
* - `title` (string) - a title to show above the action sheet
* - `message` (string) - a message to show below the title
* - `disabledButtonIndices` (array of numbers) - a list of button indices which should be disabled
*
* The 'callback' function takes one parameter, the zero-based index
* of the selected item.
Expand All @@ -49,6 +50,7 @@ const ActionSheetIOS = {
+anchor?: ?number,
+tintColor?: ColorValue | ProcessedColorValue,
+userInterfaceStyle?: string,
+disabledButtonIndices?: Array<number>,
|},
callback: (buttonIndex: number) => void,
) {
Expand Down
1 change: 1 addition & 0 deletions Libraries/ActionSheetIOS/NativeActionSheetManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface Spec extends TurboModule {
+anchor?: ?number,
+tintColor?: ?number,
+userInterfaceStyle?: ?string,
+disabledButtonIndices?: Array<number>,
|},
callback: (buttonIndex: number) => void,
) => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ namespace JS {
folly::Optional<double> anchor() const;
folly::Optional<double> tintColor() const;
NSString *userInterfaceStyle() const;
folly::Optional<facebook::react::LazyVector<double>> disabledButtonIndices() const;

SpecShowActionSheetWithOptionsOptions(NSDictionary *const v) : _v(v) {}
private:
Expand Down Expand Up @@ -2941,6 +2942,11 @@ inline NSString *JS::NativeActionSheetManager::SpecShowActionSheetWithOptionsOpt
id const p = _v[@"userInterfaceStyle"];
return RCTBridgingToString(p);
}
inline folly::Optional<facebook::react::LazyVector<double>> JS::NativeActionSheetManager::SpecShowActionSheetWithOptionsOptions::disabledButtonIndices() const
{
id const p = _v[@"disabledButtonIndices"];
return RCTBridgingToOptionalVec(p, ^double(id itemValue_0) { return RCTBridgingToDouble(itemValue_0); });
}
inline NSString *JS::NativeActionSheetManager::SpecShowShareActionSheetWithOptionsOptions::message() const
{
id const p = _v[@"message"];
Expand Down
38 changes: 38 additions & 0 deletions RNTester/js/examples/ActionSheetIOS/ActionSheetIOSExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const ScreenshotManager = NativeModules.ScreenshotManager;
const BUTTONS = ['Option 0', 'Option 1', 'Option 2', 'Delete', 'Cancel'];
const DESTRUCTIVE_INDEX = 3;
const CANCEL_INDEX = 4;
const DISABLED_BUTTON_INDICES = [1, 2];

type Props = $ReadOnly<{||}>;
type State = {|clicked: string|};
Expand Down Expand Up @@ -138,6 +139,37 @@ class ActionSheetAnchorExample extends React.Component<
};
}

class ActionSheetDisabledExample extends React.Component<Props, State> {
state = {
clicked: 'none',
};

render() {
return (
<View>
<Text onPress={this.showActionSheet} style={style.button}>
Click to show the ActionSheet
</Text>
<Text>Clicked button: {this.state.clicked}</Text>
</View>
);
}

showActionSheet = () => {
ActionSheetIOS.showActionSheetWithOptions(
{
options: BUTTONS,
cancelButtonIndex: CANCEL_INDEX,
destructiveButtonIndex: DESTRUCTIVE_INDEX,
disabledButtonIndices: DISABLED_BUTTON_INDICES,
},
buttonIndex => {
this.setState({clicked: BUTTONS[buttonIndex]});
},
);
};
}

class ShareActionSheetExample extends React.Component<
$FlowFixMeProps,
$FlowFixMeState,
Expand Down Expand Up @@ -315,6 +347,12 @@ exports.examples = [
return <ActionSheetAnchorExample />;
},
},
{
title: 'Show Action Sheet with disabled buttons',
render(): React.Element<any> {
return <ActionSheetDisabledExample />;
},
},
{
title: 'Show Share Action Sheet',
render(): React.Element<any> {
Expand Down
17 changes: 17 additions & 0 deletions React/CoreModules/RCTActionSheetManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ - (void)presentViewController:(UIViewController *)alertController
NSInteger cancelButtonIndex =
options.cancelButtonIndex() ? [RCTConvert NSInteger:@(*options.cancelButtonIndex())] : -1;
NSArray<NSNumber *> *destructiveButtonIndices;
NSArray<NSNumber *> *disabledButtonIndices =
RCTConvertVecToArray(*options.disabledButtonIndices(), ^id(double element) {
return @(element);
});
if (options.destructiveButtonIndices()) {
destructiveButtonIndices = RCTConvertVecToArray(*options.destructiveButtonIndices(), ^id(double element) {
return @(element);
Expand All @@ -98,6 +102,7 @@ - (void)presentViewController:(UIViewController *)alertController
@"destructiveButtonIndices" : destructiveButtonIndices,
@"anchor" : anchor,
@"tintColor" : tintColor,
@"disabledButtonIndices" : disabledButtonIndices,
});
return;
}
Expand Down Expand Up @@ -132,6 +137,18 @@ - (void)presentViewController:(UIViewController *)alertController
index++;
}

for (NSNumber *disabledButtonIndex in disabledButtonIndices) {
if ([disabledButtonIndex integerValue] < buttons.count) {
[alertController.actions[[disabledButtonIndex integerValue]] setEnabled:false];
} else {
RCTLogError(
@"Index %@ from `disabledButtonIndices` is out of bounds. Maximum index value is %@.",
@([disabledButtonIndex integerValue]),
@(buttons.count - 1));
return;
}
}

alertController.view.tintColor = tintColor;
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
Expand Down

0 comments on commit f0bf4b0

Please sign in to comment.