@@ -20,6 +20,7 @@ import androidx.compose.foundation.rememberScrollState
2020import androidx.compose.foundation.verticalScroll
2121import androidx.compose.material.Checkbox
2222import androidx.compose.material.MaterialTheme
23+ import androidx.compose.material.Surface
2324import androidx.compose.material.Text
2425import androidx.compose.material.TextButton
2526import androidx.compose.material.TextField
@@ -31,15 +32,19 @@ import androidx.compose.runtime.mutableStateOf
3132import androidx.compose.runtime.remember
3233import androidx.compose.runtime.setValue
3334import androidx.compose.ui.Alignment
35+ import androidx.compose.ui.ExperimentalComposeUiApi
3436import androidx.compose.ui.Modifier
3537import androidx.compose.ui.platform.LocalContext
3638import androidx.compose.ui.platform.testTag
3739import androidx.compose.ui.text.font.FontFamily
3840import androidx.compose.ui.text.input.PasswordVisualTransformation
41+ import androidx.compose.ui.text.style.TextAlign
3942import androidx.compose.ui.tooling.preview.Preview
4043import androidx.compose.ui.unit.dp
4144import androidx.compose.ui.unit.sp
4245import androidx.compose.ui.viewinterop.AndroidView
46+ import androidx.compose.ui.window.Dialog
47+ import androidx.compose.ui.window.DialogProperties
4348import radiography.ExperimentalRadiographyComposeApi
4449import radiography.Radiography
4550import radiography.ScanScopes.FocusedWindowScope
@@ -50,6 +55,9 @@ import radiography.ViewStateRenderers.DefaultsNoPii
5055import radiography.ViewStateRenderers.ViewRenderer
5156import radiography.ViewStateRenderers.androidViewStateRendererFor
5257import radiography.ViewStateRenderers.textViewRenderer
58+ import radiography.compose.slottable.SlotTableInspectable
59+ import radiography.compose.slottable.SlotTableInspector
60+ import radiography.compose.slottable.SlotTableInspectorState
5361
5462internal const val TEXT_FIELD_TEST_TAG = " text-field"
5563internal const val LIVE_HIERARCHY_TEST_TAG = " live-hierarchy"
@@ -59,84 +67,115 @@ internal const val LIVE_HIERARCHY_TEST_TAG = "live-hierarchy"
5967 ComposeSampleApp ()
6068}
6169
62- @OptIn(ExperimentalRadiographyComposeApi ::class , ExperimentalAnimationApi ::class )
70+ @OptIn(
71+ ExperimentalRadiographyComposeApi ::class ,
72+ ExperimentalAnimationApi ::class ,
73+ ExperimentalComposeUiApi ::class ,
74+ )
6375@Composable fun ComposeSampleApp () {
6476 val context = LocalContext .current
6577 val liveHierarchy = remember { mutableStateOf<String ?>(null ) }
78+ val slotTableInspectorState = remember { SlotTableInspectorState () }
79+ var showSlotTableInspector by remember { mutableStateOf(false ) }
6680
6781 var username by remember { mutableStateOf(" " ) }
6882 var password by remember { mutableStateOf(" " ) }
6983 var rememberMe by remember { mutableStateOf(false ) }
7084
71- MaterialTheme {
72- Column (
73- modifier = Modifier .padding(16 .dp),
74- horizontalAlignment = Alignment .CenterHorizontally ,
75- verticalArrangement = Arrangement .spacedBy(16 .dp)
76- ) {
77- RadiographyLogo (Modifier .height(128 .dp))
85+ SlotTableInspectable (slotTableInspectorState) {
86+ MaterialTheme {
87+ Column (
88+ modifier = Modifier .padding(16 .dp),
89+ horizontalAlignment = Alignment .CenterHorizontally ,
90+ verticalArrangement = Arrangement .spacedBy(16 .dp)
91+ ) {
92+ RadiographyLogo (Modifier .height(128 .dp))
7893
79- TextField (
80- value = username,
81- onValueChange = { username = it },
82- label = { Text (" Username" ) },
83- colors = TextFieldDefaults .outlinedTextFieldColors(),
84- modifier = Modifier .testTag(TEXT_FIELD_TEST_TAG )
85- )
86- TextField (
87- value = password,
88- onValueChange = { password = it },
89- label = { Text (" Password" ) },
90- colors = TextFieldDefaults .outlinedTextFieldColors(),
91- visualTransformation = PasswordVisualTransformation ()
92- )
93- Row (verticalAlignment = Alignment .CenterVertically ) {
94- Checkbox (checked = rememberMe, onCheckedChange = { rememberMe = it })
95- Spacer (Modifier .width(8 .dp))
96- Text (" Remember me" )
97- }
98-
99- Row (horizontalArrangement = Arrangement .spacedBy(16 .dp)) {
100- TextButton (onClick = {}) {
101- Text (" SIGN IN" )
94+ TextField (
95+ value = username,
96+ onValueChange = { username = it },
97+ label = { Text (" Username" ) },
98+ colors = TextFieldDefaults .outlinedTextFieldColors(),
99+ modifier = Modifier .testTag(TEXT_FIELD_TEST_TAG )
100+ )
101+ TextField (
102+ value = password,
103+ onValueChange = { password = it },
104+ label = { Text (" Password" ) },
105+ colors = TextFieldDefaults .outlinedTextFieldColors(),
106+ visualTransformation = PasswordVisualTransformation ()
107+ )
108+ Row (verticalAlignment = Alignment .CenterVertically ) {
109+ Checkbox (checked = rememberMe, onCheckedChange = { rememberMe = it })
110+ Spacer (Modifier .width(8 .dp))
111+ Text (" Remember me" )
102112 }
103- TextButton (onClick = {}) {
104- Text (" FORGOT PASSWORD" )
113+
114+ Row (horizontalArrangement = Arrangement .spacedBy(16 .dp)) {
115+ TextButton (onClick = {}) {
116+ Text (" SIGN IN" )
117+ }
118+ TextButton (onClick = {}) {
119+ Text (" FORGOT PASSWORD" )
120+ }
105121 }
106- }
107122
108- // Include a classic Android view in the composition.
109- AndroidView (::TextView ) {
110- @SuppressLint(" SetTextI18n" )
111- it.text = " By signing in, you agree to our Terms and Conditions."
112- }
123+ // Include a classic Android view in the composition.
124+ AndroidView (::TextView ) {
125+ @SuppressLint(" SetTextI18n" )
126+ it.text = " By signing in, you agree to our Terms and Conditions."
127+ }
113128
114- liveHierarchy.value?.let {
115- Row (
116- modifier = Modifier
117- .horizontalScroll(rememberScrollState())
118- .weight(1f )
119- ) {
120- Column (Modifier .verticalScroll(rememberScrollState())) {
121- Text (
122- liveHierarchy.value.orEmpty(),
123- fontFamily = FontFamily .Monospace ,
124- fontSize = 6 .sp,
125- modifier = Modifier .testTag(LIVE_HIERARCHY_TEST_TAG )
126- )
129+ liveHierarchy.value?.let {
130+ Row (
131+ modifier = Modifier
132+ .horizontalScroll(rememberScrollState())
133+ .weight(1f )
134+ ) {
135+ Column (Modifier .verticalScroll(rememberScrollState())) {
136+ Text (
137+ liveHierarchy.value.orEmpty(),
138+ fontFamily = FontFamily .Monospace ,
139+ fontSize = 6 .sp,
140+ modifier = Modifier .testTag(LIVE_HIERARCHY_TEST_TAG )
141+ )
142+ }
143+ }
144+ }
145+ Row {
146+ TextButton (
147+ modifier = Modifier .weight(1f ),
148+ onClick = { showSelectionDialog(context) }
149+ ) {
150+ Text (" SHOW STRING RENDERING DIALOG" , textAlign = TextAlign .Center )
151+ }
152+ TextButton (
153+ modifier = Modifier .weight(1f ),
154+ onClick = {
155+ slotTableInspectorState.captureSlotTables()
156+ showSlotTableInspector = true
157+ }) {
158+ Text (" SHOW SLOT TABLE INSPECTOR" , textAlign = TextAlign .Center )
127159 }
128160 }
129- }
130- TextButton (onClick = { showSelectionDialog(context) }) {
131- Text (" SHOW STRING RENDERING DIALOG" )
132- }
133161
134- SideEffect {
135- liveHierarchy.value = Radiography .scan(
136- viewStateRenderers = DefaultsIncludingPii ,
137- // Don't trigger infinite recursion.
138- viewFilter = skipComposeTestTagsFilter(LIVE_HIERARCHY_TEST_TAG )
139- )
162+ SideEffect {
163+ liveHierarchy.value = Radiography .scan(
164+ viewStateRenderers = DefaultsIncludingPii ,
165+ // Don't trigger infinite recursion.
166+ viewFilter = skipComposeTestTagsFilter(LIVE_HIERARCHY_TEST_TAG )
167+ )
168+ }
169+ if (showSlotTableInspector) {
170+ Dialog (
171+ onDismissRequest = { showSlotTableInspector = false },
172+ properties = DialogProperties (usePlatformDefaultWidth = false )
173+ ) {
174+ Surface {
175+ SlotTableInspector (slotTableInspectorState)
176+ }
177+ }
178+ }
140179 }
141180 }
142181 }
0 commit comments