-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Alert: implementation #1026
Comments
@necolas can you please merge this changes. |
For now I do something like this to workaround this.
|
Browser |
Does react-native-web supports Alert already? |
What do you think about implementing it using react portals? We can inject the node in the dom and use a portal to show/hide. We can ship simple styling for it and create a way to let the developer customize the appearance and the appearing/hiding transition. |
What I've done so far.
and for web, Alert.web.js
Then use it as following:
|
@joan-saum As a provisory solution you should probably fork the dependency, change as necessary - following the example above - and publish to npm to use it. |
I just created my own alert popup for web, using native-base - works pretty well https://gist.github.com/tonypee/f3ebb3a6f89e6d73255a5823092b24c6 it needs to be instantiated in the root of the app too |
very quick and dirty polyfill I whipped up if anyone else got super stuck by this: import { Alert, Platform } from 'react-native'
const alertPolyfill = (title, description, options, extra) => {
const result = window.confirm([title, description].filter(Boolean).join('\n'))
if (result) {
const confirmOption = options.find(({ style }) => style !== 'cancel')
confirmOption && confirmOption.onPress()
} else {
const cancelOption = options.find(({ style }) => style === 'cancel')
cancelOption && cancelOption.onPress()
}
}
const alert = Platform.OS === 'web' ? alertPolyfill : Alert.alert
export default alert Usage: Before: import { Alert } from 'react-native'
Alert.alert(
...
) After: import alert from './alert'
alert(
...
) |
Thank you @joshbalfour. Here's roughly the same in TypeScript for those who need it. Written as a singleton in order to be able to implement // Alert.web.ts
import { AlertButton, AlertStatic } from 'react-native';
class WebAlert implements Pick<AlertStatic, 'alert'> {
public alert(title: string, message?: string, buttons?: AlertButton[]): void {
if (buttons === undefined || buttons.length === 0) {
window.alert([title, message].filter(Boolean).join('\n'));
return;
}
const result = window.confirm([title, message].filter(Boolean).join('\n'));
if (result === true) {
const confirm = buttons.find(({ style }) => style !== 'cancel');
confirm?.onPress?.();
return;
}
const cancel = buttons.find(({ style }) => style === 'cancel');
cancel?.onPress?.();
}
}
export const Alert = new WebAlert(); // Alert.ts
export { Alert } from 'react-native'; Several things to note:
EDIT: Added |
It's meant to block on purpose! |
The Modal PR is merged in react-native-web, that means the Alert implementation will be a lot easier to implement. I'll see if I can find some time to make a PR for this |
I just did an experiment with the Modal in the canary version to implement a the Alert API on the web: https://codesandbox.io/s/alert-implementation-z4eoq?file=/src/App.js. I'm not sure how we could handle this better @necolas Is it a requirement of the web version of the Alert.api to be available before React is mounted? |
Before React is mounted? What does that mean? |
In my implementation the would have to be included somewhere in the three, I don't know if that's possible in the AppRegistry. So if you would could Alert.alert() before the |
I think I can workaround the issue I described above, but is it possible to add extra components in the root of a react-native-web app, like an |
I now have rewritten the Alert proposal to add support for Alerts outside components. It would still need something like update: fixed a bug where multiple Alerts would open |
Do you think the Codesandbox will be good enough for a PR if I
|
I went with, https://callstack.github.io/react-native-paper/dialog.html It looks pretty |
@RichardLindhout yeah something like that would be a good start |
This comment has been minimized.
This comment has been minimized.
Hi, is there any update on this? And more user-friendly / good looking than plain old browsers' window.alert / window.prompt. |
@ezekiel747 there is react-native-paper-alerts that looks pretty good on web. |
@zhigang1992 react-native-paper-alerts is a reasonable solution, thanks for that pointer. I just looked it over and went ahead with an integration of it in https://github.com/invertase/react-native-firebase-authentication-example If you're not using react-native-paper then it probably isn't attractive, but if you are - definitely worth a look - mind the styles applied in public/index.html to avoid a keyboard hiding issue if you use prompts with TextInput in the Alerts, but if you're just doing text and buttons, zero issues. |
hi there! is there any update on this? can I help on something? are there any pull request with this working progress? |
While not an actual solution for this issue, I was able to make React Native's Alert work on multiple platforms by utilizing the sweetalert2 library for the web. I've included my code below for anyone who might find it useful. Native Alert API is called for the native platforms and the code falls back to sweetalert2 for the web. The API is almost identical to the native Alert, with one addition to the AlertButton type to enable button type props for sweetalert2. It seems that the prompt method could also be implemented with sweetalert2 quite easily, but I didn't have the need for that yet. You can test it out on Snack. Install sweetalert2: Alert.web.ts: import {
type AlertType,
type AlertButton,
type AlertOptions,
} from 'react-native'
import Swal from 'sweetalert2'
export type CustomAlertButton = AlertButton & {
swalType?: 'deny' | 'cancel' | 'confirm'
}
class Alert {
static alert(
title: string,
message?: string,
buttons?: CustomAlertButton[],
options?: AlertOptions
): void {
const confirmButton = buttons
? buttons.find((button) => button.swalType === 'confirm')
: undefined
const denyButton = buttons
? buttons.find((button) => button.swalType === 'deny')
: undefined
const cancelButton = buttons
? buttons.find((button) => button.swalType === 'cancel')
: undefined
Swal.fire({
title: title,
text: message,
showConfirmButton: !!confirmButton,
showDenyButton: !!denyButton,
showCancelButton: !!cancelButton,
confirmButtonText: confirmButton?.text,
denyButtonText: denyButton?.text,
cancelButtonText: cancelButton?.text,
}).then((result) => {
if (result.isConfirmed) {
if (confirmButton?.onPress !== undefined) {
confirmButton.onPress()
}
} else if (result.isDenied) {
if (denyButton?.onPress !== undefined) {
denyButton.onPress()
}
} else if (result.isDismissed) {
if (cancelButton?.onPress !== undefined) {
cancelButton.onPress()
}
}
})
}
static prompt(
title: string,
message?: string,
callbackOrButtons?: ((text: string) => void) | CustomAlertButton[],
type?: AlertType,
defaultValue?: string,
keyboardType?: string
): void {
throw new Error('Not implemented.')
}
}
export default Alert Alert.ts import {
Alert as RNAlert,
type AlertOptions,
type AlertButton,
type AlertType,
} from 'react-native'
type CustomAlertButton = AlertButton & {
swalType?: 'deny' | 'cancel' | 'confirm'
}
export interface ExtendedAlertStatic {
alert: (
title: string,
message?: string,
buttons?: CustomAlertButton[],
options?: AlertOptions
) => void
prompt: (
title: string,
message?: string,
callbackOrButtons?: ((text: string) => void) | CustomAlertButton[],
type?: AlertType,
defaultValue?: string,
keyboardType?: string
) => void
}
const Alert: ExtendedAlertStatic = RNAlert as ExtendedAlertStatic
export default Alert |
I'm creating a multiplatform. simple for now |
https://facebook.github.io/react-native/docs/alert
The text was updated successfully, but these errors were encountered: