-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat/#8] 필드 공통 검포넌트 구현 #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
e3d4191
bcf7af1
8d217df
bc232a8
b79d25e
cd74801
0904355
f8fe6be
d13dfa9
3869aa3
48ba8af
898ff9d
822c0d5
00106e8
853dd67
c32c57f
eb17a11
e20ccf7
ee16ef6
54f1cb0
77bc749
9c45c0b
75a928c
d3779b9
09edfa6
df427b0
c6c4f33
0d641c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| package com.poti.android.core.designsystem.component.field | ||
|
|
||
| import androidx.compose.animation.AnimatedVisibility | ||
| import androidx.compose.animation.core.LinearOutSlowInEasing | ||
| import androidx.compose.animation.core.MutableTransitionState | ||
| import androidx.compose.animation.core.tween | ||
| import androidx.compose.animation.slideInVertically | ||
| import androidx.compose.animation.slideOutVertically | ||
| import androidx.compose.foundation.BorderStroke | ||
| import androidx.compose.foundation.ScrollState | ||
| import androidx.compose.foundation.layout.Column | ||
| import androidx.compose.foundation.layout.ColumnScope | ||
| import androidx.compose.foundation.layout.heightIn | ||
| import androidx.compose.foundation.layout.width | ||
| import androidx.compose.foundation.verticalScroll | ||
| import androidx.compose.material3.Surface | ||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.runtime.remember | ||
| import androidx.compose.ui.Modifier | ||
| import androidx.compose.ui.graphics.Shape | ||
| import androidx.compose.ui.platform.LocalDensity | ||
| import androidx.compose.ui.unit.Dp | ||
| import androidx.compose.ui.unit.DpOffset | ||
| import androidx.compose.ui.unit.IntOffset | ||
| import androidx.compose.ui.unit.IntRect | ||
| import androidx.compose.ui.unit.IntSize | ||
| import androidx.compose.ui.unit.LayoutDirection | ||
| import androidx.compose.ui.window.Popup | ||
| import androidx.compose.ui.window.PopupPositionProvider | ||
| import androidx.compose.ui.window.PopupProperties | ||
|
|
||
| @Composable | ||
| internal fun PotiDropdownMenu( | ||
| expandedState: MutableTransitionState<Boolean>, | ||
| onDismissRequest: () -> Unit, | ||
| parentWidth: Int, | ||
| offset: DpOffset, | ||
| scrollState: ScrollState, | ||
| shape: Shape, | ||
| border: BorderStroke, | ||
doyeon0307 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| maxHeight: Dp?, | ||
| popupProterties: PopupProperties = PopupProperties(), | ||
|
||
| content: @Composable ColumnScope.() -> Unit, | ||
| ) { | ||
| if (expandedState.currentState || expandedState.targetState) { | ||
| val density = LocalDensity.current | ||
| val popupPositionProvider = remember(offset, density) { | ||
| val offsetYPx = with(density) { offset.y.roundToPx() } | ||
| object : PopupPositionProvider { | ||
| override fun calculatePosition( | ||
| anchorBounds: IntRect, | ||
| windowSize: IntSize, | ||
| layoutDirection: LayoutDirection, | ||
| popupContentSize: IntSize, | ||
| ): IntOffset { | ||
| return IntOffset( | ||
| x = anchorBounds.left, | ||
| y = anchorBounds.bottom + offsetYPx | ||
| ) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Popup( | ||
| onDismissRequest = onDismissRequest, | ||
| popupPositionProvider = popupPositionProvider, | ||
| properties = popupProterties, | ||
| ) { | ||
| PotiDropdownMenuContent( | ||
| expandedState = expandedState, | ||
| scrollState = scrollState, | ||
| shape = shape, | ||
| border = border, | ||
| parentWidth = parentWidth, | ||
| maxHeight = maxHeight, | ||
| content = content, | ||
| ) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @Composable | ||
| private fun PotiDropdownMenuContent( | ||
| expandedState: MutableTransitionState<Boolean>, | ||
| scrollState: ScrollState, | ||
| shape: Shape, | ||
| border: BorderStroke?, | ||
| parentWidth: Int, | ||
| maxHeight: Dp?, | ||
| content: @Composable ColumnScope.() -> Unit, | ||
| ) { | ||
| val density = LocalDensity.current | ||
|
|
||
| AnimatedVisibility( | ||
| visibleState = expandedState, | ||
| enter = slideInVertically( | ||
| initialOffsetY = { -it }, | ||
| animationSpec = tween(120, easing = LinearOutSlowInEasing) | ||
| ), | ||
| exit = slideOutVertically( | ||
| targetOffsetY = { -it }, | ||
| animationSpec = tween(75, easing = LinearOutSlowInEasing) | ||
| ) | ||
| ) { | ||
| Surface( | ||
| modifier = Modifier | ||
| .width(with(density) { parentWidth.toDp() }), | ||
| shape = shape, | ||
| border = border, | ||
| ) { | ||
| Column( | ||
| modifier = | ||
| Modifier | ||
| .then( | ||
| when (maxHeight) { | ||
| null -> Modifier | ||
| else -> Modifier.heightIn(max = maxHeight) | ||
| }, | ||
| ) | ||
| .verticalScroll(scrollState), | ||
|
||
| content = content, | ||
| ) | ||
| } | ||
| } | ||
| } | ||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/team-poti/POTI-ANDROID/pull/14/changes#r2685028916
만약
PotiDropdownField가 extand 를 Boolean 으로 관리한다면...expanded: Boolean으로 받고,내부적으로
val expandedState = remember { MutableTransitionState(expanded) }인 형태..?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
죄송하지만 의도를 잘 이해하지 못햇서용..
PotiDropdownField가expandedState대신expanded: Boolean값을 관리하면 좋겠다는 의미인가요?PotiDropdownField에서는 유저 액션에 따라expandedState.target값을 조정합니다.Expanded 상태 관리는
PotiDropdownField에서, 상태에 따른 애니메이션은PotiDropdownMenu에서 처리하는 구조여서 그대로 파라미터로 전달해주도록 구현했어요.