WojciechOsak / Calendar

Kotlin Multiplatform Calendar Library
Apache License 2.0
68 stars 3 forks source link

[Feature] Items on every date #6

Closed hasanelfalakiy closed 1 month ago

hasanelfalakiy commented 1 month ago

Can you please add a feature so that I can add calendar models other than international calendars, like this photo, there are 3 calendar models besides the international calendar, the expectation is that there are 4 indicators in each date box so that users like me can enter other types of calendars, thank you IMG-20231212-WA0031-792049887

WojciechOsak commented 1 month ago

Hey @hasanelfalakiy , by looking at provided image I believe that you already can do above calendar with current library.

For example with such code you can get:


val startDate = LocalDate.today()
        val calendarAnimator by remember { mutableStateOf(CalendarAnimator(startDate)) }
        Column {
            HorizontalCalendarView(
                startDate = startDate,
                calendarAnimator = calendarAnimator
            ) { monthOffset ->
                val state = rememberCalendarState(
                    startDate = startDate,
                    monthOffset = monthOffset,
                )
                CalendarView(
                    day = { dayState ->
                        Column(horizontalAlignment = Alignment.CenterHorizontally) {
                            Text(dayState.date.dayOfMonth.toString(), fontSize = 15.sp)
                            Text("2nd line", fontSize = 10.sp)
                        }
                    },
                    config = state,
                    header = { month, year ->
                        Row(
                            horizontalArrangement = Arrangement.SpaceBetween,
                            modifier = Modifier.fillMaxWidth()
                        ) {
                            Button(onClick = {
                                val currentConfig = state.value
                                state.value = state.value.copy(
                                    monthYear = currentConfig.monthYear.toLocalDate()
                                        .minus(1, DateTimeUnit.MONTH).toMonthYear()
                                )
                            }) {
                                Text("<")
                            }
                            Text(
                                text = month.name,
                                fontSize = 20.sp,
                                textAlign = TextAlign.Center,
                                color = Color.Blue,
                            )
                            Button(onClick = {
                                val currentConfig = state.value
                                state.value = state.value.copy(
                                    monthYear = currentConfig.monthYear.toLocalDate()
                                        .plus(1, DateTimeUnit.MONTH).toMonthYear()
                                )
                            }) {
                                Text(">")
                            }
                        }
                    },
                    dayOfWeekLabel = { dayOfWeek ->
                        Text(
                            dayOfWeek.toString().substring(IntRange(0, 2)),
                            textAlign = TextAlign.Center,
                            modifier = Modifier.background(Color.Red, shape = RoundedCornerShape(50.dp))
                        )
                    },
                )
            }
        }
image

So with day composable you declare how single day cell looks like. With header composable you declare whole header with custom buttons and text above calendar view. dayOfWeekLabel is used to declare single "mon/tue/etc." cells that defines each week day.


Is it what you are looking for @hasanelfalakiy ?

hasanelfalakiy commented 1 month ago

Hey @hasanelfalakiy , by looking at provided image I believe that you already can do above calendar with current library.

For example with such code you can get:


val startDate = LocalDate.today()
      val calendarAnimator by remember { mutableStateOf(CalendarAnimator(startDate)) }
      Column {
          HorizontalCalendarView(
              startDate = startDate,
              calendarAnimator = calendarAnimator
          ) { monthOffset ->
              val state = rememberCalendarState(
                  startDate = startDate,
                  monthOffset = monthOffset,
              )
              CalendarView(
                  day = { dayState ->
                      Column(horizontalAlignment = Alignment.CenterHorizontally) {
                          Text(dayState.date.dayOfMonth.toString(), fontSize = 15.sp)
                          Text("2nd line", fontSize = 10.sp)
                      }
                  },
                  config = state,
                  header = { month, year ->
                      Row(
                          horizontalArrangement = Arrangement.SpaceBetween,
                          modifier = Modifier.fillMaxWidth()
                      ) {
                          Button(onClick = {
                              val currentConfig = state.value
                              state.value = state.value.copy(
                                  monthYear = currentConfig.monthYear.toLocalDate()
                                      .minus(1, DateTimeUnit.MONTH).toMonthYear()
                              )
                          }) {
                              Text("<")
                          }
                          Text(
                              text = month.name,
                              fontSize = 20.sp,
                              textAlign = TextAlign.Center,
                              color = Color.Blue,
                          )
                          Button(onClick = {
                              val currentConfig = state.value
                              state.value = state.value.copy(
                                  monthYear = currentConfig.monthYear.toLocalDate()
                                      .plus(1, DateTimeUnit.MONTH).toMonthYear()
                              )
                          }) {
                              Text(">")
                          }
                      }
                  },
                  dayOfWeekLabel = { dayOfWeek ->
                      Text(
                          dayOfWeek.toString().substring(IntRange(0, 2)),
                          textAlign = TextAlign.Center,
                          modifier = Modifier.background(Color.Red, shape = RoundedCornerShape(50.dp))
                      )
                  },
              )
          }
      }
image

So with day composable you declare how single day cell looks like. With header composable you declare whole header with custom buttons and text above calendar view. dayOfWeekLabel is used to declare single "mon/tue/etc." cells that defines each week day.


Is it what you are looking for @hasanelfalakiy ?

Almost, but like this what I mean is that as I circled there are 4 labels which I mean to fill the Javanese, Hijri, Pasaran (string), & Chinese calendars, the places are as I circled In this picture:IMG_20240527_063154.jpg

WojciechOsak commented 1 month ago

@hasanelfalakiy you can define such tile with all places you mentioned inside of "day" composable. For example:

day = { dayState ->
                        Box(
                            Modifier.requiredHeight(50.dp).border(1.dp, Color.Black).padding(6.dp)
                        ) {
                            Text(
                                dayState.date.dayOfMonth.toString(),
                                fontSize = 18.sp,
                                textAlign = TextAlign.Center,
                                modifier = Modifier.fillMaxSize()
                                    .align(Alignment.Center)
                            )

                            Row(
                                horizontalArrangement = Arrangement.SpaceBetween,
                                modifier = Modifier.fillMaxWidth()
                            ) {
                                Text("X", fontSize = 10.sp)
                                Text("Y", fontSize = 10.sp)
                            }
                            Row(
                                horizontalArrangement = Arrangement.SpaceBetween,
                                modifier = Modifier.fillMaxSize()
                                    .align(Alignment.BottomCenter)
                            ) {
                                Text(
                                    "18",
                                    fontSize = 10.sp,
                                    modifier = Modifier.align(Alignment.Bottom)
                                )
                                Text(
                                    "P",
                                    fontSize = 10.sp,
                                    modifier = Modifier.align(Alignment.Bottom)
                                )
                            }
                        }
                    },

with such code you will got such effect:

image

So you need define such tile composable inside of "day" parameter. Does it help @hasanelfalakiy ? Or if not what change exactly you would expect from my side in library ?

hasanelfalakiy commented 1 month ago

@hasanelfalakiy you can define such tile with all places you mentioned inside of "day" composable. For example:

day = { dayState ->
                      Box(
                          Modifier.requiredHeight(50.dp).border(1.dp, Color.Black).padding(6.dp)
                      ) {
                          Text(
                              dayState.date.dayOfMonth.toString(),
                              fontSize = 18.sp,
                              textAlign = TextAlign.Center,
                              modifier = Modifier.fillMaxSize()
                                  .align(Alignment.Center)
                          )

                          Row(
                              horizontalArrangement = Arrangement.SpaceBetween,
                              modifier = Modifier.fillMaxWidth()
                          ) {
                              Text("X", fontSize = 10.sp)
                              Text("Y", fontSize = 10.sp)
                          }
                          Row(
                              horizontalArrangement = Arrangement.SpaceBetween,
                              modifier = Modifier.fillMaxSize()
                                  .align(Alignment.BottomCenter)
                          ) {
                              Text(
                                  "18",
                                  fontSize = 10.sp,
                                  modifier = Modifier.align(Alignment.Bottom)
                              )
                              Text(
                                  "P",
                                  fontSize = 10.sp,
                                  modifier = Modifier.align(Alignment.Bottom)
                              )
                          }
                      }
                  },

with such code you will got such effect:

image

So you need define such tile composable inside of "day" parameter. Does it help @hasanelfalakiy ? Or if not what change exactly you would expect from my side in library ?

Nice, It turns out it's available, yes this is what I meant, thank you sir