Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
cc4a7c9
feat: 홈 입력창을 포커스에 따라 확장되는 형태로 바꿈
soyeonLee126 Aug 17, 2026
0f421b8
fix: 하단 바 인셋과 입력창 확장 전환에서 어긋나던 부분을 고침
soyeonLee126 Aug 17, 2026
e237959
refactor: 입력창 주변 구성요소를 디자인시스템으로 모으고 중복을 걷어냄
soyeonLee126 Aug 17, 2026
257be7c
test: 길이 제한 안내를 ViewModel 로 옮긴 동작에 맞춰 테스트를 고침
soyeonLee126 Aug 17, 2026
e7963c2
feat: 입력창 기본 상태도 텍스트와 컨트롤을 나눠 놓고, 테두리를 9-slice 로 그림
soyeonLee126 Aug 17, 2026
cf24725
fix: 입력창 좌우 여백을 20dp 로 통일
soyeonLee126 Aug 17, 2026
5c836ef
design: 손그림 테두리를 Card_Button 아트로 교체
soyeonLee126 Aug 17, 2026
e2547d0
fix: 컨트롤 터치 영역을 48dp 로 넓히고 배경 모서리를 테두리에 맞춤
soyeonLee126 Aug 17, 2026
3631f8e
Merge remote-tracking branch 'origin/develop' into fix/home-ui
soyeonLee126 Aug 18, 2026
428b106
fix: 감정 패널을 뒤로가기와 바깥 탭으로 닫고 키보드를 피함
soyeonLee126 Aug 18, 2026
48dba6e
fix: 입력창 줄 높이를 글꼴 배율에 맞춰 계산
soyeonLee126 Aug 18, 2026
f7f679f
fix: 토글 라벨 밀림을 바로잡고 9-slice 프레임 할당을 없앰
soyeonLee126 Aug 18, 2026
edbe3a7
design: 입력창 테두리를 Figma 원본 아트로 되돌림
soyeonLee126 Aug 18, 2026
05b265b
fix: 감정 패널이 셰브론으로 안 접히던 문제와 위치를 바로잡음
soyeonLee126 Aug 18, 2026
b51883d
refactor: 최소 터치 크기를 디자인시스템 토큰으로 모음
soyeonLee126 Aug 18, 2026
bd114ca
refactor: 입력창 높이를 텍스트 실측으로 계산해 lineCount 를 없앰
soyeonLee126 Aug 18, 2026
4051449
refactor: 토글의 전경색 강제를 contentColor 로 뺌
soyeonLee126 Aug 18, 2026
07f043f
refactor: 길이 초과 안내를 상태에서 유도해 lengthWarned 를 없앰
soyeonLee126 Aug 18, 2026
9415ac3
chore: 코드가 이미 말하는 주석을 걷어냄
soyeonLee126 Aug 18, 2026
2d51580
design: 포커스 상태 테두리 아트를 넣고 입력창 높이를 시안 값으로 맞춤
soyeonLee126 Aug 19, 2026
586689d
fix: 홈 세로 배치 가중치를 입력창 112dp 기준으로 다시 잡음
soyeonLee126 Aug 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ fun MainScreen(

ModelDownloadConfirmationEffect(modelDownloadPromptViewModel, snackbarHostState)

// 배경/탭바 에셋이 라이트 전용이라 다크 시안이 나올 때까지 셸은 라이트로 고정한다.
// 종이 배경과 손그림 에셋이 라이트 전용이라 다크 시안이 나올 때까지 셸은 라이트로 고정한다.
GamssTheme(darkTheme = false) {
// 종이 보드가 상태바와 탭바 뒤까지 이어져야 해서 Scaffold 바깥에 깐다.
GamssPaperBackground {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,35 @@
package com.gamss.android.core.designsystem.component

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
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.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.selection.selectable
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import com.gamss.android.core.designsystem.R
import com.gamss.android.core.designsystem.theme.GamssTheme

// 손그림 테두리는 path 조각이 500여 개라 VectorDrawable 로 넣으면 aapt 문자열 한도를 넘겨 STRING_TOO_LARGE 로 잘린다. 배경만 3배율 PNG 로 둔다.
// 높이는 디자인 62dp 에 에셋의 stroke 여백 2dp 를 더한 값.
private val BottomBarHeight = 64.dp
private val BottomBarHorizontalMargin = 20.dp
private val BottomBarBottomMargin = 8.dp
private val ItemRowHorizontalPadding = 53.dp
private val ItemIconSize = 24.dp
private val BottomBarHeight = 66.dp
private val ItemRowWidth = 255.dp
private val ItemRowHeight = 44.dp
private val ItemIconSize = 26.dp
private val ItemLabelGap = 4.dp
private val BottomBarStrokeWidth = 1.dp

/** 화면이 edge-to-edge 라 시스템 내비게이션 영역은 이 컴포넌트가 직접 피한다. */
@Composable
Expand All @@ -42,23 +39,24 @@ fun <T> GamssBottomBar(
onItemClick: (T) -> Unit,
modifier: Modifier = Modifier,
) {
val strokeColor = GamssTheme.colors.gray200
Box(
modifier = modifier
.fillMaxWidth()
// 배경과 구분선을 인셋보다 바깥에 둬야 내비게이션 영역까지 흰색이 깔린다.
.background(GamssTheme.colors.white)
.drawBehind {
// 화면 폭을 꽉 채우는 바라 좌우·아래 선은 화면 테두리에 붙어 버린다. 위쪽만 긋는다.
drawRect(color = strokeColor, size = Size(size.width, BottomBarStrokeWidth.toPx()))
}
.navigationBarsPadding()
.padding(horizontal = BottomBarHorizontalMargin, vertical = BottomBarBottomMargin)
.height(BottomBarHeight),
) {
Image(
painter = painterResource(R.drawable.bg_tab_bar),
contentDescription = null,
contentScale = ContentScale.FillBounds,
modifier = Modifier.fillMaxSize(),
)
Row(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = ItemRowHorizontalPadding),
.width(ItemRowWidth)
.height(ItemRowHeight)
.align(Alignment.Center),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
Expand All @@ -80,7 +78,7 @@ private fun <T> BottomBarItem(
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
val contentColor = if (selected) GamssTheme.colors.gray900 else GamssTheme.colors.gray300
val contentColor = if (selected) GamssTheme.colors.gray900 else GamssTheme.colors.gray400
val interactionSource = remember { MutableInteractionSource() }

Column(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.gamss.android.core.designsystem.component

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
Expand All @@ -12,16 +10,13 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.selection.toggleable
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
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.res.painterResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import com.gamss.android.core.designsystem.theme.GamssRadius
import com.gamss.android.core.designsystem.theme.GamssTheme

// Figma 노드 3331:3950 의 auto layout 값. 패널 211x94(hug), 패딩 20, 3x2 그리드, 간격 18.
Expand All @@ -35,7 +30,6 @@ private val ItemWidth = 45.dp
private val ItemMinHeight = 18.dp
private val IndicatorSize = 18.dp
private val IndicatorLabelGap = 2.dp
private val PanelBorderWidth = 1.dp
private const val COLUMNS = 3

/** 반응할 캐릭터를 고르는 패널. 한 줄에 [COLUMNS] 개씩 끊어 놓는다. */
Expand All @@ -47,9 +41,7 @@ fun <T> GamssCharacterPicker(
) {
Column(
modifier = modifier
.clip(RoundedCornerShape(GamssRadius.radius050))
.background(GamssTheme.colors.white)
.border(PanelBorderWidth, GamssTheme.colors.gray200, RoundedCornerShape(GamssRadius.radius050))
.gamssSketchyBox()
.padding(PickerPadding),
verticalArrangement = Arrangement.spacedBy(PickerGap),
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ private fun GamssInputBarEmptyPreview() {
GamssInputBar(
value = "",
onValueChange = {},
onTrailingClick = {},
onSend = {},
placeholder = "무슨 이야기를 버려볼까요?",
modifier = Modifier.fillMaxWidth(),
)
Expand All @@ -55,7 +55,7 @@ private fun GamssInputBarFilledPreview() {
GamssInputBar(
value = "오늘 발표가 너무 떨려요",
onValueChange = {},
onTrailingClick = {},
onSend = {},
modifier = Modifier.fillMaxWidth(),
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.gamss.android.core.designsystem.component

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import com.gamss.android.core.designsystem.modifier.noRippleClickable
import com.gamss.android.core.designsystem.theme.GamssTheme
import com.gamss.android.core.designsystem.theme.GamssTouchTarget

private val LabelChevronGap = 4.dp
private val ChevronSize = 16.dp
private const val CHEVRON_ROTATION = 90f

// ic_right_chevron 글리프는 24 뷰포트 안에서 치우쳐 있다. 박스 중심으로 돌리면 펼칠 때 위아래로 튄다.
private const val CHEVRON_CENTER_X = 16.85f / 24f
private const val CHEVRON_CENTER_Y = 12.03f / 24f

/** 아래위 셰브론 에셋이 없어 오른쪽 셰브론을 돌려 쓴다. */
@Composable
fun GamssDisclosureToggle(
label: String,
expanded: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier,
contentColor: Color = GamssTheme.colors.gray900,
) {
Row(
modifier = modifier
.heightIn(min = GamssTouchTarget.minimum)
.noRippleClickable(role = Role.DropdownList, onClick = onClick),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(LabelChevronGap),
) {
GamssText(
text = label,
style = GamssTheme.typography.body4Medium,
color = contentColor,
maxLines = 1,
)
Icon(
painter = painterResource(GamssIcons.RightChevron),
contentDescription = null,
tint = contentColor,
modifier = Modifier
.size(ChevronSize)
.graphicsLayer {
rotationZ = if (expanded) -CHEVRON_ROTATION else CHEVRON_ROTATION
transformOrigin = TransformOrigin(CHEVRON_CENTER_X, CHEVRON_CENTER_Y)
},
)
}
}
Loading