-
Notifications
You must be signed in to change notification settings - Fork 1
PrezelDatePicker 구현 #59
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
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
e9a247b
feat: 커스텀 DatePicker 컴포넌트 구현
HamBeomJoon ad55165
Merge remote-tracking branch 'origin/develop' into feat/#53-prezel-da…
HamBeomJoon 3ce1d48
feat: PrezelDatePicker 구현 및 관련 모델 구조 개선
HamBeomJoon cdb4fcf
refactor: PrezelDatePicker 상태 관리 로직 수정
HamBeomJoon fc7ba56
refactor: PrezelDatePicker 컴포넌트 구조 개선 및 문자열 리소스화
HamBeomJoon 7d157b6
feat: DatePicker 기능 추가 및 스타일 개선
HamBeomJoon bf3059b
refactor: DatePicker 컴포넌트 구조 개선 및 디자인 시스템 테마 적용
HamBeomJoon e41832b
refactor: DatePicker UI 모델 및 스타일 처리 로직 개선
HamBeomJoon 44d561c
refactor: DatePicker UI 컴포넌트 여백 수정 및 미리보기 추가
HamBeomJoon 767af4d
feat: PrezelDatePicker 과거 날짜 비활성화 및 가시성 제어 로직 추가
HamBeomJoon 0bc6d1a
refactor: DatePicker UI 모델의 필드명 변경 및 코드 정리
HamBeomJoon 0269dfc
Merge remote-tracking branch 'origin/develop' into feat/#53-prezel-da…
HamBeomJoon f1ef9a7
feat: PrezelDatePicker 하단 푸터 UI 개선 및 닫기 버튼 추가
HamBeomJoon 9bd4f8b
refactor: PrezelDatePicker 컴포넌트 구조 개선 및 기능 수정
HamBeomJoon ccc14c2
refactor: DatePicker에서 java.time을 kotlinx-datetime으로 마이그레이션
HamBeomJoon 64ae167
refactor: DatePickerModel 파일명을 DayCell로 변경
HamBeomJoon 6000f21
refactor: DatePicker 월 표시 형식에 문자열 리소스 적용
HamBeomJoon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
...main/java/com/team/prezel/core/designsystem/component/datepicker/DatePickerDayCellView.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| package com.team.prezel.core.designsystem.component.datepicker | ||
|
|
||
| import androidx.compose.foundation.background | ||
| import androidx.compose.foundation.clickable | ||
| import androidx.compose.foundation.layout.Box | ||
| import androidx.compose.foundation.layout.Row | ||
| import androidx.compose.foundation.layout.RowScope | ||
| import androidx.compose.foundation.layout.aspectRatio | ||
| import androidx.compose.foundation.layout.padding | ||
| import androidx.compose.foundation.layout.width | ||
| import androidx.compose.foundation.shape.CircleShape | ||
| import androidx.compose.material3.Text | ||
| import androidx.compose.material3.ripple | ||
| 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.Color | ||
| import androidx.compose.ui.unit.dp | ||
| import com.team.prezel.core.designsystem.preview.ThemePreview | ||
| import com.team.prezel.core.designsystem.theme.PrezelTheme | ||
| import kotlinx.datetime.LocalDate | ||
|
|
||
| @Composable | ||
| internal fun RowScope.DayCellView( | ||
| uiModel: DayCell?, | ||
| onClick: () -> Unit, | ||
| ) { | ||
| Box( | ||
| modifier = Modifier | ||
| .weight(1f) | ||
| .aspectRatio(1f) | ||
| .padding(PrezelTheme.spacing.V4) | ||
| .clip(CircleShape) | ||
| .background( | ||
| if (uiModel?.isSelected == true) { | ||
| PrezelTheme.colors.interactiveRegular | ||
| } else { | ||
| Color.Transparent | ||
| }, | ||
| ).clickable( | ||
| indication = ripple(), | ||
| interactionSource = null, | ||
| enabled = uiModel?.isVisible == true, | ||
| onClick = onClick, | ||
| ), | ||
| contentAlignment = Alignment.Center, | ||
| ) { | ||
| if (uiModel == null) return@Box | ||
| if (!uiModel.isVisible) return@Box | ||
|
|
||
| Text( | ||
| text = uiModel.dayText, | ||
| color = uiModel.dayTextColor(), | ||
| style = if (uiModel.isSelected) { | ||
| PrezelTheme.typography.body3Bold | ||
| } else { | ||
| PrezelTheme.typography.body3Medium | ||
| }, | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| @ThemePreview | ||
| @Composable | ||
| private fun DayCellViewPreview() { | ||
| PrezelTheme { | ||
| Row(modifier = Modifier.width(320.dp)) { | ||
| DayCellView( | ||
| uiModel = DayCell( | ||
| date = LocalDate(2024, 1, 1), | ||
| isSelected = false, | ||
| isToday = false, | ||
| isVisible = true, | ||
| ), | ||
| onClick = {}, | ||
| ) | ||
| DayCellView( | ||
| uiModel = DayCell( | ||
| date = LocalDate(2024, 1, 2), | ||
| isSelected = true, | ||
| isToday = false, | ||
| isVisible = true, | ||
| ), | ||
| onClick = {}, | ||
| ) | ||
| DayCellView( | ||
| uiModel = DayCell( | ||
| date = LocalDate(2024, 1, 3), | ||
| isSelected = false, | ||
| isToday = true, | ||
| isVisible = true, | ||
| ), | ||
| onClick = {}, | ||
| ) | ||
| } | ||
| } | ||
| } | ||
14 changes: 14 additions & 0 deletions
14
...m/src/main/java/com/team/prezel/core/designsystem/component/datepicker/DatePickerStyle.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package com.team.prezel.core.designsystem.component.datepicker | ||
|
|
||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.ui.graphics.Color | ||
| import com.team.prezel.core.designsystem.theme.PrezelTheme | ||
|
|
||
| @Composable | ||
| internal fun DayCell.dayTextColor(): Color = | ||
| when { | ||
| this.isSelected -> PrezelTheme.colors.bgRegular | ||
| this.isToday -> PrezelTheme.colors.interactiveRegular | ||
| this.isSunday -> PrezelTheme.colors.accentMagentaRegular | ||
| else -> PrezelTheme.colors.textMedium | ||
| } |
16 changes: 16 additions & 0 deletions
16
...ignsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/DayCell.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.team.prezel.core.designsystem.component.datepicker | ||
|
|
||
| import androidx.compose.runtime.Immutable | ||
| import kotlinx.datetime.DayOfWeek | ||
| import kotlinx.datetime.LocalDate | ||
|
|
||
| @Immutable | ||
| internal data class DayCell( | ||
| val date: LocalDate, | ||
| val isSelected: Boolean, | ||
| val isToday: Boolean, | ||
| val isVisible: Boolean, | ||
| ) { | ||
| val dayText: String = date.day.toString() | ||
| val isSunday: Boolean = date.dayOfWeek == DayOfWeek.SUNDAY | ||
| } |
82 changes: 82 additions & 0 deletions
82
...nsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthGrid.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| package com.team.prezel.core.designsystem.component.datepicker | ||
|
|
||
| import androidx.compose.foundation.layout.Column | ||
| import androidx.compose.foundation.layout.Row | ||
| import androidx.compose.foundation.layout.fillMaxWidth | ||
| import androidx.compose.foundation.layout.padding | ||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.runtime.remember | ||
| import androidx.compose.ui.Modifier | ||
| import com.team.prezel.core.designsystem.preview.ThemePreview | ||
| import com.team.prezel.core.designsystem.theme.PrezelTheme | ||
| import kotlinx.collections.immutable.ImmutableList | ||
| import kotlinx.datetime.DayOfWeek | ||
| import kotlinx.datetime.LocalDate | ||
| import kotlinx.datetime.YearMonth | ||
|
|
||
| @Composable | ||
| internal fun MonthGrid( | ||
|
HamBeomJoon marked this conversation as resolved.
|
||
| yearMonth: YearMonth, | ||
| selectedDate: LocalDate?, | ||
| today: LocalDate, | ||
| onSelect: (LocalDate) -> Unit, | ||
| ) { | ||
| val (cells, lastWeek) = remember(yearMonth) { | ||
| val c = buildMonthGrid(yearMonth = yearMonth, firstDayOfWeek = DayOfWeek.SUNDAY) | ||
| c to lastWeekIndexToRender(c) | ||
| } | ||
|
|
||
| Column(modifier = Modifier.padding(top = PrezelTheme.spacing.V16)) { | ||
| for (week in 0..lastWeek) { | ||
| WeekRow(cells = cells, week = week, selectedDate = selectedDate, today = today, onSelect = onSelect) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @Composable | ||
| private fun WeekRow( | ||
| cells: ImmutableList<LocalDate?>, | ||
| week: Int, | ||
| selectedDate: LocalDate?, | ||
| today: LocalDate, | ||
| onSelect: (LocalDate) -> Unit, | ||
| ) { | ||
| Row(modifier = Modifier.fillMaxWidth()) { | ||
| for (day in 0 until 7) { | ||
| val date = cells[week * 7 + day] | ||
|
|
||
| if (date == null) { | ||
| DayCellView( | ||
| uiModel = null, | ||
| ) { } | ||
| continue | ||
| } | ||
|
|
||
| val isPast = date < today | ||
| val uiModel = DayCell( | ||
| date = date, | ||
| isSelected = date == selectedDate, | ||
| isToday = date == today, | ||
| isVisible = !isPast, | ||
| ) | ||
|
|
||
| DayCellView( | ||
| uiModel = uiModel, | ||
| onClick = { onSelect(date) }, | ||
| ) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @ThemePreview | ||
| @Composable | ||
| private fun MonthGridPreview() { | ||
| PrezelTheme { | ||
| MonthGrid( | ||
| yearMonth = YearMonth(year = 2026, month = 2), | ||
| selectedDate = LocalDate(year = 2026, month = 2, day = 26), | ||
| today = LocalDate(year = 2026, month = 2, day = 25), | ||
| onSelect = {}, | ||
| ) | ||
| } | ||
| } | ||
40 changes: 40 additions & 0 deletions
40
.../src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthGridBuilder.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| package com.team.prezel.core.designsystem.component.datepicker | ||
|
|
||
| import kotlinx.collections.immutable.ImmutableList | ||
| import kotlinx.collections.immutable.toPersistentList | ||
| import kotlinx.datetime.DayOfWeek | ||
| import kotlinx.datetime.LocalDate | ||
| import kotlinx.datetime.YearMonth | ||
| import kotlinx.datetime.isoDayNumber | ||
| import kotlinx.datetime.onDay | ||
|
|
||
| internal fun buildMonthGrid( | ||
| yearMonth: YearMonth, | ||
| firstDayOfWeek: DayOfWeek, | ||
| ): ImmutableList<LocalDate?> { | ||
| val firstOfMonth = yearMonth.onDay(1) | ||
| val lastDay = yearMonth.numberOfDays | ||
|
|
||
| val shift = ((firstOfMonth.dayOfWeek.isoDayNumber - firstDayOfWeek.isoDayNumber) + 7) % 7 | ||
| val totalCells = 42 | ||
|
|
||
| return (0 until totalCells) | ||
| .map { index -> | ||
| val dayNumber = index - shift + 1 | ||
| if (dayNumber in 1..lastDay) { | ||
| yearMonth.onDay(dayNumber) | ||
| } else { | ||
| null | ||
| } | ||
| }.toPersistentList() | ||
| } | ||
|
|
||
| internal fun lastWeekIndexToRender(cells: List<LocalDate?>): Int { | ||
| // 마지막으로 실제 날짜가 존재하는 셀 인덱스 (0..41) | ||
| val last = cells.indexOfLast { it != null } | ||
| // month가 비정상일 경우 방어 | ||
| if (last < 0) return 0 | ||
|
|
||
| // 주 단위로 올림 → 마지막 날짜가 포함된 주 index (0..5) | ||
| return (last / 7).coerceIn(0, 5) | ||
| } |
56 changes: 56 additions & 0 deletions
56
...stem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthSection.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| package com.team.prezel.core.designsystem.component.datepicker | ||
|
|
||
| import androidx.compose.foundation.layout.Column | ||
| import androidx.compose.foundation.layout.padding | ||
| import androidx.compose.material3.Text | ||
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.ui.Modifier | ||
| import androidx.compose.ui.res.stringResource | ||
| import com.team.prezel.core.designsystem.R | ||
| import com.team.prezel.core.designsystem.preview.ThemePreview | ||
| import com.team.prezel.core.designsystem.theme.PrezelTheme | ||
| import kotlinx.datetime.LocalDate | ||
| import kotlinx.datetime.YearMonth | ||
| import kotlinx.datetime.number | ||
|
|
||
| @Composable | ||
| internal fun MonthSection( | ||
|
HamBeomJoon marked this conversation as resolved.
|
||
| yearMonth: YearMonth, | ||
| selectedDate: LocalDate?, | ||
| today: LocalDate, | ||
| onSelect: (LocalDate) -> Unit, | ||
| ) { | ||
| Column( | ||
| modifier = Modifier.padding(PrezelTheme.spacing.V20), | ||
| ) { | ||
| Text( | ||
| text = stringResource( | ||
| id = R.string.core_designsystem_date_picker_month_title, | ||
| yearMonth.year, | ||
| yearMonth.month.number, | ||
| ), | ||
| color = PrezelTheme.colors.textLarge, | ||
| style = PrezelTheme.typography.body3Medium, | ||
| ) | ||
|
HamBeomJoon marked this conversation as resolved.
|
||
|
|
||
| MonthGrid( | ||
| yearMonth = yearMonth, | ||
| selectedDate = selectedDate, | ||
| today = today, | ||
| onSelect = onSelect, | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| @ThemePreview | ||
| @Composable | ||
| private fun MonthSectionPreview() { | ||
| PrezelTheme { | ||
| MonthSection( | ||
| yearMonth = YearMonth(year = 2026, month = 2), | ||
| selectedDate = LocalDate(year = 2026, month = 2, day = 26), | ||
| today = LocalDate(year = 2026, month = 2, day = 25), | ||
| onSelect = {}, | ||
| ) | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.