Skip to content

refactor generic CountryCodeBottomSheet and MessengersBottomSheet fo…#2

Open
yibibyte wants to merge 1 commit intocompose-startfrom
sprint-3-practice
Open

refactor generic CountryCodeBottomSheet and MessengersBottomSheet fo…#2
yibibyte wants to merge 1 commit intocompose-startfrom
sprint-3-practice

Conversation

@yibibyte
Copy link
Owner

@yibibyte yibibyte commented Nov 28, 2025

Refactor CountryCodeBottomSheet and MessengersBottomSheet for CommonBottomSheet

Summary by Sourcery

Рефакторинг нижних листов выбора кода страны и мессенджера с использованием общего универсального компонента CommonBottomSheet.

Улучшения:

  • Заменить встроенные реализации ModalBottomSheet в фильтрах кода страны и мессенджеров на повторно используемый компонент CommonBottomSheet.
  • Упростить компонуемые элементы CountryCodeOption и MessengerOption, сделав их статeless и делегировав обработку выбора общей логике нижнего листа.
Original summary in English

Summary by Sourcery

Refactor country code and messenger selection bottom sheets to use a shared generic CommonBottomSheet component.

Enhancements:

  • Replace inlined ModalBottomSheet implementations in country code and messenger filters with the reusable CommonBottomSheet component.
  • Simplify CountryCodeOption and MessengerOption item composables to be stateless, delegating selection handling to the common bottom sheet logic.

@sourcery-ai
Copy link

sourcery-ai bot commented Nov 28, 2025

Руководство для ревьюера

Рефакторинг нижних листов (bottom sheets) с выбором кода страны и мессенджеров: логика разметки и обработки выбора делегирована общему компоненту CommonBottomSheet, благодаря чему опции стали полностью презентационными.

Диаграмма последовательностей обработки выбора через CommonBottomSheet

sequenceDiagram
    actor User
    participant MessengersBottomSheet
    participant CommonBottomSheet
    participant MessengerOption

    User->>MessengersBottomSheet: open filter_by_messaging_app
    MessengersBottomSheet->>CommonBottomSheet: render(title, items, selectedItems, onItemsSelected, onDismiss, itemContent)
    loop for each MessagingApp
        CommonBottomSheet->>MessengerOption: render(app, isSelected)
    end

    User->>CommonBottomSheet: tap app row or checkbox
    CommonBottomSheet->>CommonBottomSheet: compute newSelection
    CommonBottomSheet-->>MessengersBottomSheet: onItemsSelected(newSelection)
    MessengersBottomSheet-->>User: sheet shows updated selection state
Loading

Изменения на уровне файлов

Изменение Подробности Файлы
Заменена специализированная реализация MessengersBottomSheet на реализацию на базе CommonBottomSheet.
  • Удалены встроенный ModalBottomSheet, строка заголовка и рендеринг элементов LazyColumn — вместо этого логика делегирована в CommonBottomSheet
  • В CommonBottomSheet передаются MessagingApp.entries, текущий выбор и колбэк выбора вместе с локализованным заголовком и обработчиком закрытия
  • MessengerOption упрощён до полностью презентационной строки, которая больше не управляет выбором и обработкой кликов; его Checkbox сделан только для чтения через null в onCheckedChange
app/src/main/java/ru/yandex/practicum/contacts/presentation/messengers/MessengersBottomSheet.kt
Заменена специализированная реализация CountryCodeBottomSheet на реализацию на базе CommonBottomSheet.
  • Удалены встроенный ModalBottomSheet, строка заголовка и рендеринг элементов LazyColumn — вместо этого логика делегирована в CommonBottomSheet
  • В CommonBottomSheet передаются CountryCode.COMMON_CODES, текущий выбор и колбэк выбора вместе с локализованным заголовком и обработчиком закрытия
  • CountryCodeOption упрощён до полностью презентационной строки, которая больше не управляет выбором и обработкой кликов; его Checkbox сделан только для чтения через null в onCheckedChange
app/src/main/java/ru/yandex/practicum/contacts/presentation/country/CountryCodeBottomSheet.kt

Подсказки и команды

Взаимодействие с Sourcery

  • Запустить новое ревью: Оставьте комментарий @sourcery-ai review в pull request.
  • Продолжать обсуждения: Отвечайте напрямую на комментарии ревью от Sourcery.
  • Создать задачу GitHub из комментария к ревью: Попросите Sourcery создать
    issue из комментария к ревью, ответив на него. Также можно ответить на
    комментарий к ревью с @sourcery-ai issue, чтобы создать issue из этого комментария.
  • Сгенерировать заголовок pull request: Напишите @sourcery-ai в любом месте
    заголовка pull request, чтобы сгенерировать заголовок в любой момент. Можно также
    оставить комментарий @sourcery-ai title в pull request, чтобы (пере)сгенерировать заголовок в любой момент.
  • Сгенерировать краткое описание pull request: Напишите @sourcery-ai summary в любом месте
    тела pull request, чтобы сгенерировать описание PR в нужном месте. Можно также
    оставить комментарий @sourcery-ai summary в pull request, чтобы (пере)сгенерировать
    краткое описание в любой момент.
  • Сгенерировать руководство для ревьюера: Оставьте комментарий @sourcery-ai guide в pull request,
    чтобы (пере)сгенерировать руководство для ревьюера в любой момент.
  • Закрыть все комментарии Sourcery: Оставьте комментарий @sourcery-ai resolve в pull request,
    чтобы пометить все комментарии Sourcery как решённые. Полезно, если вы уже
    исправили все замечания и больше не хотите их видеть.
  • Отклонить все ревью от Sourcery: Оставьте комментарий @sourcery-ai dismiss в pull request,
    чтобы отклонить все существующие ревью от Sourcery. Особенно полезно, если вы
    хотите начать с чистого листа — не забудьте потом оставить комментарий
    @sourcery-ai review, чтобы запустить новое ревью!

Настройка работы

Зайдите в свою панель управления, чтобы:

  • Включать или отключать функции ревью, такие как автоматически
    сгенерированное Sourcery краткое описание pull request, руководство для ревьюера и другие.
  • Изменить язык ревью.
  • Добавлять, удалять или редактировать пользовательские инструкции для ревью.
  • Настроить другие параметры ревью.

Получение помощи

Original review guide in English

Reviewer's Guide

Refactors the country code and messengers filter bottom sheets to delegate layout and selection handling to a shared CommonBottomSheet component, simplifying the option composables to be purely presentational.

Sequence diagram for selection handling via CommonBottomSheet

sequenceDiagram
    actor User
    participant MessengersBottomSheet
    participant CommonBottomSheet
    participant MessengerOption

    User->>MessengersBottomSheet: open filter_by_messaging_app
    MessengersBottomSheet->>CommonBottomSheet: render(title, items, selectedItems, onItemsSelected, onDismiss, itemContent)
    loop for each MessagingApp
        CommonBottomSheet->>MessengerOption: render(app, isSelected)
    end

    User->>CommonBottomSheet: tap app row or checkbox
    CommonBottomSheet->>CommonBottomSheet: compute newSelection
    CommonBottomSheet-->>MessengersBottomSheet: onItemsSelected(newSelection)
    MessengersBottomSheet-->>User: sheet shows updated selection state
Loading

File-Level Changes

Change Details Files
Replace bespoke MessengersBottomSheet implementation with CommonBottomSheet-based implementation.
  • Removed inline ModalBottomSheet, header row, and LazyColumn item rendering in favor of delegating to CommonBottomSheet
  • Pass MessagingApp.entries, current selection, and selection callback into CommonBottomSheet along with localized title and dismiss handler
  • Simplified MessengerOption to a purely presentational row that no longer manages selection or click handling, and made its Checkbox read-only via null onCheckedChange
app/src/main/java/ru/yandex/practicum/contacts/presentation/messengers/MessengersBottomSheet.kt
Replace bespoke CountryCodeBottomSheet implementation with CommonBottomSheet-based implementation.
  • Removed inline ModalBottomSheet, header row, and LazyColumn item rendering in favor of delegating to CommonBottomSheet
  • Pass CountryCode.COMMON_CODES, current selection, and selection callback into CommonBottomSheet along with localized title and dismiss handler
  • Simplified CountryCodeOption to a purely presentational row that no longer manages selection or click handling, and made its Checkbox read-only via null onCheckedChange
app/src/main/java/ru/yandex/practicum/contacts/presentation/country/CountryCodeBottomSheet.kt

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Привет! Я посмотрел твои изменения — вот немного обратной связи:

  • Теперь, когда Checkbox использует onCheckedChange = null и полагается на обработчик клика родительского элемента, стоит добавить подходящий Modifier.selectable/семантику к строке (или снова включить клик по Checkbox), чтобы сохранить доступность и предсказуемость для пользователей, которые ожидают нажимать непосредственно на чекбокс.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Now that `Checkbox` uses `onCheckedChange = null` and relies on the parent click handler, consider adding appropriate `Modifier.selectable`/semantics to the row (or re-enabling Checkbox click) to preserve accessibility and discoverability for users who expect to tap directly on the checkbox.

## Individual Comments

### Comment 1
<location> `app/src/main/java/ru/yandex/practicum/contacts/presentation/messengers/MessengersBottomSheet.kt:50-52` </location>
<code_context>
     ) {
         Checkbox(
             checked = isSelected,
-            onCheckedChange = { checked ->
-                val newSelection = selectedCodes.toMutableSet()
-                if (checked) {
-                    newSelection.add(countryCode)
-                } else {
-                    newSelection.remove(countryCode)
-                }
-                onCodesSelected(newSelection)
-            }
+            onCheckedChange = null
         )
         Spacer(modifier = Modifier.width(16.dp))
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Wire the checkbox to the same selection handler used by the parent for better accessibility and UX.

The checkbox appears selected but is not directly interactive (`onCheckedChange = null`), so only the parent row in `CommonBottomSheet` toggles the state. This can confuse users and assistive technologies that expect the checkbox itself to handle taps. Please pass the same toggle lambda used in `CommonBottomSheet` down to `MessengerOption` and connect it to `onCheckedChange`, or alternatively make the row `Modifier.toggleable` with `role = Role.Checkbox` so accessibility tools correctly recognize and activate it.

Suggested implementation:

```
private fun MessengerOption(
    isSelected: Boolean,
    app: MessagingApp,
    onCheckedChange: (Boolean) -> Unit
) {
    Row(
        modifier = Modifier
    ) {
        Checkbox(
            checked = isSelected,
            onCheckedChange = onCheckedChange
        )
        Spacer(modifier = Modifier.width(16.dp))
        Text(app.name)

```

To fully wire this up, you will also need to:
1. Update all call sites of `MessengerOption` in `MessengersBottomSheet.kt` to pass the existing selection handler used by `CommonBottomSheet` for row taps. For example:
   - Before: `MessengerOption(isSelected = isSelected, app = app)`
   - After: `MessengerOption(isSelected = isSelected, app = app, onCheckedChange = { checked -> /* existing toggle logic for this app, e.g. toggleMessenger(app, checked) */ })`
2. Ensure that the lambda passed to `onCheckedChange` updates the same selection state that the parent row currently toggles, so both tapping the row and the checkbox keep the UI in sync and accessible.
</issue_to_address>

### Comment 2
<location> `app/src/main/java/ru/yandex/practicum/contacts/presentation/country/CountryCodeBottomSheet.kt:52-54` </location>
<code_context>
     ) {
         Checkbox(
             checked = isSelected,
-            onCheckedChange = { checked ->
-                val newSelection = selectedCodes.toMutableSet()
-                if (checked) {
-                    newSelection.add(countryCode)
-                } else {
-                    newSelection.remove(countryCode)
-                }
-                onCodesSelected(newSelection)
-            }
+            onCheckedChange = null
         )
         Spacer(modifier = Modifier.width(16.dp))
</code_context>

<issue_to_address>
**suggestion:** Avoid a non-interactive checkbox by delegating the selection toggle into this composable.

If `CommonBottomSheet` owns the selection, consider exposing an `onToggle` lambda from the item content slot and passing it through as `onCheckedChange` here. That way the row and checkbox both trigger the same state change and the checkbox remains interactive and accessible rather than being display-only.

Suggested implementation:

```
private fun CountryCodeOption(
    isSelected: Boolean,
    countryCode: CountryCode,
    onToggle: () -> Unit,
) {
    Row(
        modifier = Modifier
            .clickable(onClick = onToggle)
    ) {
        Checkbox(
            checked = isSelected,
            onCheckedChange = { onToggle() }
        )
        Spacer(modifier = Modifier.width(16.dp))
        Column {

```

1. Ensure `clickable` is imported at the top of the file:
   - `import androidx.compose.foundation.clickable`
2. Update all call sites of `CountryCodeOption` to pass an `onToggle` lambda that delegates to the state owner. For example, where you build the list items in `CommonBottomSheet` (or the relevant composable), change:
   - `CountryCodeOption(isSelected = isSelected, countryCode = countryCode)`
   - to something like:
     - `CountryCodeOption(isSelected = isSelected, countryCode = countryCode, onToggle = { onCodesSelected(/* updated selection */) })`
3. If you’re using a content lambda for `CommonBottomSheet` items, extend that slot to provide `onToggle: () -> Unit` to the item content so it can be forwarded into `CountryCodeOption`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Помоги мне стать полезнее! Пожалуйста, нажимай 👍 или 👎 на каждом комментарии — я буду использовать этот фидбек, чтобы улучшить обзоры.
Original comment in English

Hey there - I've reviewed your changes - here's some feedback:

  • Now that Checkbox uses onCheckedChange = null and relies on the parent click handler, consider adding appropriate Modifier.selectable/semantics to the row (or re-enabling Checkbox click) to preserve accessibility and discoverability for users who expect to tap directly on the checkbox.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Now that `Checkbox` uses `onCheckedChange = null` and relies on the parent click handler, consider adding appropriate `Modifier.selectable`/semantics to the row (or re-enabling Checkbox click) to preserve accessibility and discoverability for users who expect to tap directly on the checkbox.

## Individual Comments

### Comment 1
<location> `app/src/main/java/ru/yandex/practicum/contacts/presentation/messengers/MessengersBottomSheet.kt:50-52` </location>
<code_context>
     ) {
         Checkbox(
             checked = isSelected,
-            onCheckedChange = { checked ->
-                val newSelection = selectedCodes.toMutableSet()
-                if (checked) {
-                    newSelection.add(countryCode)
-                } else {
-                    newSelection.remove(countryCode)
-                }
-                onCodesSelected(newSelection)
-            }
+            onCheckedChange = null
         )
         Spacer(modifier = Modifier.width(16.dp))
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Wire the checkbox to the same selection handler used by the parent for better accessibility and UX.

The checkbox appears selected but is not directly interactive (`onCheckedChange = null`), so only the parent row in `CommonBottomSheet` toggles the state. This can confuse users and assistive technologies that expect the checkbox itself to handle taps. Please pass the same toggle lambda used in `CommonBottomSheet` down to `MessengerOption` and connect it to `onCheckedChange`, or alternatively make the row `Modifier.toggleable` with `role = Role.Checkbox` so accessibility tools correctly recognize and activate it.

Suggested implementation:

```
private fun MessengerOption(
    isSelected: Boolean,
    app: MessagingApp,
    onCheckedChange: (Boolean) -> Unit
) {
    Row(
        modifier = Modifier
    ) {
        Checkbox(
            checked = isSelected,
            onCheckedChange = onCheckedChange
        )
        Spacer(modifier = Modifier.width(16.dp))
        Text(app.name)

```

To fully wire this up, you will also need to:
1. Update all call sites of `MessengerOption` in `MessengersBottomSheet.kt` to pass the existing selection handler used by `CommonBottomSheet` for row taps. For example:
   - Before: `MessengerOption(isSelected = isSelected, app = app)`
   - After: `MessengerOption(isSelected = isSelected, app = app, onCheckedChange = { checked -> /* existing toggle logic for this app, e.g. toggleMessenger(app, checked) */ })`
2. Ensure that the lambda passed to `onCheckedChange` updates the same selection state that the parent row currently toggles, so both tapping the row and the checkbox keep the UI in sync and accessible.
</issue_to_address>

### Comment 2
<location> `app/src/main/java/ru/yandex/practicum/contacts/presentation/country/CountryCodeBottomSheet.kt:52-54` </location>
<code_context>
     ) {
         Checkbox(
             checked = isSelected,
-            onCheckedChange = { checked ->
-                val newSelection = selectedCodes.toMutableSet()
-                if (checked) {
-                    newSelection.add(countryCode)
-                } else {
-                    newSelection.remove(countryCode)
-                }
-                onCodesSelected(newSelection)
-            }
+            onCheckedChange = null
         )
         Spacer(modifier = Modifier.width(16.dp))
</code_context>

<issue_to_address>
**suggestion:** Avoid a non-interactive checkbox by delegating the selection toggle into this composable.

If `CommonBottomSheet` owns the selection, consider exposing an `onToggle` lambda from the item content slot and passing it through as `onCheckedChange` here. That way the row and checkbox both trigger the same state change and the checkbox remains interactive and accessible rather than being display-only.

Suggested implementation:

```
private fun CountryCodeOption(
    isSelected: Boolean,
    countryCode: CountryCode,
    onToggle: () -> Unit,
) {
    Row(
        modifier = Modifier
            .clickable(onClick = onToggle)
    ) {
        Checkbox(
            checked = isSelected,
            onCheckedChange = { onToggle() }
        )
        Spacer(modifier = Modifier.width(16.dp))
        Column {

```

1. Ensure `clickable` is imported at the top of the file:
   - `import androidx.compose.foundation.clickable`
2. Update all call sites of `CountryCodeOption` to pass an `onToggle` lambda that delegates to the state owner. For example, where you build the list items in `CommonBottomSheet` (or the relevant composable), change:
   - `CountryCodeOption(isSelected = isSelected, countryCode = countryCode)`
   - to something like:
     - `CountryCodeOption(isSelected = isSelected, countryCode = countryCode, onToggle = { onCodesSelected(/* updated selection */) })`
3. If you’re using a content lambda for `CommonBottomSheet` items, extend that slot to provide `onToggle: () -> Unit` to the item content so it can be forwarded into `CountryCodeOption`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines 50 to +52
Checkbox(
checked = isSelected,
onCheckedChange = { checked ->
val newSelection = selectedApps.toMutableSet()
if (checked) {
newSelection.add(app)
} else {
newSelection.remove(app)
}
onAppsSelected(newSelection)
}
onCheckedChange = null
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Подключите чекбокс к тому же обработчику выбора, который используется родительским элементом, чтобы улучшить доступность и UX.

Сейчас чекбокс выглядит выбранным, но напрямую не интерактивен (onCheckedChange = null), поэтому состояние переключает только родительская строка в CommonBottomSheet. Это может сбивать с толку пользователей и вспомогательные технологии, которые ожидают, что нажатия будет обрабатывать сам чекбокс. Пожалуйста, передайте ту же лямбду-переключатель, что используется в CommonBottomSheet, вниз в MessengerOption и свяжите её с onCheckedChange, либо сделайте строку Modifier.toggleable с role = Role.Checkbox, чтобы инструменты доступности корректно распознавали и активировали её.

Предлагаемая реализация:

private fun MessengerOption(
    isSelected: Boolean,
    app: MessagingApp,
    onCheckedChange: (Boolean) -> Unit
) {
    Row(
        modifier = Modifier
    ) {
        Checkbox(
            checked = isSelected,
            onCheckedChange = onCheckedChange
        )
        Spacer(modifier = Modifier.width(16.dp))
        Text(app.name)

Чтобы полностью всё связать, также нужно:

  1. Обновить все вызовы MessengerOption в MessengersBottomSheet.kt, чтобы они передавали существующий обработчик выбора, который сейчас использует CommonBottomSheet для нажатий по строке. Например:
    • До: MessengerOption(isSelected = isSelected, app = app)
    • После: MessengerOption(isSelected = isSelected, app = app, onCheckedChange = { checked -> /* существующая логика переключения для этого приложения, например toggleMessenger(app, checked) */ })
  2. Убедиться, что лямбда, передаваемая в onCheckedChange, обновляет то же состояние выбора, которое сейчас переключает родительская строка, чтобы и нажатие по строке, и по чекбоксу держали UI синхронизированным и доступным.
Original comment in English

suggestion (bug_risk): Wire the checkbox to the same selection handler used by the parent for better accessibility and UX.

The checkbox appears selected but is not directly interactive (onCheckedChange = null), so only the parent row in CommonBottomSheet toggles the state. This can confuse users and assistive technologies that expect the checkbox itself to handle taps. Please pass the same toggle lambda used in CommonBottomSheet down to MessengerOption and connect it to onCheckedChange, or alternatively make the row Modifier.toggleable with role = Role.Checkbox so accessibility tools correctly recognize and activate it.

Suggested implementation:

private fun MessengerOption(
    isSelected: Boolean,
    app: MessagingApp,
    onCheckedChange: (Boolean) -> Unit
) {
    Row(
        modifier = Modifier
    ) {
        Checkbox(
            checked = isSelected,
            onCheckedChange = onCheckedChange
        )
        Spacer(modifier = Modifier.width(16.dp))
        Text(app.name)

To fully wire this up, you will also need to:

  1. Update all call sites of MessengerOption in MessengersBottomSheet.kt to pass the existing selection handler used by CommonBottomSheet for row taps. For example:
    • Before: MessengerOption(isSelected = isSelected, app = app)
    • After: MessengerOption(isSelected = isSelected, app = app, onCheckedChange = { checked -> /* existing toggle logic for this app, e.g. toggleMessenger(app, checked) */ })
  2. Ensure that the lambda passed to onCheckedChange updates the same selection state that the parent row currently toggles, so both tapping the row and the checkbox keep the UI in sync and accessible.

Comment on lines 52 to +54
Checkbox(
checked = isSelected,
onCheckedChange = { checked ->
val newSelection = selectedCodes.toMutableSet()
if (checked) {
newSelection.add(countryCode)
} else {
newSelection.remove(countryCode)
}
onCodesSelected(newSelection)
}
onCheckedChange = null
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Избегайте неинтерактивного чекбокса, делегируя переключение выбора в этот composable.

Если выбор контролируется CommonBottomSheet, рассмотрите возможность пробросить наружу лямбду onToggle из слота контента элемента и передать её сюда как onCheckedChange. Так и строка, и чекбокс будут вызывать одно и то же изменение состояния, а чекбокс останется интерактивным и доступным, а не только отображаемым.

Предлагаемая реализация:

private fun CountryCodeOption(
    isSelected: Boolean,
    countryCode: CountryCode,
    onToggle: () -> Unit,
) {
    Row(
        modifier = Modifier
            .clickable(onClick = onToggle)
    ) {
        Checkbox(
            checked = isSelected,
            onCheckedChange = { onToggle() }
        )
        Spacer(modifier = Modifier.width(16.dp))
        Column {

  1. Убедитесь, что clickable импортирован вверху файла:
    • import androidx.compose.foundation.clickable
  2. Обновите все вызовы CountryCodeOption, чтобы они передавали лямбду onToggle, делегирующую управление владельцу состояния. Например, там, где вы строите элементы списка в CommonBottomSheet (или соответствующем composable), измените:
    • CountryCodeOption(isSelected = isSelected, countryCode = countryCode)
    • на что-то вроде:
      • CountryCodeOption(isSelected = isSelected, countryCode = countryCode, onToggle = { onCodesSelected(/* updated selection */) })
  3. Если вы используете лямбду контента для элементов CommonBottomSheet, расширьте этот слот так, чтобы он предоставлял onToggle: () -> Unit в контент элемента и его можно было пробросить дальше в CountryCodeOption.
Original comment in English

suggestion: Avoid a non-interactive checkbox by delegating the selection toggle into this composable.

If CommonBottomSheet owns the selection, consider exposing an onToggle lambda from the item content slot and passing it through as onCheckedChange here. That way the row and checkbox both trigger the same state change and the checkbox remains interactive and accessible rather than being display-only.

Suggested implementation:

private fun CountryCodeOption(
    isSelected: Boolean,
    countryCode: CountryCode,
    onToggle: () -> Unit,
) {
    Row(
        modifier = Modifier
            .clickable(onClick = onToggle)
    ) {
        Checkbox(
            checked = isSelected,
            onCheckedChange = { onToggle() }
        )
        Spacer(modifier = Modifier.width(16.dp))
        Column {

  1. Ensure clickable is imported at the top of the file:
    • import androidx.compose.foundation.clickable
  2. Update all call sites of CountryCodeOption to pass an onToggle lambda that delegates to the state owner. For example, where you build the list items in CommonBottomSheet (or the relevant composable), change:
    • CountryCodeOption(isSelected = isSelected, countryCode = countryCode)
    • to something like:
      • CountryCodeOption(isSelected = isSelected, countryCode = countryCode, onToggle = { onCodesSelected(/* updated selection */) })
  3. If you’re using a content lambda for CommonBottomSheet items, extend that slot to provide onToggle: () -> Unit to the item content so it can be forwarded into CountryCodeOption.

Copy link

@interactivetextbook interactivetextbook left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хорошая работа, молодец!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants