A callout is an anchored tip that can be used to teach people or guide them through the app without blocking them.
- Place a callout near the object being described. At the pointer’s tail or head, if possible.
- Don't use large, unformatted blocks of text in your callout. They're difficult to read and overwhelming.
- Don’t block important UI with the placement of your callout. It's a poor user experience that will lead to frustration
- Don’t open a callout from within another callout.
- Don’t show callouts on hidden elements.
- Don’t overuse callouts. Too many callouts opening automatically can be perceived as interrupting someone's workflow.
const customCallout: React.FunctionComponent = () => {
const [showCustomizedCallout, setShowCustomizedCallout] = React.useState(false);
const [isCustomizedCalloutVisible, setIsCustomizedCalloutVisible] = React.useState(false);
const toggleShowCustomizedCallout = React.useCallback(() => {
setShowCustomizedCallout(!showCustomizedCallout);
// Unmounting a callout does not invoke onDismiss; onDismiss is only invoked
// for dismissals generated by the native app. When toggling to 'show',
// the isVisible state will be corrected to 'true' by the onShow callback.
setIsCustomizedCalloutVisible(false);
}, [showCustomizedCallout, setIsCustomizedCalloutVisible, setShowCustomizedCallout]);
const onShowCustomizedCallout = React.useCallback(() => {
setIsCustomizedCalloutVisible(true);
}, [setIsCustomizedCalloutVisible]);
const onDismissCustomizedCallout = React.useCallback(() => {
setIsCustomizedCalloutVisible(false);
// setting the internal state to false will instigate unmounting the
// zombie Callout control.
setShowCustomizedCallout(false);
}, [setIsCustomizedCalloutVisible, setShowCustomizedCallout]);
const myRect: ScreenRect = { screenX: 10, screenY: 10, width: 100, height: 100 };
return (
<View>
<View style={{ flexDirection: 'column', paddingVertical: 5 }}>
<Button content="Press for Callout" onClick={toggleShowCustomizedCallout} />
<Text selectable={true}>
<Text>Visibility: </Text>
{isCustomizedCalloutVisible ? <Text style={{ color: 'green' }}>Visible</Text> : <Text style={{ color: 'red' }}>Not Visible</Text>}
</Text>
</View>
{showCustomizedCallout && (
<Callout
anchorRect={myRect}
onDismiss={onDismissCustomizedCallout}
onShow={onShowCustomizedCallout}
accessibilityLabel="Customized Callout"
accessibilityRole="alert"
accessibilityOnShowAnnouncement="Be informed that a customized callout has been opened."
>
<View style={{ padding: 20, borderWidth: 2, borderColor: 'black' }}>
<Text>just some text so it does not take focus and is not empty.</Text>
</View>
</Callout>
)}
</View>
);
};extends ICalloutTokens
| Prop | Type | Default Value | Description |
|---|---|---|---|
| accessibilityLabel | string | Used by screen readers to inform the user about the control. | |
| accessibilityOnShowAnnouncement | string | A string that should be announced when the callout is shown. | |
| accessibilityRole | string | Used by screen readers to inform the user about the purpose of the control. | |
| componentRef | React.RefObject<IFocusable> |
A RefObject to access the IFocusable interface. Use this to access the public methods and properties of the component. | |
| onShow | () => void | Callback invoked when the callout has been shown. | |
| setInitialFocus | boolean | If true then the callout will attempt to focus the first focusable element that it contains. If it doesn't find an element, no focus will be set. This means that it's the contents responsibility to either set focus or have focusable items. | |
| target | React.RefObject<React.Component> | string | Target node the callout uses for relative positioning; the anchor of the callout. A ref is the typical usage; certain components may proffer a string as an anchor target, such as anchoring to a point inside the component. |
| isBeakVisible | boolean | Adds a beak to the Callout, pointing to the anchor target. Notable Win32 limitation: Beak rendering currently limits the border width to its default, and the border width prop will not be honored. | |
| onDismiss | () => void | Callback invoked when the callout has been dismissed. | |
| onRestoreFocus | (restoreFocusEvent: RestoreFocusEvent) => void | Callback invoked during callout dismissal; if set, focus will not be restored by the callout and onRestoreFocus must result in focus being moved to the appropriate focusable target. The callee should carefully consider their scenarios to avoid dropping focus, or inappropriately moving focus from another component. Focus is not guaranteed to have entered the React-Native surface at all, and this callback is most appropriate for components strictly controlling focus. | |
| onShow | () => void | Callback invoked when the callout has been shown. | |
| setInitialFocus | boolean | If true then the callout will attempt to focus the first focusable element that it contains. If it doesn't find an element, no focus will be set. This means that it's the contents responsibility to either set focus or have focusable items. | |
| target | React.RefObject<React.Component> | string | Target node the callout uses for relative positioning; the anchor of the callout. A ref is the typical usage; certain components may proffer a string as an anchor target, such as anchoring to a point inside the component. |
extends IBackgroundColorTokens, CalloutBorderTokens
| Token | Type | Default Value | Description |
|---|---|---|---|
| anchorRect | ScreenRect | AnchorRect arbitrary anchor rectangle; coordinate system is in DIPs, relative to the React surface origin. | |
| beakWidth | number | Width of the beak on the Callout indicating its anchor. | |
| directionalHint | DirectionalHint | Defines the suggested drop direction and alignment for the Callout to use, relative to the anchor information. | |
| dismissBehaviors | DismissBehaviors[] | Defines variations on how the callout dismissal may be controlled. the async eventing of React-Native makes passing some aspects of dismissal control over to JS difficult. Moreover, the native platform or host may have competing priorities with regards to transient UI that generate bi-directional lifetime management between JS (which mounts and unmounts the component) and native (which may tear down the transient UI without JS input). This property provides control over the latter issue, enabling relevant native platform interactions with transient UI to be managed from JS. These behaviors should generally be orthogonal, and therefore combinable. | |
| gapSpace | number | Defines the size of the gap between the anchor and the Callout. Not used if no anchor information is provided. | |
| maxHeight | string or number | Defines a maximum height for the Callout. | |
| maxWidth | string or number | Defines a maximum width for the Callout. | |
| minPadding | number | Defines the minimum padding between the Callout and the display edges. |
Type ScreenRect = { screenX: number, screenY: number, width: number, height: number }
type DirectionalHint =
| 'leftTopEdge'
| 'leftCenter'
| 'leftBottomEdge'
| 'topLeftEdge'
| 'topAutoEdge'
| 'topCenter'
| 'topRightEdge'
| 'rightTopEdge'
| 'rightCenter'
| 'rightBottomEdge'
| 'bottomLeftEdge'
| 'bottomAutoEdge'
| 'bottomCenter'
| 'bottomRightEdge';export type DismissBehaviors = 'preventDismissOnKeyDown' | 'preventDismissOnClickOutside';