- This repository is the
react-native-halo-menupackage: a zero-native-code React Native hold menu built with TypeScript, Reanimated 4, React Native Worklets, and React Native Gesture Handler. - The package root is the library. The Expo demo app lives in
example/and resolves the library source through thesourceexport condition. - Treat
README.mdandCONTRIBUTING.mdas the public human docs. Use this file for agent-facing workflow, architecture, and implementation constraints.
- Install dependencies:
pnpm install - Run the demo:
pnpm --dir example start - Lint source:
pnpm run lint - Typecheck library:
pnpm run typecheck - Run tests:
pnpm run test - Check formatting:
pnpm run format:check - Build and validate package output:
pnpm run package:check - Check the example app:
pnpm run example:check - Verify worklet directives survived the build:
pnpm run worklet:check - Full CI gate:
pnpm run ci
Run targeted checks while iterating, then run the smallest reliable gate that covers the change. For public API, packaging, export, or peer dependency changes, run pnpm run package:check; before release-facing changes, run pnpm run ci.
src/index.tsis the public library entry point.src/HaloMenuProvider.tsxowns the root overlay, shared value graph, backdrop, lifted preview, action buttons, and hover label.src/HaloMenuTrigger.tsxis the default trigger wrapper.src/useHaloMenuTrigger.tsis the lower-level gesture hook and UI-to-JS bridge.src/internal/geometry.tscontains pure arc and hit-test math; keep this unit-testable.src/internal/config.tsresolves defaults for motion, layout, appearance, and colors.src/internal/state.tsdefines internal context/state contracts.src/expo/index.tsxis the optional Expo helper subpath. Do not import Expo-only modules from the core entry point.mock.jsandmock.d.tsare the published Jest mock surface.lib/,dist/,coverage/,node_modules/, native build folders, and*.tgzfiles are generated or local artifacts. Do not edit them directly.
- Keep the package zero native code. Do not add
ios/,android/, config plugins, or required native setup to the library. - Do not add new required runtime dependencies without an explicit product reason. App-specific icons, haptics, blur, and theming should remain injection points.
- Optional platform helpers must stay behind documented subpath exports with optional peers so bare React Native consumers do not pay for Expo-only code.
- Preserve the small public API. Prefer additive changes and document any public behavior change in
README.md,mock.d.ts, andllms.txtwhen relevant. - Keep
sideEffects: falsevalid: avoid module-level side effects except intentional constants and registries already used by the package.
- This package targets Reanimated 4, React Native Worklets, and React Native Gesture Handler 2.x builder APIs.
- Keep per-frame gesture tracking, hit-testing, placement, and animation work on the UI runtime using shared values and worklets.
- Do not use
PanResponderor React Native touch responder APIs for the core interaction. - Do not use
runOnJS; usescheduleOnRNfromreact-native-workletsfor JS-thread callbacks from worklets. - Memoize Gesture Handler 2.x gestures with
useMemoso recognizers do not reattach on every render. - Do not call React state setters, navigation, haptics, logging, or user callbacks directly from gesture/worklet code. Bridge them with
scheduleOnRN. - Keep existing
'worklet'directives and add them to UI-runtime bodies following the repo pattern. After build-affecting changes, runpnpm run worklet:check. - Respect OS Reduce Motion. Keep animations driven by Reanimated configs that use system reduce-motion behavior.
- Consumers need
GestureHandlerRootViewnear the app root andHaloMenuProvidermounted once inside it.
- Use TypeScript strict mode. Maintain
noUncheckedIndexedAccess,noUnusedLocals, andnoUnusedParameterscompatibility. - Follow the current Prettier style: double quotes, semicolons, trailing commas, and 2-space indentation.
- Use inline type imports where possible, matching the ESLint rule.
- Keep public types and public props documented with concise JSDoc.
- Prefer pure functions for geometry/config logic and add or update focused Jest tests for behavioral changes.
- Avoid
console.*in source. Use the provideronWarnchannel for development diagnostics. - Keep comments useful and sparse. Existing section comments are fine for complex gesture/animation code.
- For pure math, config, or public contract changes, add focused Jest coverage under
src/__tests__/. - For gesture, Reanimated, or visual behavior changes, update the example app if needed and run the relevant typecheck/build gates.
- For package export, file list, mock, peer dependency, or README install changes, run
pnpm run package:check. - For source changes that affect worklets, run
pnpm run buildbeforepnpm run worklet:checkiflib/is stale.
- Keep install instructions exact for Expo and bare React Native. Do not claim Expo Go support unless the public Expo SDK includes compatible peers.
- Changelog entries come from Conventional Commits through release tooling. Use commit types such as
feat:,fix:,docs:, andchore:. - Do not store long-lived npm tokens. Publishing uses GitHub trusted publishing with provenance.
- The worktree may contain user changes. Do not revert or overwrite unrelated edits.
- Prefer narrow, package-local changes that match the existing architecture.
- Ask before adding production dependencies, changing peer dependency ranges, or changing release/publish workflows.