Skip to content

Commit 4cea8a5

Browse files
authored
Dialog 구현 (#21)
* add: dialog * feat: OneButtonDialog content, boxbutton fillMaxWidth 구현 * feat: Dialog 구현 완료 * feat: content padding 수정 * chore: 프리뷰 파일 분리 * chore: 상수값 네이밍 수정 * feat: headline과 X 여백 8dp * feat: scrim 구현 * feat: screen에서 띄우는 preview 추가 * chore: 함수명 수정 * refactor: Radius enum 활용 * chore: Modifier 수정 * chore: 프리뷰 수정 * chore: {} 수정 * chore: 코드리뷰 반영 * chore: 불필요한 패딩 제거 * chore: scrim 컬러 제거
1 parent 07ab728 commit 4cea8a5

File tree

3 files changed

+369
-1
lines changed

3 files changed

+369
-1
lines changed
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package com.yourssu.handy.demo
2+
3+
import androidx.compose.foundation.layout.Arrangement
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.Spacer
6+
import androidx.compose.foundation.layout.fillMaxHeight
7+
import androidx.compose.foundation.layout.fillMaxWidth
8+
import androidx.compose.foundation.layout.height
9+
import androidx.compose.runtime.Composable
10+
import androidx.compose.runtime.getValue
11+
import androidx.compose.runtime.mutableStateOf
12+
import androidx.compose.runtime.remember
13+
import androidx.compose.runtime.setValue
14+
import androidx.compose.ui.Alignment
15+
import androidx.compose.ui.Modifier
16+
import androidx.compose.ui.tooling.preview.Preview
17+
import androidx.compose.ui.unit.dp
18+
import com.yourssu.handy.compose.HandyTheme
19+
import com.yourssu.handy.compose.Icon
20+
import com.yourssu.handy.compose.OneButtonDialog
21+
import com.yourssu.handy.compose.TwoButtonDialog
22+
import com.yourssu.handy.compose.button.BoxButton
23+
import com.yourssu.handy.compose.icons.HandyIcons
24+
import com.yourssu.handy.compose.icons.filled.Add
25+
26+
@Preview
27+
@Composable
28+
private fun OneButtonDialogPreview1() {
29+
HandyTheme {
30+
OneButtonDialog(
31+
title = "제목이 들어갑니다",
32+
description = "내용이 들어갑니다 내용이 들어갑니다 내용이 들어갑니다 내용이 들어갑니다",
33+
positiveText = "버튼",
34+
onPositiveClick = {},
35+
onDismiss = {}
36+
)
37+
}
38+
}
39+
40+
@Preview
41+
@Composable
42+
private fun OneButtonDialogPreview2() {
43+
HandyTheme {
44+
OneButtonDialog(
45+
title = "보다 더 정확하게 분석하기 위해 다음 질문에 대해 대답해주세요.",
46+
description = "내용이 들어갑니다 내용이 들어갑니다 내용이 들어갑니다 내용이 들어갑니다",
47+
positiveText = "버튼",
48+
onPositiveClick = {},
49+
onDismiss = {}
50+
)
51+
}
52+
}
53+
54+
@Preview
55+
@Composable
56+
private fun OneButtonDialogPreview3() {
57+
HandyTheme {
58+
OneButtonDialog(
59+
title = "제목이 들어갑니다",
60+
description = "내용이 들어갑니다 내용이 들어갑니다 내용이 들어갑니다 내용이 들어갑니다",
61+
positiveText = "버튼",
62+
onPositiveClick = {},
63+
onDismiss = {},
64+
content = { Icon(HandyIcons.Filled.Add) }
65+
)
66+
}
67+
}
68+
69+
@Preview
70+
@Composable
71+
private fun TwoButtonDialogPreview1() {
72+
HandyTheme {
73+
TwoButtonDialog(
74+
title = "제목이 들어갑니다",
75+
description = "내용이 들어갑니다 내용이 들어갑니다 내용이 들어갑니다 내용이 들어갑니다",
76+
positiveText = "버튼2",
77+
onPositiveClick = {},
78+
onDismiss = {},
79+
negativeText = "버튼1",
80+
onNegativeClick = {},
81+
)
82+
}
83+
}
84+
85+
@Preview
86+
@Composable
87+
private fun TwoButtonDialogPreview2() {
88+
HandyTheme {
89+
TwoButtonDialog(
90+
title = "보다 더 정확하게 분석하기 위해 다음 질문에 대해 대답해주세요.",
91+
description = "내용이 들어갑니다 내용이 들어갑니다 내용이 들어갑니다 내용이 들어갑니다",
92+
positiveText = "버튼2",
93+
onPositiveClick = {},
94+
onDismiss = {},
95+
negativeText = "버튼1",
96+
onNegativeClick = {},
97+
)
98+
}
99+
}
100+
101+
@Preview
102+
@Composable
103+
private fun TwoButtonDialogPreview3() {
104+
HandyTheme {
105+
TwoButtonDialog(
106+
title = "제목이 들어갑니다",
107+
description = "내용이 들어갑니다 내용이 들어갑니다 내용이 들어갑니다 내용이 들어갑니다",
108+
positiveText = "버튼2",
109+
onPositiveClick = {},
110+
onDismiss = {},
111+
negativeText = "버튼1",
112+
onNegativeClick = {},
113+
content = { Icon(HandyIcons.Filled.Add) }
114+
)
115+
}
116+
}
117+
118+
@Preview
119+
@Composable
120+
private fun DialogOnScreenPreview() {
121+
122+
var showOneButtonDialog by remember { mutableStateOf(false) }
123+
var showTwoButtonDialog by remember { mutableStateOf(false) }
124+
125+
HandyTheme {
126+
Column(
127+
horizontalAlignment = Alignment.CenterHorizontally,
128+
verticalArrangement = Arrangement.Center,
129+
modifier = Modifier
130+
.fillMaxWidth()
131+
.fillMaxHeight()
132+
) {
133+
BoxButton(text = "원버튼 다이알로그", onClick = { showOneButtonDialog = true })
134+
Spacer(modifier = Modifier.height(10.dp))
135+
BoxButton(text = "투버튼 다이알로그", onClick = { showTwoButtonDialog = true })
136+
}
137+
138+
if (showOneButtonDialog) {
139+
OneButtonDialog(
140+
title = "제목이 들어갑니다",
141+
description = "내용",
142+
positiveText = "버튼",
143+
onPositiveClick = { showOneButtonDialog = false },
144+
onDismiss = { showOneButtonDialog = false }
145+
)
146+
} else if (showTwoButtonDialog) {
147+
TwoButtonDialog(
148+
title = "제목이 들어갑니다",
149+
description = "내용",
150+
positiveText = "버튼",
151+
onPositiveClick = { showTwoButtonDialog = false },
152+
onDismiss = { showTwoButtonDialog = false },
153+
negativeText = "버튼",
154+
onNegativeClick = { showTwoButtonDialog = false }
155+
)
156+
}
157+
}
158+
}
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
package com.yourssu.handy.compose
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.clickable
5+
import androidx.compose.foundation.layout.Box
6+
import androidx.compose.foundation.layout.Column
7+
import androidx.compose.foundation.layout.Row
8+
import androidx.compose.foundation.layout.Spacer
9+
import androidx.compose.foundation.layout.fillMaxWidth
10+
import androidx.compose.foundation.layout.height
11+
import androidx.compose.foundation.layout.padding
12+
import androidx.compose.foundation.layout.width
13+
import androidx.compose.foundation.shape.RoundedCornerShape
14+
import androidx.compose.runtime.Composable
15+
import androidx.compose.ui.Alignment
16+
import androidx.compose.ui.Modifier
17+
import androidx.compose.ui.unit.dp
18+
import com.yourssu.handy.compose.DialogDefaults.dialogButtonSpacing
19+
import com.yourssu.handy.compose.DialogDefaults.dialogPadding
20+
import com.yourssu.handy.compose.DialogDefaults.dialogTextInsidePadding
21+
import com.yourssu.handy.compose.DialogDefaults.dialogWidth
22+
import com.yourssu.handy.compose.button.BoxButton
23+
import com.yourssu.handy.compose.button.BoxButtonSize
24+
import com.yourssu.handy.compose.button.BoxButtonType
25+
import com.yourssu.handy.compose.foundation.HandyTypography
26+
import com.yourssu.handy.compose.foundation.Radius
27+
import com.yourssu.handy.compose.icons.HandyIcons
28+
import com.yourssu.handy.compose.icons.filled.Close
29+
30+
31+
/**
32+
* OneButtonDialog : 선택 버튼이 하나 있는 Dialog 입니다.
33+
*
34+
* @param title Dialog 제목 text
35+
* @param positiveText 확인 버튼 text
36+
* @param onPositiveClick 확인 버튼 클릭 시 실행되는 함수
37+
* @param onDismiss 닫기(X) 버튼 클릭시 실행되는 함수
38+
* @param description Dialog 안의 설명 text (optional)
39+
* @param content Dialog 안의 content. 주로 이미지가 들어감(optional)
40+
**/
41+
@Composable
42+
fun OneButtonDialog(
43+
title: String,
44+
positiveText: String,
45+
onPositiveClick: () -> Unit,
46+
onDismiss: () -> Unit,
47+
modifier: Modifier = Modifier,
48+
description: String?,
49+
content: @Composable (() -> Unit)? = null,
50+
) {
51+
Box(
52+
modifier = modifier
53+
.background(
54+
color = HandyTheme.colors.bgBasicDefault,
55+
shape = RoundedCornerShape(Radius.XL.dp)
56+
)
57+
.width(dialogWidth)
58+
.padding(dialogPadding),
59+
) {
60+
Column {
61+
Row(
62+
modifier = Modifier.fillMaxWidth(),
63+
) {
64+
Text(
65+
text = title,
66+
style = HandyTypography.T1Sb20,
67+
color = HandyTheme.colors.textBasicPrimary,
68+
maxLines = 3,
69+
modifier = Modifier
70+
.weight(1f)
71+
)
72+
73+
Icon(
74+
imageVector = HandyIcons.Filled.Close,
75+
contentDescription = "Close",
76+
modifier = Modifier.clickable { onDismiss() }
77+
)
78+
}
79+
80+
Spacer(modifier = Modifier.height(dialogTextInsidePadding))
81+
82+
if (description != null) {
83+
Text(text = description)
84+
}
85+
86+
Spacer(modifier = Modifier.height(dialogPadding))
87+
88+
if (content != null) {
89+
Box(
90+
modifier = Modifier
91+
.align(Alignment.CenterHorizontally)
92+
.padding(bottom = dialogPadding)
93+
) {
94+
content()
95+
}
96+
}
97+
98+
BoxButton(
99+
modifier = Modifier.fillMaxWidth(),
100+
text = positiveText,
101+
onClick = { onPositiveClick() },
102+
sizeType = BoxButtonSize.L,
103+
)
104+
}
105+
}
106+
}
107+
108+
109+
/**
110+
* TwoButtonDialog : 버튼이 두개 있는 다이알로그 입니다.
111+
*
112+
* @param title Dialog 제목 text
113+
* @param positiveText 확인 버튼 text
114+
* @param negativeText 취소 버튼 text
115+
* @param onPositiveClick 확인 버튼 클릭 시 실행되는 함수
116+
* @param onNegativeClick 취소 버튼 클릭 시 실행되는 함수
117+
* @param onDismiss 닫기(X) 버튼 클릭시 실행되는 함수
118+
* @param description Dialog 안의 설명 text (optional)
119+
* @param content Dialog 안의 content. 주로 이미지가 들어감(optional)
120+
**/
121+
@Composable
122+
fun TwoButtonDialog(
123+
title: String,
124+
positiveText: String,
125+
negativeText: String,
126+
onPositiveClick: () -> Unit,
127+
onNegativeClick: () -> Unit,
128+
onDismiss: () -> Unit,
129+
modifier: Modifier = Modifier,
130+
description: String?,
131+
content: @Composable (() -> Unit)? = null,
132+
) {
133+
Box(
134+
modifier = modifier
135+
.background(
136+
color = HandyTheme.colors.bgBasicDefault,
137+
shape = RoundedCornerShape(Radius.XL.dp)
138+
)
139+
.width(dialogWidth)
140+
.padding(dialogPadding),
141+
) {
142+
Column {
143+
Row(
144+
modifier = Modifier.fillMaxWidth(),
145+
) {
146+
Text(
147+
text = title,
148+
style = HandyTypography.T1Sb20,
149+
color = HandyTheme.colors.textBasicPrimary,
150+
maxLines = 3,
151+
modifier = Modifier
152+
.weight(1f)
153+
)
154+
155+
Icon(
156+
imageVector = HandyIcons.Filled.Close,
157+
contentDescription = "Close",
158+
modifier = Modifier.clickable { onDismiss() }
159+
)
160+
}
161+
162+
Spacer(modifier = Modifier.height(dialogTextInsidePadding))
163+
164+
if (description != null) {
165+
Text(text = description)
166+
}
167+
168+
Spacer(modifier = Modifier.height(dialogPadding))
169+
170+
if (content != null) {
171+
Box(
172+
Modifier
173+
.align(Alignment.CenterHorizontally)
174+
.padding(bottom = dialogPadding)
175+
) {
176+
content()
177+
}
178+
}
179+
180+
Row(
181+
modifier = Modifier.align(Alignment.CenterHorizontally)
182+
) {
183+
BoxButton(
184+
modifier = Modifier.weight(1f),
185+
text = negativeText,
186+
onClick = { onNegativeClick() },
187+
sizeType = BoxButtonSize.L,
188+
buttonType = BoxButtonType.Secondary
189+
)
190+
191+
Spacer(modifier = Modifier.width(dialogButtonSpacing))
192+
193+
BoxButton(
194+
modifier = Modifier.weight(1f),
195+
text = positiveText,
196+
onClick = { onPositiveClick() },
197+
sizeType = BoxButtonSize.L,
198+
)
199+
}
200+
}
201+
}
202+
203+
}
204+
205+
object DialogDefaults {
206+
val dialogWidth = 296.dp
207+
val dialogPadding = 20.dp
208+
val dialogTextInsidePadding = 16.dp
209+
val dialogButtonSpacing = 8.dp
210+
}

compose/src/main/kotlin/com/yourssu/handy/compose/foundation/Radius.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package com.yourssu.handy.compose.foundation
33
import androidx.compose.ui.unit.Dp
44
import androidx.compose.ui.unit.dp
55

6-
enum class Radius(dp: Dp) {
6+
enum class Radius(val dp: Dp) {
77
XS(8.dp),
88
S(10.dp),
99
M(12.dp),

0 commit comments

Comments
 (0)