TabbedDialog.kt 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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.TabText
  33. object TabbedDialogPaddings {
  34. val Horizontal = 24.dp
  35. val Vertical = 8.dp
  36. }
  37. @Composable
  38. fun TabbedDialog(
  39. modifier: Modifier = Modifier,
  40. onDismissRequest: () -> Unit,
  41. tabTitles: List<String>,
  42. tabOverflowMenuContent: (@Composable ColumnScope.(() -> Unit) -> Unit)? = null,
  43. pagerState: PagerState = rememberPagerState { tabTitles.size },
  44. content: @Composable (Int) -> Unit,
  45. ) {
  46. AdaptiveSheet(
  47. modifier = modifier,
  48. onDismissRequest = onDismissRequest,
  49. ) {
  50. val scope = rememberCoroutineScope()
  51. Column {
  52. Row {
  53. PrimaryTabRow(
  54. modifier = Modifier.weight(1f),
  55. selectedTabIndex = pagerState.currentPage,
  56. divider = {},
  57. ) {
  58. tabTitles.fastForEachIndexed { index, tab ->
  59. Tab(
  60. selected = pagerState.currentPage == index,
  61. onClick = { scope.launch { pagerState.animateScrollToPage(index) } },
  62. text = { TabText(text = tab) },
  63. unselectedContentColor = MaterialTheme.colorScheme.onSurface,
  64. )
  65. }
  66. }
  67. tabOverflowMenuContent?.let { MoreMenu(it) }
  68. }
  69. HorizontalDivider()
  70. HorizontalPager(
  71. modifier = Modifier.animateContentSize(),
  72. state = pagerState,
  73. verticalAlignment = Alignment.Top,
  74. ) { page ->
  75. content(page)
  76. }
  77. }
  78. }
  79. }
  80. @Composable
  81. private fun MoreMenu(
  82. content: @Composable ColumnScope.(() -> Unit) -> Unit,
  83. ) {
  84. var expanded by remember { mutableStateOf(false) }
  85. Box(modifier = Modifier.wrapContentSize(Alignment.TopStart)) {
  86. IconButton(onClick = { expanded = true }) {
  87. Icon(
  88. imageVector = Icons.Default.MoreVert,
  89. contentDescription = stringResource(R.string.label_more),
  90. )
  91. }
  92. DropdownMenu(
  93. expanded = expanded,
  94. onDismissRequest = { expanded = false },
  95. ) {
  96. content { expanded = false }
  97. }
  98. }
  99. }