diff --git a/core/navigation-api/src/main/java/ru/yeahub/navigation_api/FeatureRoute.kt b/core/navigation-api/src/main/java/ru/yeahub/navigation_api/FeatureRoute.kt index d844e48a..36d1626d 100644 --- a/core/navigation-api/src/main/java/ru/yeahub/navigation_api/FeatureRoute.kt +++ b/core/navigation-api/src/main/java/ru/yeahub/navigation_api/FeatureRoute.kt @@ -9,7 +9,7 @@ package ru.yeahub.navigation_api * - Построение путей с учетом родительских маршрутов */ object FeatureRoute { - + fun createFeatureRoute(parentRoute: String, featureName: String): String = if (parentRoute.isEmpty()) featureName else "$parentRoute/$featureName" @@ -46,9 +46,11 @@ object FeatureRoute { object DetailsFeature { const val FEATURE_NAME = "details" } + object PublicQuestionsFeature { const val FEATURE_NAME = "public_questions" } + object DetailQuestionFeature { const val FEATURE_NAME = "detail_question" } @@ -56,13 +58,16 @@ object FeatureRoute { object SpecializationsFeature { const val FEATURE_NAME = "specializations" } + object CollectionsFeature { const val FEATURE_NAME = "collections" } + object PublicCollectionsFeature { const val FEATURE_NAME = "public_collections" } - object ProfileEditFeature{ + + object ProfileEditFeature { const val FEATURE_NAME = "profile_edit" } } \ No newline at end of file diff --git a/core/ui/src/main/java/ru/yeahub/core_ui/component/AlertDialog.kt b/core/ui/src/main/java/ru/yeahub/core_ui/component/AlertDialog.kt new file mode 100644 index 00000000..89a5e150 --- /dev/null +++ b/core/ui/src/main/java/ru/yeahub/core_ui/component/AlertDialog.kt @@ -0,0 +1,53 @@ +package ru.yeahub.core_ui.component + +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import ru.yeahub.core_ui.example.dynamicPreview.SmallScreenSizePreview +import ru.yeahub.core_ui.theme.Theme +import ru.yeahub.core_ui.theme.colors + +@Composable +fun UnsavedChangesDialog( + onStay: () -> Unit, + onLeave: () -> Unit, +) { + AlertDialog( + onDismissRequest = onStay, + title = { + Text( + text = "Подтвердить действие", + style = Theme.typography.head4, + ) + }, + text = { + Text( + "У вас есть несохраненные данные.\nВы хотите продолжить?", + style = Theme.typography.body3, + ) + }, + dismissButton = { + PrimaryButton(onClick = onStay) { + Text("Да") + } + }, + confirmButton = { + OutlineButton( + onClick = onLeave, + colors = YeahubButtonDefaults.secondaryOutlinedButtonColors(), + border = YeahubButtonDefaults.secondaryOutlineBorderDefaults(), + ) { + Text( + "Нет", + ) + } + }, + containerColor = colors.white900, + ) +} + +@SmallScreenSizePreview +@Composable +fun UnsavedChangesDialogPreview() { + UnsavedChangesDialog({}, {}) +} \ No newline at end of file diff --git a/core/ui/src/main/java/ru/yeahub/core_ui/component/Button.kt b/core/ui/src/main/java/ru/yeahub/core_ui/component/Button.kt index e3ca6cc4..d9d443a5 100644 --- a/core/ui/src/main/java/ru/yeahub/core_ui/component/Button.kt +++ b/core/ui/src/main/java/ru/yeahub/core_ui/component/Button.kt @@ -52,7 +52,7 @@ fun PrimaryButton( interactionSource = interactionSource, shape = shape, contentPadding = contentPadding, - content = content + content = content, ) } @@ -91,7 +91,7 @@ fun OutlineButton( interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, shape: Shape = RoundedCornerShape(12.dp), contentPadding: PaddingValues = ButtonDefaults.ContentPadding, - content: @Composable RowScope.() -> Unit + content: @Composable RowScope.() -> Unit, ) { DefaultButton( onClick = onClick, @@ -102,7 +102,7 @@ fun OutlineButton( interactionSource = interactionSource, shape = shape, contentPadding = contentPadding, - content = content + content = content, ) } @@ -116,7 +116,7 @@ private fun DefaultButton( border: BorderStroke? = null, shape: Shape = ButtonDefaults.shape, contentPadding: PaddingValues = ButtonDefaults.ContentPadding, - content: @Composable RowScope.() -> Unit + content: @Composable RowScope.() -> Unit, ) { val contentColor: Color by colors.contentColor(enabled) val containerColor: Color by colors.containerColor(enabled) @@ -129,16 +129,16 @@ private fun DefaultButton( color = containerColor, contentColor = contentColor, border = border, - interactionSource = interactionSource + interactionSource = interactionSource, ) { CompositionLocalProvider( - value = LocalContentColor provides contentColor + value = LocalContentColor provides contentColor, ) { Row( modifier = Modifier .padding(contentPadding), horizontalArrangement = Arrangement.Center, - content = content + content = content, ) } } @@ -150,13 +150,13 @@ object YeahubButtonDefaults { contentColor: Color = Theme.colors.white900, containerColor: Color = Theme.colors.purple700, disabledContentColor: Color = Theme.colors.white900, - disabledContainerColor: Color = Theme.colors.black100 + disabledContainerColor: Color = Theme.colors.black100, ): YeahubButtonColors { return YeahubButtonColors( contentColor = contentColor, containerColor = containerColor, disabledContentColor = disabledContentColor, - disabledContainerColor = disabledContainerColor + disabledContainerColor = disabledContainerColor, ) } @@ -165,13 +165,13 @@ object YeahubButtonDefaults { contentColor: Color = Theme.colors.white900, containerColor: Color = Theme.colors.red600, disabledContentColor: Color = Theme.colors.white900, - disabledContainerColor: Color = Theme.colors.red200 + disabledContainerColor: Color = Theme.colors.red200, ): YeahubButtonColors { return YeahubButtonColors( contentColor = contentColor, containerColor = containerColor, disabledContentColor = disabledContentColor, - disabledContainerColor = disabledContainerColor + disabledContainerColor = disabledContainerColor, ) } @@ -180,13 +180,13 @@ object YeahubButtonDefaults { contentColor: Color = Theme.colors.purple700, containerColor: Color = Theme.colors.purple100, disabledContentColor: Color = Theme.colors.black200, - disabledContainerColor: Color = Theme.colors.black50 + disabledContainerColor: Color = Theme.colors.black50, ): YeahubButtonColors { return YeahubButtonColors( contentColor = contentColor, containerColor = containerColor, disabledContentColor = disabledContentColor, - disabledContainerColor = disabledContainerColor + disabledContainerColor = disabledContainerColor, ) } @@ -195,13 +195,13 @@ object YeahubButtonDefaults { contentColor: Color = Theme.colors.white900, containerColor: Color = Theme.colors.red600, disabledContentColor: Color = Theme.colors.white900, - disabledContainerColor: Color = Theme.colors.red200 + disabledContainerColor: Color = Theme.colors.red200, ): YeahubButtonColors { return YeahubButtonColors( contentColor = contentColor, containerColor = containerColor, disabledContentColor = disabledContentColor, - disabledContainerColor = disabledContainerColor + disabledContainerColor = disabledContainerColor, ) } @@ -216,18 +216,44 @@ object YeahubButtonDefaults { contentColor = contentColor, containerColor = containerColor, disabledContentColor = disabledContentColor, - disabledContainerColor = disabledContainerColor + disabledContainerColor = disabledContainerColor, ) } @Composable fun outlineBorderDefaults( width: Dp = 1.dp, - borderColor: Color = Theme.colors.red200 + borderColor: Color = Theme.colors.red200, + ): BorderStroke { + return BorderStroke( + width = width, + color = borderColor, + ) + } + + @Composable + fun secondaryOutlinedButtonColors( + contentColor: Color = Theme.colors.purple700, + containerColor: Color = Color.Transparent, + disabledContentColor: Color = Theme.colors.purple200, + disabledContainerColor: Color = Color.Transparent, + ): YeahubButtonColors { + return YeahubButtonColors( + contentColor = contentColor, + containerColor = containerColor, + disabledContentColor = disabledContentColor, + disabledContainerColor = disabledContainerColor, + ) + } + + @Composable + fun secondaryOutlineBorderDefaults( + width: Dp = 1.dp, + borderColor: Color = Theme.colors.purple700, ): BorderStroke { return BorderStroke( width = width, - color = borderColor + color = borderColor, ) } } @@ -260,7 +286,7 @@ interface ButtonColors { } @Preview( - showBackground = true + showBackground = true, ) @Composable fun ButtonPreviews() { @@ -268,21 +294,21 @@ fun ButtonPreviews() { modifier = Modifier .fillMaxWidth() .padding(16.dp), - verticalArrangement = Arrangement.spacedBy(16.dp) + verticalArrangement = Arrangement.spacedBy(16.dp), ) { // Primary Button Text("Primary Buttons", style = MaterialTheme.typography.titleMedium) PrimaryButton( onClick = {}, modifier = Modifier.fillMaxWidth(), - enabled = true + enabled = true, ) { Text("Enabled Primary Button") } PrimaryButton( onClick = {}, modifier = Modifier.fillMaxWidth(), - enabled = false + enabled = false, ) { Text("Disabled Primary Button") } @@ -292,14 +318,14 @@ fun ButtonPreviews() { SecondaryButton( onClick = {}, modifier = Modifier.fillMaxWidth(), - enabled = true + enabled = true, ) { Text("Enabled Secondary Button") } SecondaryButton( onClick = {}, modifier = Modifier.fillMaxWidth(), - enabled = false + enabled = false, ) { Text("Disabled Secondary Button") } @@ -309,16 +335,25 @@ fun ButtonPreviews() { OutlineButton( onClick = {}, modifier = Modifier.fillMaxWidth(), - enabled = true + enabled = true, ) { Text("Enabled Outline Button") } OutlineButton( onClick = {}, modifier = Modifier.fillMaxWidth(), - enabled = false + enabled = false, ) { Text("Disabled Outline Button") } + OutlineButton( + onClick = {}, + colors = YeahubButtonDefaults.secondaryOutlinedButtonColors(), + border = YeahubButtonDefaults.secondaryOutlineBorderDefaults(), + modifier = Modifier.fillMaxWidth(), + enabled = true, + ) { + Text("Enabled Outline Button with secondary colors") + } } } diff --git a/core/ui/src/main/java/ru/yeahub/core_ui/component/DropDownMenu.kt b/core/ui/src/main/java/ru/yeahub/core_ui/component/DropDownMenu.kt new file mode 100644 index 00000000..1e71381d --- /dev/null +++ b/core/ui/src/main/java/ru/yeahub/core_ui/component/DropDownMenu.kt @@ -0,0 +1,217 @@ +package ru.yeahub.core_ui.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExposedDropdownMenuBox +import androidx.compose.material3.Icon +import androidx.compose.material3.MenuAnchorType +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.rotate +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import androidx.compose.ui.unit.dp +import ru.yeahub.core_ui.component.textInput.ColorsTextInputYeaHub +import ru.yeahub.core_ui.component.textInput.DefaultTextField +import ru.yeahub.core_ui.component.textInput.TextInput +import ru.yeahub.core_ui.component.textInput.TextInputColorsDefaults +import ru.yeahub.core_ui.component.textInput.getTextInputColors +import ru.yeahub.core_ui.example.dynamicPreview.StandardScreenSizePreview +import ru.yeahub.core_ui.example.staticPreview.StaticPreview +import ru.yeahub.core_ui.theme.Theme +import ru.yeahub.ui.R + +@OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class) +@Composable +fun DropDownMenu( + modifier: Modifier = Modifier, + placeholder: String, + items: List, + selected: String, + onSelected: (String) -> Unit, + shape: Shape = RoundedCornerShape(12.dp), + isExpanded: Boolean = false, + isEnabled: Boolean = true, + isError: Boolean = false, + colors: ColorsTextInputYeaHub = TextInputColorsDefaults.defaultColors(), + trailingIcon: @Composable (() -> Unit)? = { + Icon( + painterResource(R.drawable.arrow_vector), + null, + ) + }, + leadingIcon: @Composable (() -> Unit)? = null, +) { + var expanded by remember { mutableStateOf(isExpanded) } + + val trailingIconRotating: (@Composable (() -> Unit))? = trailingIcon?.let { icon -> + { Box(Modifier.rotate(if (expanded) 180f else 0f)) { icon() } } + } + + ExposedDropdownMenuBox( + modifier = modifier + .width(328.dp) + .height(58.dp), + expanded = expanded, + onExpandedChange = { if (isEnabled) expanded = it }, + ) { + DefaultTextField( + value = selected, + onValueChange = {}, + readOnly = true, + isEnabled = isEnabled, + isError = isError, + placeholder = placeholder, + trailingIcon = trailingIconRotating, + leadingIcon = leadingIcon, + shape = shape, + modifier = Modifier + .fillMaxWidth() + .menuAnchor(MenuAnchorType.PrimaryNotEditable, isEnabled), + onExpandedChange = { }, + isFocused = isExpanded, + ) + + ExposedDropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false }, + containerColor = colors.containerColor(isEnabled).value, + ) { + items.forEach { item -> + DropdownMenuItem( + text = { + Text( + item, + style = Theme.typography.body3, + color = colors.contentColor(isEnabled).value, + ) + }, + onClick = { + onSelected(item) + expanded = false + }, + ) + } + } + } +} + +class DropDownMenuParamsProvider : PreviewParameterProvider { + override val values = sequenceOf( + DropDownMenuParams( + items = listOf("Android", "Backend", "Frontend"), + placeholder = "Выбери значение", + ), + DropDownMenuParams( + items = listOf("Android", "Backend", "Frontend"), + placeholder = "Выбери значение", + isExpanded = true, + ), + DropDownMenuParams( + items = listOf("Android", "Backend", "Frontend"), + placeholder = "Выбери значение", + isError = true, + ), + DropDownMenuParams( + items = listOf("Android", "Backend", "Frontend"), + placeholder = "Выбери значение", + isEnabled = false, + ), + DropDownMenuParams( + items = listOf("Android", "Backend", "Frontend"), + placeholder = "Выбери значение", + selected = "Android Mobile Developer", + isEnabled = false, + ), + DropDownMenuParams( + items = listOf("Android", "Backend", "Frontend"), + placeholder = "Выбери значение", + selected = "Android Mobile Developer", + isEnabled = true, + ), + DropDownMenuParams( + items = listOf("Android", "Backend", "Frontend"), + placeholder = "Выбери значение", + selected = "Android Mobile Developer", + isEnabled = true, + isExpanded = true, + ), + ) +} + +@StaticPreview +@Composable +fun DropDownMenuPreview( + @PreviewParameter(DropDownMenuParamsProvider::class) params: DropDownMenuParams, +) { + Box( + Modifier + .background(Color.White) + .padding(10.dp), + ) { + DropDownMenu( + placeholder = params.placeholder, + items = params.items, + selected = params.selected, + onSelected = params.onSelected, + isExpanded = params.isExpanded, + isError = params.isError, + isEnabled = params.isEnabled, + ) + } +} + +@StandardScreenSizePreview +@Composable +fun DropDownMenuPreview() { + val items = listOf("Android", "Backend", "Frontend") + var selected: String by rememberSaveable { mutableStateOf("") } + + Column(modifier = Modifier.padding(12.dp)) { + DropDownMenu( + placeholder = "Выбери значение", + items = items, + onSelected = { selected = it }, + selected = selected, + colors = getTextInputColors(), + ) + TextInput( + value = "", + onValueChange = { }, + label = "label", + expanded = false, + onExpandedChange = { }, + onQueryChanged = { }, + ) + } +} + +data class DropDownMenuParams( + val placeholder: String, + val items: List, + val selected: String = "", + val onSelected: (String) -> Unit = {}, + val modifier: Modifier = Modifier, + val isEnabled: Boolean = true, + val isError: Boolean = false, + val isExpanded: Boolean = false, + val colors: ColorsTextInputYeaHub = getTextInputColors(), +) \ No newline at end of file diff --git a/core/ui/src/main/java/ru/yeahub/core_ui/component/TabBar.kt b/core/ui/src/main/java/ru/yeahub/core_ui/component/TabBar.kt new file mode 100644 index 00000000..dd1c5667 --- /dev/null +++ b/core/ui/src/main/java/ru/yeahub/core_ui/component/TabBar.kt @@ -0,0 +1,141 @@ +package ru.yeahub.core_ui.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.ScrollableTabRow +import androidx.compose.material3.Tab +import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import ru.yeahub.core_ui.example.dynamicPreview.StandardScreenSizePreview +import ru.yeahub.core_ui.theme.Theme + +@Immutable +data class CoreTopTabsColors( + val containerColor: Color, + val indicatorColor: Color, + val selectedTextColor: Color, + val unselectedTextColor: Color, +) + +object CoreTopTabsDefaults { + @Composable + fun colors( + containerColor: Color = Theme.colors.white900, + indicatorColor: Color = Theme.colors.purple700, + selectedTextColor: Color = Theme.colors.black900, + unselectedTextColor: Color = Theme.colors.black500, + ) = CoreTopTabsColors( + containerColor = containerColor, + indicatorColor = indicatorColor, + selectedTextColor = selectedTextColor, + unselectedTextColor = unselectedTextColor, + ) +} + +@Composable +fun CoreTopTabs( + tabs: List, + selectedIndex: Int, + onSelected: (Int) -> Unit, + modifier: Modifier = Modifier, + colors: CoreTopTabsColors = CoreTopTabsDefaults.colors(), + edgePadding: Dp = 0.dp, + tabSpacing: Dp = 0.dp, + indicatorHeight: Dp = 2.dp, + indicatorHorizontalPadding: Dp = 16.dp, +) { + ScrollableTabRow( + selectedTabIndex = selectedIndex, + modifier = modifier, + containerColor = colors.containerColor, + contentColor = colors.selectedTextColor, + edgePadding = edgePadding, + divider = { HorizontalDivider(thickness = 0.dp) }, + indicator = { positions -> + val pos = positions[selectedIndex] + Box( + Modifier + .tabIndicatorOffset(pos) + .padding(horizontal = indicatorHorizontalPadding) + .height(indicatorHeight) + .background(colors.indicatorColor), + ) + }, + ) { + tabs.forEachIndexed { index, title -> + val isSelected = index == selectedIndex + Tab( + selected = isSelected, + onClick = { onSelected(index) }, + text = { + Text( + text = title, + color = if (isSelected) colors.selectedTextColor else colors.unselectedTextColor, + style = Theme.typography.head6, + maxLines = 1, + softWrap = false, + overflow = TextOverflow.Visible, + ) + }, + ) + } + } +} + +data class YhTabsParams( + val items: List, + val selectedIndex: Int, +) + +class YhTabsParamsProvider : PreviewParameterProvider { + override val values = sequenceOf( + YhTabsParams(listOf("Личная информация", "Обо мне", "Навыки"), 0), + YhTabsParams( + listOf( + "Tab 1", + "Очень длинный таб", + "Очень длинный таб", + "Очень длинный таб", + "Tab 1", + "Tab 1", + ), + 2, + ), + ) +} + +@StandardScreenSizePreview +@Composable +fun YhTabsPreview( + @PreviewParameter(YhTabsParamsProvider::class) p: YhTabsParams, +) { + var selected by remember { mutableIntStateOf(p.selectedIndex) } + + Box( + Modifier + .background(Color.White) + .padding(0.dp), + ) { + CoreTopTabs( + tabs = p.items, + selectedIndex = selected, + onSelected = { selected = it }, + ) + } +} \ No newline at end of file diff --git a/core/ui/src/main/java/ru/yeahub/core_ui/component/UploadPhotoButton.kt b/core/ui/src/main/java/ru/yeahub/core_ui/component/UploadPhotoButton.kt new file mode 100644 index 00000000..3fbe0863 --- /dev/null +++ b/core/ui/src/main/java/ru/yeahub/core_ui/component/UploadPhotoButton.kt @@ -0,0 +1,110 @@ +package ru.yeahub.core_ui.component + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawWithCache +import androidx.compose.ui.geometry.CornerRadius +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.PathEffect +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import ru.yeahub.core_ui.theme.Theme +import ru.yeahub.ui.R + +@Composable +fun UploadPhotoButton( + modifier: Modifier = Modifier, + title: String = "Кликни для изменения", + helper: String = "JPG, PNG, JPEG (не более 5мб)", + onClick: () -> Unit, +) { + val shape = RoundedCornerShape(12.dp) + + Surface( + modifier = modifier + .fillMaxWidth() + .height(164.dp) + .dashedRoundedBorder( + color = Theme.colors.purple400, + strokeWidth = 2.dp, + cornerRadius = 12.dp, + dashLength = 8.dp, + gapLength = 8.dp, + ) + .clickable(onClick = onClick), + shape = shape, + color = Color.Transparent, + ) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 16.dp, vertical = 28.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Icon( + painter = painterResource(R.drawable.image), + contentDescription = null, + tint = Theme.colors.purple700, + modifier = Modifier.size(32.dp), + ) + + Spacer(Modifier.height(12.dp)) + + Text(text = title, style = Theme.typography.body3, color = Theme.colors.purple700) + + Spacer(Modifier.height(12.dp)) + + Text(text = helper, style = Theme.typography.body7, color = Theme.colors.black200) + } + } +} + +@Preview(showBackground = true) +@Composable +fun UploadPhotoButtonPreview() { + Column(Modifier.padding(16.dp)) { + UploadPhotoButton(onClick = {}) + } +} + +fun Modifier.dashedRoundedBorder( + color: Color, + strokeWidth: Dp = 2.dp, + cornerRadius: Dp = 12.dp, + dashLength: Dp = 12.dp, + gapLength: Dp = 12.dp, +) = drawWithCache { + val strokePx = strokeWidth.toPx() + val radiusPx = cornerRadius.toPx() + val dashPx = dashLength.toPx() + val gapPx = gapLength.toPx() + val stroke = Stroke( + width = strokePx, + pathEffect = PathEffect.dashPathEffect(floatArrayOf(dashPx, gapPx), 0f), + ) + onDrawBehind { + drawRoundRect( + color = color, + style = stroke, + cornerRadius = CornerRadius(radiusPx, radiusPx), + ) + } +} \ No newline at end of file diff --git a/core/ui/src/main/java/ru/yeahub/core_ui/example/dynamicPreview/SmallScreenSizePreview.kt b/core/ui/src/main/java/ru/yeahub/core_ui/example/dynamicPreview/SmallScreenSizePreview.kt new file mode 100644 index 00000000..3b19ff76 --- /dev/null +++ b/core/ui/src/main/java/ru/yeahub/core_ui/example/dynamicPreview/SmallScreenSizePreview.kt @@ -0,0 +1,13 @@ +package ru.yeahub.core_ui.example.dynamicPreview + +import androidx.compose.ui.tooling.preview.Preview + +private const val SMALL_SCREEN_WIDTH_DP = 320 +private const val SMALL_SCREEN_HEIGHT_DP = 480 + +@Preview( + widthDp = SMALL_SCREEN_WIDTH_DP, + heightDp = SMALL_SCREEN_HEIGHT_DP, + showBackground = true, +) +annotation class SmallScreenSizePreview() diff --git a/core/ui/src/main/java/ru/yeahub/core_ui/theme/Typography.kt b/core/ui/src/main/java/ru/yeahub/core_ui/theme/Typography.kt index 78a60294..b8411339 100644 --- a/core/ui/src/main/java/ru/yeahub/core_ui/theme/Typography.kt +++ b/core/ui/src/main/java/ru/yeahub/core_ui/theme/Typography.kt @@ -62,6 +62,12 @@ data class Typography( fontSize = 22.sp, lineHeight = 26.sp, ), + val head6: TextStyle = TextStyle( + fontFamily = sfProDisplay, + fontWeight = FontWeight.SemiBold, + fontSize = 16.sp, + lineHeight = 24.sp, + ), //Body val body1: TextStyle = TextStyle( fontFamily = manrope, diff --git a/core/ui/src/main/res/drawable/image.xml b/core/ui/src/main/res/drawable/image.xml new file mode 100644 index 00000000..6d444a37 --- /dev/null +++ b/core/ui/src/main/res/drawable/image.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/feature/profile-edit/impl/src/main/java/ru/yeahub/profile_edit/impl/ProfileEditFeatureImpl.kt b/feature/profile-edit/impl/src/main/java/ru/yeahub/profile_edit/impl/ProfileEditFeatureImpl.kt index b27b502f..b9e97579 100644 --- a/feature/profile-edit/impl/src/main/java/ru/yeahub/profile_edit/impl/ProfileEditFeatureImpl.kt +++ b/feature/profile-edit/impl/src/main/java/ru/yeahub/profile_edit/impl/ProfileEditFeatureImpl.kt @@ -10,7 +10,6 @@ import ru.yeahub.navigation_api.NavigationPathManager class ProfileEditFeatureImpl : FeatureApi { override fun getFeatureName(): String = FeatureRoute.ProfileEditFeature.FEATURE_NAME - override fun registerGraph( navGraphBuilder: NavGraphBuilder, navController: NavHostController,