Skip to content

Latest commit

 

History

History
137 lines (110 loc) · 18.9 KB

File metadata and controls

137 lines (110 loc) · 18.9 KB

Callout

Purpose

A callout is an anchored tip that can be used to teach people or guide them through the app without blocking them.

Do's:

  • Place a callout near the object being described. At the pointer’s tail or head, if possible.

Don't:

  • 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.

Sample Code:

Rectangle Shimmer

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>
  );
};

Props:

Callout Component:

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.

Callout Tokens

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';