mirror of
https://github.com/bitwarden/android.git
synced 2024-11-27 03:49:36 +03:00
Remove BitwardenReadOnlyTextFieldWithActions (#597)
This commit is contained in:
parent
8f22231c4a
commit
96a9a41836
5 changed files with 64 additions and 133 deletions
|
@ -1,99 +0,0 @@
|
|||
package com.x8bit.bitwarden.ui.platform.components
|
||||
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.semantics.clearAndSetSemantics
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.semantics.text
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.x8bit.bitwarden.R
|
||||
|
||||
/**
|
||||
* Represents a Bitwarden-styled text field accompanied by a series of actions.
|
||||
* This component allows for a more versatile design by accepting
|
||||
* icons or actions next to the text field. This composable is read-only and because it uses
|
||||
* the BitwardenTextField we clear the semantics here to prevent talk back from clarifying the
|
||||
* component is "editable" or "disabled".
|
||||
*
|
||||
* @param label Label for the text field.
|
||||
* @param value Current text in the text field.
|
||||
* @param modifier [Modifier] applied to this layout composable.
|
||||
* @param singleLine when `true`, this text field becomes a single line that horizontally scrolls
|
||||
* instead of wrapping onto multiple lines.
|
||||
* @param textStyle An optional style that may be used to override the default used.
|
||||
* @param shouldAddCustomLineBreaks If `true`, line breaks will be inserted to allow for filling
|
||||
* an entire line before breaking. `false` by default.
|
||||
* @param visualTransformation Transforms the visual representation of the input [value].
|
||||
* @param actions A lambda containing the set of actions (usually icons or similar) to display
|
||||
* next to the text field. This lambda extends [RowScope],
|
||||
* providing flexibility in the layout definition.
|
||||
*/
|
||||
@Composable
|
||||
fun BitwardenReadOnlyTextFieldWithActions(
|
||||
label: String,
|
||||
value: String,
|
||||
modifier: Modifier = Modifier,
|
||||
singleLine: Boolean = true,
|
||||
textStyle: TextStyle? = null,
|
||||
shouldAddCustomLineBreaks: Boolean = false,
|
||||
visualTransformation: VisualTransformation = VisualTransformation.None,
|
||||
actions: @Composable RowScope.() -> Unit = {},
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.semantics(mergeDescendants = true) {},
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
BitwardenTextField(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.clearAndSetSemantics {
|
||||
contentDescription = "$label, $value"
|
||||
text = AnnotatedString(label)
|
||||
},
|
||||
readOnly = true,
|
||||
singleLine = singleLine,
|
||||
label = label,
|
||||
value = value,
|
||||
onValueChange = {},
|
||||
textStyle = textStyle,
|
||||
shouldAddCustomLineBreaks = shouldAddCustomLineBreaks,
|
||||
visualTransformation = visualTransformation,
|
||||
)
|
||||
BitwardenRowOfActions(actions)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun BitwardenReadOnlyTextFieldWithActions_preview() {
|
||||
BitwardenReadOnlyTextFieldWithActions(
|
||||
label = "Username",
|
||||
value = "john.doe",
|
||||
actions = {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_tooltip),
|
||||
contentDescription = "",
|
||||
modifier = Modifier.size(24.dp),
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_tooltip),
|
||||
contentDescription = "",
|
||||
modifier = Modifier.size(24.dp),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
|
@ -33,7 +33,7 @@ fun BitwardenStepper(
|
|||
if (clampedValue != value && clampedValue != null) {
|
||||
onValueChange(clampedValue)
|
||||
}
|
||||
BitwardenReadOnlyTextFieldWithActions(
|
||||
BitwardenTextFieldWithActions(
|
||||
label = label,
|
||||
// we use a space instead of empty string to make sure label is shown small and above
|
||||
// the input
|
||||
|
@ -68,6 +68,8 @@ fun BitwardenStepper(
|
|||
isEnabled = isIncrementEnabled,
|
||||
)
|
||||
},
|
||||
readOnly = true,
|
||||
onValueChange = {},
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,10 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
||||
|
@ -36,6 +39,9 @@ fun BitwardenTextFieldWithActions(
|
|||
value: String,
|
||||
onValueChange: (String) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
textStyle: TextStyle? = null,
|
||||
shouldAddCustomLineBreaks: Boolean = false,
|
||||
visualTransformation: VisualTransformation = VisualTransformation.None,
|
||||
readOnly: Boolean = false,
|
||||
singleLine: Boolean = true,
|
||||
keyboardType: KeyboardType = KeyboardType.Text,
|
||||
|
@ -43,7 +49,9 @@ fun BitwardenTextFieldWithActions(
|
|||
actions: @Composable RowScope.() -> Unit = {},
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.semantics(mergeDescendants = true) { },
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
BitwardenTextField(
|
||||
|
@ -56,6 +64,9 @@ fun BitwardenTextFieldWithActions(
|
|||
onValueChange = onValueChange,
|
||||
keyboardType = keyboardType,
|
||||
trailingIconContent = trailingIconContent,
|
||||
textStyle = textStyle,
|
||||
shouldAddCustomLineBreaks = shouldAddCustomLineBreaks,
|
||||
visualTransformation = visualTransformation,
|
||||
)
|
||||
BitwardenRowOfActions(actions)
|
||||
}
|
||||
|
@ -65,9 +76,10 @@ fun BitwardenTextFieldWithActions(
|
|||
@Composable
|
||||
private fun BitwardenTextFieldWithActions_preview() {
|
||||
BitwardenTheme {
|
||||
BitwardenReadOnlyTextFieldWithActions(
|
||||
BitwardenTextFieldWithActions(
|
||||
label = "Username",
|
||||
value = "user@example.com",
|
||||
onValueChange = {},
|
||||
actions = {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_tooltip),
|
||||
|
|
|
@ -53,10 +53,10 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenMediumTopAppBar
|
|||
import com.x8bit.bitwarden.ui.platform.components.BitwardenMultiSelectButton
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenOverflowActionItem
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenPasswordField
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenReadOnlyTextFieldWithActions
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenScaffold
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenStepper
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTextField
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTextFieldWithActions
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenWideSwitch
|
||||
import com.x8bit.bitwarden.ui.platform.components.OverflowMenuItemData
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.IconResource
|
||||
|
@ -290,7 +290,7 @@ private fun GeneratedStringItem(
|
|||
onCopyClick: () -> Unit,
|
||||
onRegenerateClick: () -> Unit,
|
||||
) {
|
||||
BitwardenReadOnlyTextFieldWithActions(
|
||||
BitwardenTextFieldWithActions(
|
||||
label = "",
|
||||
value = generatedText,
|
||||
singleLine = false,
|
||||
|
@ -310,6 +310,8 @@ private fun GeneratedStringItem(
|
|||
onClick = onRegenerateClick,
|
||||
)
|
||||
},
|
||||
onValueChange = {},
|
||||
readOnly = true,
|
||||
textStyle = LocalNonMaterialTypography.current.sensitiveInfoSmall,
|
||||
shouldAddCustomLineBreaks = true,
|
||||
visualTransformation = nonLetterColorVisualTransformation(),
|
||||
|
|
|
@ -7,13 +7,13 @@ import androidx.compose.ui.test.assert
|
|||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.assertIsOff
|
||||
import androidx.compose.ui.test.assertIsOn
|
||||
import androidx.compose.ui.test.assertTextEquals
|
||||
import androidx.compose.ui.test.filterToOne
|
||||
import androidx.compose.ui.test.hasAnyAncestor
|
||||
import androidx.compose.ui.test.hasContentDescription
|
||||
import androidx.compose.ui.test.hasProgressBarRangeInfo
|
||||
import androidx.compose.ui.test.isDialog
|
||||
import androidx.compose.ui.test.onAllNodesWithText
|
||||
import androidx.compose.ui.test.onChildren
|
||||
import androidx.compose.ui.test.onLast
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
|
@ -230,15 +230,17 @@ class GeneratorScreenTest : BaseComposeTest() {
|
|||
.assertIsOff()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithContentDescription("Minimum numbers, 1")
|
||||
.onChildren()
|
||||
.onNodeWithText("Minimum numbers")
|
||||
.assertTextEquals("Minimum numbers", "1")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("\u2212"))
|
||||
.performScrollTo()
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithContentDescription("Minimum numbers, 1")
|
||||
.onChildren()
|
||||
.onNodeWithText("Minimum numbers")
|
||||
.assertTextEquals("Minimum numbers", "1")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("+"))
|
||||
.performScrollTo()
|
||||
.assertIsDisplayed()
|
||||
|
@ -367,8 +369,9 @@ class GeneratorScreenTest : BaseComposeTest() {
|
|||
fun `in Passcode_Password state, decrementing the minimum numbers counter should send MinNumbersCounterChange action`() {
|
||||
val initialMinNumbers = 1
|
||||
|
||||
composeTestRule.onNodeWithContentDescription("Minimum numbers, 1")
|
||||
.onChildren()
|
||||
composeTestRule.onNodeWithText("Minimum numbers")
|
||||
.assertTextEquals("Minimum numbers", "1")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("\u2212"))
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
@ -387,8 +390,9 @@ class GeneratorScreenTest : BaseComposeTest() {
|
|||
fun `in Passcode_Password state, incrementing the minimum numbers counter should send MinNumbersCounterChange action`() {
|
||||
val initialMinNumbers = 1
|
||||
|
||||
composeTestRule.onNodeWithContentDescription("Minimum numbers, 1")
|
||||
.onChildren()
|
||||
composeTestRule.onNodeWithText("Minimum numbers")
|
||||
.assertTextEquals("Minimum numbers", "1")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("+"))
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
@ -420,8 +424,9 @@ class GeneratorScreenTest : BaseComposeTest() {
|
|||
),
|
||||
)
|
||||
|
||||
composeTestRule.onNodeWithContentDescription("Minimum numbers, $initialMinNumbers")
|
||||
.onChildren()
|
||||
composeTestRule.onNodeWithText("Minimum numbers")
|
||||
.assertTextEquals("Minimum numbers", "$initialMinNumbers")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("\u2212"))
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
@ -447,8 +452,9 @@ class GeneratorScreenTest : BaseComposeTest() {
|
|||
),
|
||||
)
|
||||
|
||||
composeTestRule.onNodeWithContentDescription("Minimum numbers, $initialMinNumbers")
|
||||
.onChildren()
|
||||
composeTestRule.onNodeWithText("Minimum numbers")
|
||||
.assertTextEquals("Minimum numbers", "$initialMinNumbers")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("+"))
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
@ -461,8 +467,9 @@ class GeneratorScreenTest : BaseComposeTest() {
|
|||
fun `in Passcode_Password state, decrementing the minimum special characters counter should send MinSpecialCharactersChange action`() {
|
||||
val initialSpecialChars = 1
|
||||
|
||||
composeTestRule.onNodeWithContentDescription("Minimum special, 1")
|
||||
.onChildren()
|
||||
composeTestRule.onNodeWithText("Minimum special")
|
||||
.assertTextEquals("Minimum special", "1")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("\u2212"))
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
@ -481,8 +488,9 @@ class GeneratorScreenTest : BaseComposeTest() {
|
|||
fun `in Passcode_Password state, incrementing the minimum special characters counter should send MinSpecialCharactersChange action`() {
|
||||
val initialSpecialChars = 1
|
||||
|
||||
composeTestRule.onNodeWithContentDescription("Minimum special, 1")
|
||||
.onChildren()
|
||||
composeTestRule.onNodeWithText("Minimum special")
|
||||
.assertTextEquals("Minimum special", "1")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("+"))
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
@ -514,8 +522,9 @@ class GeneratorScreenTest : BaseComposeTest() {
|
|||
),
|
||||
)
|
||||
|
||||
composeTestRule.onNodeWithContentDescription("Minimum special, $initialSpecialChars")
|
||||
.onChildren()
|
||||
composeTestRule.onNodeWithText("Minimum special")
|
||||
.assertTextEquals("Minimum special", "$initialSpecialChars")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("\u2212"))
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
@ -541,8 +550,9 @@ class GeneratorScreenTest : BaseComposeTest() {
|
|||
),
|
||||
)
|
||||
|
||||
composeTestRule.onNodeWithContentDescription("Minimum special, $initialSpecialChars")
|
||||
.onChildren()
|
||||
composeTestRule.onNodeWithText("Minimum special")
|
||||
.assertTextEquals("Minimum special", "$initialSpecialChars")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("+"))
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
@ -595,8 +605,9 @@ class GeneratorScreenTest : BaseComposeTest() {
|
|||
|
||||
// Unicode for "minus" used for content description
|
||||
composeTestRule
|
||||
.onNodeWithContentDescription("Number of words, $initialNumWords")
|
||||
.onChildren()
|
||||
.onNodeWithText("Number of words")
|
||||
.assertTextEquals("Number of words", "$initialNumWords")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("\u2212"))
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
@ -629,8 +640,9 @@ class GeneratorScreenTest : BaseComposeTest() {
|
|||
|
||||
// Unicode for "minus" used for content description
|
||||
composeTestRule
|
||||
.onNodeWithContentDescription("Number of words, $initialNumWords")
|
||||
.onChildren()
|
||||
.onNodeWithText("Number of words")
|
||||
.assertTextEquals("Number of words", "$initialNumWords")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("\u2212"))
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
@ -656,8 +668,9 @@ class GeneratorScreenTest : BaseComposeTest() {
|
|||
|
||||
// Unicode for "minus" used for content description
|
||||
composeTestRule
|
||||
.onNodeWithContentDescription("Number of words, $initialNumWords")
|
||||
.onChildren()
|
||||
.onNodeWithText("Number of words")
|
||||
.assertTextEquals("Number of words", "$initialNumWords")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("+"))
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
@ -681,8 +694,9 @@ class GeneratorScreenTest : BaseComposeTest() {
|
|||
)
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithContentDescription("Number of words, 3")
|
||||
.onChildren()
|
||||
.onNodeWithText("Number of words")
|
||||
.assertTextEquals("Number of words", "3")
|
||||
.onSiblings()
|
||||
.filterToOne(hasContentDescription("+"))
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
|
Loading…
Reference in a new issue