-
Notifications
You must be signed in to change notification settings - Fork 138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deprecate AlertMacOS in favor of Alert #662
Conversation
@@ -156,10 +169,53 @@ class Alert { | |||
// [TODO(macOS ISS#2323203) | |||
} else if (Platform.OS === 'macos') { | |||
const defaultInputs = [{default: defaultValue}]; | |||
AlertMacOS.prompt(title, message, callbackOrButtons, type, defaultInputs); | |||
promptMacOS(title, message, callbackOrButtons, type, defaultInputs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't add modal
and critical
arguments here, as the original implementation didn't have that. However, I can see that it may be necessary to add in the future, which would change the prompt function signature. Ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@HeyImChris @tom-un @NickGerleman How have you historically dealt with such deviating decision making?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Long-term I think it would be best to refactor the prompt
in RN core to have the same API as alert
. This way we could fit all extra platform-specific options into the last options
argument. It be a breaking change, but I may be worth it. Should also be pretty simple to write a codemod, although I have no experience in that yet (would be happy to contribute). If that makes sense to you, I can tag Eli from the RN core and see what's his thoughts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a whole bunch of different solutions to public API deviation. The north star is to unify core APIs to be more desktop friendly. This is definitely the hardest option from both technical and non technical perspectives though. I've historically pushed pretty aggressively for doing this, as it saves a lot of pain in the long run, can benefit a greater ecosystem, and tends to produce higher quality changes.
For smaller components/Libares, something like AlertMacOS is not a particularly bad option. The benefit of having a separate component is that you can provide custom typings easily, and are insulated from upstream refactorings that tend to break forking in high traffic areas. Downside is you don't get upstream refactorings as well, and consumption is annoying.
The really problematic cases I've seen have been for adding extra parameters to public methods, or extra methods/props. The story for discoverability and documentation is bad, and needing usage to be untyped has been really problematic for us.
I think this is more problematic for a team like Office though, where we simultaneously want to upgrade many projects across many repos to a new version of React Native at once. That sort of thing becomes really risky without good typings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @NickGerleman. This basically sums up my struggle with this issue, involving API decisions and balancing the ease of keeping the fork up to date.
I could throw a proposal on D&P repo to change the prompt
API to be somewhat more generic:
-static prompt(title, message?, callbackOrButtons?, type?, defaultValue?, keyboardType?)
+static prompt(title, message?, callbackOrButtons?, options?)
which would allow to put android/ios/macos/windows specific options there. As you mentioned, this approach leads to less type safe code, since one could omit props that's specific for certain platform or pass the ones for another platform, thinking it works for theirs as well. Naming conventions like prefixing with macos_
would help a bit.
Otherwise the sane decision would be to stay with AlertMacOS
(or Alert.macos.js with an API of AlertMacOS), which provides the best type safety, but diverges from upstream implementation. However, since the issue was about deprecating AlertMacOS and going with Alert, I tried to figure out what's possible without it.
Let me know how and if we should proceed further :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a really good question and something that I've struggled with before. Maybe I'm in the minority here but I find that forcing platforms to conform to an API set that doesn't make sense for the platform to not be worth the benefits of having one API.
Having "options" at the end is a good solution if we needed to keep the API identical, but I'm not convinced we need to do that. We can still #ifdef and share code between iOS/macOS when possible and also have reasonable APIs that make sense for the platforms they're on.
I always have to remind myself that RN isn't "write once, run anywhere", it's "learn once, write anywhere" so it's okay for platforms APIs to sometimes vary when it makes sense.
#define UIAlertController NSViewController | ||
#endif // ]TODO(macOS ISS#2323203) | ||
|
||
@interface RCTAlertController : UIAlertController |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@HeyImChris @thymikee : we are adding subclass of uialertcontroller when Apple documentation says "The UIAlertController class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified." ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, didn't notice that. It comes from the upstream facebook@f319ff3
// [TODO(macOS ISS#2323203) | ||
defaultInputs?: DefaultInputsArray, | ||
modal?: ?boolean, | ||
critical?: ?boolean, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The macOS Alert styles are critical, informational, and warning so I don't think toggling on a "critical" as a bool correctly encapsulates the three options available
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK Flow has no enums, so then this should probably be a string union?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would require changes to the RCTAlertManager.mm
, as it currently takes critical
as a boolean.
649076c
to
8973d60
Compare
Thanks @Saadnajmi, appreciated! Glad it finally made through :D |
Please select one of the following
Summary
Fixes #354 by introducing an internal
promptMacOS
function to Alert module, copying implementation from AlertMacOS. Figured that would be the least disruptive and non-breaking way of introducing this, as it allows us to put the deprecation warning directly insideAlertMacOS.prompt
, also called byAlertMacOS.alert
.Builds on top of #661, to be rebased once it's merged.
Changelog
[macOS] [Deprecated] - Deprecate AlertMacOS in favor of Alert
Test Plan
Existing RNTester tests.
Microsoft Reviewers: Open in CodeFlow