blob: d7262ddacfdf30ae042124db3c0a9d161efdd400 [file] [log] [blame] [view]
Dana Friedd8fac742024-07-08 17:55:021# Help Bubbles
2
Dana Fried154c57f2024-10-23 17:21:583[Help bubbles](./common/help_bubble/help_bubble.h) are the core visual component of both
Dana Friedd8fac742024-07-08 17:55:024[IPH](./feature-promos.md) and [Tutorials](./tutorials.md).
5
6A help bubble is tinted bubble (blue in the default theme) with the following
7elements:
8 - Text
9 - Title (optional)
10 - Icon (optional)
11 - Close button (X)
12 - Action buttons (typically between zero and two)
13 - Alternative and/or assist message for screen readers
14
15Most (but not all) help bubbles also have a visible arrow that points to the
16_anchor element_ - the UI element the bubble refers to. For example, a promo for
17a new button in the toolbar would have an arrow pointing to the button.
18
Dana Fried0aefb202025-03-14 15:57:3519You should be using the Feature Promo (IPH) or Tutorial Systems,
20or [ShowPromoInPage](/chrome/browser/ui/user_education/show_promo_in_page.h)
21or [StartutorialInPage](/chrome/browser/ui/user_education/start_tutorial_in_page.h)
Dana Friedd8fac742024-07-08 17:55:0222to display help bubbles.
23
Dana Fried0aefb202025-03-14 15:57:3524> Help bubbles can be created directly via a
25[HelpBubbleFactory](./common/help_bubble/help_bubble_factory.h) and a
26[HelpBubbleParams](./common/help_bubble/help_bubble_params.h) object, however,
27it's bad form to create your own help bubbles directly unless you are 100%
Dana Friedd8fac742024-07-08 17:55:0228sure what you are doing! If you are tempted, please contact
29[Frizzle Team](mailto:[email protected]) first and see if there's a more
30idiomatic way to achieve your goal.
31
Dana Fried0aefb202025-03-14 15:57:3532You can also create [help bubbles with custom UI](./custom-help-bubbles.md)
33which can be used for IPH when something other than a normal help bubble is
34required (for example, a WebUI dialog with several links the user can click);
35see that page for more information.
36
Dana Friedd8fac742024-07-08 17:55:0237## Help Bubble Arrows
38
39When creating an IPH or Tutorial experience, you will want to specify the arrow
40for each bubble. This specifies where the little visible arrow that points to
41the anchor goes on the help bubble, and by extension, how the help bubble itself
42positions itself.
43
44For example if the arrow is `kTopRight`, then the arrow will be placed on top of
45the help bubble, towards the right side of the bubble (left in RTL). This places
46the help bubble below the anchor element, with the bulk of the bubble falling to
47the left. Help bubbles can auto-reflect if they would fall outside the browser
48window or the screen, but it's best to choose an arrow that maximizes the
49likelihood that the bubble will fit, and minimizes interference with UI the user
50will be trying to interact with.
51
52Your UX designer should have already determined the ideal arrow positioning in
53their specifications; by default you should find the option that best matches
54their design.
55
56### "No Arrow"
57
58The `HelpBubbleArrow::kNone` option places the help bubble directly beneath the
59anchor, with no visible arrow. This is almost always used with the
60`kTopContainerElementId` element, which results in the help bubble sitting just
61below the toolbar (or bookmarks bar if present), in the middle of the browser
62window. Be careful when using this option, because it is the most obtrusive
63position for a help bubble possible!
64
65## Anchor Elements
66
67As mentioned above, any UI element may be an anchor. This is handled through the
68[ElementTracker](/ui/base/interaction/element_tracker.h) system. This associates
69a `TrackedElement` object with each UI element that is properly tagged with an
70[ElementIdentifier](/ui/base/interaction/element_identifier.h) and visible to
71the user.
72
73It is sufficient to assign an identifier; the tracker will do the rest. However,
74note that a help bubble cannot show if the anchor element is not visible, as
75there may be no corresponding `TrackedElement`.
76
77### Creating and Assigning Identifiers
78
79Element identifiers are declared via macros such as
80`DECLARE/DEFINE_ELEMENT_IDENTIFIER_VALUE()`. Convention is to put identifiers in
81either
82[`browser_element_identifiers.h`](/chrome/browser/ui/browser_element_identifiers.h)/[`.cc`](/chrome/browser/ui/browser_element_identifiers.cc)
83or in the class which conceptually owns the identifier, using
84`DECLARE/DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE()`.
85
86For most `View`s, assign an identifier via
87`SetProperty(kElementIdentifierKey, <element_id>)`. For menu items (both Views
88and Mac native context menus), use `SimpleMenuModel::SetElementIdentifierAt()`.
89For WebUI elements, the process is more complex; see
90[this documentation](./webui/README.md) for info.
91
92### Element Contexts
93
94A concept you will run into when trying to anchor help bubbles is the
95`ElementContext`. Each potential anchor element exists within a context, and
96each help bubble will look for an anchor in a specific context or contexts.
97
98Contexts exist to handle cases where there are multiple browser windows, so that
99the user cannot trigger a help bubble in a different window by accident. When
100showing an IPH or Tutorial help bubble, the default is to look for the anchor in
101the current context only.
102
103Contexts exist for:
104 - A browser or app window and all menus and secondary UI associated with that
105 window.
106 - A WebUI page.
107 - Some tab-modal dialogs.
108
109> The reason for the latter two being their own contexts is because tabs can be
110 moved between windows. This creates some complexity that will hopefully be
111 remedied with future updates.
112
113If you are trying to show a help bubble through either the IPH or Tutorials
114system and the bubble is not appearing, consider whether the
115`FeaturePromoSpecification` or tutorial step needs to explicitly specify "in any
116context". This usually happens when attempting to show a help bubble anchored to
117a WebUI page.
118
119### Anchor Element Filters
120
121In some cases, you may be able to apply a "filter" function to the anchor of a
122help bubble. What this means is that the eligible anchor element(s) (based on
123identifier and context) will be passed to a function that can do _pretty much
124anything_ and then return the actual anchor element. The returned element need
125not be one of the initial elements found, and can be any UI element.
126
127Filters are often used for:
128 - Selecting one out of a set of dynamic items, such as tabs, that all share the
129 same identifier.
130 - Locating a UI element that was not assigned an identifier due to technical
131 limitations, such as specific rows of information in a cookies dialog.
132 - In this case, the initial anchor ID will usually be for the dialog or
133 container, and then the actual anchor is located from there.
134 - It is common to use `ElementTrackerViews::GetElementForView(..., true)`
135 in order to create a temporary TrackedElement for the actual anchor.
136 - This approach does not work well for non-Views elements.
137
138## Available Help Bubble Implementations
139
140The help bubble infrastructure is presentation framework-agnostic. Currently,
141the following help bubble types are supported in Chrome Desktop:
1421. Views help bubble anchored to a View
1432. Views help bubble anchored to a native Mac menu
1443. Views help bubble anchored to a WebUI element in a non-tab WebUI
1454. WebUI help bubble anchored to a WebUI element in a tab WebUI
146
147The correct type of help bubble implementation is chosen automatically based on
148the anchor view.
149
150Some other platforms (e.g. ChromeOS) have created additional types of help
151bubbles for specific applications; creating a new help bubble implementation
152isn't particularly hard; see existing classes derived from
Dana Fried154c57f2024-10-23 17:21:58153[HelpBubble](./common/help_bubble/help_bubble.h) and
154[HelpBubbleFactory](./common/help_bubble/help_bubble_factory.h).
Dana Friedd8fac742024-07-08 17:55:02155
156The key takeaway is that in the vast majority of User Education code, the logic
157around help bubbles doesn't (and shouldn't!) care which factory or which help
158bubble implementation is being used; all of the logic should be in the
159factories.
160
161If you are considering extending help bubbles to new frameworks, feel free to
162reach out to [Frizzle Team](mailto:[email protected]) for guidance.