Skip to content

Commit 591dfa5

Browse files
authored
Tooltip component examples (#373)
* Tooltip component examples * Apply Spotless * Addressing PR comments * use LaunchedEffect to fix tooltip bug * Apply Spotless * Updated content descriptions --------- Co-authored-by: jakeroseman <[email protected]>
1 parent a0b94c0 commit 591dfa5

File tree

3 files changed

+216
-1
lines changed

3 files changed

+216
-1
lines changed

compose/snippets/src/main/java/com/example/compose/snippets/SnippetsActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import com.example.compose.snippets.components.ScaffoldExample
4848
import com.example.compose.snippets.components.SliderExamples
4949
import com.example.compose.snippets.components.SwitchExamples
5050
import com.example.compose.snippets.components.TimePickerExamples
51+
import com.example.compose.snippets.components.TooltipExamples
5152
import com.example.compose.snippets.graphics.ApplyPolygonAsClipImage
5253
import com.example.compose.snippets.graphics.BitmapFromComposableFullSnippet
5354
import com.example.compose.snippets.graphics.BrushExamplesScreen
@@ -115,6 +116,7 @@ class SnippetsActivity : ComponentActivity() {
115116
TopComponentsDestination.DatePickerExamples -> DatePickerExamples()
116117
TopComponentsDestination.CarouselExamples -> CarouselExamples()
117118
TopComponentsDestination.MenusExample -> MenusExamples()
119+
TopComponentsDestination.TooltipExamples -> TooltipExamples()
118120
}
119121
}
120122
}
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
/*
2+
* Copyright 2024 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.compose.snippets.components
18+
19+
import androidx.compose.foundation.layout.Arrangement
20+
import androidx.compose.foundation.layout.Row
21+
import androidx.compose.foundation.layout.fillMaxSize
22+
import androidx.compose.foundation.layout.fillMaxWidth
23+
import androidx.compose.foundation.layout.padding
24+
import androidx.compose.material.icons.Icons
25+
import androidx.compose.material.icons.filled.Camera
26+
import androidx.compose.material.icons.filled.Favorite
27+
import androidx.compose.material.icons.filled.Info
28+
import androidx.compose.material3.ExperimentalMaterial3Api
29+
import androidx.compose.material3.Icon
30+
import androidx.compose.material3.IconButton
31+
import androidx.compose.material3.PlainTooltip
32+
import androidx.compose.material3.RichTooltip
33+
import androidx.compose.material3.Text
34+
import androidx.compose.material3.TextButton
35+
import androidx.compose.material3.TooltipBox
36+
import androidx.compose.material3.TooltipDefaults
37+
import androidx.compose.material3.TooltipState
38+
import androidx.compose.runtime.Composable
39+
import androidx.compose.runtime.LaunchedEffect
40+
import androidx.compose.runtime.getValue
41+
import androidx.compose.runtime.mutableStateOf
42+
import androidx.compose.runtime.remember
43+
import androidx.compose.runtime.setValue
44+
import androidx.compose.ui.Alignment
45+
import androidx.compose.ui.Modifier
46+
import androidx.compose.ui.text.style.TextAlign
47+
import androidx.compose.ui.tooling.preview.Preview
48+
import androidx.compose.ui.unit.DpSize
49+
import androidx.compose.ui.unit.dp
50+
51+
@Composable
52+
fun TooltipExamples() {
53+
Text(
54+
"Long press an icon to see the tooltip.",
55+
modifier = Modifier.fillMaxWidth().padding(16.dp),
56+
textAlign = TextAlign.Center
57+
)
58+
Row(
59+
horizontalArrangement = Arrangement.SpaceEvenly,
60+
verticalAlignment = Alignment.CenterVertically,
61+
modifier = Modifier.fillMaxSize()
62+
) {
63+
PlainTooltipExample()
64+
RichTooltipExample()
65+
AdvancedRichTooltipExample()
66+
}
67+
}
68+
69+
@Preview
70+
@Composable
71+
private fun TooltipExamplesPreview() {
72+
TooltipExamples()
73+
}
74+
75+
@OptIn(ExperimentalMaterial3Api::class)
76+
// [START android_compose_components_plaintooltipexample]
77+
@Composable
78+
fun PlainTooltipExample(
79+
modifier: Modifier = Modifier,
80+
plainTooltipText: String = "Add to favorites"
81+
) {
82+
var tooltipState by remember { mutableStateOf(TooltipState()) }
83+
TooltipBox(
84+
modifier = modifier,
85+
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
86+
tooltip = {
87+
PlainTooltip { Text(plainTooltipText) }
88+
},
89+
state = tooltipState
90+
) {
91+
IconButton(onClick = { /* Do something... */ }) {
92+
Icon(
93+
imageVector = Icons.Filled.Favorite,
94+
contentDescription = "Add to favorites"
95+
)
96+
}
97+
}
98+
99+
// Reset tooltipState after closing the tooltip.
100+
LaunchedEffect(tooltipState.isVisible) {
101+
if (!tooltipState.isVisible) {
102+
tooltipState = TooltipState()
103+
}
104+
}
105+
}
106+
107+
// [END android_compose_components_plaintooltipexample]
108+
109+
@Preview
110+
@Composable
111+
private fun PlainTooltipSamplePreview() {
112+
PlainTooltipExample()
113+
}
114+
115+
@OptIn(ExperimentalMaterial3Api::class)
116+
// [START android_compose_components_richtooltipexample]
117+
@Composable
118+
fun RichTooltipExample(
119+
modifier: Modifier = Modifier,
120+
richTooltipSubheadText: String = "Rich Tooltip",
121+
richTooltipText: String = "Rich tooltips support multiple lines of informational text."
122+
) {
123+
var tooltipState by remember { mutableStateOf(TooltipState(isPersistent = true)) }
124+
125+
TooltipBox(
126+
modifier = modifier,
127+
positionProvider = TooltipDefaults.rememberRichTooltipPositionProvider(),
128+
tooltip = {
129+
RichTooltip(
130+
title = { Text(richTooltipSubheadText) }
131+
) {
132+
Text(richTooltipText)
133+
}
134+
},
135+
state = tooltipState
136+
) {
137+
IconButton(onClick = { /* Icon button's click event */ }) {
138+
Icon(
139+
imageVector = Icons.Filled.Info,
140+
contentDescription = "Show more information"
141+
)
142+
}
143+
}
144+
145+
// Reset tooltipState after closing the tooltip.
146+
LaunchedEffect(tooltipState.isVisible) {
147+
if (!tooltipState.isVisible) {
148+
tooltipState = TooltipState(isPersistent = true)
149+
}
150+
}
151+
}
152+
// [END android_compose_components_richtooltipexample]
153+
154+
@Preview
155+
@Composable
156+
private fun RichTooltipSamplePreview() {
157+
RichTooltipExample()
158+
}
159+
160+
@OptIn(ExperimentalMaterial3Api::class)
161+
// [START android_compose_components_advancedrichtooltipexample]
162+
@Composable
163+
fun AdvancedRichTooltipExample(
164+
modifier: Modifier = Modifier,
165+
richTooltipSubheadText: String = "Custom Rich Tooltip",
166+
richTooltipText: String = "Rich tooltips support multiple lines of informational text.",
167+
richTooltipActionText: String = "Dismiss"
168+
) {
169+
var tooltipState by remember { mutableStateOf(TooltipState(isPersistent = true)) }
170+
171+
TooltipBox(
172+
modifier = modifier,
173+
positionProvider = TooltipDefaults.rememberRichTooltipPositionProvider(),
174+
tooltip = {
175+
RichTooltip(
176+
title = { Text(richTooltipSubheadText) },
177+
action = {
178+
Row {
179+
TextButton(onClick = { tooltipState.dismiss() }) {
180+
Text(richTooltipActionText)
181+
}
182+
}
183+
},
184+
caretSize = DpSize(32.dp, 16.dp)
185+
) {
186+
Text(richTooltipText)
187+
}
188+
},
189+
state = tooltipState
190+
) {
191+
IconButton(onClick = { tooltipState.dismiss() }) {
192+
Icon(
193+
imageVector = Icons.Filled.Camera,
194+
contentDescription = "Open camera"
195+
)
196+
}
197+
}
198+
199+
// Reset tooltipState after closing the tooltip.
200+
LaunchedEffect(tooltipState.isVisible) {
201+
if (!tooltipState.isVisible) {
202+
tooltipState = TooltipState(isPersistent = true)
203+
}
204+
}
205+
}
206+
// [END android_compose_components_advancedrichtooltipexample]
207+
208+
@Preview
209+
@Composable
210+
private fun RichTooltipWithCustomCaretSamplePreview() {
211+
AdvancedRichTooltipExample()
212+
}

compose/snippets/src/main/java/com/example/compose/snippets/navigation/Destination.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,6 @@ enum class TopComponentsDestination(val route: String, val title: String) {
4646
TimePickerExamples("timePickerExamples", "Time Pickers"),
4747
DatePickerExamples("datePickerExamples", "Date Pickers"),
4848
CarouselExamples("carouselExamples", "Carousel"),
49-
MenusExample("menusExamples", "Menus")
49+
MenusExample("menusExamples", "Menus"),
50+
TooltipExamples("tooltipExamples", "Tooltips")
5051
}

0 commit comments

Comments
 (0)