Skip to content

fix(sdds-acore/uikit-compose): ListItem, Text and Icon#793

Merged
malilex merged 2 commits into
mainfrom
hotfix/01-06-2026
Jun 1, 2026
Merged

fix(sdds-acore/uikit-compose): ListItem, Text and Icon#793
malilex merged 2 commits into
mainfrom
hotfix/01-06-2026

Conversation

@malilex
Copy link
Copy Markdown
Collaborator

@malilex malilex commented May 29, 2026

sdds-uikit-compose

List

  • Исправлен механизм получения fallback значения для помеченного deprecated параметра gap

ListItem

  • Добавлена возможность установить вертикальное выравнивание контента на уровне стиля

Text

  • Добавлены перегрузки для Text с возможностью указать цвет без ColorProducer.

Icon

  • Icon теперь учитывает явно переданный параметр tint

plasma-homeds-compose

ListNumbered

  • Counter теперь прибит к верху в ListItem

What/why changed

Это обязательный блок и заголовок!

Более подробное описание решаемой проблемы.

Summary by CodeRabbit

  • New Features

    • List items now support configurable vertical gravity/alignment.
    • Separate start/end content color customization for list items and cells; icons/tints follow these content colors.
    • Theme/motion styling restored to include content start/end color motion.
  • Chores

    • Bumped multiple module and token package patch versions and internal tooling versions.

…y. Icon and Text now respects color and brush specified by user.
@malilex malilex self-assigned this May 29, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

Adds content-start/end color properties and gravity alignment across cell/list styling, refactors Text API to use Color/Brush overloads, extends motion and theme-builder support, updates fixtures, and bumps multiple package patch versions.

Changes

Content Display and Styling Enhancements

Layer / File(s) Summary
Version patch bumps across packages
gradle/libs.versions.toml, sdds-core/plugin_theme_builder/gradle.properties, sdds-core/uikit-compose/gradle.properties, tokens/*/gradle.properties
All Gradle property files increment versionPatch from 0 to 1.
Text API refactored from producers to concrete types
sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/Text.kt
Text composable overloads now accept concrete Color and Brush parameters instead of ColorProducer and BrushProducer. New variants added for TextSource, String, and AnnotatedString with textColor/textBrush.
Icon brush producer conditional selection
sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/Icon.kt
Icon composable now computes brushProducer conditionally: uses provided brush only when tint is default, otherwise derives brush solely from explicit tint.
List dimensions deprecated property computation
sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/ListStyle.kt
Deprecated dimension properties now derive from corresponding StatefulValue instances via getDefaultValue() instead of hardcoded constants.
Cell content color properties in contracts and implementation
sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/CellStyle.kt
CellColors interface adds contentStartColor and contentEndColor as StatefulValue<Brush>. CellColorsBuilder provides multi-type setters. DefaultCellColors stores and defaults these values to computed title brush.
Theme builder support for cell content colors
sdds-core/plugin_theme_builder/.../CellConfig.kt, CellComposeVariationGenerator.kt, tokens/plasma.homeds.compose/.../CellStyles.kt
CellProperties model adds content color fields with parent merging. Code generator emits .colors block entries and treats these colors as generation triggers. Theme implementation configures colors from primary/secondary text palette.
BaseCell tint application for content colors
sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/internal/cell/BaseCell.kt
Start and end content now apply tints from their respective content color properties instead of shared title color.
ListItem gravity property and wiring
sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/ListItemStyle.kt, ListItem.kt, sdds-core/plugin_theme_builder/.../ListItemConfig.kt, ListItemComposeVariationGenerator.kt, tokens/plasma.homeds.compose/.../ListNumberedItemStyles.kt
ListItemStyle adds gravity: CellGravity property (defaults to Center). Builder, theme builder, and composables all wire and apply gravity. Theme builder maps string enum values to CellGravity constants in generated code.
ListItem content color properties
sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/ListItemStyle.kt, ListItem.kt, sdds-core/plugin_theme_builder/.../ListItemConfig.kt, ListItemComposeVariationGenerator.kt, tokens/plasma.homeds.compose/.../ListItemStyles.kt
ListItemColors adds contentStartColor and contentEndColor as StatefulValue<Brush> with builder support. ListItemStyle.toCellStyle() maps these to CellStyle. Theme builder and code generator support these properties with parent merging and generated code emission.
Cell motion style properties for content colors
sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/motion/components/cell/CellMotionStyle.kt
CellMotionStyle interface adds contentStartColor and contentEndColor as MotionProperty<Brush>. Builder and implementation updated to store, configure, and default these to noMotion().
ListItem motion style properties for content colors
sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/motion/components/list/ListItemMotionStyle.kt
ListItemMotionStyleBuilder adds configuration methods for content boundary motion colors. Implementation stores and defaults to noMotion() when unset.
ListStory fixture with endContent and None options
integration-core/uikit-compose-fixtures/.../ListStory.kt, playground/sandbox-integration-test/.../ScenarioTabs.kt
ListUiState adds endContent property. Content enums gain None option. Rendering wires endContent via helper and conditionally renders label/subtitle when state strings are non-blank. Import ordering fixed.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Poem

🐰 Colors at the start and end unfurl,
Gravity nudges list items to their place,
Text sheds producers for a simpler world,
Motion paints the subtle flow of space,
Fixtures hop and show the new-found grace.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(sdds-acore/uikit-compose): ListItem, Text and Icon' clearly matches the main changes: ListItem now supports vertical content alignment via style-level gravity, Text gained Color/Brush overloads without ColorProducer, and Icon respects explicit tint parameters. The title accurately summarizes the primary components modified.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hotfix/01-06-2026

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (2)
sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/CellStyle.kt (1)

856-857: ⚡ Quick win

Document implicit fallback to title brush.

When contentStartColor and contentEndColor are not explicitly configured, they fall back to defaultTitleBrush. This coupling creates an implicit dependency where content colors track title color by default. While this may be intentional for visual consistency, the behavior is not documented in the interface or builder.

Suggested documentation addition

Add KDoc to the interface properties:

     /**
-     * Кисть контента в начале
+     * Кисть контента в начале.
+     * По умолчанию использует кисть тайтла, если не задана явно.
      */
     val contentStartColor: StatefulValue<Brush>

     /**
-     * Кисть контента в конце
+     * Кисть контента в конце.
+     * По умолчанию использует кисть тайтла, если не задана явно.
      */
     val contentEndColor: StatefulValue<Brush>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/CellStyle.kt`
around lines 856 - 857, Document the implicit fallback where contentStartColor
and contentEndColor default to defaultTitleBrush by adding KDoc on the CellStyle
interface/builder properties (contentStartColor, contentEndColor) explaining
that when these are null they will track the title color via defaultTitleBrush;
mention the intent (visual consistency), the coupling/side-effect, and expected
override behavior so callers know this implicit dependency (refer to the
CellStyle builder/implementation that sets contentStartColor = contentStartColor
?: defaultTitleBrush and contentEndColor = contentEndColor ?:
defaultTitleBrush).
integration-core/uikit-compose-fixtures/src/main/kotlin/com/sdds/compose/uikit/fixtures/stories/list/ListStory.kt (1)

143-195: ⚡ Quick win

Prefer explicit None branches instead of else in enum when blocks.

Both when expressions currently use else -> null; this drops exhaustiveness checks for future enum additions. Map None explicitly in each block.

♻️ Suggested change
-        else -> null
+        ListItemStartContent.None -> null
@@
-        else -> null
+        ListItemEndContent.None -> null
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@integration-core/uikit-compose-fixtures/src/main/kotlin/com/sdds/compose/uikit/fixtures/stories/list/ListStory.kt`
around lines 143 - 195, The when branches in getStartContent (handling
ListItemStartContent) and getEndContent (handling ListItemEndContent) use else
-> null which disables exhaustiveness checking; replace the else branches with
explicit ListItemStartContent.None -> null and ListItemEndContent.None -> null
respectively so the when remains exhaustive and future enum additions will
trigger compiler warnings.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/list/item/compose/ListItemComposeVariationGenerator.kt`:
- Around line 70-74: The current when-expression in
ListItemComposeVariationGenerator that assigns enumValue silently coerces
unknown gravity tokens to "Top"; change it to treat unrecognized values as the
style default "Center" (or log/warn about invalid tokens) instead of defaulting
to "Top" so configuration mistakes aren't hidden—locate the when block that sets
enumValue and replace the else branch to return "Center" (and optionally emit a
warning including the original token) to preserve expected defaults.
- Around line 166-171: ListItemProperties.hasColors() currently returns true
only if backgroundColor, titleColor, disclosureIconColor, contentStartColor, or
contentEndColor are non-null, so subtitleColor and labelColor are omitted and
colorsCall() may be skipped; update hasColors() to also check subtitleColor and
labelColor so that when either is set the function returns true and the .colors
{ ... } block is emitted. Locate the hasColors() function and add null checks
for subtitleColor and labelColor alongside the existing checks to ensure color
configuration is preserved.

In `@sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/CellStyle.kt`:
- Around line 580-588: Rename the two properties contentStartColor and
contentEndColor to contentStartBrush and contentEndBrush (type remains
StatefulValue<Brush>) so they follow the existing Brush suffix convention used
by titleBrush, labelBrush, subtitleBrush, disclosureTextBrush, and
disclosureIconBrush; keep any public builder/factory methods named
contentStartColor(...) and contentEndColor(...) if you want to preserve the
existing API surface for callers, but update all internal references and
implementations (DefaultCellColors, BaseCell usage, CellConfig, theme builder
generator, generated theme code, and any motion style properties) to use the new
property names contentStartBrush/contentEndBrush to ensure consistency across
the codebase.

In `@sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/Icon.kt`:
- Around line 42-46: The current brushProducer logic wrongly gates using the
explicit brush on tint equality; update the Icon.kt logic so brushProducer uses
the provided brush whenever it is non-null and only falls back to BrushProducer
{ tint.asBrush() } when brush == null (do not check tint == LocalTint.current to
decide precedence). Concretely, change the construction of brushProducer
(symbol: brushProducer) to prefer the non-null parameter brush (wrap it in
BrushProducer if needed) and otherwise produce a brush from tint
(tint.asBrush()); then add a regression test verifying the path tint !=
LocalTint.current && brush != null returns/uses the provided brush.

---

Nitpick comments:
In
`@integration-core/uikit-compose-fixtures/src/main/kotlin/com/sdds/compose/uikit/fixtures/stories/list/ListStory.kt`:
- Around line 143-195: The when branches in getStartContent (handling
ListItemStartContent) and getEndContent (handling ListItemEndContent) use else
-> null which disables exhaustiveness checking; replace the else branches with
explicit ListItemStartContent.None -> null and ListItemEndContent.None -> null
respectively so the when remains exhaustive and future enum additions will
trigger compiler warnings.

In `@sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/CellStyle.kt`:
- Around line 856-857: Document the implicit fallback where contentStartColor
and contentEndColor default to defaultTitleBrush by adding KDoc on the CellStyle
interface/builder properties (contentStartColor, contentEndColor) explaining
that when these are null they will track the title color via defaultTitleBrush;
mention the intent (visual consistency), the coupling/side-effect, and expected
override behavior so callers know this implicit dependency (refer to the
CellStyle builder/implementation that sets contentStartColor = contentStartColor
?: defaultTitleBrush and contentEndColor = contentEndColor ?:
defaultTitleBrush).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ecfc8d7c-216c-4e25-8393-140a837e715d

📥 Commits

Reviewing files that changed from the base of the PR and between 8ba4967 and 3d7a5c5.

⛔ Files ignored due to path filters (2)
  • tokens/plasma.homeds.compose/screenshots-compose/testCellMAvatarIcon_dark.png is excluded by !**/*.png
  • tokens/plasma.homeds.compose/screenshots-compose/testCellMAvatarIcon_light.png is excluded by !**/*.png
📒 Files selected for processing (27)
  • gradle/libs.versions.toml
  • integration-core/uikit-compose-fixtures/src/main/kotlin/com/sdds/compose/uikit/fixtures/stories/list/ListStory.kt
  • playground/sandbox-integration-test/src/main/kotlin/com/sdds/playground/integrationtest/components/scenario/ScenarioTabs.kt
  • sdds-core/plugin_theme_builder/gradle.properties
  • sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/cell/CellConfig.kt
  • sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/cell/compose/CellComposeVariationGenerator.kt
  • sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/list/item/ListItemConfig.kt
  • sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/list/item/compose/ListItemComposeVariationGenerator.kt
  • sdds-core/uikit-compose/gradle.properties
  • sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/CellStyle.kt
  • sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/Icon.kt
  • sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/ListItem.kt
  • sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/ListItemStyle.kt
  • sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/ListStyle.kt
  • sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/Text.kt
  • sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/internal/cell/BaseCell.kt
  • sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/motion/components/cell/CellMotionStyle.kt
  • sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/motion/components/list/ListItemMotionStyle.kt
  • tokens/plasma-stards-compose/gradle.properties
  • tokens/plasma.giga.compose/gradle.properties
  • tokens/plasma.homeds.compose/gradle.properties
  • tokens/plasma.homeds.compose/src/main/kotlin/com/sdds/plasma/homeds/styles/cell/CellStyles.kt
  • tokens/plasma.homeds.compose/src/main/kotlin/com/sdds/plasma/homeds/styles/listitem/ListItemStyles.kt
  • tokens/plasma.homeds.compose/src/main/kotlin/com/sdds/plasma/homeds/styles/listitem/ListNumberedItemStyles.kt
  • tokens/plasma.sd.service.compose/gradle.properties
  • tokens/sdds-sbcom-compose/gradle.properties
  • tokens/sdds.serv.compose/gradle.properties

@salutedevs
Copy link
Copy Markdown
Collaborator

salutedevs commented May 29, 2026

📦 Собранные Release APK

📲 Как установить APK на Android-устройство:

  1. Распакуйте архив.
  2. Скопируйте нужный .apk на устройство (через USB, Telegram, Google Drive и т.д.).
  3. Откройте .apk на устройстве и подтвердите установку.
    Если потребуется, включите Разрешение на установку из неизвестных источников в настройках устройства.

💻 Установка через USB (ADB):

  1. Включите Отладку по USB на устройстве (Настройки → Для разработчиков).
  2. Подключите устройство к компьютеру по USB.
  3. Убедитесь, что устройство отображается:
    adb devices
  4. Установите .apk:
    adb install path/to/your.apk
    Если приложение уже установлено и нужно обновить:
    adb install -r path/to/your.apk

@salutedevs
Copy link
Copy Markdown
Collaborator

salutedevs commented May 29, 2026

📘Артефакты документации опубликованы:

Comment thread sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/ListItemStyle.kt Outdated
Comment thread gradle/libs.versions.toml
@malilex malilex requested a review from luizasok June 1, 2026 07:19
raininforest
raininforest previously approved these changes Jun 1, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/Icon.kt (1)

43-47: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Past review issue remains unresolved: equality check is unreliable for parameter precedence.

Updating the KDoc to match the implementation does not fix the underlying design flaw flagged in the past review. The condition tint == LocalTint.current cannot reliably distinguish "user explicitly passed a tint value" from "tint defaulted to LocalTint.current":

  • If a caller writes Icon(painter, ..., tint = Color.Gray) and LocalTint.current happens to be Color.Gray, the condition evaluates to true even though tint was explicitly provided.
  • If LocalTint.current is customized, a caller omitting the tint parameter will get tint != LocalTint.current and unintentionally bypass the brush.

This creates unpredictable behavior when both tint and brush are provided.

🔧 Recommended fix: use simple null-based precedence
-    val brushProducer = if (tint == LocalTint.current) {
-        brush ?: BrushProducer { tint.asBrush() }
-    } else {
-        BrushProducer { tint.asBrush() }
-    }
+    val brushProducer = brush ?: BrushProducer { tint.asBrush() }

Update the KDoc to reflect simple precedence: "brush takes priority when non-null; otherwise tint is used."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/Icon.kt`
around lines 43 - 47, The equality check tint == LocalTint.current in the
brushProducer selection is unreliable for determining whether callers passed an
explicit tint; change the logic to a null-based precedence: if brush != null use
brush, otherwise fall back to tint.asBrush(); update the brushProducer
assignment (and any related code using BrushProducer and the tint parameter) to
implement this null-first precedence and adjust the KDoc to state "brush takes
priority when non-null; otherwise tint is used."
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/Icon.kt`:
- Around line 43-47: The equality check tint == LocalTint.current in the
brushProducer selection is unreliable for determining whether callers passed an
explicit tint; change the logic to a null-based precedence: if brush != null use
brush, otherwise fall back to tint.asBrush(); update the brushProducer
assignment (and any related code using BrushProducer and the tint parameter) to
implement this null-first precedence and adjust the KDoc to state "brush takes
priority when non-null; otherwise tint is used."

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 29ef2407-5775-4754-9d33-7fd1d2cc46cb

📥 Commits

Reviewing files that changed from the base of the PR and between 3d7a5c5 and 7eb5599.

📒 Files selected for processing (3)
  • sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/list/item/compose/ListItemComposeVariationGenerator.kt
  • sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/Icon.kt
  • sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/ListItemStyle.kt
🚧 Files skipped from review as they are similar to previous changes (2)
  • sdds-core/uikit-compose/src/main/kotlin/com/sdds/compose/uikit/ListItemStyle.kt
  • sdds-core/plugin_theme_builder/src/main/kotlin/com/sdds/plugin/themebuilder/internal/components/list/item/compose/ListItemComposeVariationGenerator.kt

@malilex malilex merged commit a6593e8 into main Jun 1, 2026
52 checks passed
@malilex malilex deleted the hotfix/01-06-2026 branch June 1, 2026 09:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants