Skip to content

List: make the reorder drag visible on dark backgrounds - #518

Open
humbuckr wants to merge 1 commit into
skiptools:mainfrom
humbuckr:dark-theme-drag-affordance
Open

List: make the reorder drag visible on dark backgrounds#518
humbuckr wants to merge 1 commit into
skiptools:mainfrom
humbuckr:dark-theme-drag-affordance

Conversation

@humbuckr

Copy link
Copy Markdown

Fixes the problem reported in #517.

The problem

RenderReorderableItem styles the dragged row with Modifier.shadow(8.dp) and
nothing else. A shadow expresses elevation by darkening what is around the
row — so over a dark page it expresses nothing. On #000 there is nothing left
to darken, and the row under your finger is pixel-identical to the rows at rest.
A reorder on a dark-themed app has no visible affordance at all.

The change

Draw a tonal lift alongside the shadow, which is Material's own answer for
elevation on dark surfaces: the surface itself gets lighter.

let dragTint = MaterialTheme.colorScheme.onSurface.copy(alpha: Float(0.10))
itemModifier = itemModifier.drawWithContent {
    drawContent()
    drawRect(color: dragTint)
}

Two choices worth flagging for review:

  • Over the content, not behind it. A list row almost always paints its own
    background, so a tint drawn behind it would never be seen.
  • onSurface, not a fixed colour, so it follows the scheme in both
    directions — lighter on dark themes, darker on light ones. Light themes keep
    the shadow they already had and gain a subtle press-like tint; dark themes gain
    the only feedback they can receive.

Happy to put it behind an environment hook in the shape of material3Ripple
instead, if you would rather this be opt-in than a default.

Why apps cannot work around it

  • onMove is invoked from onDragEnd, so SwiftUI code learns about the move
    only on drop.
  • Modifier.detectReorderAfterLongPress claims the long press, so an app's own
    .onLongPressGesture(..., onPressingChanged:) on the row never fires.
  • And that callback is one-way regardless: onLongPressChange() calls
    onChanged(true) and nothing ever calls it with false.

Testing

Built and run on device: Android 14, Samsung SM-A326U (Dimensity 700), release
build, a 24-row playlist on a #121212 page with #252525 rows. Before the
patch, dragging produced no visible change; after it, the dragged row lifts while
held and returns to rest on drop. Light-theme rendering unchanged apart from the
new tint.

A dragged row is styled with Modifier.shadow(8.dp) and nothing else. A shadow
expresses elevation by darkening what is around the row, so over a dark page it
expresses nothing — on #000 there is nothing left to darken, and the row being
dragged is pixel-identical to the rows at rest. A reorder on a dark-themed app
therefore has no visible affordance at all.

Material's own answer for elevation on dark surfaces is tonal: the surface gets
lighter. This draws that alongside the shadow, so light themes keep the shadow
they already had and dark themes gain feedback they never had.

Drawn over the content rather than behind it, because a list row usually paints
its own background and a tint behind it would never be seen. Tinted with
onSurface so it follows the colour scheme in both directions.

Apps cannot work around this today: SwiftUI's onMove is invoked from onDragEnd,
detectReorderAfterLongPress claims the long press before any app gesture sees
it, and onLongPressChange() only ever calls onChanged(true).

Tested on device — Android 14, Samsung SM-A326U, a playlist of 24 rows on a
#121212 page: the dragged row now lifts visibly and returns to rest on drop.

Refs skiptools#517
@cla-bot

cla-bot Bot commented Aug 31, 2026

Copy link
Copy Markdown

Thank you for your pull request and welcome to the Skip community. We require contributors to sign our contributor license agreement (CLA), and we don't seem to have the user(s) @humbuckr on file. In order for us to review and merge your code, for each noted user please add your GitHub username to Skip's .clabot file

@marcprux

Copy link
Copy Markdown
Member

This looks useful?

Could you post a before and after screenshot of a row being dragged with this effect?

@humbuckr

humbuckr commented Aug 31, 2026 via email

Copy link
Copy Markdown
Author

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.

2 participants