Merge pull request 'sprint-1' (#1) from sprint-1 into master
Reviewed-on: #1
This commit is contained in:
commit
053cbfec6c
@ -56,4 +56,6 @@ dependencies {
|
|||||||
androidTestImplementation(libs.androidx.ui.test.junit4)
|
androidTestImplementation(libs.androidx.ui.test.junit4)
|
||||||
debugImplementation(libs.androidx.ui.tooling)
|
debugImplementation(libs.androidx.ui.tooling)
|
||||||
debugImplementation(libs.androidx.ui.test.manifest)
|
debugImplementation(libs.androidx.ui.test.manifest)
|
||||||
|
|
||||||
|
implementation(project(":core"))
|
||||||
}
|
}
|
@ -1,47 +1,413 @@
|
|||||||
package com.example.uikit
|
package com.example.uikit
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.safeDrawingPadding
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
|
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.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.unit.dp
|
||||||
import com.example.uikit.ui.theme.UikitTheme
|
import com.example.core.component.button.AppButton
|
||||||
|
import com.example.core.component.button.BubbleButton
|
||||||
|
import com.example.core.component.button.BubbleButtonState
|
||||||
|
import com.example.core.component.button.ButtonState
|
||||||
|
import com.example.core.component.button.CartButton
|
||||||
|
import com.example.core.component.button.LoginButton
|
||||||
|
import com.example.core.component.button.OutlinedAppButton
|
||||||
|
import com.example.core.component.button.SecondaryAppButton
|
||||||
|
import com.example.core.component.card.CartCard
|
||||||
|
import com.example.core.component.card.PrimaryCard
|
||||||
|
import com.example.core.component.card.ProjectCard
|
||||||
|
import com.example.core.component.header.BigHeader
|
||||||
|
import com.example.core.component.header.SmallHeader
|
||||||
|
import com.example.core.component.input.EnterInputField
|
||||||
|
import com.example.core.component.search.AppSearchField
|
||||||
|
import com.example.core.component.select.AppSelector
|
||||||
|
import com.example.core.component.select.Option
|
||||||
|
import com.example.core.component.tabbar.BottomTabBar
|
||||||
|
import com.example.core.component.tabbar.Catalog
|
||||||
|
import com.example.core.component.tabbar.Home
|
||||||
|
import com.example.core.component.tabbar.Profile
|
||||||
|
import com.example.core.component.tabbar.Projects
|
||||||
|
import com.example.core.theme.CustomIcons
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
|
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
setContent {
|
setContent {
|
||||||
UikitTheme {
|
CustomTheme {
|
||||||
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
Scaffold { tabPadding ->
|
||||||
Greeting(
|
var currentDestination by rememberSaveable { mutableStateOf("com.example.core.component.tabbar.Home") }
|
||||||
name = "Android",
|
Scaffold(
|
||||||
modifier = Modifier.padding(innerPadding)
|
bottomBar = {
|
||||||
)
|
BottomTabBar(
|
||||||
|
tabs = listOf(Home, Catalog, Projects, Profile),
|
||||||
|
hierarchy = sequenceOf(currentDestination),
|
||||||
|
onTabClick = {
|
||||||
|
currentDestination = it::class.qualifiedName.toString()
|
||||||
|
},
|
||||||
|
bottomPadding = tabPadding.calculateBottomPadding()
|
||||||
|
)
|
||||||
|
},
|
||||||
|
containerColor = CustomTheme.colors.white
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.safeDrawingPadding()
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.background(CustomTheme.colors.white)
|
||||||
|
.verticalScroll(rememberScrollState()),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(
|
||||||
|
15.dp,
|
||||||
|
alignment = Alignment.CenterVertically
|
||||||
|
),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Text(text = "Инпуты", style = CustomTheme.typography.title1ExtraBold)
|
||||||
|
var fieldValue1 by rememberSaveable { mutableStateOf("") }
|
||||||
|
var errorMessage1 by rememberSaveable { mutableStateOf("") }
|
||||||
|
EnterInputField(
|
||||||
|
value = fieldValue1,
|
||||||
|
onValueChange = {
|
||||||
|
fieldValue1 = it
|
||||||
|
errorMessage1 = ""
|
||||||
|
},
|
||||||
|
errorMessage = errorMessage1,
|
||||||
|
label = "",
|
||||||
|
hint = "Введите имя"
|
||||||
|
)
|
||||||
|
|
||||||
|
var fieldValue2 by rememberSaveable { mutableStateOf("Иван") }
|
||||||
|
var errorMessage2 by rememberSaveable { mutableStateOf("") }
|
||||||
|
EnterInputField(
|
||||||
|
value = fieldValue2,
|
||||||
|
onValueChange = {
|
||||||
|
fieldValue2 = it
|
||||||
|
errorMessage2 = ""
|
||||||
|
},
|
||||||
|
errorMessage = errorMessage2,
|
||||||
|
label = "",
|
||||||
|
hint = "Введите имя"
|
||||||
|
)
|
||||||
|
|
||||||
|
var fieldValue3 by rememberSaveable { mutableStateOf("") }
|
||||||
|
var errorMessage3 by rememberSaveable { mutableStateOf("") }
|
||||||
|
EnterInputField(
|
||||||
|
value = fieldValue3,
|
||||||
|
onValueChange = {
|
||||||
|
fieldValue3 = it
|
||||||
|
errorMessage3 = ""
|
||||||
|
},
|
||||||
|
errorMessage = errorMessage3,
|
||||||
|
label = "Имя",
|
||||||
|
hint = "Введите имя"
|
||||||
|
)
|
||||||
|
|
||||||
|
var fieldValue4 by rememberSaveable { mutableStateOf("") }
|
||||||
|
var errorMessage4 by rememberSaveable { mutableStateOf("Введите ваше имя") }
|
||||||
|
EnterInputField(
|
||||||
|
value = fieldValue4,
|
||||||
|
onValueChange = {
|
||||||
|
fieldValue4 = it
|
||||||
|
errorMessage4 = ""
|
||||||
|
},
|
||||||
|
errorMessage = errorMessage4,
|
||||||
|
label = "Имя",
|
||||||
|
hint = "Введите имя"
|
||||||
|
)
|
||||||
|
|
||||||
|
var fieldValue5 by rememberSaveable { mutableStateOf("") }
|
||||||
|
var errorMessage5 by rememberSaveable { mutableStateOf("") }
|
||||||
|
EnterInputField(
|
||||||
|
value = fieldValue5,
|
||||||
|
onValueChange = {
|
||||||
|
fieldValue5 = it
|
||||||
|
errorMessage5 = ""
|
||||||
|
},
|
||||||
|
errorMessage = errorMessage5,
|
||||||
|
label = "Имя",
|
||||||
|
hint = "Введите имя"
|
||||||
|
)
|
||||||
|
|
||||||
|
var fieldValue6 by rememberSaveable { mutableStateOf("Введите имя") }
|
||||||
|
var errorMessage6 by rememberSaveable { mutableStateOf("") }
|
||||||
|
EnterInputField(
|
||||||
|
value = fieldValue6,
|
||||||
|
onValueChange = {
|
||||||
|
fieldValue6 = it
|
||||||
|
errorMessage6 = ""
|
||||||
|
},
|
||||||
|
errorMessage = errorMessage6,
|
||||||
|
label = "Имя",
|
||||||
|
hint = "Введите имя"
|
||||||
|
)
|
||||||
|
|
||||||
|
var fieldValue7 by rememberSaveable { mutableStateOf("123456789") }
|
||||||
|
var errorMessage7 by rememberSaveable { mutableStateOf("") }
|
||||||
|
EnterInputField(
|
||||||
|
value = fieldValue7,
|
||||||
|
onValueChange = {
|
||||||
|
fieldValue7 = it
|
||||||
|
errorMessage7 = ""
|
||||||
|
},
|
||||||
|
errorMessage = errorMessage7,
|
||||||
|
label = "",
|
||||||
|
isPassword = true,
|
||||||
|
hint = "Введите имя"
|
||||||
|
)
|
||||||
|
|
||||||
|
var fieldValue8 by rememberSaveable { mutableStateOf("") }
|
||||||
|
var errorMessage8 by rememberSaveable { mutableStateOf("") }
|
||||||
|
EnterInputField(
|
||||||
|
value = fieldValue8,
|
||||||
|
onValueChange = {
|
||||||
|
fieldValue8 = it
|
||||||
|
errorMessage8 = ""
|
||||||
|
},
|
||||||
|
errorMessage = errorMessage8,
|
||||||
|
label = "",
|
||||||
|
hint = "--.--.----"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
* F6.user5@local.ru
|
||||||
|
* Pa$$w0rd
|
||||||
|
* */
|
||||||
|
|
||||||
|
Text(text = "Селекты", style = CustomTheme.typography.title1ExtraBold)
|
||||||
|
|
||||||
|
var selectedOption1 by remember { mutableStateOf<Option?>(null) }
|
||||||
|
|
||||||
|
AppSelector(
|
||||||
|
selectedOption = selectedOption1,
|
||||||
|
options = listOf(
|
||||||
|
Option(label = "Мужской"),
|
||||||
|
Option(label = "Женский")
|
||||||
|
),
|
||||||
|
onOptionSelect = { selectedOption1 = it },
|
||||||
|
hint = "Пол"
|
||||||
|
)
|
||||||
|
|
||||||
|
var selectedOption2 by remember { mutableStateOf<Option?>(Option("Мужской")) }
|
||||||
|
|
||||||
|
AppSelector(
|
||||||
|
selectedOption = selectedOption2,
|
||||||
|
options = listOf(
|
||||||
|
Option(label = "Мужской"),
|
||||||
|
Option(label = "Женский")
|
||||||
|
),
|
||||||
|
onOptionSelect = { selectedOption2 = it },
|
||||||
|
hint = "Пол"
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(text = "Поиск", style = CustomTheme.typography.title1ExtraBold)
|
||||||
|
var searchFieldValue by rememberSaveable { mutableStateOf("") }
|
||||||
|
|
||||||
|
AppSearchField(
|
||||||
|
value = searchFieldValue,
|
||||||
|
onValueChange = { searchFieldValue = it },
|
||||||
|
hint = "Искать описание"
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(text = "Кнопки", style = CustomTheme.typography.title1ExtraBold)
|
||||||
|
|
||||||
|
AppButton(
|
||||||
|
label = "Подтвердить",
|
||||||
|
onClick = {},
|
||||||
|
state = ButtonState.Big
|
||||||
|
)
|
||||||
|
|
||||||
|
AppButton(
|
||||||
|
label = "Подтвердить",
|
||||||
|
onClick = {},
|
||||||
|
state = ButtonState.Big,
|
||||||
|
enabled = false
|
||||||
|
)
|
||||||
|
|
||||||
|
OutlinedAppButton(
|
||||||
|
label = "Подтвердить",
|
||||||
|
onClick = {},
|
||||||
|
state = ButtonState.Big
|
||||||
|
)
|
||||||
|
|
||||||
|
SecondaryAppButton(
|
||||||
|
label = "Подтвердить",
|
||||||
|
onClick = {},
|
||||||
|
state = ButtonState.Big
|
||||||
|
)
|
||||||
|
|
||||||
|
AppButton(
|
||||||
|
label = "Добавить",
|
||||||
|
onClick = {},
|
||||||
|
state = ButtonState.Small
|
||||||
|
)
|
||||||
|
|
||||||
|
OutlinedAppButton(
|
||||||
|
label = "Убрать",
|
||||||
|
onClick = {},
|
||||||
|
state = ButtonState.Small
|
||||||
|
)
|
||||||
|
|
||||||
|
AppButton(
|
||||||
|
label = "Добавить",
|
||||||
|
onClick = {},
|
||||||
|
state = ButtonState.Small,
|
||||||
|
enabled = false
|
||||||
|
)
|
||||||
|
|
||||||
|
SecondaryAppButton(
|
||||||
|
label = "Подтвердить",
|
||||||
|
onClick = {},
|
||||||
|
state = ButtonState.Small
|
||||||
|
)
|
||||||
|
|
||||||
|
AppButton(
|
||||||
|
label = "Популярное",
|
||||||
|
onClick = {},
|
||||||
|
state = ButtonState.Chips
|
||||||
|
)
|
||||||
|
|
||||||
|
AppButton(
|
||||||
|
label = "Популярное",
|
||||||
|
onClick = {},
|
||||||
|
state = ButtonState.Chips,
|
||||||
|
enabled = false
|
||||||
|
)
|
||||||
|
|
||||||
|
CartButton(
|
||||||
|
onClick = {},
|
||||||
|
totalPrice = 500
|
||||||
|
)
|
||||||
|
|
||||||
|
LoginButton(
|
||||||
|
icon = CustomIcons.vk,
|
||||||
|
label = "Войти с VK",
|
||||||
|
onClick = {}
|
||||||
|
)
|
||||||
|
|
||||||
|
LoginButton(
|
||||||
|
icon = CustomIcons.yandex,
|
||||||
|
label = "Войти с Yandex",
|
||||||
|
onClick = {}
|
||||||
|
)
|
||||||
|
|
||||||
|
Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||||
|
BubbleButton(
|
||||||
|
state = BubbleButtonState.Small,
|
||||||
|
icon = CustomIcons.back
|
||||||
|
)
|
||||||
|
|
||||||
|
BubbleButton(
|
||||||
|
state = BubbleButtonState.Big,
|
||||||
|
icon = CustomIcons.filter
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var inCartFirst by rememberSaveable { mutableStateOf(false) }
|
||||||
|
|
||||||
|
Text(text = "Карточки", style = CustomTheme.typography.title1ExtraBold)
|
||||||
|
|
||||||
|
PrimaryCard(
|
||||||
|
title = "Рубашка Воскресенье для машинного \n" +
|
||||||
|
"вязания",
|
||||||
|
category = "Мужская одежда",
|
||||||
|
price = 300,
|
||||||
|
inCart = inCartFirst,
|
||||||
|
onAddToCartClick = { inCartFirst = true },
|
||||||
|
onRemoveFromCartClick = { inCartFirst = false },
|
||||||
|
)
|
||||||
|
|
||||||
|
var inCartSecond by rememberSaveable { mutableStateOf(true) }
|
||||||
|
|
||||||
|
PrimaryCard(
|
||||||
|
title = "Рубашка Воскресенье для машинного \n" +
|
||||||
|
"вязания",
|
||||||
|
category = "Мужская одежда",
|
||||||
|
price = 300,
|
||||||
|
inCart = inCartSecond,
|
||||||
|
onAddToCartClick = { inCartSecond = true },
|
||||||
|
onRemoveFromCartClick = { inCartSecond = false },
|
||||||
|
)
|
||||||
|
|
||||||
|
var currentQuantity by rememberSaveable { mutableIntStateOf(1) }
|
||||||
|
CartCard(
|
||||||
|
title = "Рубашка воскресенье для машинного вязания",
|
||||||
|
price = 300,
|
||||||
|
currentQuantity = currentQuantity,
|
||||||
|
onChangeQuantity = { currentQuantity = it }
|
||||||
|
)
|
||||||
|
|
||||||
|
ProjectCard(
|
||||||
|
title = "Мой первый проект",
|
||||||
|
dayElapsed = 2,
|
||||||
|
onOpenClick = {}
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(text = "Хэдэр", style = CustomTheme.typography.title1ExtraBold)
|
||||||
|
|
||||||
|
BigHeader(
|
||||||
|
title = "Корзина",
|
||||||
|
startContent = {
|
||||||
|
BubbleButton(
|
||||||
|
state = BubbleButtonState.Small,
|
||||||
|
icon = CustomIcons.back
|
||||||
|
)
|
||||||
|
},
|
||||||
|
endContent = {
|
||||||
|
Icon(
|
||||||
|
painter = CustomIcons.delete,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = CustomTheme.colors.inputIcon
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
SmallHeader(
|
||||||
|
title = "Корзина",
|
||||||
|
startContent = {
|
||||||
|
BubbleButton(
|
||||||
|
state = BubbleButtonState.Small,
|
||||||
|
icon = CustomIcons.back
|
||||||
|
)
|
||||||
|
},
|
||||||
|
endContent = {
|
||||||
|
Icon(
|
||||||
|
painter = CustomIcons.delete,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = CustomTheme.colors.inputIcon
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(Modifier.height(100.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|
||||||
Text(
|
|
||||||
text = "Hello $name!",
|
|
||||||
modifier = modifier
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview(showBackground = true)
|
|
||||||
@Composable
|
|
||||||
fun GreetingPreview() {
|
|
||||||
UikitTheme {
|
|
||||||
Greeting("Android")
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,11 +0,0 @@
|
|||||||
package com.example.uikit.ui.theme
|
|
||||||
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
|
|
||||||
val Purple80 = Color(0xFFD0BCFF)
|
|
||||||
val PurpleGrey80 = Color(0xFFCCC2DC)
|
|
||||||
val Pink80 = Color(0xFFEFB8C8)
|
|
||||||
|
|
||||||
val Purple40 = Color(0xFF6650a4)
|
|
||||||
val PurpleGrey40 = Color(0xFF625b71)
|
|
||||||
val Pink40 = Color(0xFF7D5260)
|
|
@ -1,58 +0,0 @@
|
|||||||
package com.example.uikit.ui.theme
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.os.Build
|
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.darkColorScheme
|
|
||||||
import androidx.compose.material3.dynamicDarkColorScheme
|
|
||||||
import androidx.compose.material3.dynamicLightColorScheme
|
|
||||||
import androidx.compose.material3.lightColorScheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
|
|
||||||
private val DarkColorScheme = darkColorScheme(
|
|
||||||
primary = Purple80,
|
|
||||||
secondary = PurpleGrey80,
|
|
||||||
tertiary = Pink80
|
|
||||||
)
|
|
||||||
|
|
||||||
private val LightColorScheme = lightColorScheme(
|
|
||||||
primary = Purple40,
|
|
||||||
secondary = PurpleGrey40,
|
|
||||||
tertiary = Pink40
|
|
||||||
|
|
||||||
/* Other default colors to override
|
|
||||||
background = Color(0xFFFFFBFE),
|
|
||||||
surface = Color(0xFFFFFBFE),
|
|
||||||
onPrimary = Color.White,
|
|
||||||
onSecondary = Color.White,
|
|
||||||
onTertiary = Color.White,
|
|
||||||
onBackground = Color(0xFF1C1B1F),
|
|
||||||
onSurface = Color(0xFF1C1B1F),
|
|
||||||
*/
|
|
||||||
)
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun UikitTheme(
|
|
||||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
|
||||||
// Dynamic color is available on Android 12+
|
|
||||||
dynamicColor: Boolean = true,
|
|
||||||
content: @Composable () -> Unit
|
|
||||||
) {
|
|
||||||
val colorScheme = when {
|
|
||||||
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
|
||||||
val context = LocalContext.current
|
|
||||||
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
darkTheme -> DarkColorScheme
|
|
||||||
else -> LightColorScheme
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialTheme(
|
|
||||||
colorScheme = colorScheme,
|
|
||||||
typography = Typography,
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package com.example.uikit.ui.theme
|
|
||||||
|
|
||||||
import androidx.compose.material3.Typography
|
|
||||||
import androidx.compose.ui.text.TextStyle
|
|
||||||
import androidx.compose.ui.text.font.FontFamily
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
|
|
||||||
// Set of Material typography styles to start with
|
|
||||||
val Typography = Typography(
|
|
||||||
bodyLarge = TextStyle(
|
|
||||||
fontFamily = FontFamily.Default,
|
|
||||||
fontWeight = FontWeight.Normal,
|
|
||||||
fontSize = 16.sp,
|
|
||||||
lineHeight = 24.sp,
|
|
||||||
letterSpacing = 0.5.sp
|
|
||||||
)
|
|
||||||
/* Other default text styles to override
|
|
||||||
titleLarge = TextStyle(
|
|
||||||
fontFamily = FontFamily.Default,
|
|
||||||
fontWeight = FontWeight.Normal,
|
|
||||||
fontSize = 22.sp,
|
|
||||||
lineHeight = 28.sp,
|
|
||||||
letterSpacing = 0.sp
|
|
||||||
),
|
|
||||||
labelSmall = TextStyle(
|
|
||||||
fontFamily = FontFamily.Default,
|
|
||||||
fontWeight = FontWeight.Medium,
|
|
||||||
fontSize = 11.sp,
|
|
||||||
lineHeight = 16.sp,
|
|
||||||
letterSpacing = 0.5.sp
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
)
|
|
@ -3,4 +3,6 @@ plugins {
|
|||||||
alias(libs.plugins.android.application) apply false
|
alias(libs.plugins.android.application) apply false
|
||||||
alias(libs.plugins.kotlin.android) apply false
|
alias(libs.plugins.kotlin.android) apply false
|
||||||
alias(libs.plugins.kotlin.compose) apply false
|
alias(libs.plugins.kotlin.compose) apply false
|
||||||
|
alias(libs.plugins.android.library) apply false
|
||||||
|
alias(libs.plugins.kotlin.serialization) apply false
|
||||||
}
|
}
|
1
core/.gitignore
vendored
Normal file
1
core/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/build
|
63
core/build.gradle.kts
Normal file
63
core/build.gradle.kts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
plugins {
|
||||||
|
alias(libs.plugins.android.library)
|
||||||
|
alias(libs.plugins.kotlin.android)
|
||||||
|
alias(libs.plugins.kotlin.compose)
|
||||||
|
alias(libs.plugins.kotlin.serialization)
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "com.example.core"
|
||||||
|
compileSdk = 35
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdk = 33
|
||||||
|
|
||||||
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
consumerProguardFiles("consumer-rules.pro")
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
isMinifyEnabled = false
|
||||||
|
proguardFiles(
|
||||||
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
|
"proguard-rules.pro"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
|
targetCompatibility = JavaVersion.VERSION_11
|
||||||
|
}
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "11"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildFeatures {
|
||||||
|
compose = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(libs.kotlinx.serialization.json)
|
||||||
|
debugImplementation(libs.ui.tooling)
|
||||||
|
debugImplementation(libs.androidx.ui.tooling.preview)
|
||||||
|
api(platform(libs.androidx.compose.bom))
|
||||||
|
api(libs.androidx.activity.compose)
|
||||||
|
api(libs.androidx.ui)
|
||||||
|
api(libs.androidx.ui.graphics)
|
||||||
|
api(libs.androidx.ui.tooling.preview)
|
||||||
|
api(libs.androidx.material3)
|
||||||
|
api(libs.material)
|
||||||
|
|
||||||
|
implementation(libs.androidx.core.ktx)
|
||||||
|
implementation(libs.androidx.appcompat)
|
||||||
|
implementation(libs.material)
|
||||||
|
testImplementation(libs.junit)
|
||||||
|
androidTestImplementation(libs.androidx.junit)
|
||||||
|
androidTestImplementation(libs.androidx.espresso.core)
|
||||||
|
androidTestImplementation(platform(libs.androidx.compose.bom))
|
||||||
|
androidTestImplementation(libs.androidx.ui.test.junit4)
|
||||||
|
debugImplementation(libs.androidx.ui.tooling)
|
||||||
|
debugImplementation(libs.androidx.ui.test.manifest)
|
||||||
|
}
|
0
core/consumer-rules.pro
Normal file
0
core/consumer-rules.pro
Normal file
21
core/proguard-rules.pro
vendored
Normal file
21
core/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
65
core/src/androidTest/java/com/example/core/ComponentsTest.kt
Normal file
65
core/src/androidTest/java/com/example/core/ComponentsTest.kt
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package com.example.core
|
||||||
|
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.test.assertIsDisplayed
|
||||||
|
import androidx.compose.ui.test.junit4.createAndroidComposeRule
|
||||||
|
import androidx.compose.ui.test.onNodeWithTag
|
||||||
|
import androidx.compose.ui.test.onNodeWithText
|
||||||
|
import androidx.compose.ui.test.performClick
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import com.example.core.component.button.AppButton
|
||||||
|
import com.example.core.component.button.ButtonState
|
||||||
|
import com.example.core.component.select.AppSelector
|
||||||
|
import com.example.core.component.select.Option
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class ComponentsTest {
|
||||||
|
@get:Rule
|
||||||
|
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun test_input_error() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun test_app_selector() {
|
||||||
|
composeTestRule.setContent {
|
||||||
|
var selectedOption1 by remember { mutableStateOf<Option?>(null) }
|
||||||
|
|
||||||
|
AppSelector(
|
||||||
|
selectedOption = selectedOption1,
|
||||||
|
options = listOf(
|
||||||
|
Option(label = "Мужской"),
|
||||||
|
Option(label = "Женский")
|
||||||
|
),
|
||||||
|
onOptionSelect = { selectedOption1 = it },
|
||||||
|
hint = "Пол"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
composeTestRule.onNodeWithText("Пол").performClick()
|
||||||
|
composeTestRule.onNodeWithTag("AppBottomSheet").assertIsDisplayed()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun test_chips_button() {
|
||||||
|
composeTestRule.setContent {
|
||||||
|
AppButton(
|
||||||
|
label = "Популярное",
|
||||||
|
onClick = {},
|
||||||
|
state = ButtonState.Chips,
|
||||||
|
enabled = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
composeTestRule.onNodeWithText("Популярное").assertIsDisplayed()
|
||||||
|
}
|
||||||
|
}
|
4
core/src/main/AndroidManifest.xml
Normal file
4
core/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
</manifest>
|
@ -0,0 +1,60 @@
|
|||||||
|
package com.example.core.component.button
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AppButton(
|
||||||
|
label: String, // Текст кнопки
|
||||||
|
onClick: () -> Unit, // Действие на клик
|
||||||
|
state: ButtonState, // Состояние
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
enabled: Boolean = true
|
||||||
|
) {
|
||||||
|
Box(contentAlignment = Alignment.Center, modifier = modifier) {
|
||||||
|
val commonCondition = state is ButtonState.Chips
|
||||||
|
Button(
|
||||||
|
modifier = modifier
|
||||||
|
.then(state.width())
|
||||||
|
.height(state.height()),
|
||||||
|
onClick = onClick,
|
||||||
|
shape = RoundedCornerShape(10.dp),
|
||||||
|
enabled = enabled,
|
||||||
|
colors = ButtonDefaults.buttonColors().copy(
|
||||||
|
containerColor = CustomTheme.colors.accent,
|
||||||
|
disabledContainerColor = if (commonCondition) CustomTheme.colors.inputBg else CustomTheme.colors.accentInactive
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = label,
|
||||||
|
style = state.typography()
|
||||||
|
.copy(
|
||||||
|
color = if (commonCondition && !enabled) CustomTheme.colors.description else CustomTheme.colors.white,
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
),
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier
|
||||||
|
.then(state.width())
|
||||||
|
.padding(horizontal = state.padding()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.example.core.component.button
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BubbleButton(
|
||||||
|
state: BubbleButtonState, // cостояние
|
||||||
|
icon: Painter,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
modifier = modifier
|
||||||
|
.size(state.size())
|
||||||
|
.clip(RoundedCornerShape(state.roundness()))
|
||||||
|
.background(CustomTheme.colors.inputBg)
|
||||||
|
) {
|
||||||
|
Icon(painter = icon, contentDescription = null, tint = CustomTheme.colors.description)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.example.core.component.button
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
interface BubbleButtonState {
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun roundness(): Dp // радиус скругления
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun size(): Dp // размер
|
||||||
|
|
||||||
|
object Small : BubbleButtonState {
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun roundness(): Dp = CustomTheme.elevation.spacing8dp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun size(): Dp = CustomTheme.elevation.spacing32dp
|
||||||
|
}
|
||||||
|
|
||||||
|
object Big : BubbleButtonState {
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun roundness(): Dp = 10.dp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun size(): Dp = CustomTheme.elevation.spacing48dp
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package com.example.core.component.button
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@SuppressLint("ModifierFactoryExtensionFunction")
|
||||||
|
interface ButtonState {
|
||||||
|
|
||||||
|
fun width(): Modifier // т.к fillmaxWith не является конкретной шириной, то возвращаемый тип modifier
|
||||||
|
|
||||||
|
fun height(): Dp // высота
|
||||||
|
|
||||||
|
fun padding(): Dp // отступы основного текста кнопки от контейнера
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun typography(): TextStyle
|
||||||
|
|
||||||
|
object Big : ButtonState {
|
||||||
|
|
||||||
|
override fun width(): Modifier = Modifier.fillMaxWidth()
|
||||||
|
|
||||||
|
override fun height(): Dp = 56.dp
|
||||||
|
|
||||||
|
override fun padding(): Dp = 0.dp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun typography(): TextStyle = CustomTheme.typography.title3Semibold
|
||||||
|
}
|
||||||
|
|
||||||
|
object Small : ButtonState {
|
||||||
|
|
||||||
|
override fun width(): Modifier = Modifier.width(98.dp)
|
||||||
|
|
||||||
|
override fun height(): Dp = 40.dp
|
||||||
|
|
||||||
|
override fun padding(): Dp = 13.5.dp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun typography(): TextStyle = CustomTheme.typography.captionSemibold
|
||||||
|
}
|
||||||
|
|
||||||
|
object Chips : ButtonState {
|
||||||
|
|
||||||
|
override fun width(): Modifier = Modifier.width(129.dp)
|
||||||
|
|
||||||
|
override fun height(): Dp = 48.dp
|
||||||
|
|
||||||
|
override fun padding(): Dp = 20.dp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun typography(): TextStyle = CustomTheme.typography.textMedium
|
||||||
|
}
|
||||||
|
|
||||||
|
object Login : ButtonState {
|
||||||
|
|
||||||
|
override fun width(): Modifier = Modifier.fillMaxWidth()
|
||||||
|
|
||||||
|
override fun height(): Dp = 60.dp
|
||||||
|
|
||||||
|
override fun padding(): Dp = 0.dp
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun typography(): TextStyle = CustomTheme.typography.title3Medium
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
package com.example.core.component.button
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
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.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.R
|
||||||
|
import com.example.core.theme.CustomIcons
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CartButton(
|
||||||
|
onClick: () -> Unit,
|
||||||
|
totalPrice: Int, // цена на кнопке
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
val state = ButtonState.Big
|
||||||
|
|
||||||
|
Box(contentAlignment = Alignment.CenterStart, modifier = modifier) {
|
||||||
|
Button(
|
||||||
|
modifier = modifier
|
||||||
|
.then(state.width())
|
||||||
|
.height(state.height()),
|
||||||
|
onClick = onClick,
|
||||||
|
shape = RoundedCornerShape(10.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors().copy(
|
||||||
|
containerColor = CustomTheme.colors.accent,
|
||||||
|
disabledContentColor = CustomTheme.colors.accentInactive
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
|
||||||
|
|
||||||
|
Icon(
|
||||||
|
painter = CustomIcons.cart,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = CustomTheme.colors.white,
|
||||||
|
modifier = Modifier.padding(horizontal = CustomTheme.elevation.spacing16dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.in_cart),
|
||||||
|
style = state.typography().copy(color = CustomTheme.colors.white)
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(Modifier.weight(1f))
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.total_price, totalPrice),
|
||||||
|
style = state.typography().copy(color = CustomTheme.colors.white)
|
||||||
|
)
|
||||||
|
Spacer(Modifier.width(CustomTheme.elevation.spacing16dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package com.example.core.component.button
|
||||||
|
|
||||||
|
import androidx.compose.animation.animateColorAsState
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
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.Icon
|
||||||
|
import androidx.compose.material3.VerticalDivider
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.theme.CustomIcons
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* для установки цвета и обработки крайних случаев изменения по значению
|
||||||
|
* в кнопке есть параметр количества */
|
||||||
|
@Composable
|
||||||
|
fun ChangeQuantityButton(
|
||||||
|
currentQuantity: Int,
|
||||||
|
onIncrementClick: () -> Unit, // обработка увеличения количества
|
||||||
|
onDecrementClick: () -> Unit, // обработка уменьшения количества
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.Center,
|
||||||
|
modifier = modifier
|
||||||
|
.width(CustomTheme.elevation.spacing64dp)
|
||||||
|
.height(CustomTheme.elevation.spacing32dp)
|
||||||
|
.clip(RoundedCornerShape(8.dp))
|
||||||
|
.background(CustomTheme.colors.inputBg)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
modifier = Modifier.padding(horizontal = 6.dp)
|
||||||
|
) {
|
||||||
|
val minusCondition = currentQuantity > 1
|
||||||
|
val minusTint by animateColorAsState(if (minusCondition) CustomTheme.colors.placeholder else CustomTheme.colors.inputIcon)
|
||||||
|
Icon(
|
||||||
|
painter = CustomIcons.minus,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = minusTint,
|
||||||
|
modifier = Modifier.then(
|
||||||
|
if (minusCondition) {
|
||||||
|
Modifier.clickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
null,
|
||||||
|
onClick = onDecrementClick
|
||||||
|
)
|
||||||
|
} else Modifier
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
VerticalDivider(
|
||||||
|
thickness = 1.dp,
|
||||||
|
color = CustomTheme.colors.inputStroke,
|
||||||
|
modifier = Modifier.padding(
|
||||||
|
horizontal = 6.dp,
|
||||||
|
vertical = CustomTheme.elevation.spacing8dp
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val plusCondition = currentQuantity < 100
|
||||||
|
val plusTint by animateColorAsState(if (plusCondition) CustomTheme.colors.placeholder else CustomTheme.colors.inputIcon)
|
||||||
|
|
||||||
|
Icon(
|
||||||
|
painter = CustomIcons.plus,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = plusTint,
|
||||||
|
modifier = Modifier.then(
|
||||||
|
if (plusCondition) {
|
||||||
|
Modifier.clickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
null,
|
||||||
|
onClick = onIncrementClick
|
||||||
|
)
|
||||||
|
} else Modifier
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.example.core.component.button
|
||||||
|
|
||||||
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.OutlinedButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun LoginButton(
|
||||||
|
icon: Painter,
|
||||||
|
label: String,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
val state = ButtonState.Login
|
||||||
|
|
||||||
|
OutlinedButton(
|
||||||
|
modifier = modifier
|
||||||
|
.then(state.width())
|
||||||
|
.height(state.height()),
|
||||||
|
onClick = onClick,
|
||||||
|
shape = RoundedCornerShape(10.dp),
|
||||||
|
border = BorderStroke(width = 1.dp, color = CustomTheme.colors.inputStroke)
|
||||||
|
) {
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Image(painter = icon, contentDescription = null)
|
||||||
|
Spacer(Modifier.width(CustomTheme.elevation.spacing16dp))
|
||||||
|
Text(text = label, style = state.typography())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.example.core.component.button
|
||||||
|
|
||||||
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.OutlinedButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun OutlinedAppButton(
|
||||||
|
label: String,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
state: ButtonState,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Box(contentAlignment = Alignment.Center, modifier = modifier) {
|
||||||
|
OutlinedButton(
|
||||||
|
modifier = modifier
|
||||||
|
.then(state.width())
|
||||||
|
.height(state.height()),
|
||||||
|
onClick = onClick,
|
||||||
|
shape = RoundedCornerShape(10.dp),
|
||||||
|
border = BorderStroke(width = 1.dp, color = CustomTheme.colors.accent)
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = label,
|
||||||
|
style = state.typography()
|
||||||
|
.copy(color = CustomTheme.colors.accent, textAlign = TextAlign.Center),
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier.then(state.width()).padding(horizontal = state.padding())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.example.core.component.button
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SecondaryAppButton(
|
||||||
|
label: String,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
state: ButtonState,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
enabled: Boolean = true
|
||||||
|
) {
|
||||||
|
Box(contentAlignment = Alignment.Center, modifier = modifier) {
|
||||||
|
Button(
|
||||||
|
modifier = modifier
|
||||||
|
.then(state.width())
|
||||||
|
.height(state.height()),
|
||||||
|
onClick = onClick,
|
||||||
|
shape = RoundedCornerShape(10.dp),
|
||||||
|
enabled = enabled,
|
||||||
|
colors = ButtonDefaults.buttonColors().copy(
|
||||||
|
containerColor = CustomTheme.colors.inputBg,
|
||||||
|
disabledContentColor = CustomTheme.colors.accentInactive
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
Text(
|
||||||
|
text = label,
|
||||||
|
style = state.typography()
|
||||||
|
.copy(color = CustomTheme.colors.black, textAlign = TextAlign.Center),
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
modifier = Modifier
|
||||||
|
.then(state.width())
|
||||||
|
.padding(horizontal = state.padding())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.example.core.component.card
|
||||||
|
|
||||||
|
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.padding
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.draw.shadow
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* общий фон для карточек */
|
||||||
|
@Composable
|
||||||
|
fun AppCardBackground(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
content: @Composable () -> Unit
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.shadow(
|
||||||
|
elevation = 20.dp,
|
||||||
|
shape = RoundedCornerShape(CustomTheme.elevation.spacing12dp),
|
||||||
|
clip = false,
|
||||||
|
spotColor = Color(0xFFE4E8F5).copy(alpha = 0.6f)
|
||||||
|
)
|
||||||
|
.clip(RoundedCornerShape(CustomTheme.elevation.spacing12dp))
|
||||||
|
.background(CustomTheme.colors.white)
|
||||||
|
) {
|
||||||
|
Box(modifier = Modifier.padding(CustomTheme.elevation.spacing16dp)) {
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package com.example.core.component.card
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.R
|
||||||
|
import com.example.core.component.button.ChangeQuantityButton
|
||||||
|
import com.example.core.theme.CustomIcons
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CartCard(
|
||||||
|
title: String,
|
||||||
|
price: Int,
|
||||||
|
currentQuantity: Int,
|
||||||
|
onChangeQuantity: (Int) -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
AppCardBackground(modifier = modifier) {
|
||||||
|
Column {
|
||||||
|
Row {
|
||||||
|
Text(
|
||||||
|
text = title,
|
||||||
|
style = CustomTheme.typography.headlineMedium,
|
||||||
|
modifier = Modifier.weight(2f)
|
||||||
|
)
|
||||||
|
|
||||||
|
Row(horizontalArrangement = Arrangement.End, modifier = Modifier.weight(1f)) {
|
||||||
|
Icon(
|
||||||
|
painter = CustomIcons.close,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = CustomTheme.colors.description
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spacer(Modifier.height(34.dp))
|
||||||
|
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.total_price, price),
|
||||||
|
style = CustomTheme.typography.title3Medium,
|
||||||
|
modifier = Modifier.weight(1.7f)
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.cart_card_quantity, currentQuantity),
|
||||||
|
style = CustomTheme.typography.textRegular
|
||||||
|
)
|
||||||
|
|
||||||
|
Row(modifier = Modifier.weight(1f), horizontalArrangement = Arrangement.End) {
|
||||||
|
/**
|
||||||
|
* обработка количества уже без дополнительных проверок */
|
||||||
|
ChangeQuantityButton(
|
||||||
|
currentQuantity = currentQuantity,
|
||||||
|
onIncrementClick = { onChangeQuantity(currentQuantity.inc()) },
|
||||||
|
onDecrementClick = { onChangeQuantity(currentQuantity.dec()) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.example.core.component.card
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import com.example.core.R
|
||||||
|
import com.example.core.component.button.AppButton
|
||||||
|
import com.example.core.component.button.ButtonState
|
||||||
|
import com.example.core.component.button.OutlinedAppButton
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun PrimaryCard(
|
||||||
|
title: String,
|
||||||
|
category: String,
|
||||||
|
price: Int,
|
||||||
|
inCart: Boolean,
|
||||||
|
onAddToCartClick: () -> Unit,
|
||||||
|
onRemoveFromCartClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
AppCardBackground(modifier = modifier) {
|
||||||
|
Column {
|
||||||
|
Text(text = title, style = CustomTheme.typography.headlineMedium)
|
||||||
|
Spacer(Modifier.height(CustomTheme.elevation.spacing16dp))
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
|
Text(
|
||||||
|
text = category,
|
||||||
|
style = CustomTheme.typography.captionSemibold.copy(
|
||||||
|
color = CustomTheme.colors.placeholder
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(Modifier.height(CustomTheme.elevation.spacing4dp))
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.total_price, price),
|
||||||
|
style = CustomTheme.typography.title3Semibold
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inCart) {
|
||||||
|
OutlinedAppButton(
|
||||||
|
label = stringResource(R.string.drop),
|
||||||
|
onClick = onRemoveFromCartClick,
|
||||||
|
state = ButtonState.Small
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
AppButton(
|
||||||
|
label = stringResource(R.string.add),
|
||||||
|
onClick = onAddToCartClick,
|
||||||
|
state = ButtonState.Small
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package com.example.core.component.card
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.pluralStringResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.R
|
||||||
|
import com.example.core.component.button.AppButton
|
||||||
|
import com.example.core.component.button.ButtonState
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ProjectCard(
|
||||||
|
title: String,
|
||||||
|
dayElapsed: Int,
|
||||||
|
onOpenClick: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
AppCardBackground(modifier = modifier) {
|
||||||
|
Column {
|
||||||
|
Text(text = title, style = CustomTheme.typography.headlineMedium)
|
||||||
|
Spacer(Modifier.height(44.dp))
|
||||||
|
Row(verticalAlignment = Alignment.Bottom) {
|
||||||
|
Text(
|
||||||
|
text = pluralStringResource(R.plurals.elapsed_days, dayElapsed, dayElapsed),
|
||||||
|
style = CustomTheme.typography.captionSemibold.copy(
|
||||||
|
color = CustomTheme.colors.placeholder
|
||||||
|
),
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
|
||||||
|
AppButton(
|
||||||
|
label = stringResource(R.string.open),
|
||||||
|
onClick = onOpenClick,
|
||||||
|
state = ButtonState.Small
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.example.core.component.header
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BigHeader(
|
||||||
|
title: String,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
startContent: @Composable () -> Unit = {},
|
||||||
|
endContent: @Composable () -> Unit = {}
|
||||||
|
) {
|
||||||
|
Column(modifier = modifier) {
|
||||||
|
Box(contentAlignment = Alignment.CenterEnd, modifier = modifier.fillMaxWidth()) {
|
||||||
|
Box(modifier = Modifier.align(Alignment.CenterStart)) {
|
||||||
|
startContent()
|
||||||
|
}
|
||||||
|
|
||||||
|
endContent()
|
||||||
|
}
|
||||||
|
Spacer(Modifier.height(CustomTheme.elevation.spacing24dp))
|
||||||
|
Text(text = title, style = CustomTheme.typography.title1ExtraBold)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.example.core.component.header
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SmallHeader(
|
||||||
|
title: String,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
startContent: @Composable () -> Unit,
|
||||||
|
endContent: @Composable () -> Unit
|
||||||
|
) {
|
||||||
|
Box(modifier = modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
|
||||||
|
|
||||||
|
Box(modifier = Modifier.align(Alignment.CenterStart)) {
|
||||||
|
startContent()
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(text = title, style = CustomTheme.typography.title1SemiBold)
|
||||||
|
|
||||||
|
Box(modifier = Modifier.align(Alignment.CenterEnd)) {
|
||||||
|
endContent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,177 @@
|
|||||||
|
package com.example.core.component.input
|
||||||
|
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.animateColorAsState
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
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.width
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
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.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
|
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||||
|
import androidx.compose.ui.text.input.VisualTransformation
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.theme.CustomIcons
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun EnterInputField(
|
||||||
|
value: String,
|
||||||
|
onValueChange: (String) -> Unit,
|
||||||
|
label: String, // названия поля (надпись над полем)
|
||||||
|
hint: String, // подсказка
|
||||||
|
errorMessage: String, // сообщенме об ошибке
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
isPassword: Boolean = false, // являяется ли паролем (для отображения и скрытия)
|
||||||
|
keyboardOptions: KeyboardOptions = KeyboardOptions.Default // смена типа клавиатуры (только цифры и тд)
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* отслеживание состояния фокуса для обводки активного поля
|
||||||
|
* */
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
|
||||||
|
var hasFocus by rememberSaveable { mutableStateOf(false) }
|
||||||
|
|
||||||
|
var showPassword by rememberSaveable { mutableStateOf(false) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Установка цвета рамки в зависимости от состояния
|
||||||
|
* */
|
||||||
|
val borderColor by animateColorAsState(
|
||||||
|
when {
|
||||||
|
errorMessage.isNotBlank() -> CustomTheme.colors.error
|
||||||
|
errorMessage.isBlank() && hasFocus -> CustomTheme.colors.accent
|
||||||
|
value.isEmpty() || (value.isNotEmpty() && label.isNotEmpty()) || isPassword -> CustomTheme.colors.inputStroke
|
||||||
|
else -> CustomTheme.colors.inputIcon
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* установка цвета поверх конентка в случае ошибки
|
||||||
|
* */
|
||||||
|
val overlayErrorColor by animateColorAsState(
|
||||||
|
if (errorMessage.isNotBlank()) CustomTheme.colors.error.copy(alpha = 0.1f) else Color.Transparent
|
||||||
|
)
|
||||||
|
|
||||||
|
Column(modifier = modifier) {
|
||||||
|
if (label.isNotBlank()) {
|
||||||
|
Text(
|
||||||
|
text = label,
|
||||||
|
style = CustomTheme.typography.captionRegular.copy(
|
||||||
|
color = CustomTheme.colors.description
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(Modifier.height(CustomTheme.elevation.spacing8dp))
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.CenterStart,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(CustomTheme.elevation.spacing48dp)
|
||||||
|
.clip(RoundedCornerShape(10.dp))
|
||||||
|
.background(CustomTheme.colors.inputBg)
|
||||||
|
.border(width = 1.dp, color = borderColor, shape = RoundedCornerShape(10.dp))
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.background(overlayErrorColor)
|
||||||
|
)
|
||||||
|
|
||||||
|
Row(modifier = Modifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Spacer(Modifier.width(14.dp))
|
||||||
|
|
||||||
|
Box(contentAlignment = Alignment.CenterStart, modifier = Modifier.weight(1f)) {
|
||||||
|
|
||||||
|
if (value.isEmpty()) {
|
||||||
|
Text(
|
||||||
|
text = hint,
|
||||||
|
style = CustomTheme.typography.textRegular.copy(
|
||||||
|
color = CustomTheme.colors.placeholder
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicTextField(
|
||||||
|
value = value,
|
||||||
|
onValueChange = onValueChange,
|
||||||
|
singleLine = true,
|
||||||
|
cursorBrush = SolidColor(CustomTheme.colors.accent),
|
||||||
|
textStyle = CustomTheme.typography.textRegular,
|
||||||
|
keyboardOptions = keyboardOptions,
|
||||||
|
visualTransformation = if (isPassword && !showPassword) {
|
||||||
|
PasswordVisualTransformation()
|
||||||
|
} else VisualTransformation.None,
|
||||||
|
modifier = Modifier
|
||||||
|
.focusRequester(focusRequester)
|
||||||
|
.onFocusChanged { focusState ->
|
||||||
|
hasFocus = focusState.hasFocus
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPassword) {
|
||||||
|
val icon =
|
||||||
|
if (showPassword) CustomIcons.showPassword else CustomIcons.hidePassword
|
||||||
|
Icon(
|
||||||
|
painter = icon,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.clickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = null
|
||||||
|
) { showPassword = !showPassword }
|
||||||
|
)
|
||||||
|
Spacer(Modifier.width(15.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* отображение текста ошибки в случае ее наличия
|
||||||
|
* */
|
||||||
|
AnimatedVisibility(visible = errorMessage.isNotBlank()) {
|
||||||
|
Column {
|
||||||
|
Spacer(Modifier.height(CustomTheme.elevation.spacing8dp))
|
||||||
|
Text(
|
||||||
|
text = errorMessage,
|
||||||
|
style = CustomTheme.typography.captionRegular.copy(
|
||||||
|
color = CustomTheme.colors.error
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
package com.example.core.component.search
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
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.width
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
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.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.theme.CustomIcons
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AppSearchField(
|
||||||
|
value: String,
|
||||||
|
onValueChange: (String) -> Unit,
|
||||||
|
hint: String,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
|
||||||
|
var hasFocus by rememberSaveable { mutableStateOf(false) }
|
||||||
|
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.CenterStart,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(CustomTheme.elevation.spacing48dp)
|
||||||
|
.clip(RoundedCornerShape(10.dp))
|
||||||
|
.background(CustomTheme.colors.inputBg)
|
||||||
|
.border(
|
||||||
|
width = 1.dp,
|
||||||
|
color = CustomTheme.colors.inputStroke,
|
||||||
|
shape = RoundedCornerShape(10.dp)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Column(modifier = modifier) {
|
||||||
|
Row(modifier = Modifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Spacer(Modifier.width(14.dp))
|
||||||
|
Icon(
|
||||||
|
painter = CustomIcons.search,
|
||||||
|
tint = CustomTheme.colors.description,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
Spacer(Modifier.width(CustomTheme.elevation.spacing8dp))
|
||||||
|
|
||||||
|
Box(contentAlignment = Alignment.CenterStart, modifier = Modifier.weight(1f)) {
|
||||||
|
|
||||||
|
if (value.isEmpty()) {
|
||||||
|
Text(
|
||||||
|
text = hint,
|
||||||
|
style = CustomTheme.typography.textRegular.copy(
|
||||||
|
color = CustomTheme.colors.placeholder
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicTextField(
|
||||||
|
value = value,
|
||||||
|
onValueChange = onValueChange,
|
||||||
|
singleLine = true,
|
||||||
|
cursorBrush = SolidColor(CustomTheme.colors.accent),
|
||||||
|
textStyle = CustomTheme.typography.textRegular,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.focusRequester(focusRequester)
|
||||||
|
.onFocusChanged { focusState ->
|
||||||
|
hasFocus = focusState.hasFocus
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (hasFocus) {
|
||||||
|
Icon(
|
||||||
|
painter = CustomIcons.close,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = CustomTheme.colors.description,
|
||||||
|
modifier = Modifier.clickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = null
|
||||||
|
) { onValueChange("") }
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(Modifier.width(14.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package com.example.core.component.select
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.ModalBottomSheet
|
||||||
|
import androidx.compose.material3.SheetState
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.theme.CustomIcons
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* общее диалоговое окно
|
||||||
|
* */
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun AppBottomSheet(
|
||||||
|
sheetState: SheetState, // состояние, для управлением отображения
|
||||||
|
onDismissRequest: () -> Unit, // обработка запроса на закрытие
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
content: @Composable () -> Unit // контент
|
||||||
|
) {
|
||||||
|
ModalBottomSheet(
|
||||||
|
sheetState = sheetState,
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
dragHandle = null,
|
||||||
|
containerColor = CustomTheme.colors.white,
|
||||||
|
modifier = modifier
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 20.dp)
|
||||||
|
) {
|
||||||
|
Spacer(Modifier.height(CustomTheme.elevation.spacing24dp))
|
||||||
|
Box {
|
||||||
|
Image(
|
||||||
|
painter = CustomIcons.closeSheet,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.align(Alignment.TopEnd)
|
||||||
|
)
|
||||||
|
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
Spacer(Modifier.height(84.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
package com.example.core.component.select
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
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.heightIn
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.rememberModalBottomSheetState
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.platform.testTag
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.theme.CustomIcons
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun AppSelector(
|
||||||
|
selectedOption: Option?, // выбранная опция, если null то отображается подсказка
|
||||||
|
options: List<Option>, // список опций
|
||||||
|
onOptionSelect: (Option) -> Unit, // обработка нажатия
|
||||||
|
hint: String, // подсказка
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
var showSheet by rememberSaveable { mutableStateOf(false) }
|
||||||
|
val sheetState = rememberModalBottomSheetState()
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
if (showSheet) {
|
||||||
|
AppBottomSheet(
|
||||||
|
sheetState = sheetState,
|
||||||
|
onDismissRequest = { showSheet = false },
|
||||||
|
modifier = Modifier.testTag("AppBottomSheet")
|
||||||
|
) {
|
||||||
|
Column(verticalArrangement = Arrangement.Center) {
|
||||||
|
options.forEach { option ->
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.heightIn(min = 40.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clickable(
|
||||||
|
remember { MutableInteractionSource() },
|
||||||
|
null
|
||||||
|
) {
|
||||||
|
scope.launch {
|
||||||
|
onOptionSelect(option)
|
||||||
|
sheetState.hide()
|
||||||
|
}.invokeOnCompletion {
|
||||||
|
if (!sheetState.isVisible) {
|
||||||
|
showSheet = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = option.label,
|
||||||
|
style = CustomTheme.typography.title2ExtraBold
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column(modifier = modifier) {
|
||||||
|
Box(
|
||||||
|
contentAlignment = Alignment.CenterStart,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(CustomTheme.elevation.spacing48dp)
|
||||||
|
.clip(RoundedCornerShape(10.dp))
|
||||||
|
.background(CustomTheme.colors.inputBg)
|
||||||
|
.border(
|
||||||
|
width = 1.dp,
|
||||||
|
color = CustomTheme.colors.inputStroke,
|
||||||
|
shape = RoundedCornerShape(10.dp)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.clickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = null
|
||||||
|
) { showSheet = true },
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Spacer(Modifier.width(14.dp))
|
||||||
|
|
||||||
|
Box(contentAlignment = Alignment.CenterStart, modifier = Modifier.weight(1f)) {
|
||||||
|
selectedOption?.let {
|
||||||
|
Text(
|
||||||
|
text = selectedOption.label,
|
||||||
|
style = CustomTheme.typography.headlineRegular
|
||||||
|
)
|
||||||
|
} ?: run {
|
||||||
|
Text(
|
||||||
|
text = hint,
|
||||||
|
style = CustomTheme.typography.textRegular.copy(
|
||||||
|
color = CustomTheme.colors.placeholder
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Icon(
|
||||||
|
painter = CustomIcons.more,
|
||||||
|
tint = CustomTheme.colors.description,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
Spacer(Modifier.width(14.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.example.core.component.select
|
||||||
|
|
||||||
|
/**
|
||||||
|
* класс опции, есть возможность установик эмоджи
|
||||||
|
* */
|
||||||
|
data class Option(
|
||||||
|
val label: String,
|
||||||
|
val iconId: Int? = null
|
||||||
|
)
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.example.core.component.tabbar
|
||||||
|
|
||||||
|
import androidx.annotation.Keep
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
|
import com.example.core.R
|
||||||
|
import com.example.core.theme.CustomIcons
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Общий интерфейс для всех вкладок меню навигации
|
||||||
|
* */
|
||||||
|
interface BottomTab {
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun icon(): Painter
|
||||||
|
|
||||||
|
fun labelResId(): Int
|
||||||
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
@Serializable
|
||||||
|
object Home : BottomTab {
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun icon(): Painter = CustomIcons.home
|
||||||
|
|
||||||
|
override fun labelResId(): Int = R.string.home
|
||||||
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
@Serializable
|
||||||
|
object Catalog : BottomTab {
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun icon(): Painter = CustomIcons.catalog
|
||||||
|
|
||||||
|
override fun labelResId(): Int = R.string.catalog
|
||||||
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
@Serializable
|
||||||
|
object Projects : BottomTab {
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun icon(): Painter = CustomIcons.projects
|
||||||
|
|
||||||
|
override fun labelResId(): Int = R.string.projects
|
||||||
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
@Serializable
|
||||||
|
object Profile : BottomTab {
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun icon(): Painter = CustomIcons.profile
|
||||||
|
|
||||||
|
override fun labelResId(): Int = R.string.profile
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package com.example.core.component.tabbar
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.offset
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BottomTabBar(
|
||||||
|
tabs: List<BottomTab>,
|
||||||
|
hierarchy: Sequence<String?>?,
|
||||||
|
onTabClick: (BottomTab) -> Unit,
|
||||||
|
bottomPadding: Dp,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.background(CustomTheme.colors.white)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(67.dp)
|
||||||
|
.offset(y = -bottomPadding)
|
||||||
|
.background(CustomTheme.colors.white)
|
||||||
|
.clickable(interactionSource = remember { MutableInteractionSource() }, null) { }
|
||||||
|
|
||||||
|
) {
|
||||||
|
HorizontalDivider(thickness = 1.dp, color = Color(0xFFA0A0A0).copy(alpha = 0.3f))
|
||||||
|
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.SpaceAround,
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp)
|
||||||
|
) {
|
||||||
|
tabs.forEach { tab ->
|
||||||
|
BottomTabBarItem(
|
||||||
|
bottomTab = tab,
|
||||||
|
selected = hierarchy?.any { it == tab::class.qualifiedName } ?: false,
|
||||||
|
modifier = Modifier.clickable(
|
||||||
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
|
indication = null
|
||||||
|
) {
|
||||||
|
onTabClick(tab)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.example.core.component.tabbar
|
||||||
|
|
||||||
|
import androidx.compose.animation.animateColorAsState
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import com.example.core.theme.CustomTheme
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BottomTabBarItem(
|
||||||
|
bottomTab: BottomTab,
|
||||||
|
selected: Boolean,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
val tintColor by animateColorAsState(if (selected) CustomTheme.colors.accent else CustomTheme.colors.inputIcon)
|
||||||
|
Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
|
Icon(
|
||||||
|
painter = bottomTab.icon(),
|
||||||
|
contentDescription = null,
|
||||||
|
tint = tintColor,
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = stringResource(bottomTab.labelResId()),
|
||||||
|
style = CustomTheme.typography.caption2Regular.copy(color = tintColor)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
21
core/src/main/java/com/example/core/theme/Color.kt
Normal file
21
core/src/main/java/com/example/core/theme/Color.kt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package com.example.core.theme
|
||||||
|
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
val Accent = Color(0xFF2074F2)
|
||||||
|
val AccentInactive = Color(0xFFC9D4FB)
|
||||||
|
val Black = Color(0xFF000000)
|
||||||
|
val White = Color(0xFFFFFFFF)
|
||||||
|
val Error = Color(0xFFFD3535)
|
||||||
|
val Success = Color(0xFF00B412)
|
||||||
|
val InputBg = Color(0xFFF5F5F9)
|
||||||
|
val InputStroke = Color(0xFFEBEBEB)
|
||||||
|
val InputIcon = Color(0xFFB8C1CC)
|
||||||
|
val Placeholder = Color(0xFF939396)
|
||||||
|
val Description = Color(0xFF8787A1)
|
||||||
|
val CardStroke = Color(0xFFF2F2F2)
|
67
core/src/main/java/com/example/core/theme/CustomIcons.kt
Normal file
67
core/src/main/java/com/example/core/theme/CustomIcons.kt
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package com.example.core.theme
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import com.example.core.R
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
object CustomIcons {
|
||||||
|
val showPassword: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_eye_show)
|
||||||
|
|
||||||
|
val hidePassword: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_eye_close)
|
||||||
|
|
||||||
|
val closeSheet: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_close_sheet)
|
||||||
|
|
||||||
|
val more: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_chevron_down)
|
||||||
|
|
||||||
|
val close: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_close)
|
||||||
|
|
||||||
|
val search: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_search)
|
||||||
|
|
||||||
|
val cart: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_shopping_cart)
|
||||||
|
|
||||||
|
val vk: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_vk)
|
||||||
|
|
||||||
|
val yandex: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_yandex)
|
||||||
|
|
||||||
|
val back: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_chevron_left)
|
||||||
|
|
||||||
|
val filter: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_filter)
|
||||||
|
|
||||||
|
val home: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_home)
|
||||||
|
|
||||||
|
val catalog: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_catalog)
|
||||||
|
|
||||||
|
val projects: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_projects)
|
||||||
|
|
||||||
|
val profile: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_profile)
|
||||||
|
|
||||||
|
val minus: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_minus)
|
||||||
|
|
||||||
|
val plus: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_plus)
|
||||||
|
|
||||||
|
val delete: Painter
|
||||||
|
@Composable get() = painterResource(R.drawable.icon_delete)
|
||||||
|
}
|
191
core/src/main/java/com/example/core/theme/CustomTheme.kt
Normal file
191
core/src/main/java/com/example/core/theme/CustomTheme.kt
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
package com.example.core.theme
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import androidx.compose.runtime.staticCompositionLocalOf
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class CustomColors(
|
||||||
|
val accent: Color,
|
||||||
|
val accentInactive: Color,
|
||||||
|
val black: Color,
|
||||||
|
val white: Color,
|
||||||
|
val error: Color,
|
||||||
|
val success: Color,
|
||||||
|
val inputBg: Color,
|
||||||
|
val inputStroke: Color,
|
||||||
|
val inputIcon: Color,
|
||||||
|
val placeholder: Color,
|
||||||
|
val description: Color,
|
||||||
|
val cardStroke: Color
|
||||||
|
)
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class CustomTypography(
|
||||||
|
val title1SemiBold: TextStyle,
|
||||||
|
val title1ExtraBold: TextStyle,
|
||||||
|
val title2Regular: TextStyle,
|
||||||
|
val title2SemiBold: TextStyle,
|
||||||
|
val title2ExtraBold: TextStyle,
|
||||||
|
val title3Regular: TextStyle,
|
||||||
|
val title3Medium: TextStyle,
|
||||||
|
val title3Semibold: TextStyle,
|
||||||
|
val headlineRegular: TextStyle,
|
||||||
|
val headlineMedium: TextStyle,
|
||||||
|
val textRegular: TextStyle,
|
||||||
|
val textMedium: TextStyle,
|
||||||
|
val captionRegular: TextStyle,
|
||||||
|
val captionSemibold: TextStyle,
|
||||||
|
val caption2Regular: TextStyle,
|
||||||
|
val caption2Bold: TextStyle
|
||||||
|
)
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
data class CustomElevation(
|
||||||
|
val spacing4dp: Dp,
|
||||||
|
val spacing8dp: Dp,
|
||||||
|
val spacing12dp: Dp,
|
||||||
|
val spacing16dp: Dp,
|
||||||
|
val spacing20dp: Dp,
|
||||||
|
val spacing24dp: Dp,
|
||||||
|
val spacing32dp: Dp,
|
||||||
|
val spacing40dp: Dp,
|
||||||
|
val spacing48dp: Dp,
|
||||||
|
val spacing56dp: Dp,
|
||||||
|
val spacing64dp: Dp
|
||||||
|
)
|
||||||
|
|
||||||
|
val LocalCustomColors = staticCompositionLocalOf {
|
||||||
|
CustomColors(
|
||||||
|
accent = Color.Unspecified,
|
||||||
|
accentInactive = Color.Unspecified,
|
||||||
|
black = Color.Unspecified,
|
||||||
|
white = Color.Unspecified,
|
||||||
|
error = Color.Unspecified,
|
||||||
|
success = Color.Unspecified,
|
||||||
|
inputBg = Color.Unspecified,
|
||||||
|
inputStroke = Color.Unspecified,
|
||||||
|
inputIcon = Color.Unspecified,
|
||||||
|
placeholder = Color.Unspecified,
|
||||||
|
description = Color.Unspecified,
|
||||||
|
cardStroke = Color.Unspecified
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val LocalCustomTypography = staticCompositionLocalOf {
|
||||||
|
CustomTypography(
|
||||||
|
title1SemiBold = TextStyle.Default,
|
||||||
|
title1ExtraBold = TextStyle.Default,
|
||||||
|
title2Regular = TextStyle.Default,
|
||||||
|
title2SemiBold = TextStyle.Default,
|
||||||
|
title2ExtraBold = TextStyle.Default,
|
||||||
|
title3Regular = TextStyle.Default,
|
||||||
|
title3Medium = TextStyle.Default,
|
||||||
|
title3Semibold = TextStyle.Default,
|
||||||
|
headlineRegular = TextStyle.Default,
|
||||||
|
headlineMedium = TextStyle.Default,
|
||||||
|
textRegular = TextStyle.Default,
|
||||||
|
textMedium = TextStyle.Default,
|
||||||
|
captionRegular = TextStyle.Default,
|
||||||
|
captionSemibold = TextStyle.Default,
|
||||||
|
caption2Regular = TextStyle.Default,
|
||||||
|
caption2Bold = TextStyle.Default
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val LocalCustomElevation = staticCompositionLocalOf {
|
||||||
|
CustomElevation(
|
||||||
|
spacing4dp = Dp.Unspecified,
|
||||||
|
spacing8dp = Dp.Unspecified,
|
||||||
|
spacing12dp = Dp.Unspecified,
|
||||||
|
spacing16dp = Dp.Unspecified,
|
||||||
|
spacing20dp = Dp.Unspecified,
|
||||||
|
spacing24dp = Dp.Unspecified,
|
||||||
|
spacing32dp = Dp.Unspecified,
|
||||||
|
spacing40dp = Dp.Unspecified,
|
||||||
|
spacing48dp = Dp.Unspecified,
|
||||||
|
spacing56dp = Dp.Unspecified,
|
||||||
|
spacing64dp = Dp.Unspecified
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CustomTheme(content: @Composable () -> Unit) {
|
||||||
|
|
||||||
|
val customColors = CustomColors(
|
||||||
|
accent = Accent,
|
||||||
|
accentInactive = AccentInactive,
|
||||||
|
black = Black,
|
||||||
|
white = White,
|
||||||
|
error = Error,
|
||||||
|
success = Success,
|
||||||
|
inputBg = InputBg,
|
||||||
|
inputStroke = InputStroke,
|
||||||
|
inputIcon = InputIcon,
|
||||||
|
placeholder = Placeholder,
|
||||||
|
description = Description,
|
||||||
|
cardStroke = CardStroke
|
||||||
|
)
|
||||||
|
|
||||||
|
val customTypography = CustomTypography(
|
||||||
|
title1SemiBold = Title1SemiBold,
|
||||||
|
title1ExtraBold = Title1ExtraBold,
|
||||||
|
title2Regular = Title2Regular,
|
||||||
|
title2SemiBold = Title2SemiBold,
|
||||||
|
title2ExtraBold = Title2ExtraBold,
|
||||||
|
title3Regular = Title3Regular,
|
||||||
|
title3Medium = Title3Medium,
|
||||||
|
title3Semibold = Title3Semibold,
|
||||||
|
headlineRegular = HeadlineRegular,
|
||||||
|
headlineMedium = HeadlineMedium,
|
||||||
|
textRegular = TextRegular,
|
||||||
|
textMedium = TextMedium,
|
||||||
|
captionRegular = CaptionRegular,
|
||||||
|
captionSemibold = CaptionSemibold,
|
||||||
|
caption2Regular = Caption2Regular,
|
||||||
|
caption2Bold = Caption2Bold
|
||||||
|
)
|
||||||
|
|
||||||
|
val customElevation = CustomElevation(
|
||||||
|
spacing4dp = 4.dp,
|
||||||
|
spacing8dp = 8.dp,
|
||||||
|
spacing12dp = 12.dp,
|
||||||
|
spacing16dp = 16.dp,
|
||||||
|
spacing20dp = 20.dp,
|
||||||
|
spacing24dp = 24.dp,
|
||||||
|
spacing32dp = 32.dp,
|
||||||
|
spacing40dp = 40.dp,
|
||||||
|
spacing48dp = 48.dp,
|
||||||
|
spacing56dp = 56.dp,
|
||||||
|
spacing64dp = 64.dp
|
||||||
|
)
|
||||||
|
|
||||||
|
CompositionLocalProvider(
|
||||||
|
LocalCustomColors provides customColors,
|
||||||
|
LocalCustomTypography provides customTypography,
|
||||||
|
LocalCustomElevation provides customElevation,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
object CustomTheme {
|
||||||
|
|
||||||
|
val colors: CustomColors
|
||||||
|
@Composable get() = LocalCustomColors.current
|
||||||
|
|
||||||
|
val typography: CustomTypography
|
||||||
|
@Composable get() = LocalCustomTypography.current
|
||||||
|
|
||||||
|
val elevation: CustomElevation
|
||||||
|
@Composable get() = LocalCustomElevation.current
|
||||||
|
}
|
19
core/src/main/java/com/example/core/theme/Font.kt
Normal file
19
core/src/main/java/com/example/core/theme/Font.kt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package com.example.core.theme
|
||||||
|
|
||||||
|
import androidx.compose.ui.text.font.Font
|
||||||
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import com.example.core.R
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
val RobotoFontFamily = FontFamily(
|
||||||
|
Font(resId = R.font.roboto_extra_bold, weight = FontWeight.ExtraBold),
|
||||||
|
Font(resId = R.font.roboto_semibold, weight = FontWeight.SemiBold),
|
||||||
|
Font(resId = R.font.roboto_regular, weight = FontWeight.Normal),
|
||||||
|
Font(resId = R.font.roboto_medium, weight = FontWeight.Medium),
|
||||||
|
Font(resId = R.font.roboto_bold, weight = FontWeight.Bold)
|
||||||
|
)
|
155
core/src/main/java/com/example/core/theme/Typography.kt
Normal file
155
core/src/main/java/com/example/core/theme/Typography.kt
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
package com.example.core.theme
|
||||||
|
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Автор: Манякин Дмитрий (user5)
|
||||||
|
* Дата создания: 26.05.2025
|
||||||
|
* */
|
||||||
|
|
||||||
|
val Title1SemiBold = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
fontSize = 24.sp,
|
||||||
|
lineHeight = 28.sp,
|
||||||
|
letterSpacing = 0.0033.em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val Title1ExtraBold = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.ExtraBold,
|
||||||
|
fontSize = 24.sp,
|
||||||
|
lineHeight = 28.sp,
|
||||||
|
letterSpacing = 0.0033.em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val Title2Regular = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontSize = 20.sp,
|
||||||
|
lineHeight = 28.sp,
|
||||||
|
letterSpacing = 0.0038.em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val Title2SemiBold = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
fontSize = 20.sp,
|
||||||
|
lineHeight = 28.sp,
|
||||||
|
letterSpacing = 0.0038.em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val Title2ExtraBold = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.ExtraBold,
|
||||||
|
fontSize = 20.sp,
|
||||||
|
lineHeight = 28.sp,
|
||||||
|
letterSpacing = 0.0038.em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val Title3Regular = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontSize = 17.sp,
|
||||||
|
lineHeight = 24.sp,
|
||||||
|
letterSpacing = 0.em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val Title3Medium = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontSize = 17.sp,
|
||||||
|
lineHeight = 24.sp,
|
||||||
|
letterSpacing = 0.em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val Title3Semibold = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
fontSize = 17.sp,
|
||||||
|
lineHeight = 24.sp,
|
||||||
|
letterSpacing = 0.em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val HeadlineRegular = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
lineHeight = 20.sp,
|
||||||
|
letterSpacing = (-0.0032).em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val HeadlineMedium = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontSize = 16.sp,
|
||||||
|
lineHeight = 20.sp,
|
||||||
|
letterSpacing = (-0.0032).em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val TextRegular = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontSize = 15.sp,
|
||||||
|
lineHeight = 20.sp,
|
||||||
|
letterSpacing = 0.em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val TextMedium = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
fontSize = 15.sp,
|
||||||
|
lineHeight = 20.sp,
|
||||||
|
letterSpacing = 0.em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val CaptionRegular = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
lineHeight = 20.sp,
|
||||||
|
letterSpacing = 0.em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val CaptionSemibold = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
lineHeight = 20.sp,
|
||||||
|
letterSpacing = 0.em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val Caption2Regular = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.Normal,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
lineHeight = 16.sp,
|
||||||
|
letterSpacing = 0.em,
|
||||||
|
color = Black
|
||||||
|
)
|
||||||
|
|
||||||
|
val Caption2Bold = TextStyle(
|
||||||
|
fontFamily = RobotoFontFamily,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontSize = 12.sp,
|
||||||
|
lineHeight = 16.sp,
|
||||||
|
letterSpacing = 0.em,
|
||||||
|
color = Black
|
||||||
|
)
|
35
core/src/main/res/drawable/icon_catalog.xml
Normal file
35
core/src/main/res/drawable/icon_catalog.xml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="32"
|
||||||
|
android:viewportHeight="32">
|
||||||
|
<path
|
||||||
|
android:pathData="M7,23.479V8.521C7,7.129 8.129,6 9.521,6H22.479C23.871,6 25,7.129 25,8.521V23.479C25,24.871 23.871,26 22.479,26H9.521C8.129,26 7,24.871 7,23.479Z"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#B8C1CC"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M11,16V11H16V16H11Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#B8C1CC"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M20,11H21"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#B8C1CC"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M20,16H21"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#B8C1CC"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M11,21L21,21"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#B8C1CC"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_check.xml
Normal file
11
core/src/main/res/drawable/icon_check.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="M16.666,4A1,1 0,0 0,15.959 4.293L7.5,12.752 4.041,9.293a1,1 0,0 0,-1.414 0,1 1,0 0,0 0,1.414l4.166,4.166a1,1 0,0 0,1.414 0L17.373,5.707a1,1 0,0 0,0 -1.414A1,1 0,0 0,16.666 4Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_chevron_down.xml
Normal file
11
core/src/main/res/drawable/icon_chevron_down.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="m5,7.5a1,1 0,0 0,-0.707 0.293,1 1,0 0,0 0,1.414l5,5a1,1 0,0 0,1.414 0l5,-5a1,1 0,0 0,0 -1.414,1 1,0 0,0 -1.414,0L10,12.086 5.707,7.793A1,1 0,0 0,5 7.5Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_chevron_left.xml
Normal file
11
core/src/main/res/drawable/icon_chevron_left.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="m11.5,4a1,1 0,0 0,-0.707 0.293l-5,5a1,1 0,0 0,0 1.414l5,5a1,1 0,0 0,1.414 0,1 1,0 0,0 0,-1.414L7.914,10 12.207,5.707a1,1 0,0 0,0 -1.414A1,1 0,0 0,11.5 4Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_chevron_right.xml
Normal file
11
core/src/main/res/drawable/icon_chevron_right.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="m7.5,4a1,1 0,0 0,-0.707 0.293,1 1,0 0,0 0,1.414L11.086,10 6.793,14.293a1,1 0,0 0,0 1.414,1 1,0 0,0 1.414,0l5,-5a1,1 0,0 0,0 -1.414l-5,-5A1,1 0,0 0,7.5 4Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_close.xml
Normal file
11
core/src/main/res/drawable/icon_close.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="m5,4a1,1 0,0 0,-0.707 0.293,1 1,0 0,0 0,1.414L8.586,10 4.293,14.293a1,1 0,0 0,0 1.414,1 1,0 0,0 1.414,0L10,11.414l4.293,4.293a1,1 0,0 0,1.414 0,1 1,0 0,0 0,-1.414L11.414,10 15.707,5.707a1,1 0,0 0,0 -1.414A1,1 0,0 0,15 4,1 1,0 0,0 14.293,4.293L10,8.586 5.707,4.293A1,1 0,0 0,5 4Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
14
core/src/main/res/drawable/icon_close_sheet.xml
Normal file
14
core/src/main/res/drawable/icon_close_sheet.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M12,24C18.627,24 24,18.627 24,12C24,5.373 18.627,0 12,0C5.373,0 0,5.373 0,12C0,18.627 5.373,24 12,24Z"
|
||||||
|
android:strokeAlpha="0.12"
|
||||||
|
android:fillColor="#B8C1CC"
|
||||||
|
android:fillAlpha="0.12"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M16.736,7.264C17.088,7.615 17.088,8.185 16.736,8.536L13.273,12L16.736,15.464C17.059,15.786 17.085,16.292 16.817,16.644L16.736,16.736C16.385,17.088 15.815,17.088 15.464,16.736L12,13.273L8.536,16.736C8.185,17.088 7.615,17.088 7.264,16.736C6.912,16.385 6.912,15.815 7.264,15.464L10.727,12L7.264,8.536C6.941,8.214 6.915,7.709 7.183,7.356L7.264,7.264C7.615,6.912 8.185,6.912 8.536,7.264L12,10.727L15.464,7.264C15.815,6.912 16.385,6.912 16.736,7.264Z"
|
||||||
|
android:fillColor="#7E7E9A"/>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_delete.xml
Normal file
11
core/src/main/res/drawable/icon_delete.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="m8.334,0.666c-0.707,0 -1.387,0.281 -1.887,0.781 -0.5,0.5 -0.781,1.18 -0.781,1.887L5.666,4h-1.5L2.5,4a1,1 0,0 0,-1 1,1 1,0 0,0 1,1h0.666v10.666c0,0.707 0.281,1.387 0.781,1.887 0.5,0.5 1.18,0.781 1.887,0.781h8.332c0.707,0 1.387,-0.282 1.887,-0.781 0.5,-0.5 0.781,-1.18 0.781,-1.887L16.834,6L17.5,6a1,1 0,0 0,1 -1,1 1,0 0,0 -1,-1h-1.666,-1.5L14.334,3.334c0,-0.707 -0.282,-1.387 -0.781,-1.887 -0.5,-0.5 -1.18,-0.781 -1.887,-0.781zM8.334,2.666h3.332c0.177,0 0.347,0.07 0.473,0.195 0.125,0.125 0.195,0.295 0.195,0.473L12.334,4L7.666,4L7.666,3.334c0,-0.177 0.07,-0.347 0.195,-0.473C7.987,2.736 8.157,2.666 8.334,2.666ZM5.166,6h9.668v10.666c0,0.177 -0.07,0.347 -0.195,0.473 -0.125,0.125 -0.295,0.195 -0.473,0.195L5.834,17.334c-0.177,0 -0.347,-0.07 -0.473,-0.195C5.236,17.013 5.166,16.843 5.166,16.666ZM8.334,8.166a1,1 0,0 0,-1 1v5a1,1 0,0 0,1 1,1 1,0 0,0 1,-1L9.334,9.166a1,1 0,0 0,-1 -1zM11.666,8.166a1,1 0,0 0,-1 1v5a1,1 0,0 0,1 1,1 1,0 0,0 1,-1L12.666,9.166a1,1 0,0 0,-1 -1z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_download.xml
Normal file
11
core/src/main/res/drawable/icon_download.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="m10,1.5a1,1 0,0 0,-1 1v7.586L6.541,7.627A1,1 0,0 0,5.834 7.334,1 1,0 0,0 5.127,7.627a1,1 0,0 0,0 1.414L9.293,13.207A1,1 0,0 0,10 13.5,1 1,0 0,0 10.707,13.207l4.166,-4.166a1,1 0,0 0,0 -1.414,1 1,0 0,0 -1.414,0L11,10.086L11,2.5a1,1 0,0 0,-1 -1zM2.5,11.5a1,1 0,0 0,-1 1v3.334c0,0.707 0.281,1.385 0.781,1.885C2.781,18.219 3.459,18.5 4.166,18.5L15.834,18.5c0.707,0 1.385,-0.281 1.885,-0.781C18.219,17.219 18.5,16.541 18.5,15.834L18.5,12.5a1,1 0,0 0,-1 -1,1 1,0 0,0 -1,1v3.334c0,0.177 -0.07,0.345 -0.195,0.471C16.179,16.43 16.011,16.5 15.834,16.5L4.166,16.5C3.989,16.5 3.821,16.43 3.695,16.305 3.57,16.179 3.5,16.011 3.5,15.834L3.5,12.5a1,1 0,0 0,-1 -1z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
13
core/src/main/res/drawable/icon_eye_close.xml
Normal file
13
core/src/main/res/drawable/icon_eye_close.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<group>
|
||||||
|
<clip-path
|
||||||
|
android:pathData="M0,0h20v20h-20z"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M0.818,0.14C0.632,-0.047 0.33,-0.047 0.144,0.14C-0.042,0.326 -0.042,0.628 0.144,0.814L4.255,4.925C2.555,6.245 1.131,7.887 0.066,9.757C-0.022,9.907 -0.022,10.093 0.066,10.243C2.235,13.906 4.999,16.215 8.064,16.921C8.7,17.068 9.35,17.142 10.002,17.142C11.763,17.118 13.481,16.592 14.954,15.627L19.185,19.86V19.86C19.372,20.046 19.673,20.046 19.86,19.86C20.046,19.674 20.046,19.372 19.86,19.186L0.818,0.14ZM8.019,8.689L11.313,11.984H11.314C10.699,12.386 9.933,12.481 9.239,12.243C8.545,12.004 7.999,11.458 7.761,10.764C7.523,10.07 7.618,9.304 8.019,8.689L8.019,8.689ZM8.281,15.993C5.544,15.362 3.044,13.292 1.036,10H1.036C2.034,8.293 3.357,6.798 4.931,5.601L7.344,8.014C6.694,8.873 6.501,9.994 6.827,11.02C7.153,12.047 7.957,12.851 8.983,13.177C10.009,13.503 11.13,13.31 11.989,12.66L14.266,14.938H14.266C12.488,16.065 10.337,16.444 8.281,15.993L8.281,15.993ZM10.35,7.655L9.421,6.726C9.613,6.687 9.807,6.668 10.002,6.667C10.886,6.667 11.734,7.018 12.359,7.643C12.984,8.268 13.335,9.116 13.335,10C13.334,10.195 13.315,10.39 13.276,10.581L12.347,9.652H12.348C12.273,9.149 12.038,8.683 11.679,8.324C11.319,7.964 10.853,7.729 10.35,7.655ZM19.934,9.757V9.757C20.022,9.907 20.022,10.093 19.934,10.243C19.096,11.686 18.057,13.003 16.849,14.155L16.174,13.479V13.479C17.26,12.452 18.2,11.281 18.969,10C16.532,6.006 13.356,3.81 10.002,3.81C9.005,3.82 8.019,4.021 7.097,4.401L6.359,3.663C7.503,3.141 8.745,2.867 10.002,2.858C13.774,2.858 17.301,5.308 19.934,9.757L19.934,9.757Z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
</group>
|
||||||
|
</vector>
|
16
core/src/main/res/drawable/icon_eye_show.xml
Normal file
16
core/src/main/res/drawable/icon_eye_show.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<group>
|
||||||
|
<clip-path
|
||||||
|
android:pathData="M0,0h20v20h-20z"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M10,6.955C9.216,6.955 8.464,7.266 7.909,7.82C7.355,8.374 7.043,9.126 7.043,9.91C7.042,10.694 7.353,11.446 7.908,12C8.462,12.555 9.214,12.867 9.998,12.867C10.782,12.867 11.534,12.556 12.088,12.001C12.642,11.447 12.954,10.695 12.954,9.911C12.953,9.128 12.642,8.376 12.088,7.822C11.535,7.268 10.783,6.956 10,6.955L10,6.955ZM10,11.225C9.651,11.225 9.316,11.087 9.069,10.84C8.822,10.594 8.683,10.259 8.682,9.91C8.682,9.561 8.821,9.226 9.068,8.979C9.315,8.732 9.65,8.593 9.999,8.594C10.348,8.594 10.683,8.733 10.929,8.98C11.176,9.227 11.314,9.562 11.314,9.911C11.313,10.259 11.175,10.593 10.929,10.84C10.682,11.086 10.348,11.225 10,11.225L10,11.225Z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M17.471,7.507L18.226,6.666C18.421,6.447 18.485,6.141 18.393,5.863C18.302,5.584 18.069,5.376 17.782,5.316C17.495,5.256 17.198,5.354 17.003,5.572L16.274,6.381V6.381C15.722,5.933 15.124,5.544 14.49,5.222L14.982,4.311V4.311C15.087,4.059 15.06,3.771 14.91,3.543C14.759,3.315 14.505,3.177 14.231,3.175C13.958,3.173 13.702,3.307 13.548,3.533L12.967,4.605C12.268,4.393 11.548,4.258 10.82,4.204V3.169C10.82,2.876 10.664,2.605 10.41,2.459C10.156,2.312 9.844,2.312 9.59,2.459C9.336,2.605 9.18,2.876 9.18,3.169V4.202C8.452,4.256 7.732,4.391 7.034,4.603L6.452,3.533C6.313,3.275 6.047,3.112 5.754,3.103C5.461,3.095 5.186,3.244 5.032,3.493C4.879,3.743 4.87,4.055 5.009,4.313L5.501,5.224C4.867,5.546 4.269,5.935 3.717,6.383L2.988,5.574V5.574C2.793,5.356 2.496,5.258 2.209,5.318C1.922,5.378 1.689,5.586 1.598,5.865C1.506,6.143 1.57,6.449 1.765,6.667L2.529,7.507C1.959,8.123 1.469,8.808 1.071,9.546C0.958,9.776 0.958,10.046 1.071,10.275C1.182,10.496 3.83,15.649 10,15.649C16.17,15.649 18.824,10.496 18.929,10.275C19.043,10.046 19.043,9.776 18.929,9.546C18.531,8.808 18.041,8.123 17.471,7.507L17.471,7.507ZM10,14.009C5.683,14.009 3.416,10.988 2.746,9.911C3.418,8.847 5.712,5.809 10,5.809C11.033,5.802 12.059,5.988 13.025,6.356L13.098,6.385H13.098C14.068,6.775 14.957,7.341 15.72,8.056C15.745,8.085 15.771,8.116 15.8,8.144C15.829,8.171 15.84,8.173 15.858,8.187L15.858,8.187C16.392,8.704 16.86,9.282 17.254,9.911C16.582,10.974 14.288,14.009 10,14.009L10,14.009Z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
</group>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_file_text.xml
Normal file
11
core/src/main/res/drawable/icon_file_text.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="M5,0.916C4.359,0.916 3.744,1.172 3.291,1.625 2.838,2.078 2.584,2.693 2.584,3.334L2.584,16.666c0,0.641 0.254,1.256 0.707,1.709C3.744,18.828 4.359,19.084 5,19.084h10c0.641,0 1.256,-0.256 1.709,-0.709 0.453,-0.453 0.707,-1.068 0.707,-1.709L17.416,6.666A0.75,0.75 0,0 0,17.359 6.379,0.75 0.75,0 0,0 17.197,6.137v-0.002a0.75,0.75 0,0 0,-0.018 -0.016l-4.977,-4.977 -0.006,-0.006A0.75,0.75 0,0 0,11.98 0.99,0.75 0.75,0 0,0 11.92,0.967 0.75,0.75 0,0 0,11.666 0.916ZM5,2.416h5.916v4.25a0.75,0.75 0,0 0,0.75 0.75h4.25v9.25c0,0.243 -0.095,0.476 -0.268,0.648C15.476,17.486 15.243,17.584 15,17.584L5,17.584c-0.243,0 -0.476,-0.097 -0.648,-0.27C4.179,17.142 4.084,16.909 4.084,16.666L4.084,3.334c0,-0.243 0.095,-0.476 0.268,-0.648C4.524,2.513 4.757,2.416 5,2.416ZM12.416,3.477 L14.855,5.916L12.416,5.916ZM6.666,6.75a0.75,0.75 0,0 0,-0.75 0.75,0.75 0.75,0 0,0 0.75,0.75L7.5,8.25 8.334,8.25a0.75,0.75 0,0 0,0.75 -0.75,0.75 0.75,0 0,0 -0.75,-0.75L7.5,6.75ZM6.666,10.084a0.75,0.75 0,0 0,-0.75 0.75,0.75 0.75,0 0,0 0.75,0.75h6.668a0.75,0.75 0,0 0,0.75 -0.75,0.75 0.75,0 0,0 -0.75,-0.75zM6.666,13.416a0.75,0.75 0,0 0,-0.75 0.75,0.75 0.75,0 0,0 0.75,0.75h6.668a0.75,0.75 0,0 0,0.75 -0.75,0.75 0.75,0 0,0 -0.75,-0.75z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_filter.xml
Normal file
11
core/src/main/res/drawable/icon_filter.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="M1.666,1.5A1,1 0,0 0,0.902 3.146L7.334,10.75v5.084a1,1 0,0 0,0.553 0.895L11.219,18.395A1,1 0,0 0,12.666 17.5v-6.75l6.432,-7.604A1,1 0,0 0,18.334 1.5ZM3.822,3.5L16.178,3.5l-5.275,6.238a1,1 0,0 0,-0.236 0.645v5.498L9.334,15.215L9.334,10.383A1,1 0,0 0,9.098 9.738Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
9
core/src/main/res/drawable/icon_home.xml
Normal file
9
core/src/main/res/drawable/icon_home.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="32"
|
||||||
|
android:viewportHeight="32">
|
||||||
|
<path
|
||||||
|
android:pathData="M27.481,15.773L23.809,12.624V8.373C23.809,8.112 23.598,7.901 23.337,7.901H20.878C20.617,7.901 20.405,8.112 20.405,8.373V9.702L16.315,6.195C16.136,6.034 15.865,6.034 15.685,6.195L4.52,15.773C4.368,15.903 4.314,16.113 4.385,16.3C4.455,16.486 4.635,16.608 4.835,16.605H8.191V25.446C8.191,25.707 8.403,25.919 8.663,25.919H10.307C10.568,25.919 10.78,25.707 10.78,25.446C10.78,25.186 10.568,24.974 10.307,24.974H9.136V16.132C9.136,15.872 8.924,15.66 8.663,15.66H6.104L16,7.184L25.897,15.66H23.337C23.076,15.66 22.865,15.872 22.865,16.132V24.974H21.69C21.43,24.974 21.218,25.186 21.218,25.446C21.218,25.707 21.43,25.919 21.69,25.919H23.337C23.598,25.919 23.809,25.707 23.809,25.446V16.605H27.176C27.375,16.608 27.555,16.486 27.625,16.3C27.696,16.113 27.642,15.903 27.491,15.773L27.481,15.773ZM21.353,8.846H22.865V11.815L21.353,10.518V8.846ZM20.408,17.732H11.592C11.331,17.732 11.119,17.943 11.119,18.204V26.391C11.119,26.652 11.331,26.864 11.592,26.864H20.408C20.669,26.864 20.881,26.652 20.881,26.391V18.204C20.881,17.943 20.669,17.732 20.408,17.732ZM16.671,18.677V20.859L16.561,20.792L16.56,20.793C16.374,20.68 16.135,20.71 15.981,20.865L15.553,21.296L15.333,21.044V18.677L16.671,18.677ZM19.939,25.919H12.068V18.677H14.391V21.221C14.39,21.337 14.432,21.449 14.508,21.536L15.178,22.298C15.265,22.396 15.388,22.454 15.519,22.458C15.645,22.459 15.766,22.409 15.855,22.32L16.378,21.791L16.885,22.106C17.031,22.193 17.212,22.195 17.36,22.112C17.507,22.028 17.599,21.872 17.6,21.703V18.677H19.936L19.939,25.919Z"
|
||||||
|
android:fillColor="#B8C1CC"/>
|
||||||
|
</vector>
|
15
core/src/main/res/drawable/icon_map.xml
Normal file
15
core/src/main/res/drawable/icon_map.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<group>
|
||||||
|
<clip-path
|
||||||
|
android:pathData="M0,0h20v20h-20z"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m13.334,4a1,1 0,0 0,-1 1v13.334a1,1 0,0 0,1 1,1 1,0 0,0 1,-1V5a1,1 0,0 0,-1 -1zM6.666,0.666a1,1 0,0 0,-1 1V15a1,1 0,0 0,1 1,1 1,0 0,0 1,-1V1.666a1,1 0,0 0,-1 -1zM7.113,0.771A1,1 0,0 0,6.17 0.799L0.338,4.131A1,1 0,0 0,-0.166 5v13.334a1,1 0,0 0,1.496 0.867l5.367,-3.068 6.189,3.096a1,1 0,0 0,0.943 -0.027l5.832,-3.332A1,1 0,0 0,20.166 15V1.666A1,1 0,0 0,18.67 0.799L13.303,3.867ZM6.697,2.801 L12.887,5.895a1,1 0,0 0,0.943 -0.025L18.166,3.391v11.029l-4.863,2.779 -6.189,-3.094a1,1 0,0 0,-0.943 0.025L1.834,16.609V5.582Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</group>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_message_circle.xml
Normal file
11
core/src/main/res/drawable/icon_message_circle.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="M10.416,1.5C9.161,1.497 7.923,1.79 6.803,2.355 5.46,3.026 4.33,4.058 3.541,5.334 2.752,6.61 2.335,8.081 2.334,9.582 2.331,10.648 2.652,11.672 3.063,12.652l-1.512,4.531a1,1 0,0 0,1.266 1.266l4.531,-1.512c0.981,0.41 2.005,0.731 3.072,0.729 1.5,-0.001 2.97,-0.418 4.246,-1.207 1.275,-0.789 2.306,-1.917 2.977,-3.258v-0.002C18.209,12.077 18.503,10.837 18.5,9.58L18.5,9.166a1,1 0,0 0,-0.002 -0.055C18.389,7.129 17.552,5.256 16.148,3.852 14.745,2.448 12.871,1.611 10.889,1.502A1,1 0,0 0,10.834 1.5h-0.414zM10.414,3.5a1,1 0,0 0,0.002 0h0.369c1.488,0.084 2.895,0.711 3.949,1.766C15.789,6.32 16.416,7.726 16.5,9.215v0.369a1,1 0,0 0,0 0.002c0.002,0.942 -0.218,1.872 -0.643,2.713a1,1 0,0 0,-0.002 0.004c-0.505,1.01 -1.282,1.861 -2.242,2.455 -0.961,0.594 -2.068,0.908 -3.197,0.908a1,1 0,0 0,-0.002 0C9.472,15.668 8.542,15.448 7.701,15.023A1,1 0,0 0,6.934 14.969L4.082,15.918 5.031,13.066A1,1 0,0 0,4.977 12.299C4.552,11.458 4.332,10.528 4.334,9.586a1,1 0,0 0,0 -0.002C4.334,8.454 4.648,7.347 5.242,6.387 5.836,5.426 6.687,4.65 7.697,4.145a1,1 0,0 0,0.004 -0.002C8.542,3.718 9.472,3.498 10.414,3.5Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
15
core/src/main/res/drawable/icon_mic.xml
Normal file
15
core/src/main/res/drawable/icon_mic.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<group>
|
||||||
|
<clip-path
|
||||||
|
android:pathData="M0,0h20v20h-20z"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m6.666,18.166a1,1 0,0 0,-1 1,1 1,0 0,0 1,1h6.668a1,1 0,0 0,1 -1,1 1,0 0,0 -1,-1zM10,14.834a1,1 0,0 0,-1 1v3.332a1,1 0,0 0,1 1,1 1,0 0,0 1,-1v-3.332a1,1 0,0 0,-1 -1zM4.166,7.334a1,1 0,0 0,-1 1L3.166,10c0,1.812 0.721,3.551 2.002,4.832C6.449,16.113 8.188,16.834 10,16.834c1.812,0 3.551,-0.721 4.832,-2.002C16.113,13.551 16.834,11.812 16.834,10L16.834,8.334a1,1 0,0 0,-1 -1,1 1,0 0,0 -1,1L14.834,10c0,1.282 -0.509,2.511 -1.416,3.418 -0.907,0.907 -2.136,1.416 -3.418,1.416 -1.282,0 -2.511,-0.509 -3.418,-1.416C5.675,12.511 5.166,11.282 5.166,10L5.166,8.334a1,1 0,0 0,-1 -1zM10,-0.166c-0.928,0 -1.819,0.369 -2.475,1.025C6.869,1.515 6.5,2.406 6.5,3.334L6.5,10c0,0.928 0.369,1.819 1.025,2.475C8.181,13.131 9.072,13.5 10,13.5c0.928,0 1.818,-0.369 2.475,-1.025C13.131,11.819 13.5,10.928 13.5,10L13.5,3.334C13.5,2.406 13.131,1.515 12.475,0.859 11.818,0.203 10.928,-0.166 10,-0.166ZM10,1.834c0.398,0 0.779,0.158 1.061,0.439C11.342,2.555 11.5,2.936 11.5,3.334L11.5,10c0,0.398 -0.158,0.779 -0.439,1.061C10.779,11.342 10.398,11.5 10,11.5 9.602,11.5 9.221,11.342 8.939,11.061 8.658,10.779 8.5,10.398 8.5,10L8.5,3.334C8.5,2.936 8.658,2.555 8.939,2.273 9.221,1.992 9.602,1.834 10,1.834Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</group>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_minus.xml
Normal file
11
core/src/main/res/drawable/icon_minus.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="m4.166,9a1,1 0,0 0,-1 1,1 1,0 0,0 1,1H15.834a1,1 0,0 0,1 -1,1 1,0 0,0 -1,-1z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
27
core/src/main/res/drawable/icon_more_horizontal.xml
Normal file
27
core/src/main/res/drawable/icon_more_horizontal.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="M10,10.833C10.46,10.833 10.833,10.46 10.833,10C10.833,9.54 10.46,9.167 10,9.167C9.54,9.167 9.167,9.54 9.167,10C9.167,10.46 9.54,10.833 10,10.833Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#B8C1CC"
|
||||||
|
android:strokeColor="#B8C1CC"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M15.833,10.833C16.294,10.833 16.667,10.46 16.667,10C16.667,9.54 16.294,9.167 15.833,9.167C15.373,9.167 15,9.54 15,10C15,10.46 15.373,10.833 15.833,10.833Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#B8C1CC"
|
||||||
|
android:strokeColor="#B8C1CC"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M4.167,10.833C4.627,10.833 5,10.46 5,10C5,9.54 4.627,9.167 4.167,9.167C3.706,9.167 3.333,9.54 3.333,10C3.333,10.46 3.706,10.833 4.167,10.833Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#B8C1CC"
|
||||||
|
android:strokeColor="#B8C1CC"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_paperclip.xml
Normal file
11
core/src/main/res/drawable/icon_paperclip.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="m13.15,0.156c-1.149,0 -2.254,0.457 -3.066,1.27L2.426,9.084C1.3,10.209 0.668,11.738 0.668,13.33c0,1.592 0.632,3.119 1.758,4.244 1.125,1.125 2.652,1.758 4.244,1.758 1.592,0 3.121,-0.632 4.246,-1.758l7.658,-7.658a1,1 0,0 0,0 -1.414,1 1,0 0,0 -1.414,0L9.502,16.16c-0.751,0.751 -1.77,1.172 -2.832,1.172 -1.062,0 -2.079,-0.421 -2.83,-1.172 -0.751,-0.751 -1.172,-1.768 -1.172,-2.83 0,-1.062 0.421,-2.081 1.172,-2.832L11.498,2.84C11.936,2.402 12.531,2.156 13.15,2.156c0.62,0 1.212,0.245 1.65,0.684 0.438,0.438 0.684,1.033 0.684,1.652 0,0.62 -0.245,1.212 -0.684,1.65L7.135,13.801c-0.125,0.125 -0.295,0.195 -0.473,0.195 -0.177,0 -0.345,-0.07 -0.471,-0.195a1,1 0,0 0,-0.002 0C6.064,13.675 5.994,13.508 5.994,13.33c0,-0.177 0.07,-0.347 0.195,-0.473L13.266,5.791a1,1 0,0 0,0 -1.414A1,1 0,0 0,11.852 4.375l-7.074,7.068a1,1 0,0 0,-0.002 0c-0.5,0.5 -0.781,1.18 -0.781,1.887 0,0.707 0.281,1.385 0.781,1.885 0.5,0.5 1.18,0.781 1.887,0.781 0.707,0 1.387,-0.281 1.887,-0.781L16.215,7.557c0.813,-0.813 1.27,-1.915 1.27,-3.064 0,-1.149 -0.457,-2.254 -1.27,-3.066C15.402,0.613 14.3,0.156 13.15,0.156Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_plus.xml
Normal file
11
core/src/main/res/drawable/icon_plus.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="m10,3.166a1,1 0,0 0,-1 1V9H4.166a1,1 0,0 0,-1 1,1 1,0 0,0 1,1H9v4.834a1,1 0,0 0,1 1,1 1,0 0,0 1,-1V11h4.834a1,1 0,0 0,1 -1,1 1,0 0,0 -1,-1H11V4.166a1,1 0,0 0,-1 -1z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
16
core/src/main/res/drawable/icon_profile.xml
Normal file
16
core/src/main/res/drawable/icon_profile.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="32"
|
||||||
|
android:viewportHeight="32">
|
||||||
|
<path
|
||||||
|
android:pathData="M16,10m-4,0a4,4 0,1 1,8 0a4,4 0,1 1,-8 0"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#B8C1CC"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M16,17C20.502,17 24,20.326 24,24.25V24.251C24,24.251 24,24.253 23.999,24.256C23.997,24.262 23.99,24.277 23.974,24.304C23.937,24.361 23.858,24.454 23.7,24.57C23.376,24.809 22.841,25.061 22.081,25.285C20.573,25.731 18.425,26 16,26C13.575,26 11.427,25.731 9.919,25.285C9.159,25.061 8.624,24.809 8.3,24.57C8.142,24.454 8.063,24.361 8.026,24.304C8.01,24.277 8.003,24.262 8.001,24.256C8,24.253 8,24.251 8,24.251V24.25C8,20.326 11.498,17 16,17Z"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#B8C1CC"/>
|
||||||
|
</vector>
|
27
core/src/main/res/drawable/icon_projects.xml
Normal file
27
core/src/main/res/drawable/icon_projects.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M7.369,1.837H2.683C2.456,1.837 2.305,1.987 2.305,2.212V6.825C2.305,7.05 2.456,7.2 2.683,7.2H7.331C7.558,7.2 7.709,7.049 7.709,6.825V2.212C7.746,1.987 7.557,1.837 7.369,1.837ZM6.991,6.45H3.061V2.587H6.953V6.45H6.991Z"
|
||||||
|
android:fillColor="#B8C1CC"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M7.369,9.3H2.683C2.456,9.3 2.305,9.45 2.305,9.675V14.287C2.305,14.512 2.456,14.662 2.683,14.662H7.331C7.558,14.662 7.709,14.512 7.709,14.287V9.675C7.746,9.487 7.557,9.3 7.369,9.3ZM6.991,13.95H3.061V10.05H6.953V13.95H6.991Z"
|
||||||
|
android:fillColor="#B8C1CC"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M7.369,16.8H2.683C2.456,16.8 2.305,16.95 2.305,17.175V21.787C2.305,22.012 2.456,22.162 2.683,22.162H7.331C7.558,22.162 7.709,22.012 7.709,21.787V17.175C7.746,16.987 7.557,16.8 7.369,16.8ZM6.991,21.412H3.061V17.55H6.953V21.412H6.991Z"
|
||||||
|
android:fillColor="#B8C1CC"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M4.194,5.662C4.269,5.737 4.383,5.774 4.458,5.774C4.572,5.774 4.647,5.737 4.723,5.662L6.537,3.862C6.688,3.712 6.688,3.487 6.537,3.337C6.386,3.187 6.159,3.187 6.008,3.337L4.458,4.874L4.043,4.462C3.891,4.312 3.665,4.312 3.514,4.462C3.362,4.612 3.362,4.837 3.514,4.987L4.194,5.662Z"
|
||||||
|
android:fillColor="#B8C1CC"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M4.194,13.162C4.269,13.237 4.345,13.274 4.458,13.274C4.572,13.274 4.647,13.237 4.723,13.162L6.537,11.362C6.688,11.212 6.688,10.987 6.537,10.837C6.386,10.687 6.159,10.687 6.008,10.837L4.458,12.374L4.043,11.962C3.891,11.812 3.665,11.812 3.514,11.962C3.362,12.112 3.362,12.337 3.514,12.487L4.194,13.162Z"
|
||||||
|
android:fillColor="#B8C1CC"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M4.194,20.662C4.269,20.737 4.383,20.774 4.458,20.774C4.572,20.774 4.647,20.737 4.723,20.662L6.537,18.862C6.688,18.712 6.688,18.487 6.537,18.337C6.386,18.187 6.159,18.187 6.008,18.337L4.458,19.874L4.043,19.462C3.891,19.312 3.665,19.312 3.514,19.462C3.362,19.612 3.362,19.837 3.514,19.987L4.194,20.662Z"
|
||||||
|
android:fillColor="#B8C1CC"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M23.655,13.462H19.423C19.196,13.462 19.045,13.612 19.045,13.837C18.289,13.575 18.553,13.725 18.175,13.537L18.176,5.887C18.176,5.775 18.138,5.7 18.062,5.625L12.508,0.112C12.432,0.038 12.319,0 12.243,0H0.378C0.151,0 0,0.15 0,0.375V23.625C0,23.85 0.151,24 0.378,24H17.76C17.987,24 18.138,23.85 18.138,23.625V21.45H19.007C19.045,21.638 19.196,21.75 19.385,21.75H23.617C23.844,21.75 23.995,21.6 23.995,21.375V13.838C24.033,13.613 23.844,13.463 23.655,13.463L23.655,13.462ZM19.045,14.587V20.7H11.752C11.223,20.7 11.185,20.287 11.185,20.175C11.185,20.024 11.223,19.912 11.299,19.8C11.374,19.687 11.525,19.65 11.676,19.65C11.903,19.65 12.054,19.5 12.054,19.275C12.054,19.049 11.903,18.9 11.676,18.9H11.147C10.618,18.9 10.58,18.487 10.58,18.375C10.58,18.187 10.694,17.85 11.11,17.85C11.299,17.85 11.45,17.699 11.487,17.512C11.487,17.324 11.374,17.137 11.185,17.099H10.921C10.316,17.137 10.089,17.024 10.014,16.725C9.976,16.574 10.014,16.387 10.089,16.274C10.203,16.162 10.354,16.087 10.505,16.087C10.732,16.087 10.883,15.937 10.883,15.712C10.883,15.487 10.732,15.337 10.505,15.337H9.938C9.523,15.337 9.409,15 9.409,14.812C9.409,14.737 9.447,14.287 9.976,14.287H12.621C13.226,14.287 13.717,14.024 13.944,13.612C14.133,13.199 14.208,12.487 13.339,11.362C13.037,10.987 12.923,10.499 13.075,10.124C13.264,9.599 13.793,9.374 14.133,9.337C14.095,12.074 16.816,13.687 18.025,14.249C18.062,14.325 19.045,14.587 19.045,14.587L19.045,14.587ZM12.621,1.274L16.891,5.512H12.621V1.274ZM17.42,23.249H0.793V0.749H11.865V5.887C11.865,6.112 12.016,6.262 12.243,6.262H17.42V13.087C16.286,12.374 14.888,11.099 14.926,9.337C14.926,9.149 14.85,8.924 14.699,8.812C14.548,8.662 14.321,8.624 14.132,8.624C13.263,8.737 12.658,9.224 12.394,9.899C12.167,10.537 12.318,11.249 12.772,11.849C13.263,12.449 13.452,13.012 13.301,13.274C13.188,13.499 12.81,13.537 12.658,13.537H10.013C9.144,13.537 8.691,14.174 8.691,14.812C8.691,15.262 8.955,15.749 9.409,15.974C9.258,16.274 9.22,16.574 9.295,16.912C9.409,17.362 9.711,17.624 10.013,17.737C9.9,17.924 9.862,18.149 9.862,18.374C9.862,18.824 10.127,19.312 10.58,19.537C10.467,19.724 10.429,19.949 10.429,20.174C10.429,20.812 10.882,21.449 11.752,21.449H17.42L17.42,23.249ZM23.277,21.037H19.8V14.212H23.277V21.037Z"
|
||||||
|
android:fillColor="#B8C1CC"/>
|
||||||
|
</vector>
|
11
core/src/main/res/drawable/icon_search.xml
Normal file
11
core/src/main/res/drawable/icon_search.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<path
|
||||||
|
android:pathData="M9.166,1.5C4.944,1.5 1.5,4.944 1.5,9.166c0,4.222 3.444,7.668 7.666,7.668 1.752,0 3.368,-0.596 4.662,-1.592l2.965,2.965a1,1 0,0 0,1.414 0,1 1,0 0,0 0,-1.414L15.242,13.828C16.238,12.534 16.834,10.918 16.834,9.166 16.834,4.944 13.388,1.5 9.166,1.5ZM9.166,3.5c3.141,0 5.668,2.525 5.668,5.666 0,1.529 -0.6,2.911 -1.576,3.928a1,1 0,0 0,-0.09 0.074,1 1,0 0,0 -0.063,0.078c-1.018,0.983 -2.405,1.588 -3.939,1.588C6.025,14.834 3.5,12.308 3.5,9.166 3.5,6.025 6.025,3.5 9.166,3.5Z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
15
core/src/main/res/drawable/icon_send.xml
Normal file
15
core/src/main/res/drawable/icon_send.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<group>
|
||||||
|
<clip-path
|
||||||
|
android:pathData="M0,0h20v20h-20z"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M18.004,0.723 L1.336,6.557a1,1 0,0 0,-0.076 1.857l7.148,3.178 3.178,7.148a1,1 0,0 0,1.857 -0.076L19.277,1.996A1,1 0,0 0,18.004 0.723ZM16.703,3.297 L12.389,15.623 10.08,10.428A1,1 0,0 0,9.572 9.92L4.377,7.611ZM17.627,0.959 L8.459,10.127a1,1 0,0 0,0 1.414,1 1,0 0,0 1.414,0L19.041,2.373a1,1 0,0 0,0 -1.414,1 1,0 0,0 -1.414,0z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</group>
|
||||||
|
</vector>
|
15
core/src/main/res/drawable/icon_shopping_cart.xml
Normal file
15
core/src/main/res/drawable/icon_shopping_cart.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="20"
|
||||||
|
android:viewportHeight="20">
|
||||||
|
<group>
|
||||||
|
<clip-path
|
||||||
|
android:pathData="M0,0h20v20h-20z"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m0.834,-0.166a1,1 0,0 0,-1 1,1 1,0 0,0 1,1L3.348,1.834L5.42,12.188c0.122,0.614 0.456,1.164 0.943,1.557 0.487,0.392 1.097,0.602 1.723,0.59h8.061c0.626,0.012 1.237,-0.198 1.725,-0.59 0.487,-0.392 0.821,-0.943 0.943,-1.557a1,1 0,0 0,0.002 -0.008L20.148,5.188A1,1 0,0 0,19.166 4L5.82,4L5.146,0.637A1,1 0,0 0,4.166 -0.166ZM6.221,6L17.957,6l-1.105,5.805v-0.008c-0.031,0.154 -0.112,0.29 -0.234,0.389 -0.122,0.098 -0.275,0.151 -0.432,0.148a1,1 0,0 0,-0.02 0L8.066,12.334a1,1 0,0 0,-0.02 0C7.89,12.337 7.739,12.284 7.617,12.186 7.495,12.087 7.411,11.95 7.381,11.797a1,1 0,0 0,0 -0.002zM16.666,15.666c-1.001,0 -1.832,0.833 -1.832,1.834 0,1.001 0.831,1.834 1.832,1.834 1.001,0 1.834,-0.833 1.834,-1.834 0,-1.001 -0.833,-1.834 -1.834,-1.834zM16.666,17.334c0.08,0 0.168,0.086 0.168,0.166 0,0.08 -0.088,0.166 -0.168,0.166C16.586,17.666 16.5,17.58 16.5,17.5c0,-0.08 0.086,-0.166 0.166,-0.166zM7.5,15.666c-1.001,0 -1.834,0.833 -1.834,1.834 0,1.001 0.833,1.834 1.834,1.834 1.001,0 1.834,-0.833 1.834,-1.834 0,-1.001 -0.833,-1.834 -1.834,-1.834zM7.5,17.334c0.08,0 0.166,0.086 0.166,0.166 0,0.08 -0.086,0.166 -0.166,0.166 -0.08,0 -0.166,-0.086 -0.166,-0.166 0,-0.08 0.086,-0.166 0.166,-0.166z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:fillColor="#b8c1cc"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</group>
|
||||||
|
</vector>
|
17
core/src/main/res/drawable/icon_vk.xml
Normal file
17
core/src/main/res/drawable/icon_vk.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="33dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="33"
|
||||||
|
android:viewportHeight="32">
|
||||||
|
<group>
|
||||||
|
<clip-path
|
||||||
|
android:pathData="M0.5,0h32v32h-32z"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M0.5,0H32.5V32H0.5V0Z"
|
||||||
|
android:fillColor="#0077FF"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M8.571,8.622C7.611,9.76 7.611,11.467 7.611,14.915V17.067C7.611,20.498 7.611,22.222 8.571,23.36C8.731,23.573 8.927,23.751 9.105,23.911C10.26,24.871 11.985,24.871 15.416,24.871H17.567C20.998,24.871 22.722,24.871 23.86,23.911C24.074,23.751 24.251,23.556 24.411,23.378C25.371,22.222 25.371,20.498 25.371,17.067V14.933C25.371,11.502 25.371,9.778 24.411,8.64C24.251,8.427 24.056,8.249 23.878,8.071C22.722,7.111 20.998,7.111 17.567,7.111H15.434C12.002,7.111 10.278,7.111 9.14,8.053C8.927,8.231 8.749,8.409 8.589,8.622H8.571ZM10.634,13.298C10.722,14.524 11.131,15.858 11.7,16.764C12.749,18.489 14.349,19.378 16.678,19.502L17.069,19.538V16.978L17.354,17.013C18.473,17.156 19.611,18.044 20.091,19.182L20.234,19.538H20.589C21.176,19.538 22.278,19.573 22.278,19.538C22.06,18.797 21.696,18.107 21.208,17.508C20.719,16.91 20.116,16.415 19.434,16.053L19.291,15.964L19.522,15.787C20.666,15.063 21.493,13.932 21.834,12.622V12.444H19.967L19.825,12.8C19.469,13.689 18.634,14.649 17.905,15.004C17.638,15.129 17.371,15.2 17.069,15.236V12.444H15.345V17.369L15.078,17.28C14.367,17.013 13.691,16.355 13.282,15.573C12.927,14.915 12.678,13.867 12.607,12.942L12.589,12.444H10.58L10.651,13.298H10.634Z"
|
||||||
|
android:fillColor="#ffffff"
|
||||||
|
android:fillType="evenOdd"/>
|
||||||
|
</group>
|
||||||
|
</vector>
|
9
core/src/main/res/drawable/icon_yandex.xml
Normal file
9
core/src/main/res/drawable/icon_yandex.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="33dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="33"
|
||||||
|
android:viewportHeight="32">
|
||||||
|
<path
|
||||||
|
android:pathData="M6.17,0C3.029,0 0.5,2.529 0.5,5.67V26.33C0.5,29.471 3.029,32 6.17,32H21.376L32.5,16.004L21.376,0H6.17V0ZM14.685,5.842H18.298C18.52,5.842 18.647,5.923 18.647,6.114V26.026C18.647,26.162 18.583,26.243 18.393,26.243H16.428C16.302,26.243 16.207,26.134 16.207,26.053V18.681H14.621L10.216,26.053C10.153,26.189 10.026,26.243 9.836,26.243H7.586C7.333,26.243 7.175,26.053 7.333,25.808L12.181,18.3C9.583,17.321 8.125,15.335 8.125,12.642C8.125,8.154 11.136,5.842 14.685,5.842L14.685,5.842ZM14.59,7.582C12.657,7.582 10.755,8.969 10.755,12.37C10.755,15.634 12.783,16.94 14.875,16.94H16.207V7.582H14.59Z"
|
||||||
|
android:fillColor="#FFC107"/>
|
||||||
|
</vector>
|
BIN
core/src/main/res/font/roboto_bold.ttf
Normal file
BIN
core/src/main/res/font/roboto_bold.ttf
Normal file
Binary file not shown.
BIN
core/src/main/res/font/roboto_extra_bold.ttf
Normal file
BIN
core/src/main/res/font/roboto_extra_bold.ttf
Normal file
Binary file not shown.
BIN
core/src/main/res/font/roboto_medium.ttf
Normal file
BIN
core/src/main/res/font/roboto_medium.ttf
Normal file
Binary file not shown.
BIN
core/src/main/res/font/roboto_regular.ttf
Normal file
BIN
core/src/main/res/font/roboto_regular.ttf
Normal file
Binary file not shown.
BIN
core/src/main/res/font/roboto_semibold.ttf
Normal file
BIN
core/src/main/res/font/roboto_semibold.ttf
Normal file
Binary file not shown.
19
core/src/main/res/values/strings.xml
Normal file
19
core/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="in_cart">В корзину</string>
|
||||||
|
<string name="total_price">%1$s ₽</string>
|
||||||
|
<string name="home">Главная</string>
|
||||||
|
<string name="catalog">Каталог</string>
|
||||||
|
<string name="projects">Проекты</string>
|
||||||
|
<string name="profile">Профиль</string>
|
||||||
|
<string name="drop">Убрать</string>
|
||||||
|
<string name="add">Добавить</string>
|
||||||
|
<string name="cart_card_quantity">%1$s штук</string>
|
||||||
|
<string name="open">Открыть</string>
|
||||||
|
|
||||||
|
<plurals name="elapsed_days">
|
||||||
|
<item quantity="one">Прошел %1$s день</item>
|
||||||
|
<item quantity="few">Прошло %1$s дня</item>
|
||||||
|
<item quantity="many">Прошло %1$s дней</item>
|
||||||
|
</plurals>
|
||||||
|
</resources>
|
17
core/src/test/java/com/example/core/ExampleUnitTest.kt
Normal file
17
core/src/test/java/com/example/core/ExampleUnitTest.kt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package com.example.core
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
class ExampleUnitTest {
|
||||||
|
@Test
|
||||||
|
fun addition_isCorrect() {
|
||||||
|
assertEquals(4, 2 + 2)
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,52 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.9.2"
|
agp = "8.9.2"
|
||||||
kotlin = "2.0.21"
|
androidPdfViewer = "3.2.0-beta.3"
|
||||||
|
kotlin = "2.1.20"
|
||||||
coreKtx = "1.16.0"
|
coreKtx = "1.16.0"
|
||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
junitVersion = "1.2.1"
|
junitVersion = "1.2.1"
|
||||||
espressoCore = "3.6.1"
|
espressoCore = "3.6.1"
|
||||||
lifecycleRuntimeKtx = "2.9.0"
|
lifecycleRuntimeKtx = "2.8.7"
|
||||||
activityCompose = "1.10.1"
|
activityCompose = "1.10.1"
|
||||||
composeBom = "2024.09.00"
|
composeBom = "2025.04.01"
|
||||||
|
appcompat = "1.7.0"
|
||||||
|
material = "1.12.0"
|
||||||
|
jetbrainsKotlinJvm = "2.1.20"
|
||||||
|
|
||||||
|
retrofit = "2.11.0"
|
||||||
|
okhttp3 = "4.12.0"
|
||||||
|
kotlinxSerializationConverter = "1.0.0"
|
||||||
|
kotlinxSerializationJson = "1.8.0"
|
||||||
|
navigationCompose = "2.9.0"
|
||||||
|
dagger = "2.55"
|
||||||
|
hiltNavigationCompose = "1.2.0"
|
||||||
|
datastorePreferences = "1.1.6"
|
||||||
|
javaxInject = "1"
|
||||||
|
kotlinxCoroutinesTest = "1.10.2"
|
||||||
|
uiTooling = "1.8.2"
|
||||||
|
coil = "3.1.0"
|
||||||
|
materialIconsExtended = "1.7.8"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
|
androidx-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended", version.ref = "materialIconsExtended" }
|
||||||
|
coil-compose = { group = "io.coil-kt.coil3", name = "coil-compose", version.ref = "coil" }
|
||||||
|
coil-network-http = { group = "io.coil-kt.coil3", name = "coil-network-okhttp", version.ref = "coil" }
|
||||||
|
|
||||||
|
mockwebserver = { group = "com.squareup.okhttp3", name = "mockwebserver", version.ref = "okhttp3" }
|
||||||
|
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinxCoroutinesTest" }
|
||||||
|
javax-inject = { group = "javax.inject", name = "javax.inject", version.ref = "javaxInject" }
|
||||||
|
android-pdf-viewer = { group = "com.github.mhiew", name = "android-pdf-viewer", version.ref = "androidPdfViewer" }
|
||||||
|
androidx-datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastorePreferences" }
|
||||||
|
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "dagger" }
|
||||||
|
hilt-android-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "dagger" }
|
||||||
|
hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
|
||||||
|
navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
|
||||||
|
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
|
||||||
|
retrofit2-kotlinx-serialization-converter = { group = "com.jakewharton.retrofit", name = "retrofit2-kotlinx-serialization-converter", version.ref = "kotlinxSerializationConverter" }
|
||||||
|
logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp3" }
|
||||||
|
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp3" }
|
||||||
|
retrofit2 = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
|
||||||
|
|
||||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||||
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||||
@ -24,9 +61,16 @@ androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-toolin
|
|||||||
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
||||||
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
||||||
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
|
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
|
||||||
|
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
|
||||||
|
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
||||||
|
ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "uiTooling" }
|
||||||
|
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
|
dagger-hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "dagger" }
|
||||||
|
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||||
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
||||||
|
android-library = { id = "com.android.library", version.ref = "agp" }
|
||||||
|
jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "jetbrainsKotlinJvm" }
|
@ -21,4 +21,4 @@ dependencyResolutionManagement {
|
|||||||
|
|
||||||
rootProject.name = "uikit"
|
rootProject.name = "uikit"
|
||||||
include(":app")
|
include(":app")
|
||||||
|
include(":core")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user