a11y: improve accessibility on rich text editor options.
This commit is contained in:
@@ -13,6 +13,7 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.selection.toggleable
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.ripple
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -21,6 +22,8 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.semantics.clearAndSetSemantics
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
@@ -32,9 +35,10 @@ import io.element.android.libraries.designsystem.theme.iconSuccessPrimaryBackgro
|
||||
@Composable
|
||||
internal fun FormattingOption(
|
||||
state: FormattingOptionState,
|
||||
toggleable: Boolean,
|
||||
onClick: () -> Unit,
|
||||
imageVector: ImageVector,
|
||||
contentDescription: String?,
|
||||
contentDescription: String,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val backgroundColor = when (state) {
|
||||
@@ -52,6 +56,7 @@ internal fun FormattingOption(
|
||||
modifier = modifier
|
||||
.clickable(
|
||||
onClick = onClick,
|
||||
enabled = state != FormattingOptionState.Disabled,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = ripple(
|
||||
bounded = false,
|
||||
@@ -59,6 +64,20 @@ internal fun FormattingOption(
|
||||
),
|
||||
)
|
||||
.size(48.dp)
|
||||
.then(
|
||||
if (toggleable) {
|
||||
Modifier.toggleable(
|
||||
value = state == FormattingOptionState.Selected,
|
||||
enabled = state != FormattingOptionState.Disabled,
|
||||
onValueChange = { onClick() },
|
||||
)
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
)
|
||||
.clearAndSetSemantics {
|
||||
this.contentDescription = contentDescription
|
||||
}
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
@@ -84,21 +103,24 @@ internal fun FormattingOptionPreview() = ElementPreview {
|
||||
Row {
|
||||
FormattingOption(
|
||||
state = FormattingOptionState.Default,
|
||||
toggleable = false,
|
||||
onClick = { },
|
||||
imageVector = CompoundIcons.Bold(),
|
||||
contentDescription = null,
|
||||
contentDescription = "",
|
||||
)
|
||||
FormattingOption(
|
||||
state = FormattingOptionState.Selected,
|
||||
toggleable = true,
|
||||
onClick = { },
|
||||
imageVector = CompoundIcons.Italic(),
|
||||
contentDescription = null,
|
||||
contentDescription = "",
|
||||
)
|
||||
FormattingOption(
|
||||
state = FormattingOptionState.Disabled,
|
||||
toggleable = false,
|
||||
onClick = { },
|
||||
imageVector = CompoundIcons.Underline(),
|
||||
contentDescription = null,
|
||||
contentDescription = "",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,24 +104,28 @@ internal fun TextFormatting(
|
||||
) {
|
||||
FormattingOption(
|
||||
state = state.actions[ComposerAction.BOLD].toButtonState(),
|
||||
toggleable = true,
|
||||
onClick = { onInlineFormatClick(InlineFormat.Bold) },
|
||||
imageVector = CompoundIcons.Bold(),
|
||||
contentDescription = stringResource(R.string.rich_text_editor_format_bold)
|
||||
)
|
||||
FormattingOption(
|
||||
state = state.actions[ComposerAction.ITALIC].toButtonState(),
|
||||
toggleable = true,
|
||||
onClick = { onInlineFormatClick(InlineFormat.Italic) },
|
||||
imageVector = CompoundIcons.Italic(),
|
||||
contentDescription = stringResource(R.string.rich_text_editor_format_italic)
|
||||
)
|
||||
FormattingOption(
|
||||
state = state.actions[ComposerAction.UNDERLINE].toButtonState(),
|
||||
toggleable = true,
|
||||
onClick = { onInlineFormatClick(InlineFormat.Underline) },
|
||||
imageVector = CompoundIcons.Underline(),
|
||||
contentDescription = stringResource(R.string.rich_text_editor_format_underline)
|
||||
)
|
||||
FormattingOption(
|
||||
state = state.actions[ComposerAction.STRIKE_THROUGH].toButtonState(),
|
||||
toggleable = true,
|
||||
onClick = { onInlineFormatClick(InlineFormat.StrikeThrough) },
|
||||
imageVector = CompoundIcons.Strikethrough(),
|
||||
contentDescription = stringResource(R.string.rich_text_editor_format_strikethrough)
|
||||
@@ -141,6 +145,7 @@ internal fun TextFormatting(
|
||||
|
||||
FormattingOption(
|
||||
state = state.actions[ComposerAction.LINK].toButtonState(),
|
||||
toggleable = true,
|
||||
onClick = { linkDialogAction = state.linkAction },
|
||||
imageVector = CompoundIcons.Link(),
|
||||
contentDescription = stringResource(R.string.rich_text_editor_link)
|
||||
@@ -148,42 +153,49 @@ internal fun TextFormatting(
|
||||
|
||||
FormattingOption(
|
||||
state = state.actions[ComposerAction.UNORDERED_LIST].toButtonState(),
|
||||
toggleable = true,
|
||||
onClick = { onToggleListClick(ordered = false) },
|
||||
imageVector = CompoundIcons.ListBulleted(),
|
||||
contentDescription = stringResource(R.string.rich_text_editor_bullet_list)
|
||||
)
|
||||
FormattingOption(
|
||||
state = state.actions[ComposerAction.ORDERED_LIST].toButtonState(),
|
||||
toggleable = true,
|
||||
onClick = { onToggleListClick(ordered = true) },
|
||||
imageVector = CompoundIcons.ListNumbered(),
|
||||
contentDescription = stringResource(R.string.rich_text_editor_numbered_list)
|
||||
)
|
||||
FormattingOption(
|
||||
state = state.actions[ComposerAction.INDENT].toButtonState(),
|
||||
toggleable = false,
|
||||
onClick = { onIndentClick() },
|
||||
imageVector = CompoundIcons.IndentIncrease(),
|
||||
contentDescription = stringResource(R.string.rich_text_editor_indent)
|
||||
)
|
||||
FormattingOption(
|
||||
state = state.actions[ComposerAction.UNINDENT].toButtonState(),
|
||||
toggleable = false,
|
||||
onClick = { onUnindentClick() },
|
||||
imageVector = CompoundIcons.IndentDecrease(),
|
||||
contentDescription = stringResource(R.string.rich_text_editor_unindent)
|
||||
)
|
||||
FormattingOption(
|
||||
state = state.actions[ComposerAction.INLINE_CODE].toButtonState(),
|
||||
toggleable = true,
|
||||
onClick = { onInlineFormatClick(InlineFormat.InlineCode) },
|
||||
imageVector = CompoundIcons.InlineCode(),
|
||||
contentDescription = stringResource(R.string.rich_text_editor_inline_code)
|
||||
)
|
||||
FormattingOption(
|
||||
state = state.actions[ComposerAction.CODE_BLOCK].toButtonState(),
|
||||
toggleable = true,
|
||||
onClick = { onCodeBlockClick() },
|
||||
imageVector = CompoundIcons.Code(),
|
||||
contentDescription = stringResource(R.string.rich_text_editor_code_block)
|
||||
)
|
||||
FormattingOption(
|
||||
state = state.actions[ComposerAction.QUOTE].toButtonState(),
|
||||
toggleable = true,
|
||||
onClick = { onQuoteClick() },
|
||||
imageVector = CompoundIcons.Quote(),
|
||||
contentDescription = stringResource(R.string.rich_text_editor_quote)
|
||||
|
||||
Reference in New Issue
Block a user