react-native-earl-gamepad 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,9 @@
1
1
  # react-native-earl-gamepad
2
+ ![npm](https://img.shields.io/npm/v/react-native-earl-gamepad)
3
+ ![downloads](https://img.shields.io/npm/dm/react-native-earl-gamepad)
4
+ ![license](https://img.shields.io/npm/l/react-native-earl-gamepad)
2
5
 
3
6
  WebView-based gamepad bridge for React Native. Polls `navigator.getGamepads()` in a hidden WebView and surfaces buttons, sticks, d-pad, and connection events to JS.
4
-
5
7
  - Components: `GamepadBridge`, `useGamepad`, and `GamepadDebug`.
6
8
  - Deadzone handling (default `0.15`) with auto-clear on disconnect.
7
9
  - Typed events for buttons, axes, d-pad, and status.
@@ -45,6 +47,50 @@ export function Controls() {
45
47
  }
46
48
  ```
47
49
 
50
+ ### Control Logic Example
51
+
52
+ Here is an example of mapping D-pad events to movement vectors
53
+
54
+ ```tsx
55
+ import { useState, useCallback } from "react";
56
+ import { GamepadBridge, type DpadEvent } from "react-native-earl-gamepad";
57
+ type MoveKey = keyof typeof MOVES;
58
+
59
+ const MOVES: Record<string, [number, number]> = {
60
+ up: [1, 0],
61
+ down: [-1, 0],
62
+ right: [0, 1],
63
+ left: [0, -1],
64
+ stop: [0, 0],
65
+
66
+ axis_left_x_neg: [0, -1],
67
+ axis_left_x_pos: [0, 1],
68
+ axis_left_y_pos: [1, 0],
69
+ axis_left_y_neg: [-1, 0],
70
+
71
+ // add more
72
+ }; // example only for the control logic
73
+
74
+ export function Controls() {
75
+ const [active, setActive] = useState<string | null>(null);
76
+
77
+ const handleDpad = useCallback(
78
+ (event: DpadEvent) => {
79
+ const key = event.key as MoveKey;
80
+ if (event.pressed) {
81
+ if (active !== key) {
82
+ console.log("Dpad press", key);
83
+ }
84
+ } else if (active === key) {
85
+ // do something
86
+ }
87
+ },
88
+ [active]
89
+ );
90
+ return <GamepadBridge enabled onDpad={handleDpad} axisThreshold={0.15} />;
91
+ }
92
+ ```
93
+
48
94
  ### Hook for stateful consumption
49
95
 
50
96
  `useGamepad` keeps pressed state and axes for you. You still need to render the provided `bridge` element once.
@@ -1,5 +1,5 @@
1
- import { StyleProp, ViewStyle } from 'react-native';
2
- import type { AxisEvent, ButtonEvent, DpadEvent, StatusEvent } from './types';
1
+ import { StyleProp, ViewStyle } from "react-native";
2
+ import type { AxisEvent, ButtonEvent, DpadEvent, StatusEvent } from "./types";
3
3
  type Props = {
4
4
  enabled?: boolean;
5
5
  axisThreshold?: number;
@@ -118,16 +118,16 @@ function GamepadBridge({ enabled = true, axisThreshold = 0.15, onDpad, onButton,
118
118
  const handleMessage = (event) => {
119
119
  try {
120
120
  const data = JSON.parse(event.nativeEvent.data);
121
- if (data.type === 'dpad') {
121
+ if (data.type === "dpad") {
122
122
  onDpad === null || onDpad === void 0 ? void 0 : onDpad(data);
123
123
  }
124
- else if (data.type === 'button') {
124
+ else if (data.type === "button") {
125
125
  onButton === null || onButton === void 0 ? void 0 : onButton(data);
126
126
  }
127
- else if (data.type === 'axis') {
127
+ else if (data.type === "axis") {
128
128
  onAxis === null || onAxis === void 0 ? void 0 : onAxis(data);
129
129
  }
130
- else if (data.type === 'status') {
130
+ else if (data.type === "status") {
131
131
  onStatus === null || onStatus === void 0 ? void 0 : onStatus(data);
132
132
  }
133
133
  }
@@ -135,5 +135,10 @@ function GamepadBridge({ enabled = true, axisThreshold = 0.15, onDpad, onButton,
135
135
  // ignore malformed messages
136
136
  }
137
137
  };
138
- return ((0, jsx_runtime_1.jsx)(react_native_webview_1.default, { ref: webviewRef, source: { html }, originWhitelist: ['*'], onMessage: handleMessage, javaScriptEnabled: true, onLoad: focusBridge, onLayout: focusBridge, onTouchStart: focusBridge, style: style !== null && style !== void 0 ? style : { width: 1, height: 1, position: 'absolute', opacity: 0 } }));
138
+ return ((0, jsx_runtime_1.jsx)(react_native_webview_1.default, { ref: webviewRef, source: { html }, originWhitelist: ["*"], onMessage: handleMessage, javaScriptEnabled: true, onLoad: focusBridge, onLayout: focusBridge, onTouchStart: focusBridge, style: style !== null && style !== void 0 ? style : {
139
+ width: 1,
140
+ height: 1,
141
+ position: "absolute",
142
+ opacity: 0,
143
+ } }));
139
144
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-earl-gamepad",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "React Native gamepad bridge via WebView (buttons, sticks, d-pad, status).",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",