Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLinkStyles
Expand Down Expand Up @@ -198,7 +199,11 @@ private fun ProgramsText(
if (parts.size > 1) append(parts[1])
}

Text(style = HorizonTypography.p1, text = fullText)
Text(
modifier = Modifier.semantics(mergeDescendants = true) {},
style = HorizonTypography.p1,
text = fullText
)
}

@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import com.instructure.horizon.features.learn.course.lti.CourseToolsScreen
Expand All @@ -45,6 +49,7 @@ import com.instructure.horizon.horizonui.foundation.HorizonColors
import com.instructure.horizon.horizonui.foundation.HorizonTypography
import com.instructure.horizon.horizonui.molecules.ProgressBar
import com.instructure.horizon.horizonui.organisms.tabrow.TabRow
import com.instructure.horizon.horizonui.selectable
import kotlinx.coroutines.launch

@Composable
Expand Down Expand Up @@ -143,12 +148,17 @@ private fun Tab(tab: CourseDetailsTab, isSelected: Boolean, modifier: Modifier =
modifier = modifier
.padding(bottom = 2.dp)
) {
val context = LocalContext.current
Text(
stringResource(tab.titleRes),
style = HorizonTypography.p1,
color = color,
modifier = Modifier
.padding(top = 20.dp)
.semantics {
role = Role.Tab
selectable(context, isSelected)
}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
@file:OptIn(ExperimentalComposeUiApi::class)

package com.instructure.horizon.features.learn.course.score

import androidx.compose.animation.AnimatedContent
Expand Down Expand Up @@ -41,11 +43,15 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.invisibleToUser
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
Expand Down Expand Up @@ -352,28 +358,36 @@ private fun GroupWeightsContent(assignmentGroups: List<AssignmentGroupScoreItem>

@Composable
private fun GroupWeightItem(assignmentGroup: AssignmentGroupScoreItem) {
val groupWeightText = stringResource(
R.string.weightPercentageValue,
assignmentGroup.groupWeight
)
val mergedContentDescription = "${assignmentGroup.name}, $groupWeightText"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should string resources in this case. Different languages might handle a comma and word order differently.


Column(
modifier = Modifier
.padding(vertical = 16.dp)
.semantics(mergeDescendants = true) {
contentDescription = mergedContentDescription
}
) {
Column (
modifier = Modifier.padding(horizontal = 24.dp),
) {
Text(
text = assignmentGroup.name.orEmpty(),
text = assignmentGroup.name,
style = HorizonTypography.p1,
color = HorizonColors.Text.body()
color = HorizonColors.Text.body(),
modifier = Modifier.semantics { invisibleToUser() }
)

HorizonSpace(SpaceSize.SPACE_8)

Text(
text = stringResource(
R.string.weightPercentageValue,
assignmentGroup.groupWeight
),
text = groupWeightText,
style = HorizonTypography.p1,
color = HorizonColors.Text.body()
color = HorizonColors.Text.body(),
modifier = Modifier.semantics { invisibleToUser() }
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2025 - present Instructure, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.instructure.horizon.horizonui

import android.content.Context
import androidx.compose.ui.semantics.LiveRegionMode
import androidx.compose.ui.semantics.SemanticsPropertyReceiver
import androidx.compose.ui.semantics.liveRegion
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.semantics.stateDescription
import com.instructure.horizon.R

fun SemanticsPropertyReceiver.expandable(context: Context, expanded: Boolean) {
val expandedStateDesc = context.getString(R.string.a11y_expanded)
val collapsedStateDesc = context.getString(R.string.a11y_collapsed)
val expandActionLabel = context.getString(R.string.a11y_expand)
val collapseActionLabel = context.getString(R.string.a11y_collapse)

stateDescription = if (expanded) expandedStateDesc else collapsedStateDesc
liveRegion = LiveRegionMode.Assertive
onClick(if (expanded) collapseActionLabel else expandActionLabel) { false }
}

fun SemanticsPropertyReceiver.selectable(context: Context, selected: Boolean) {
val selectedStateDesc = context.getString(R.string.a11y_selected)
val unselectedStateDesc = context.getString(R.string.a11y_unselected)

stateDescription = if (selected) selectedStateDesc else unselectedStateDesc
liveRegion = LiveRegionMode.Assertive
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,25 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.invisibleToUser
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.instructure.horizon.R
import com.instructure.horizon.horizonui.expandable
import com.instructure.horizon.horizonui.foundation.HorizonColors
import com.instructure.horizon.horizonui.foundation.HorizonCornerRadius
import com.instructure.horizon.horizonui.foundation.HorizonSpace
import com.instructure.horizon.horizonui.foundation.HorizonTypography
import com.instructure.horizon.horizonui.foundation.SpaceSize

@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun CollapsableContentCard(
title: String,
Expand All @@ -65,13 +71,18 @@ fun CollapsableContentCard(
.padding(vertical = 16.dp)
) {
Column(
modifier = Modifier.clickable { onExpandChanged(!expanded) }
modifier = Modifier
.clickable { onExpandChanged(!expanded) }
.semantics {
invisibleToUser()
}
){
Text(
title,
style = HorizonTypography.h2,
color = HorizonColors.Text.body(),
modifier = Modifier.padding(horizontal = 24.dp)
modifier = Modifier
.padding(horizontal = 24.dp)
)

HorizonSpace(SpaceSize.SPACE_16)
Expand All @@ -80,11 +91,15 @@ fun CollapsableContentCard(
targetValue = if (expanded) 180f else 0f,
label = "rotationAnimation"
)

val context = LocalContext.current
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp)
.semantics(mergeDescendants = true) {
expandable(context, expanded)
}

) {
Icon(
painter = painterResource(R.drawable.keyboard_arrow_down),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.instructure.canvasapi2.utils.ContextKeeper
import com.instructure.horizon.R
import com.instructure.horizon.horizonui.expandable
import com.instructure.horizon.horizonui.foundation.HorizonColors
import com.instructure.horizon.horizonui.foundation.HorizonCornerRadius
import com.instructure.horizon.horizonui.foundation.HorizonSpace
Expand Down Expand Up @@ -98,8 +100,13 @@ fun ModuleContainer(state: ModuleHeaderState, modifier: Modifier = Modifier, con
Column {
val onClick = state.onClick
val clickModifier = if (onClick != null) Modifier.clickable { onClick() } else Modifier
val context = LocalContext.current

Column(modifier = clickModifier.padding(16.dp)) {
Column(modifier = clickModifier
.semantics(mergeDescendants = true) {
expandable(context, state.expanded)
}
.padding(16.dp)) {
ModuleHeader(state = state)
if (state.subtitle != null && state.expanded) {
HorizonSpace(SpaceSize.SPACE_24)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ private fun RowScope.ModuleItemCardIcon(state: ModuleItemCardState, modifier: Mo
HorizonSpace(SpaceSize.SPACE_8)
Icon(
painterResource(R.drawable.lock),
contentDescription = null,
contentDescription = stringResource(R.string.a11y_locked),
tint = HorizonColors.Surface.institution(),
modifier = modifier
)
Expand All @@ -128,7 +128,7 @@ private fun RowScope.ModuleItemCardIcon(state: ModuleItemCardState, modifier: Mo
HorizonSpace(SpaceSize.SPACE_8)
Icon(
painterResource(R.drawable.check_circle_full),
contentDescription = null,
contentDescription = stringResource(R.string.a11y_completed),
tint = HorizonColors.Surface.institution(),
modifier = modifier
)
Expand All @@ -138,7 +138,7 @@ private fun RowScope.ModuleItemCardIcon(state: ModuleItemCardState, modifier: Mo
HorizonSpace(SpaceSize.SPACE_8)
Icon(
painterResource(R.drawable.circle),
contentDescription = null,
contentDescription = stringResource(R.string.a11y_not_completed),
tint = HorizonColors.LineAndBorder.lineStroke(),
modifier = modifier
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.stateDescription
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.instructure.canvasapi2.utils.ContextKeeper
Expand All @@ -55,7 +61,8 @@ fun SingleSelect(
state: SingleSelectState,
modifier: Modifier = Modifier
) {

val expandedState = stringResource(R.string.a11y_expanded)
val collapsedState = stringResource(R.string.a11y_collapsed)
Input(
label = state.label,
helperText = state.helperText,
Expand All @@ -65,6 +72,15 @@ fun SingleSelect(
.onFocusChanged {
state.onFocusChanged(it.isFocused)
}
.clearAndSetSemantics {
role = Role.DropdownList
stateDescription = if (state.isMenuOpen) expandedState else collapsedState
contentDescription = if (state.selectedOption != null) {
"${state.label}, ${state.selectedOption}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should string resources in this case. Different languages might handle a comma and word order differently.

} else {
state.label ?: ""
}
}
) {
Column(
modifier = Modifier
Expand Down
8 changes: 8 additions & 0 deletions libs/horizon/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -370,4 +370,12 @@
<string name="dashboardCompletedCourseDetails">Congrats! You’ve completed your course. View your progress and scores on the Learn page.</string>
<string name="a11y_inboxComposeSelectCourse">Select Course</string>
<string name="a11y_close">Close</string>
<string name="a11y_expanded">Expanded</string>
<string name="a11y_collapsed">Collapsed</string>
<string name="a11y_expand">Expand</string>
<string name="a11y_collapse">Collapse</string>
<string name="a11y_completed">Completed</string>
<string name="a11y_not_completed">Not completed</string>
<string name="a11y_locked">Locked</string>
<string name="a11y_unselected">Unselected</string>
</resources>
Loading