Skip to content

Commit

Permalink
Donburi/don 1061 configurable year label (#2189)
Browse files Browse the repository at this point in the history
* DON-1061 Add configuration to CalendarParams to show/hide floating year label and year in month label

* DON-1061 Add snap test

* Updated snapshots

* DON-1061 Update documentation

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
henrik-sky and github-actions[bot] authored Jan 29, 2025
1 parent fd01ed9 commit 9809c6a
Show file tree
Hide file tree
Showing 13 changed files with 77 additions and 15 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ import net.skyscanner.backpack.demo.data.CalendarStorySelection
import net.skyscanner.backpack.demo.data.CalendarStorySelection.PreselectedRange
import net.skyscanner.backpack.demo.data.CalendarStoryType
import net.skyscanner.backpack.demo.meta.ComposeStory
import net.skyscanner.backpack.meta.StoryKind
import net.skyscanner.backpack.demo.ui.LocalAutomationMode
import net.skyscanner.backpack.demo.ui.LocalFloatingNotification
import net.skyscanner.backpack.meta.StoryKind

@Composable
@Calendar2Component
Expand Down Expand Up @@ -83,6 +83,12 @@ fun CalendarPreSelectedRange(modifier: Modifier = Modifier) =
fun CalendarSelectionIconLabelStory(modifier: Modifier = Modifier) =
CalendarDemo(CalendarStoryType.WithIconAsLabels, modifier)

@Composable
@Calendar2Component
@ComposeStory("Year in month label no floating year")
fun CalendarNoFloatingYearLabel(modifier: Modifier = Modifier) =
CalendarDemo(CalendarStoryType.YearLabelInMonthHeader, modifier)

@Composable
private fun CalendarDemo(
type: CalendarStoryType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
package net.skyscanner.backpack.demo.data

import net.skyscanner.backpack.R
import kotlin.math.roundToInt
import net.skyscanner.backpack.calendar2.CalendarParams
import net.skyscanner.backpack.calendar2.CalendarSelection
import net.skyscanner.backpack.calendar2.CellInfo
Expand All @@ -32,6 +31,7 @@ import java.time.LocalDate
import java.time.Month
import java.time.Period
import java.time.YearMonth
import kotlin.math.roundToInt

private val now = LocalDate.of(2019, 1, 1)
private val range = now..(now + Period.ofYears(2))
Expand All @@ -45,6 +45,7 @@ enum class CalendarStoryType {
WithLabels,
WithIconAsLabels,
PreselectedRange,
YearLabelInMonthHeader,
;

companion object {
Expand Down Expand Up @@ -143,6 +144,7 @@ enum class CalendarStoryType {
resId = R.drawable.bpk_search_sm,
tint = R.color.bpkCoreAccent,
)

else -> CellLabel.Text("£${(it.dayOfMonth * 2.35f).roundToInt()}")
},
status = when (price) {
Expand All @@ -157,6 +159,13 @@ enum class CalendarStoryType {
)
},
)

YearLabelInMonthHeader -> CalendarParams(
now = now,
range = range,
selectionMode = CalendarParams.SelectionMode.Range(),
yearLabelInMonthHeader = true,
)
}

private fun rangeSelectionModeWithAccessibilityLabels() = CalendarParams.SelectionMode.Range(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ object BpkCalendarTestCases {
),
)

val WithYearInMonthLabel = DefaultRange.copy(
yearLabelInMonthHeader = true,
)

private fun disabledDayOfTheWeekInfo(
range: ClosedRange<LocalDate>,
disabledDayOfWeek: DayOfWeek,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import net.skyscanner.backpack.BpkTestVariant
import net.skyscanner.backpack.Variants
import net.skyscanner.backpack.compose.BpkSnapshotTest
import net.skyscanner.backpack.calendar2.BpkCalendarTestCases
import net.skyscanner.backpack.calendar2.CalendarParams
import net.skyscanner.backpack.compose.BpkSnapshotTest
import org.junit.Test

class BpkCalendarTest : BpkSnapshotTest() {
Expand Down Expand Up @@ -147,6 +147,13 @@ class BpkCalendarTest : BpkSnapshotTest() {
snap(controller)
}

@Test
@Variants(BpkTestVariant.Default, BpkTestVariant.DarkMode)
fun withYearInMonthLabel() {
val controller = createController(BpkCalendarTestCases.Params.WithYearInMonthLabel)
snap(controller)
}

private fun snap(controller: BpkCalendarController) =
snap(padding = 0.dp) {
BpkCalendar(controller = controller)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@ class CalendarCellsLayoutTests {
}
}

@Test
fun header_has_year() {
testCalendarWith(
CalendarSettings.Default.copy(
yearLabelInMonthHeader = true,
),
) {
verify {
assertEquals("January 2000", (state.cells[0] as CalendarCell.Header).title)
}
}
}

@Test
fun there_are_leading_spaces_in_month() {
testCalendarWith(CalendarSettings.Default) {
Expand Down Expand Up @@ -134,6 +147,19 @@ class CalendarCellsLayoutTests {
}
}

@Test
fun header_has_year_in_secondary_month() {
testCalendarWith(
CalendarSettings.Default.copy(
yearLabelInMonthHeader = true,
),
) {
verify {
assertEquals("February 2000", (state.cells[43] as CalendarCell.Header).title)
}
}
}

@Test
fun select_whole_month_button_is_shown_when_whole_month_selection_is_enabled() {
val selectableRange =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ package net.skyscanner.backpack.calendar2

import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import java.text.SimpleDateFormat
import java.util.Locale
import net.skyscanner.backpack.calendar2.CalendarParams.MonthSelectionMode
import net.skyscanner.backpack.util.InternalBackpackApi
import java.text.SimpleDateFormat
import java.time.LocalDate
import java.time.YearMonth
import java.time.chrono.IsoChronology
import java.time.format.DateTimeFormatterBuilder
import java.time.format.FormatStyle
import java.time.format.TextStyle
import java.time.temporal.WeekFields
import java.util.Locale

/**
* Describes the calendar configuration.
Expand All @@ -44,6 +44,7 @@ import java.time.temporal.WeekFields
* @param dayOfWeekText [TextStyle] to format days of week in calendar header. Beware of the fact that some Chinese languages may require SHORT style instead of NARROW.
* @param now [LocalDate] a date for the calendar to consider as current
* @param monthSelectionMode [MonthSelectionMode] setting describing the month selection behaviour
* @param yearLabelInMonthHeader [Boolean] controls whether year is displayed inline with the month name or if the existing floating version is used
*/
@Immutable
data class CalendarParams(
Expand All @@ -55,12 +56,13 @@ data class CalendarParams(
val dateContentDescriptionStyle: FormatStyle = FormatStyle.FULL,
val now: LocalDate = LocalDate.now(),
val monthSelectionMode: MonthSelectionMode = MonthSelectionMode.Disabled,
val yearLabelInMonthHeader: Boolean = false,
) {

@InternalBackpackApi
val weekFields = WeekFields.of(locale)

internal val monthsFormatter = SimpleDateFormat("LLLL", locale)
internal val monthsFormatter = SimpleDateFormat(if (yearLabelInMonthHeader) "LLLL yyyy" else "LLLL", locale)

internal val dateContentDescriptionFormatter = DateTimeFormatterBuilder()
.appendLocalized(dateContentDescriptionStyle, null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import androidx.compose.ui.test.onLast
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollToIndex
import java.util.Locale
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.TestScope
Expand All @@ -45,6 +44,7 @@ import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import java.time.LocalDate
import java.util.Locale

@OptIn(ExperimentalCoroutinesApi::class)
class BpkCalendarTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,15 @@ fun BpkCalendar(
modifier = Modifier.fillMaxSize(),
)

BpkCalendarBadge(
firstVisibleItemYear = controller.firstVisibleItemYear,
params = state.params,
modifier = Modifier
.align(Alignment.TopCenter)
.padding(top = BpkSpacing.Base),
)
if (!state.params.yearLabelInMonthHeader) {
BpkCalendarBadge(
firstVisibleItemYear = controller.firstVisibleItemYear,
params = state.params,
modifier = Modifier
.align(Alignment.TopCenter)
.padding(top = BpkSpacing.Base),
)
}
}
}
}
8 changes: 7 additions & 1 deletion docs/compose/Calendar2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
| --- | --- |
| <img src="https://raw.githubusercontent.com/Skyscanner/backpack-android/main/docs/compose/Calendar2/screenshots/day-labels.png" alt="Labeled Calendar2 component" width="375" /> | <img src="https://raw.githubusercontent.com/Skyscanner/backpack-android/main/docs/compose/Calendar2/screenshots/day-labels_dm.png" alt="Labeled Calendar2 component - dark mode" width="375" /> |

## Icon as labeled
## Icon as label

| Day | Night |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
Expand All @@ -29,6 +29,12 @@
| --- | --- |
| <img src="https://raw.githubusercontent.com/Skyscanner/backpack-android/main/docs/compose/Calendar2/screenshots/pre-selected-range.png" alt="Range Calendar2 component" width="375" /> | <img src="https://raw.githubusercontent.com/Skyscanner/backpack-android/main/docs/compose/Calendar2/screenshots/pre-selected-range_dm.png" alt="Range Calendar2 component - dark mode" width="375" /> |

## Year in Month Label, no floating year

| Day | Night |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| <img src="https://raw.githubusercontent.com/Skyscanner/backpack-android/main/docs/compose/Calendar2/screenshots/year-in-month-label-no-floating-year.png" alt="Calendar2 component showing year in month label" width="375" /> | <img src="https://raw.githubusercontent.com/Skyscanner/backpack-android/main/docs/compose/Calendar2/screenshots/year-in-month-label-no-floating-year_dm.png" alt="Calendar2 component showing year in month label - dark mode" width="375" /> |

## Installation

Backpack Android is available through [Maven Central](https://search.maven.org/artifact/net.skyscanner.backpack/backpack-compose). Check the main [Readme](https://github.com/skyscanner/backpack-android#installation) for a complete installation guide.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 9809c6a

Please sign in to comment.