home / skills / onekeyhq / app-monorepo / 1k-ui-recipes

1k-ui-recipes skill

/.claude/skills/1k-ui-recipes

This skill helps you apply OneKey UI recipes to improve tab bar offset, transitions, collapsible headers, and Android touch bypass.

npx playbooks add skill onekeyhq/app-monorepo --skill 1k-ui-recipes

Review the files below or copy the command above to add this skill to your agents.

Files (5)
SKILL.md
3.6 KB
---
name: 1k-ui-recipes
description: UI recipes for scroll offset (useScrollContentTabBarOffset), view transitions (startViewTransition), horizontal scroll in collapsible tab headers (CollapsibleTabContext), and Android bottom tab touch interception workaround.
allowed-tools: Read, Grep, Glob
---

# OneKey UI Recipes

Bite-sized solutions for common UI issues.

## Quick Reference

| Recipe | Guide | Key Points |
|--------|-------|------------|
| iOS Tab Bar Scroll Offset | [ios-tab-bar-scroll-offset.md](references/rules/ios-tab-bar-scroll-offset.md) | Use `useScrollContentTabBarOffset` for `paddingBottom` on iOS tab pages |
| Smooth State Transitions | [start-view-transition.md](references/rules/start-view-transition.md) | Wrap heavy state updates in `startViewTransition` for fade on web |
| Horizontal Scroll in Collapsible Tab Headers | [collapsible-tab-horizontal-scroll.md](references/rules/collapsible-tab-horizontal-scroll.md) | Bidirectional `Gesture.Pan()` + programmatic `scrollTo` via `CollapsibleTabContext` |
| Android Bottom Tab Touch Interception | [android-bottom-tab-touch-intercept.md](references/rules/android-bottom-tab-touch-intercept.md) | **Temporary** — `GestureDetector` + `Gesture.Tap()` in `.android.tsx` to bypass native tab bar touch stealing |

## Critical Rules Summary

### 1. iOS Tab Bar Scroll Content Offset

Use `useScrollContentTabBarOffset` to add dynamic `paddingBottom` to scroll containers inside tab pages. Returns tab bar height on iOS, `undefined` on other platforms.

```typescript
import { useScrollContentTabBarOffset } from '@onekeyhq/components';

const tabBarHeight = useScrollContentTabBarOffset();
<ScrollView contentContainerStyle={{ paddingBottom: tabBarHeight }} />
```

### 2. Smooth State Transitions with `startViewTransition`

Wrap heavy state updates in `startViewTransition` — fade on web/desktop via View Transition API, `setTimeout` fallback on native.

```typescript
import { startViewTransition } from '@onekeyhq/components';

startViewTransition(() => {
  setIsReady(true);
});
```

### 3. Horizontal Scroll in Collapsible Tab Headers (Native)

When placing a horizontal scroller inside `renderHeader` of collapsible tabs, use `Gesture.Pan()` that handles **both** directions — horizontal drives `translateX`, vertical calls `scrollTo` on the focused tab's ScrollView via `CollapsibleTabContext`.

```typescript
import { CollapsibleTabContext } from '@onekeyhq/components';
```

> **Do NOT** import directly from `react-native-collapsible-tab-view/src/Context`. Always use the `@onekeyhq/components` re-export.

### 4. Android Bottom Tab Touch Interception (Temporary Workaround)

> **Temporary fix** — the root cause is `react-native-bottom-tabs` intercepting touches even when hidden. This workaround should be removed once the upstream issue is fixed.

On Android, `react-native-bottom-tabs` intercepts touches in the tab bar region even when the tab bar is `GONE`. Buttons near the bottom of the screen become unclickable. Fix by creating a `.android.tsx` variant that wraps buttons with `GestureDetector` + `Gesture.Tap()`:

```typescript
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import { runOnJS } from 'react-native-reanimated';

const tapGesture = useMemo(
  () => Gesture.Tap().onEnd(() => { 'worklet'; runOnJS(onPress)(); }),
  [onPress],
);

<GestureDetector gesture={tapGesture}>
  <View>
    <Button>Label</Button>
  </View>
</GestureDetector>
```

> Use `.android.tsx` file extension so other platforms are unaffected.

---

## Related Skills

- `/1k-cross-platform` - Platform-specific development
- `/1k-performance` - Performance optimization
- `/1k-coding-patterns` - General coding patterns

Overview

This skill provides compact UI recipes for common cross-platform issues in a TypeScript React/React Native wallet app. It covers scroll offset handling for iOS tab pages, smooth view transitions on web/desktop, horizontal scrolling inside collapsible tab headers on native, and a temporary Android bottom-tab touch interception workaround. Each recipe is focused, practical, and ready to drop into production code.

How this skill works

Each recipe exposes a small API or pattern you can import and apply directly: a hook returns the dynamic tab-bar offset for scroll padding; a helper wraps heavy state updates to trigger a view transition; a context + gesture pattern synchronizes horizontal pan with the active tab's scroll view; and an Android-only gesture wrapper prevents native tab bar touch interception. Recipes prefer platform-specific files and re-exports for stable imports.

When to use it

  • Add bottom padding to ScrollView/FlatList on iOS tab pages so content isn't hidden by the tab bar.
  • Smoothly reveal heavy UI state changes on web/desktop using the View Transition API fallback.
  • Enable horizontal scrollers inside collapsible tab headers without breaking vertical scrolling.
  • Work around Android bottom tab components intercepting touches when hidden (temporary).
  • Prefer platform-specific variants (.android.tsx) when behavior must differ by OS.

Best practices

  • Import shared contexts and hooks from the components package re-exports, not upstream internals.
  • Use useScrollContentTabBarOffset only for tab page scroll containers; it returns undefined off iOS.
  • Wrap heavy state updates in startViewTransition to get smooth fades where supported.
  • Implement horizontal pan with bidirectional Gesture.Pan(): horizontal for translateX, vertical to call scrollTo via CollapsibleTabContext.
  • Keep the Android GestureDetector workaround isolated in .android.tsx and remove when upstream fixes the intercept bug.

Example use cases

  • Prevent the last list item from being obscured by the iOS bottom tab bar by applying paddingBottom from useScrollContentTabBarOffset.
  • Wrap a large state toggle that loads many components in startViewTransition to show a fade instead of a hard jump on web.
  • Place a category pill scroller inside a collapsible profile header that horizontally scrolls while preserving vertical tab scroll behavior.
  • Make a bottom-anchored confirm button clickable on Android by wrapping it with a GestureDetector in a .android.tsx file.

FAQ

Does useScrollContentTabBarOffset work on Android or web?

No — it returns the tab bar height on iOS and undefined on other platforms. Only apply the value when defined.

Is the Android touch interception fix permanent?

No — it is a temporary workaround. Keep it isolated to .android.tsx and remove once the upstream library is fixed.