TabbedDialog.kt 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package eu.kanade.presentation.components
  2. import androidx.compose.animation.animateContentSize
  3. import androidx.compose.foundation.layout.Box
  4. import androidx.compose.foundation.layout.Column
  5. import androidx.compose.foundation.layout.ColumnScope
  6. import androidx.compose.foundation.layout.Row
  7. import androidx.compose.foundation.layout.wrapContentSize
  8. import androidx.compose.foundation.pager.PagerState
  9. import androidx.compose.foundation.pager.rememberPagerState
  10. import androidx.compose.material.icons.Icons
  11. import androidx.compose.material.icons.filled.MoreVert
  12. import androidx.compose.material3.HorizontalDivider
  13. import androidx.compose.material3.Icon
  14. import androidx.compose.material3.IconButton
  15. import androidx.compose.material3.MaterialTheme
  16. import androidx.compose.material3.PrimaryTabRow
  17. import androidx.compose.material3.Tab
  18. import androidx.compose.runtime.Composable
  19. import androidx.compose.runtime.getValue
  20. import androidx.compose.runtime.mutableStateOf
  21. import androidx.compose.runtime.remember
  22. import androidx.compose.runtime.rememberCoroutineScope
  23. import androidx.compose.runtime.setValue
  24. import androidx.compose.ui.Alignment
  25. import androidx.compose.ui.Modifier
  26. import androidx.compose.ui.res.stringResource
  27. import androidx.compose.ui.unit.dp
  28. import androidx.compose.ui.util.fastForEachIndexed
  29. import eu.kanade.tachiyomi.R
  30. import kotlinx.coroutines.launch
  31. import tachiyomi.presentation.core.components.HorizontalPager
  32. import tachiyomi.presentation.core.components.material.TabIndicator
  33. import tachiyomi.presentation.core.components.material.TabText
  34. object TabbedDialogPaddings {
  35. val Horizontal = 24.dp
  36. val Vertical = 8.dp
  37. }
  38. @Composable
  39. fun TabbedDialog(
  40. modifier: Modifier = Modifier,
  41. onDismissRequest: () -> Unit,
  42. tabTitles: List<String>,
  43. tabOverflowMenuContent: (@Composable ColumnScope.(() -> Unit) -> Unit)? = null,
  44. pagerState: PagerState = rememberPagerState { tabTitles.size },
  45. content: @Composable (Int) -> Unit,
  46. ) {
  47. AdaptiveSheet(
  48. modifier = modifier,
  49. onDismissRequest = onDismissRequest,
  50. ) {
  51. val scope = rememberCoroutineScope()
  52. Column {
  53. Row {
  54. PrimaryTabRow(
  55. modifier = Modifier.weight(1f),
  56. selectedTabIndex = pagerState.currentPage,
  57. indicator = { TabIndicator(it[pagerState.currentPage], pagerState.currentPageOffsetFraction) },
  58. divider = {},
  59. ) {
  60. tabTitles.fastForEachIndexed { index, tab ->
  61. Tab(
  62. selected = pagerState.currentPage == index,
  63. onClick = { scope.launch { pagerState.animateScrollToPage(index) } },
  64. text = { TabText(text = tab) },
  65. unselectedContentColor = MaterialTheme.colorScheme.onSurface,
  66. )
  67. }
  68. }
  69. tabOverflowMenuContent?.let { MoreMenu(it) }
  70. }
  71. HorizontalDivider()
  72. HorizontalPager(
  73. modifier = Modifier.animateContentSize(),
  74. state = pagerState,
  75. verticalAlignment = Alignment.Top,
  76. ) { page ->
  77. content(page)
  78. }
  79. }
  80. }
  81. }
  82. @Composable
  83. private fun MoreMenu(
  84. content: @Composable ColumnScope.(() -> Unit) -> Unit,
  85. ) {
  86. var expanded by remember { mutableStateOf(false) }
  87. Box(modifier = Modifier.wrapContentSize(Alignment.TopStart)) {
  88. IconButton(onClick = { expanded = true }) {
  89. Icon(
  90. imageVector = Icons.Default.MoreVert,
  91. contentDescription = stringResource(R.string.label_more),
  92. )
  93. }
  94. DropdownMenu(
  95. expanded = expanded,
  96. onDismissRequest = { expanded = false },
  97. ) {
  98. content { expanded = false }
  99. }
  100. }
  101. }