Skip to content

feat: rebuild sample app as an 8-screen haptic verification harness - #86

Merged
l2hyunwoo merged 12 commits into
mainfrom
feature/sample-redesign
Jul 4, 2026
Merged

feat: rebuild sample app as an 8-screen haptic verification harness#86
l2hyunwoo merged 12 commits into
mainfrom
feature/sample-redesign

Conversation

@l2hyunwoo

@l2hyunwoo l2hyunwoo commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Rebuilds the sample app from a single preset list into an 8-screen verification harness, where each screen isolates one DSL feature and renders it on a shared timeline so the haptic is visible, not just felt. Adds a small public capability read API the home screen needs, and bundles the handoff's fonts.

Design source: a high-fidelity handoff (tokens, per-screen specs, an interactive prototype). The work ports that design to Compose Multiplatform on the existing Material3/own-theme patterns.

What changed

  • HapticCapabilities read API (jindong-compose): public HapticCapabilities(isSupported, hasAmplitudeControl, platform) + HapticPlatform enum + rememberHapticCapabilities(). hasAmplitudeControl is promoted onto the HapticExecutor interface (Android reads Vibrator.hasAmplitudeControl(); iOS Core Haptics is continuous, so true). LocalHapticExecutor stays internal. API dumps regenerated.
  • Design system (sample/shared): light/dark color tokens, typography (Instrument Sans for UI, IBM Plex Mono for numbers and section labels), spacing/radius, all exposed through a JindongTheme with staticCompositionLocalOf.
  • Shared components: JindongScaffold (56dp app bar + scrolling body), HapticTimeline (a single Canvas drawing one bar per event plus a playhead), CapabilityBadge, PlayButton, LabeledSlider, chips, segmented toggle.
  • 8 screens + 1-depth navigation: Home/Capability, Single, Intensity Lab, Timing, Repeat, Repeat w/ Index, Preset Gallery (the ten existing presets preserved), and Reactive. A sealed Screen + rememberSaveable host, no navigation library.
  • Safe-area insets: JindongScaffold consumes status-bar, navigation-bar, and horizontal cutout insets, so the app bar clears the status bar and Dynamic Island on both platforms.
  • Vector icons: self-defined ImageVectors replace emoji glyphs (play, theme toggle, chevrons, close, caret), which rendered as inconsistent color emoji on iOS. No material-icons dependency added.

How it draws the timeline

Each screen builds its pattern with the public buildHapticPattern { } on every recomposition and maps the resulting events to bars. This path is independent of the executor, so the timeline always reflects the current control values.

Known limitation: vibration replay (tracked by #84)

The actual vibration on screens 05/06/07 (and the Play replay on 01-04) currently repeats the first-compiled pattern instead of the latest one, because rememberHapticPattern memoizes with no keys. On screen 05 this shows up as Fade in and Fade out feeling identical; on the gallery, every card plays the same pattern. This is the bug fixed by #84.

This PR does not touch that code. Each screen already passes its state as Jindong(*keys), so once #84 lands the vibration self-heals with no further changes here. The on-screen timeline is unaffected and stays live now, which is why the harness is already useful for visual verification.

Screenshots

Android

image

iOS

image

Verification

  • Android and iOS compile; apiCheck and spotlessCheck pass; existing library tests (90 core + 40 compose) pass on Android host and iOS simulator.
  • Run on a real Android device (Galaxy, LRA with amplitude control): all eight screens render, the capability badges show real device values, light/dark toggle works, and a Play fires a vibration (confirmed via VibrationThread amplitude logs).
  • Run on the iOS simulator and a real iPhone: renders identically; capability badges correctly report the platform.

Out of scope

iOS-only parameters (IosHapticParameters: sharpness/ADSR) are not reachable from the public DSL, so they are excluded from this harness.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Added haptics capability reporting (supported status, amplitude-control availability, and platform) and a Compose helper to remember current capabilities.
    • Introduced an amplitude-control flag in the haptics executor.
    • Expanded the sample app with new navigation shell, theme toggle, and multiple interactive demo screens plus refreshed reusable UI components (icons, timeline visuals, and controls).
  • Bug Fixes

    • Improved capability detection so the sample’s messaging and enabled features better reflect actual haptic and amplitude-step support.

@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@l2hyunwoo, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 16 minutes and 39 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2cdf0e56-ba10-4d81-9641-5c769620def6

📥 Commits

Reviewing files that changed from the base of the PR and between 9fc7146 and 6e858de.

⛔ Files ignored due to path filters (4)
  • sample/shared/src/commonMain/composeResources/font/ibm_plex_mono_medium.ttf is excluded by !**/*.ttf
  • sample/shared/src/commonMain/composeResources/font/ibm_plex_mono_regular.ttf is excluded by !**/*.ttf
  • sample/shared/src/commonMain/composeResources/font/ibm_plex_mono_semibold.ttf is excluded by !**/*.ttf
  • sample/shared/src/commonMain/composeResources/font/instrument_sans_variable.ttf is excluded by !**/*.ttf
📒 Files selected for processing (45)
  • jindong-compose/api/jindong-compose.api
  • jindong-compose/api/jindong-compose.klib.api
  • jindong-compose/src/androidMain/kotlin/io/github/compose/jindong/HapticCapabilities.android.kt
  • jindong-compose/src/commonMain/kotlin/io/github/compose/jindong/HapticCapabilities.kt
  • jindong-compose/src/commonTest/kotlin/io/github/compose/jindong/HapticCapabilitiesTest.kt
  • jindong-compose/src/iosMain/kotlin/io/github/compose/jindong/HapticCapabilities.ios.kt
  • jindong-core/api/jindong-core.api
  • jindong-core/api/jindong-core.klib.api
  • jindong-core/src/androidMain/kotlin/io/github/compose/jindong/core/executor/HapticExecutor.android.kt
  • jindong-core/src/commonMain/kotlin/io/github/compose/jindong/core/executor/HapticExecutor.kt
  • jindong-core/src/commonTest/kotlin/io/github/compose/jindong/core/executor/HapticExecutorCapabilityTest.kt
  • jindong-core/src/commonTest/kotlin/io/github/compose/jindong/core/fake/FakeHapticExecutor.kt
  • jindong-core/src/iosMain/kotlin/io/github/compose/jindong/core/executor/HapticExecutor.ios.kt
  • sample/shared/build.gradle.kts
  • sample/shared/src/androidMain/kotlin/io/github/compose/jindong/sample/nav/PlatformBackHandler.android.kt
  • sample/shared/src/commonMain/composeResources/files/IBMPlexMono-OFL.txt
  • sample/shared/src/commonMain/composeResources/files/InstrumentSans-OFL.txt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/SampleApp.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/CapabilityBadge.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/Chip.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/HapticTimeline.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/JindongIcons.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/JindongScaffold.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/LabeledSlider.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/MonoLabel.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/PlayButton.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/ScreenPieces.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/SegmentedToggle.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/nav/AppRoot.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/nav/PlatformBackHandler.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/nav/Screen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/HarnessLogic.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/HomeScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/IntensityLabScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/PresetGalleryScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/ReactiveScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/RepeatScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/RepeatWithIndexScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/SingleHapticScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/TimingScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/theme/Dimens.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/theme/JindongColors.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/theme/JindongTheme.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/theme/JindongTypography.kt
  • sample/shared/src/iosMain/kotlin/io/github/compose/jindong/sample/nav/PlatformBackHandler.ios.kt
📝 Walkthrough

Walkthrough

Adds amplitude control to HapticExecutor, introduces HapticCapabilities/HapticPlatform with rememberHapticCapabilities(), and rebuilds the sample app around a themed navigation shell, shared UI components, and seven haptic screens.

Changes

HapticExecutor amplitude control

Layer / File(s) Summary
Interface and ABI
jindong-core/src/commonMain/.../HapticExecutor.kt, jindong-core/api/jindong-core.api, jindong-core/api/jindong-core.klib.api
Adds hasAmplitudeControl: Boolean to HapticExecutor and updates both ABI dumps.
Platform implementations and tests
jindong-core/src/androidMain/.../HapticExecutor.android.kt, jindong-core/src/iosMain/.../HapticExecutor.ios.kt, jindong-core/src/commonTest/.../FakeHapticExecutor.kt, jindong-core/src/commonTest/.../HapticExecutorCapabilityTest.kt
Android reads vibrator.hasAmplitudeControl(), iOS returns isSupported, the fake overrides true, and tests cover the fake capability values.

Haptic capability snapshot API

Layer / File(s) Summary
Types and composable snapshot
jindong-compose/src/commonMain/.../HapticCapabilities.kt, jindong-compose/src/androidMain/.../HapticCapabilities.android.kt, jindong-compose/src/iosMain/.../HapticCapabilities.ios.kt
Defines HapticPlatform, HapticCapabilities, rememberHapticCapabilities(), and platform actual implementations of hapticPlatform().
ABI updates and data test
jindong-compose/api/jindong-compose.api, jindong-compose/api/jindong-compose.klib.api, jindong-compose/src/commonTest/.../HapticCapabilitiesTest.kt
Updates the public API dumps for the new capability types and verifies HapticCapabilities property retention.

Sample app rebuild

Layer / File(s) Summary
Theme tokens and fonts
sample/shared/src/commonMain/kotlin/.../theme/*, sample/shared/src/commonMain/composeResources/files/*-OFL.txt
Adds JindongColors, JindongTypography, Dimens, and JindongTheme, plus bundled font license files.
Reusable UI components
sample/shared/src/commonMain/kotlin/.../components/*
Adds the shared badges, chips, timeline, icons, sliders, labels, buttons, scaffold, spacing helpers, and segmented toggle.
Screen model and app shell
sample/shared/src/commonMain/kotlin/.../nav/*, sample/shared/src/androidMain/kotlin/.../PlatformBackHandler.android.kt, sample/shared/src/iosMain/kotlin/.../PlatformBackHandler.ios.kt, sample/shared/build.gradle.kts, sample/shared/src/commonMain/kotlin/.../SampleApp.kt
Defines screen routing, back-handler contracts and actuals, the root app shell, and the sample entry-point refactor.
Harness logic and home hub
sample/shared/src/commonMain/kotlin/.../screens/HarnessLogic.kt, sample/shared/src/commonMain/kotlin/.../screens/HomeScreen.kt
Adds shared haptic harness data/functions and the home screen that surfaces device capabilities and module navigation.
Seven haptic module screens
sample/shared/src/commonMain/kotlin/.../screens/SingleHapticScreen.kt, IntensityLabScreen.kt, TimingScreen.kt, RepeatScreen.kt, RepeatWithIndexScreen.kt, PresetGalleryScreen.kt, ReactiveScreen.kt
Adds the seven interactive haptic screens with state, timeline visualization, and playback wiring.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • wisemuji

🐇 I tapped my paw and listened near,
the haptics changed from soft to clear.
With caps and screens in tidy rows,
the little bunny’s library grows.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 56.47% 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
Title check ✅ Passed The title clearly summarizes the main change: rebuilding the sample app into an 8-screen haptic verification harness.
Description check ✅ Passed The description covers the summary, implementation details, verification, screenshots, and known limitation; only the issue link section is missing.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/sample-redesign

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions

github-actions Bot commented Jun 28, 2026

Copy link
Copy Markdown

@l2hyunwoo
l2hyunwoo requested a review from wisemuji June 28, 2026 10:48

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 16

🧹 Nitpick comments (1)
jindong-compose/src/commonTest/kotlin/io/github/compose/jindong/HapticCapabilitiesTest.kt (1)

22-37: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a composition-level test for rememberHapticCapabilities().

This only verifies that HapticCapabilities stores constructor args. It does not exercise the new rememberHapticCapabilities() path, so a regression in reading LocalHapticExecutor or resolving the platform would still pass. Add a provider-backed test with a fake executor and assert the returned snapshot.

🤖 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
`@jindong-compose/src/commonTest/kotlin/io/github/compose/jindong/HapticCapabilitiesTest.kt`
around lines 22 - 37, Add a composition-level test that exercises
rememberHapticCapabilities() instead of only testing the HapticCapabilities
constructor. Use a provider-backed setup with a fake LocalHapticExecutor to
verify the composable reads from composition and resolves the platform
correctly, then assert the returned snapshot values. Keep the existing
HapticCapabilitiesTest focused on constructor behavior, and add a new test case
that names rememberHapticCapabilities() and LocalHapticExecutor so the
regression path is covered.
🤖 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
`@jindong-core/src/commonMain/kotlin/io/github/compose/jindong/core/executor/HapticExecutor.kt`:
- Around line 37-47: The new hasAmplitudeControl member on HapticExecutor is a
breaking API change for downstream implementers; if this release should preserve
compatibility, move the capability behind a separate interface or provide a
defaulted way to expose it. Update HapticExecutor and any related
implementations/helpers that reference the capability so existing
implementations do not need to add new members immediately.

In
`@jindong-core/src/iosMain/kotlin/io/github/compose/jindong/core/executor/HapticExecutor.ios.kt`:
- Around line 58-60: The iOS haptic capabilities currently report amplitude
control as always true in HapticExecutor, which creates an invalid state when
Core Haptics is unavailable. Update the HapticExecutor.ios implementation so
hasAmplitudeControl is only true when the device is actually supported, and make
sure rememberHapticCapabilities and any UI badges relying on it use the real
support state instead of a hard-coded constant.

In
`@sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/Chip.kt`:
- Around line 59-70: Move the click handling from the inner Column/Row onto the
outer Box in the Chip composables so the full `Dimens.minTouch` area is
tappable. Update the chip implementations identified by `Chip` and the shared
clickable modifier chain to keep the visual styling on the inner content but
apply `clickable(onClick = onClick)` to the min-touch container. Also apply the
same fix to the other chip variant referenced by the comment so both
implementations use the larger hit target.

In
`@sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/JindongScaffold.kt`:
- Around line 145-155: Update the clickable controls in JindongScaffold to
expose proper button semantics: add role = Role.Button to both the back action
and the other clickable control, and in the back icon block set the Icon
contentDescription to null so the label is not announced twice. Locate the back
control and icon setup in JindongScaffold and adjust the existing
clickable/semantics chain rather than adding new UI.

In
`@sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/ScreenPieces.kt`:
- Around line 84-96: The zero-decimal branch in formatFixed currently truncates
by calling value.toLong(), which is inconsistent with the rounding used in the
rest of the helper. Update the decimals <= 0 path in formatFixed to apply the
same half-up rounding before converting to a whole-number string, so values like
1.9f format consistently with the fractional case.

In
`@sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/SegmentedToggle.kt`:
- Around line 52-70: Each segment in SegmentedToggle should have its own 48dp
minimum tap target instead of relying on the parent Row. Move the minimum
height/touch enforcement onto the child segment Box in the forEachIndexed loop,
alongside the clickable modifier, so short labels still produce a full-size hit
area. Keep the existing row spacing and selection styling, but ensure each
segment wrapper independently respects Dimens.minTouch.

In
`@sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/nav/AppRoot.kt`:
- Around line 41-45: Restore Android system-back handling in AppRoot so the back
gesture/button navigates from the current screen back to Screen.Home instead of
exiting the app. Keep the existing app-bar chevron behavior in JindongScaffold
as a fallback, but add an Android-specific back hook in the AppRoot host when
current != Screen.Home, using the existing navigation state and screen switch
logic.

In
`@sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/IntensityLabScreen.kt`:
- Around line 271-285: The PlayChip touch target is split across two nodes, so
the advertised 48dp area is not actually clickable. Update PlayChip so the
minimum size and the clickable handler live on the same modifier chain/node (the
one that draws the bordered pill), and keep the outer wrapper only if it is no
longer needed for hit testing.
- Around line 148-155: The Play all sequence in Jindong(playAll) does not match
the staircase timeline because it uses a longer inter-pulse gap than the
rendered pattern. Update the Sequence playback logic so the Delay between Haptic
events matches the same timing used by the timeline/staircase rendering, keeping
ascendingPresets in sync with the visual preview.
- Around line 159-160: The custom haptic preview in IntensityLabScreen should
not auto-play when the custom slider changes. Update the Jindong(...) usage tied
to ilCustom so slider movement only updates state and does not retrigger
Haptic(100.ms, HapticIntensity.Custom(ilCustom)); keep playback gated behind the
explicit Play control in CustomCard, similar to the other non-reactive modules.

In
`@sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/PresetGalleryScreen.kt`:
- Around line 195-205: The play chip’s touch target is still too small because
only the inner clickable Box in PresetGalleryScreen is interactive while the
outer defaultMinSize wrapper is not. Move the clickable modifier to the outer
Box (or otherwise make the 48dp container itself handle clicks) so the full
minimum touch area is tappable, while preserving the inner visual styling with
clip/border/padding.

In
`@sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/ReactiveScreen.kt`:
- Around line 117-128: The regression oracle is ineffective because `CaseCard`
receives `actual` from the same `expectedActual` state used for `expected`, so
failures in `singleBar`, `reactiveCountPattern`, or `TimelineMapper.toBars`
cannot be detected. Update the affected `CaseCard` usages in `ReactiveScreen` so
`actual` is derived from the rendered output/state independently of the expected
value, or change these fields to explicit explanatory labels if they are not
meant to be assertions.

In
`@sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/RepeatScreen.kt`:
- Around line 168-177: The repeatPattern() helper is offsetting each
ScheduledHapticEvent by a fixed +10ms, which makes the preview timeline diverge
from the actual Repeat { Haptic(); Delay() } playback starting at 0ms. Update
repeatPattern() in RepeatScreen so the generated start times align with the real
replayed pattern (keep the same 150ms spacing, but remove the artificial offset)
and ensure HapticPattern is built from the corrected event timestamps.

In
`@sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/RepeatWithIndexScreen.kt`:
- Around line 212-224: The preview/playback timing is inconsistent in
repeatIndexPattern, since the helper currently offsets each ScheduledHapticEvent
by 10ms while the RepeatWithIndex DSL path starts at 0ms. Update
repeatIndexPattern to use the same start-time scheme as the DSL-generated
timeline so both paths schedule events identically, and keep the change
localized to the repeatIndexPattern helper and any matching RepeatWithIndex
screen preview logic.

In
`@sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/SingleHapticScreen.kt`:
- Around line 182-188: The Jindong block in SingleHapticScreen is keyed on
sgDur, sgChip, and sgInt as well as playTrigger, which makes haptics re-run on
slider/chip edits instead of only on Play. Update the Jindong invocation so
execution is driven only by playTrigger, while still reading the live state
values inside the block for Haptic and resolvedIntensity. Keep the screen state
updates intact, but remove the non-Play keys from the Jindong call.

In
`@sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/TimingScreen.kt`:
- Around line 191-200: The click target is attached to the inner chip Box
instead of the outer min-sized container, so the tappable area does not match
the intended touch target. Update the TimingScreen layout so the outer Box with
defaultMinSize(minHeight = Dimens.minTouch) also owns the clickable/onClick
behavior, and keep the inner Box only for clipping/border/visual styling. This
ensures the add-node affordance uses the full minimum touch area while
preserving the chip appearance.

---

Nitpick comments:
In
`@jindong-compose/src/commonTest/kotlin/io/github/compose/jindong/HapticCapabilitiesTest.kt`:
- Around line 22-37: Add a composition-level test that exercises
rememberHapticCapabilities() instead of only testing the HapticCapabilities
constructor. Use a provider-backed setup with a fake LocalHapticExecutor to
verify the composable reads from composition and resolves the platform
correctly, then assert the returned snapshot values. Keep the existing
HapticCapabilitiesTest focused on constructor behavior, and add a new test case
that names rememberHapticCapabilities() and LocalHapticExecutor so the
regression path is covered.
🪄 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

Run ID: 07e1c527-25a1-4fd2-b1b0-1448e4d9a375

📥 Commits

Reviewing files that changed from the base of the PR and between 9f7bf95 and 75bfb01.

⛔ Files ignored due to path filters (4)
  • sample/shared/src/commonMain/composeResources/font/ibm_plex_mono_medium.ttf is excluded by !**/*.ttf
  • sample/shared/src/commonMain/composeResources/font/ibm_plex_mono_regular.ttf is excluded by !**/*.ttf
  • sample/shared/src/commonMain/composeResources/font/ibm_plex_mono_semibold.ttf is excluded by !**/*.ttf
  • sample/shared/src/commonMain/composeResources/font/instrument_sans_variable.ttf is excluded by !**/*.ttf
📒 Files selected for processing (41)
  • jindong-compose/api/jindong-compose.api
  • jindong-compose/api/jindong-compose.klib.api
  • jindong-compose/src/androidMain/kotlin/io/github/compose/jindong/HapticCapabilities.android.kt
  • jindong-compose/src/commonMain/kotlin/io/github/compose/jindong/HapticCapabilities.kt
  • jindong-compose/src/commonTest/kotlin/io/github/compose/jindong/HapticCapabilitiesTest.kt
  • jindong-compose/src/iosMain/kotlin/io/github/compose/jindong/HapticCapabilities.ios.kt
  • jindong-core/api/jindong-core.api
  • jindong-core/api/jindong-core.klib.api
  • jindong-core/src/androidMain/kotlin/io/github/compose/jindong/core/executor/HapticExecutor.android.kt
  • jindong-core/src/commonMain/kotlin/io/github/compose/jindong/core/executor/HapticExecutor.kt
  • jindong-core/src/commonTest/kotlin/io/github/compose/jindong/core/executor/HapticExecutorCapabilityTest.kt
  • jindong-core/src/commonTest/kotlin/io/github/compose/jindong/core/fake/FakeHapticExecutor.kt
  • jindong-core/src/iosMain/kotlin/io/github/compose/jindong/core/executor/HapticExecutor.ios.kt
  • sample/shared/src/commonMain/composeResources/files/IBMPlexMono-OFL.txt
  • sample/shared/src/commonMain/composeResources/files/InstrumentSans-OFL.txt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/SampleApp.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/CapabilityBadge.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/Chip.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/HapticTimeline.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/JindongIcons.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/JindongScaffold.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/LabeledSlider.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/MonoLabel.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/PlayButton.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/ScreenPieces.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/components/SegmentedToggle.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/nav/AppRoot.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/nav/Screen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/HarnessLogic.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/HomeScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/IntensityLabScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/PresetGalleryScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/ReactiveScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/RepeatScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/RepeatWithIndexScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/SingleHapticScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/screens/TimingScreen.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/theme/Dimens.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/theme/JindongColors.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/theme/JindongTheme.kt
  • sample/shared/src/commonMain/kotlin/io/github/compose/jindong/sample/theme/JindongTypography.kt

@l2hyunwoo
l2hyunwoo force-pushed the feature/sample-redesign branch from 9fc7146 to 6e858de Compare June 28, 2026 11:54

@wisemuji wisemuji left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks amazing!!! 🚀

@l2hyunwoo
l2hyunwoo merged commit b71e993 into main Jul 4, 2026
3 checks passed
@l2hyunwoo
l2hyunwoo deleted the feature/sample-redesign branch July 4, 2026 05:06
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