@ankhorage/zora-game 0.4.0 → 0.5.0
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/CHANGELOG.md +14 -0
- package/README.md +1 -1
- package/dist/ZORA_GAME_COMPONENT_META.d.ts +52 -1
- package/dist/ZORA_GAME_COMPONENT_META.d.ts.map +1 -1
- package/dist/ZORA_GAME_PLUGIN.d.ts +52 -1
- package/dist/ZORA_GAME_PLUGIN.d.ts.map +1 -1
- package/dist/ZORA_PLUGIN_METADATA.d.ts +52 -1
- package/dist/ZORA_PLUGIN_METADATA.d.ts.map +1 -1
- package/dist/features/game-presentation/adapters/inbound/GameInputZone.d.ts +2 -2
- package/dist/features/game-presentation/adapters/inbound/GameInputZone.d.ts.map +1 -1
- package/dist/features/game-presentation/adapters/inbound/GameInputZone.js +19 -5
- package/dist/features/game-presentation/adapters/inbound/GameInputZone.js.map +1 -1
- package/dist/features/game-presentation/adapters/inbound/createGameKeyboardEvent.d.ts +16 -0
- package/dist/features/game-presentation/adapters/inbound/createGameKeyboardEvent.d.ts.map +1 -0
- package/dist/features/game-presentation/adapters/inbound/createGameKeyboardEvent.js +16 -0
- package/dist/features/game-presentation/adapters/inbound/createGameKeyboardEvent.js.map +1 -0
- package/dist/features/game-presentation/adapters/inbound/useGameInputZoneResponder.d.ts +6 -0
- package/dist/features/game-presentation/adapters/inbound/useGameInputZoneResponder.d.ts.map +1 -1
- package/dist/features/game-presentation/adapters/inbound/useGameInputZoneResponder.js +15 -0
- package/dist/features/game-presentation/adapters/inbound/useGameInputZoneResponder.js.map +1 -1
- package/dist/features/game-presentation/composition/createGameBindingContext.d.ts.map +1 -1
- package/dist/features/game-presentation/composition/createGameBindingContext.js +1 -0
- package/dist/features/game-presentation/composition/createGameBindingContext.js.map +1 -1
- package/dist/features/game-presentation/meta/gameInputZoneMeta.d.ts +52 -1
- package/dist/features/game-presentation/meta/gameInputZoneMeta.d.ts.map +1 -1
- package/dist/features/game-presentation/meta/gameInputZoneMeta.js +47 -1
- package/dist/features/game-presentation/meta/gameInputZoneMeta.js.map +1 -1
- package/dist/features/game-presentation/public.d.ts +1 -1
- package/dist/features/game-presentation/public.d.ts.map +1 -1
- package/dist/features/game-presentation/public.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/gamePresentation.d.ts +7 -0
- package/dist/types/gamePresentation.d.ts.map +1 -1
- package/dist/types/gamePresentation.js.map +1 -1
- package/package.json +1 -1
- package/src/ZORA_PLUGIN_METADATA.test.ts +19 -10
- package/src/features/game-presentation/adapters/inbound/GameInputZone.tsx +36 -9
- package/src/features/game-presentation/adapters/inbound/createGameKeyboardEvent.test.ts +51 -0
- package/src/features/game-presentation/adapters/inbound/createGameKeyboardEvent.ts +33 -0
- package/src/features/game-presentation/adapters/inbound/useGameInputZoneResponder.ts +22 -0
- package/src/features/game-presentation/composition/createGameBindingContext.test.ts +20 -1
- package/src/features/game-presentation/composition/createGameBindingContext.ts +1 -0
- package/src/features/game-presentation/meta/gameInputZoneMeta.ts +47 -1
- package/src/features/game-presentation/public.ts +1 -0
- package/src/index.ts +1 -0
- package/src/types/gamePresentation.ts +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @ankhorage/zora-game
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 16cf5a7: Add declarative web keyboard bindings to GameInputZone while preserving its existing native/mobile
|
|
8
|
+
pointer and touch normalization path.
|
|
9
|
+
|
|
10
|
+
## 0.4.1
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- bba6595: Expose the current local game entities as a repeatable binding array while preserving the canonical
|
|
15
|
+
map-shaped GameSession entity storage.
|
|
16
|
+
|
|
3
17
|
## 0.4.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# @ankhorage/zora-game
|
|
5
5
|
|
|
6
|
-
         
|
|
7
7
|
|
|
8
8
|
Generic game presentation primitives for React Native and React Native Web apps built on ZORA.
|
|
9
9
|
|
|
@@ -346,7 +346,7 @@ export declare const ZORA_GAME_COMPONENT_META: {
|
|
|
346
346
|
readonly GameInputZone: {
|
|
347
347
|
readonly name: "GameInputZone";
|
|
348
348
|
readonly category: "component";
|
|
349
|
-
readonly description: "Normalizes pointer
|
|
349
|
+
readonly description: "Normalizes pointer/touch positions and optional keyboard bindings into generic game events.";
|
|
350
350
|
readonly directManifestNode: true;
|
|
351
351
|
readonly allowedChildren: readonly [];
|
|
352
352
|
readonly blueprint: {
|
|
@@ -443,6 +443,57 @@ export declare const ZORA_GAME_COMPONENT_META: {
|
|
|
443
443
|
readonly authority: "instance";
|
|
444
444
|
};
|
|
445
445
|
};
|
|
446
|
+
readonly keyboardBindings: {
|
|
447
|
+
readonly type: "array";
|
|
448
|
+
readonly category: "Input";
|
|
449
|
+
readonly label: "Keyboard bindings";
|
|
450
|
+
readonly default: readonly [];
|
|
451
|
+
readonly itemSchema: readonly [{
|
|
452
|
+
readonly key: "key";
|
|
453
|
+
readonly schema: {
|
|
454
|
+
readonly type: "string";
|
|
455
|
+
readonly category: "Input";
|
|
456
|
+
readonly label: "Key";
|
|
457
|
+
readonly authoring: {
|
|
458
|
+
readonly authority: "instance";
|
|
459
|
+
};
|
|
460
|
+
};
|
|
461
|
+
}, {
|
|
462
|
+
readonly key: "eventType";
|
|
463
|
+
readonly schema: {
|
|
464
|
+
readonly type: "string";
|
|
465
|
+
readonly category: "Input";
|
|
466
|
+
readonly label: "Event type";
|
|
467
|
+
readonly authoring: {
|
|
468
|
+
readonly authority: "instance";
|
|
469
|
+
};
|
|
470
|
+
};
|
|
471
|
+
}, {
|
|
472
|
+
readonly key: "entityId";
|
|
473
|
+
readonly schema: {
|
|
474
|
+
readonly type: "string";
|
|
475
|
+
readonly category: "Input";
|
|
476
|
+
readonly label: "Entity id";
|
|
477
|
+
readonly authoring: {
|
|
478
|
+
readonly authority: "instance";
|
|
479
|
+
};
|
|
480
|
+
};
|
|
481
|
+
}, {
|
|
482
|
+
readonly key: "preventDefault";
|
|
483
|
+
readonly schema: {
|
|
484
|
+
readonly type: "boolean";
|
|
485
|
+
readonly category: "Input";
|
|
486
|
+
readonly label: "Prevent browser default";
|
|
487
|
+
readonly default: false;
|
|
488
|
+
readonly authoring: {
|
|
489
|
+
readonly authority: "instance";
|
|
490
|
+
};
|
|
491
|
+
};
|
|
492
|
+
}];
|
|
493
|
+
readonly authoring: {
|
|
494
|
+
readonly authority: "instance";
|
|
495
|
+
};
|
|
496
|
+
};
|
|
446
497
|
readonly accessibilityLabel: {
|
|
447
498
|
readonly type: "string";
|
|
448
499
|
readonly category: "Accessibility";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZORA_GAME_COMPONENT_META.d.ts","sourceRoot":"","sources":["../src/ZORA_GAME_COMPONENT_META.ts"],"names":[],"mappings":"AAMA,8EAA8E;AAC9E,eAAO,MAAM,wBAAwB
|
|
1
|
+
{"version":3,"file":"ZORA_GAME_COMPONENT_META.d.ts","sourceRoot":"","sources":["../src/ZORA_GAME_COMPONENT_META.ts"],"names":[],"mappings":"AAMA,8EAA8E;AAC9E,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAM3B,CAAC"}
|
|
@@ -361,7 +361,7 @@ export declare const ZORA_GAME_PLUGIN: {
|
|
|
361
361
|
readonly GameInputZone: {
|
|
362
362
|
readonly name: "GameInputZone";
|
|
363
363
|
readonly category: "component";
|
|
364
|
-
readonly description: "Normalizes pointer
|
|
364
|
+
readonly description: "Normalizes pointer/touch positions and optional keyboard bindings into generic game events.";
|
|
365
365
|
readonly directManifestNode: true;
|
|
366
366
|
readonly allowedChildren: readonly [];
|
|
367
367
|
readonly blueprint: {
|
|
@@ -458,6 +458,57 @@ export declare const ZORA_GAME_PLUGIN: {
|
|
|
458
458
|
readonly authority: "instance";
|
|
459
459
|
};
|
|
460
460
|
};
|
|
461
|
+
readonly keyboardBindings: {
|
|
462
|
+
readonly type: "array";
|
|
463
|
+
readonly category: "Input";
|
|
464
|
+
readonly label: "Keyboard bindings";
|
|
465
|
+
readonly default: readonly [];
|
|
466
|
+
readonly itemSchema: readonly [{
|
|
467
|
+
readonly key: "key";
|
|
468
|
+
readonly schema: {
|
|
469
|
+
readonly type: "string";
|
|
470
|
+
readonly category: "Input";
|
|
471
|
+
readonly label: "Key";
|
|
472
|
+
readonly authoring: {
|
|
473
|
+
readonly authority: "instance";
|
|
474
|
+
};
|
|
475
|
+
};
|
|
476
|
+
}, {
|
|
477
|
+
readonly key: "eventType";
|
|
478
|
+
readonly schema: {
|
|
479
|
+
readonly type: "string";
|
|
480
|
+
readonly category: "Input";
|
|
481
|
+
readonly label: "Event type";
|
|
482
|
+
readonly authoring: {
|
|
483
|
+
readonly authority: "instance";
|
|
484
|
+
};
|
|
485
|
+
};
|
|
486
|
+
}, {
|
|
487
|
+
readonly key: "entityId";
|
|
488
|
+
readonly schema: {
|
|
489
|
+
readonly type: "string";
|
|
490
|
+
readonly category: "Input";
|
|
491
|
+
readonly label: "Entity id";
|
|
492
|
+
readonly authoring: {
|
|
493
|
+
readonly authority: "instance";
|
|
494
|
+
};
|
|
495
|
+
};
|
|
496
|
+
}, {
|
|
497
|
+
readonly key: "preventDefault";
|
|
498
|
+
readonly schema: {
|
|
499
|
+
readonly type: "boolean";
|
|
500
|
+
readonly category: "Input";
|
|
501
|
+
readonly label: "Prevent browser default";
|
|
502
|
+
readonly default: false;
|
|
503
|
+
readonly authoring: {
|
|
504
|
+
readonly authority: "instance";
|
|
505
|
+
};
|
|
506
|
+
};
|
|
507
|
+
}];
|
|
508
|
+
readonly authoring: {
|
|
509
|
+
readonly authority: "instance";
|
|
510
|
+
};
|
|
511
|
+
};
|
|
461
512
|
readonly accessibilityLabel: {
|
|
462
513
|
readonly type: "string";
|
|
463
514
|
readonly category: "Accessibility";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZORA_GAME_PLUGIN.d.ts","sourceRoot":"","sources":["../src/ZORA_GAME_PLUGIN.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oDAAoD,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,0DAA0D,CAAC;AACtF,OAAO,EAAE,SAAS,EAAE,MAAM,yDAAyD,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,6DAA6D,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,MAAM,2DAA2D,CAAC;AAGxF,+FAA+F;AAC/F,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"ZORA_GAME_PLUGIN.d.ts","sourceRoot":"","sources":["../src/ZORA_GAME_PLUGIN.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oDAAoD,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,0DAA0D,CAAC;AACtF,OAAO,EAAE,SAAS,EAAE,MAAM,yDAAyD,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,6DAA6D,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,MAAM,2DAA2D,CAAC;AAGxF,+FAA+F;AAC/F,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CASnB,CAAC"}
|
|
@@ -349,7 +349,7 @@ export declare const ZORA_PLUGIN_METADATA: {
|
|
|
349
349
|
readonly GameInputZone: {
|
|
350
350
|
readonly name: "GameInputZone";
|
|
351
351
|
readonly category: "component";
|
|
352
|
-
readonly description: "Normalizes pointer
|
|
352
|
+
readonly description: "Normalizes pointer/touch positions and optional keyboard bindings into generic game events.";
|
|
353
353
|
readonly directManifestNode: true;
|
|
354
354
|
readonly allowedChildren: readonly [];
|
|
355
355
|
readonly blueprint: {
|
|
@@ -446,6 +446,57 @@ export declare const ZORA_PLUGIN_METADATA: {
|
|
|
446
446
|
readonly authority: "instance";
|
|
447
447
|
};
|
|
448
448
|
};
|
|
449
|
+
readonly keyboardBindings: {
|
|
450
|
+
readonly type: "array";
|
|
451
|
+
readonly category: "Input";
|
|
452
|
+
readonly label: "Keyboard bindings";
|
|
453
|
+
readonly default: readonly [];
|
|
454
|
+
readonly itemSchema: readonly [{
|
|
455
|
+
readonly key: "key";
|
|
456
|
+
readonly schema: {
|
|
457
|
+
readonly type: "string";
|
|
458
|
+
readonly category: "Input";
|
|
459
|
+
readonly label: "Key";
|
|
460
|
+
readonly authoring: {
|
|
461
|
+
readonly authority: "instance";
|
|
462
|
+
};
|
|
463
|
+
};
|
|
464
|
+
}, {
|
|
465
|
+
readonly key: "eventType";
|
|
466
|
+
readonly schema: {
|
|
467
|
+
readonly type: "string";
|
|
468
|
+
readonly category: "Input";
|
|
469
|
+
readonly label: "Event type";
|
|
470
|
+
readonly authoring: {
|
|
471
|
+
readonly authority: "instance";
|
|
472
|
+
};
|
|
473
|
+
};
|
|
474
|
+
}, {
|
|
475
|
+
readonly key: "entityId";
|
|
476
|
+
readonly schema: {
|
|
477
|
+
readonly type: "string";
|
|
478
|
+
readonly category: "Input";
|
|
479
|
+
readonly label: "Entity id";
|
|
480
|
+
readonly authoring: {
|
|
481
|
+
readonly authority: "instance";
|
|
482
|
+
};
|
|
483
|
+
};
|
|
484
|
+
}, {
|
|
485
|
+
readonly key: "preventDefault";
|
|
486
|
+
readonly schema: {
|
|
487
|
+
readonly type: "boolean";
|
|
488
|
+
readonly category: "Input";
|
|
489
|
+
readonly label: "Prevent browser default";
|
|
490
|
+
readonly default: false;
|
|
491
|
+
readonly authoring: {
|
|
492
|
+
readonly authority: "instance";
|
|
493
|
+
};
|
|
494
|
+
};
|
|
495
|
+
}];
|
|
496
|
+
readonly authoring: {
|
|
497
|
+
readonly authority: "instance";
|
|
498
|
+
};
|
|
499
|
+
};
|
|
449
500
|
readonly accessibilityLabel: {
|
|
450
501
|
readonly type: "string";
|
|
451
502
|
readonly category: "Accessibility";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZORA_PLUGIN_METADATA.d.ts","sourceRoot":"","sources":["../src/ZORA_PLUGIN_METADATA.ts"],"names":[],"mappings":"AAIA,sFAAsF;AACtF,eAAO,MAAM,oBAAoB
|
|
1
|
+
{"version":3,"file":"ZORA_PLUGIN_METADATA.d.ts","sourceRoot":"","sources":["../src/ZORA_PLUGIN_METADATA.ts"],"names":[],"mappings":"AAIA,sFAAsF;AACtF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BM,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { GameInputZoneProps } from '../../../../types/gamePresentation';
|
|
2
|
-
/*** Capture pointer/touch geometry and
|
|
3
|
-
export declare function GameInputZone({ x, y, width, height, zIndex, enabled, continuous, accessibilityLabel, testID, ...inputProps }: GameInputZoneProps): import("react").JSX.Element;
|
|
2
|
+
/*** Capture pointer/touch geometry and optional keyboard input as normalized generic Game events. */
|
|
3
|
+
export declare function GameInputZone({ x, y, width, height, zIndex, enabled, continuous, keyboardBindings, accessibilityLabel, testID, ...inputProps }: GameInputZoneProps): import("react").JSX.Element;
|
|
4
4
|
//# sourceMappingURL=GameInputZone.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GameInputZone.d.ts","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/GameInputZone.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAI7E,
|
|
1
|
+
{"version":3,"file":"GameInputZone.d.ts","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/GameInputZone.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAI7E,qGAAqG;AACrG,wBAAgB,aAAa,CAAC,EAC5B,CAAK,EACL,CAAK,EACL,KAAW,EACX,MAAY,EACZ,MAAU,EACV,OAAc,EACd,UAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,MAAM,EACN,GAAG,UAAU,EACd,EAAE,kBAAkB,+BAiCpB"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { StyleSheet, View } from 'react-native';
|
|
1
|
+
import { Platform, StyleSheet, View } from 'react-native';
|
|
2
2
|
import { toGamePercentage } from '../../utils/toGamePercentage';
|
|
3
3
|
import { useGameInputZoneResponder } from './useGameInputZoneResponder';
|
|
4
|
-
/*** Capture pointer/touch geometry and
|
|
5
|
-
export function GameInputZone({ x = 0, y = 0, width = 100, height = 100, zIndex = 0, enabled = true, continuous = true, accessibilityLabel, testID, ...inputProps }) {
|
|
6
|
-
const { dispatchPointer, handleLayout, shouldSetResponder } = useGameInputZoneResponder({
|
|
4
|
+
/*** Capture pointer/touch geometry and optional keyboard input as normalized generic Game events. */
|
|
5
|
+
export function GameInputZone({ x = 0, y = 0, width = 100, height = 100, zIndex = 0, enabled = true, continuous = true, keyboardBindings, accessibilityLabel, testID, ...inputProps }) {
|
|
6
|
+
const { dispatchKeyboard, dispatchPointer, handleLayout, shouldSetResponder } = useGameInputZoneResponder({
|
|
7
7
|
...inputProps,
|
|
8
8
|
x,
|
|
9
9
|
y,
|
|
@@ -11,11 +11,25 @@ export function GameInputZone({ x = 0, y = 0, width = 100, height = 100, zIndex
|
|
|
11
11
|
height,
|
|
12
12
|
enabled,
|
|
13
13
|
continuous,
|
|
14
|
+
...(keyboardBindings === undefined ? {} : { keyboardBindings }),
|
|
14
15
|
});
|
|
15
|
-
|
|
16
|
+
const keyboardProps = createGameInputZoneKeyboardProps({
|
|
17
|
+
dispatchKeyboard,
|
|
18
|
+
enabled,
|
|
19
|
+
keyboardBindings,
|
|
20
|
+
});
|
|
21
|
+
return (<View {...keyboardProps} {...(accessibilityLabel === undefined ? {} : { accessibilityLabel })} {...(testID === undefined ? {} : { testID })} {...(continuous
|
|
16
22
|
? { onResponderGrant: dispatchPointer, onResponderMove: dispatchPointer }
|
|
17
23
|
: { onResponderRelease: dispatchPointer })} collapsable={false} onLayout={handleLayout} onStartShouldSetResponder={shouldSetResponder} pointerEvents={enabled ? 'auto' : 'none'} style={createInputZoneStyle({ x, y, width, height, zIndex })}/>);
|
|
18
24
|
}
|
|
25
|
+
/*** Add a focusable web keyboard target only when the input zone owns key bindings. */
|
|
26
|
+
function createGameInputZoneKeyboardProps({ dispatchKeyboard, enabled, keyboardBindings, }) {
|
|
27
|
+
if (Platform.OS !== 'web' || !enabled || keyboardBindings === undefined)
|
|
28
|
+
return {};
|
|
29
|
+
if (keyboardBindings.length === 0)
|
|
30
|
+
return {};
|
|
31
|
+
return { onKeyDown: dispatchKeyboard, tabIndex: 0 };
|
|
32
|
+
}
|
|
19
33
|
/*** Convert field-relative input-zone props into one absolute React Native style. */
|
|
20
34
|
function createInputZoneStyle({ x, y, width, height, zIndex }) {
|
|
21
35
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GameInputZone.js","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/GameInputZone.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAkB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"GameInputZone.js","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/GameInputZone.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Platform, StyleSheet, View, type ViewStyle } from 'react-native';\n\nimport type { GameInputZoneProps } from '../../../../types/gamePresentation';\nimport { toGamePercentage } from '../../utils/toGamePercentage';\nimport { useGameInputZoneResponder } from './useGameInputZoneResponder';\n\n/*** Capture pointer/touch geometry and optional keyboard input as normalized generic Game events. */\nexport function GameInputZone({\n x = 0,\n y = 0,\n width = 100,\n height = 100,\n zIndex = 0,\n enabled = true,\n continuous = true,\n keyboardBindings,\n accessibilityLabel,\n testID,\n ...inputProps\n}: GameInputZoneProps) {\n const { dispatchKeyboard, dispatchPointer, handleLayout, shouldSetResponder } =\n useGameInputZoneResponder({\n ...inputProps,\n x,\n y,\n width,\n height,\n enabled,\n continuous,\n ...(keyboardBindings === undefined ? {} : { keyboardBindings }),\n });\n const keyboardProps = createGameInputZoneKeyboardProps({\n dispatchKeyboard,\n enabled,\n keyboardBindings,\n });\n\n return (\n <View\n {...keyboardProps}\n {...(accessibilityLabel === undefined ? {} : { accessibilityLabel })}\n {...(testID === undefined ? {} : { testID })}\n {...(continuous\n ? { onResponderGrant: dispatchPointer, onResponderMove: dispatchPointer }\n : { onResponderRelease: dispatchPointer })}\n collapsable={false}\n onLayout={handleLayout}\n onStartShouldSetResponder={shouldSetResponder}\n pointerEvents={enabled ? 'auto' : 'none'}\n style={createInputZoneStyle({ x, y, width, height, zIndex })}\n />\n );\n}\n\ninterface GameInputZoneKeyboardPropsInput {\n readonly dispatchKeyboard: (event: { readonly key: string; preventDefault(): void }) => void;\n readonly enabled: boolean;\n readonly keyboardBindings: GameInputZoneProps['keyboardBindings'];\n}\n\n/*** Add a focusable web keyboard target only when the input zone owns key bindings. */\nfunction createGameInputZoneKeyboardProps({\n dispatchKeyboard,\n enabled,\n keyboardBindings,\n}: GameInputZoneKeyboardPropsInput) {\n if (Platform.OS !== 'web' || !enabled || keyboardBindings === undefined) return {};\n if (keyboardBindings.length === 0) return {};\n\n return { onKeyDown: dispatchKeyboard, tabIndex: 0 as const };\n}\n\ninterface InputZoneStyleInput {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n readonly zIndex: number;\n}\n\n/*** Convert field-relative input-zone props into one absolute React Native style. */\nfunction createInputZoneStyle({ x, y, width, height, zIndex }: InputZoneStyleInput): ViewStyle {\n return {\n left: toGamePercentage(x),\n top: toGamePercentage(y),\n width: toGamePercentage(width),\n height: toGamePercentage(height),\n zIndex,\n ...styles.root,\n };\n}\n\nconst styles = StyleSheet.create({\n root: {\n position: 'absolute',\n },\n});\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { GameEvent } from '@ankhorage/game';
|
|
2
|
+
import type { GameKeyboardBinding } from '../../../../types/gamePresentation';
|
|
3
|
+
interface CreateGameKeyboardEventInput {
|
|
4
|
+
readonly bindings: readonly GameKeyboardBinding[];
|
|
5
|
+
readonly fallbackEventType: string;
|
|
6
|
+
readonly fallbackEntityId?: string;
|
|
7
|
+
readonly key: string;
|
|
8
|
+
}
|
|
9
|
+
interface GameKeyboardEventResult {
|
|
10
|
+
readonly event: GameEvent;
|
|
11
|
+
readonly preventDefault: boolean;
|
|
12
|
+
}
|
|
13
|
+
/*** Map one configured keyboard key into a generic Game event. */
|
|
14
|
+
export declare function createGameKeyboardEvent(input: CreateGameKeyboardEventInput): GameKeyboardEventResult | undefined;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=createGameKeyboardEvent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createGameKeyboardEvent.d.ts","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/createGameKeyboardEvent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAE9E,UAAU,4BAA4B;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAClD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,uBAAuB;IAC/B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAED,kEAAkE;AAClE,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,4BAA4B,GAClC,uBAAuB,GAAG,SAAS,CAarC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*** Map one configured keyboard key into a generic Game event. */
|
|
2
|
+
export function createGameKeyboardEvent(input) {
|
|
3
|
+
const binding = input.bindings.find((candidate) => candidate.key === input.key);
|
|
4
|
+
if (binding === undefined)
|
|
5
|
+
return undefined;
|
|
6
|
+
const entityId = binding.entityId ?? input.fallbackEntityId;
|
|
7
|
+
return {
|
|
8
|
+
event: {
|
|
9
|
+
type: binding.eventType ?? input.fallbackEventType,
|
|
10
|
+
...(entityId === undefined ? {} : { entityId }),
|
|
11
|
+
payload: { key: input.key },
|
|
12
|
+
},
|
|
13
|
+
preventDefault: binding.preventDefault ?? false,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=createGameKeyboardEvent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createGameKeyboardEvent.js","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/createGameKeyboardEvent.ts"],"names":[],"mappings":"AAgBA,kEAAkE;AAClE,MAAM,UAAU,uBAAuB,CACrC,KAAmC;IAEnC,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC;IAChF,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAE5C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC,gBAAgB,CAAC;IAC5D,OAAO;QACL,KAAK,EAAE;YACL,IAAI,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC,iBAAiB;YAClD,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;YAC/C,OAAO,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE;SAC5B;QACD,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,KAAK;KAChD,CAAC;AACJ,CAAC","sourcesContent":["import type { GameEvent } from '@ankhorage/game';\n\nimport type { GameKeyboardBinding } from '../../../../types/gamePresentation';\n\ninterface CreateGameKeyboardEventInput {\n readonly bindings: readonly GameKeyboardBinding[];\n readonly fallbackEventType: string;\n readonly fallbackEntityId?: string;\n readonly key: string;\n}\n\ninterface GameKeyboardEventResult {\n readonly event: GameEvent;\n readonly preventDefault: boolean;\n}\n\n/*** Map one configured keyboard key into a generic Game event. */\nexport function createGameKeyboardEvent(\n input: CreateGameKeyboardEventInput,\n): GameKeyboardEventResult | undefined {\n const binding = input.bindings.find((candidate) => candidate.key === input.key);\n if (binding === undefined) return undefined;\n\n const entityId = binding.entityId ?? input.fallbackEntityId;\n return {\n event: {\n type: binding.eventType ?? input.fallbackEventType,\n ...(entityId === undefined ? {} : { entityId }),\n payload: { key: input.key },\n },\n preventDefault: binding.preventDefault ?? false,\n };\n}\n"]}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import type { GestureResponderEvent, LayoutChangeEvent } from 'react-native';
|
|
2
2
|
import type { GameInputZoneProps } from '../../../../types/gamePresentation';
|
|
3
|
+
interface GameKeyboardInputEvent {
|
|
4
|
+
readonly key: string;
|
|
5
|
+
preventDefault(): void;
|
|
6
|
+
}
|
|
3
7
|
/*** Own React Native responder measurement and event dispatch for one Game input zone. */
|
|
4
8
|
export declare function useGameInputZoneResponder(props: GameInputZoneProps): {
|
|
9
|
+
dispatchKeyboard: (event: GameKeyboardInputEvent) => void;
|
|
5
10
|
dispatchPointer: (event: GestureResponderEvent) => void;
|
|
6
11
|
handleLayout: (event: LayoutChangeEvent) => void;
|
|
7
12
|
shouldSetResponder: () => boolean;
|
|
8
13
|
};
|
|
14
|
+
export {};
|
|
9
15
|
//# sourceMappingURL=useGameInputZoneResponder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGameInputZoneResponder.d.ts","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/useGameInputZoneResponder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"useGameInputZoneResponder.d.ts","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/useGameInputZoneResponder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAK7E,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,cAAc,IAAI,IAAI,CAAC;CACxB;AAOD,0FAA0F;AAC1F,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,kBAAkB;8BA+BvD,sBAAsB;6BApBtB,qBAAqB;0BANgB,iBAAiB;;EA8CjE"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { GameRuntimeContext } from '../../composition/GameRuntimeContext';
|
|
3
|
+
import { createGameKeyboardEvent } from './createGameKeyboardEvent';
|
|
3
4
|
import { createGamePointerEvent } from './createGamePointerEvent';
|
|
4
5
|
/*** Own React Native responder measurement and event dispatch for one Game input zone. */
|
|
5
6
|
export function useGameInputZoneResponder(props) {
|
|
@@ -28,7 +29,21 @@ export function useGameInputZoneResponder(props) {
|
|
|
28
29
|
if (gameEvent !== undefined)
|
|
29
30
|
runtime.dispatch(gameEvent);
|
|
30
31
|
}, [props.entityId, props.eventType, props.height, props.width, props.x, props.y, runtime]);
|
|
32
|
+
const dispatchKeyboard = React.useCallback((event) => {
|
|
33
|
+
const result = createGameKeyboardEvent({
|
|
34
|
+
bindings: props.keyboardBindings ?? [],
|
|
35
|
+
fallbackEventType: props.eventType,
|
|
36
|
+
...(props.entityId === undefined ? {} : { fallbackEntityId: props.entityId }),
|
|
37
|
+
key: event.key,
|
|
38
|
+
});
|
|
39
|
+
if (result === undefined)
|
|
40
|
+
return;
|
|
41
|
+
if (result.preventDefault)
|
|
42
|
+
event.preventDefault();
|
|
43
|
+
runtime.dispatch(result.event);
|
|
44
|
+
}, [props.entityId, props.eventType, props.keyboardBindings, runtime]);
|
|
31
45
|
return {
|
|
46
|
+
dispatchKeyboard,
|
|
32
47
|
dispatchPointer,
|
|
33
48
|
handleLayout,
|
|
34
49
|
shouldSetResponder: () => props.enabled ?? true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGameInputZoneResponder.js","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/useGameInputZoneResponder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"useGameInputZoneResponder.js","sourceRoot":"","sources":["../../../../../src/features/game-presentation/adapters/inbound/useGameInputZoneResponder.ts"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport type { GestureResponderEvent, LayoutChangeEvent } from 'react-native';\n\nimport type { GameInputZoneProps } from '../../../../types/gamePresentation';\nimport { GameRuntimeContext } from '../../composition/GameRuntimeContext';\nimport { createGameKeyboardEvent } from './createGameKeyboardEvent';\nimport { createGamePointerEvent } from './createGamePointerEvent';\n\ninterface GameKeyboardInputEvent {\n readonly key: string;\n preventDefault(): void;\n}\n\ninterface MeasuredSize {\n readonly width: number;\n readonly height: number;\n}\n\n/*** Own React Native responder measurement and event dispatch for one Game input zone. */\nexport function useGameInputZoneResponder(props: GameInputZoneProps) {\n const runtime = React.useContext(GameRuntimeContext);\n if (runtime === null) throw new Error('GameInputZone must be rendered inside Game.');\n\n const measuredSizeRef = React.useRef<MeasuredSize>({ width: 0, height: 0 });\n const handleLayout = React.useCallback((event: LayoutChangeEvent) => {\n const { width, height } = event.nativeEvent.layout;\n measuredSizeRef.current = { width, height };\n }, []);\n\n const dispatchPointer = React.useCallback(\n (event: GestureResponderEvent) => {\n const measured = measuredSizeRef.current;\n const gameEvent = createGamePointerEvent({\n eventType: props.eventType,\n ...(props.entityId === undefined ? {} : { entityId: props.entityId }),\n localX: event.nativeEvent.locationX,\n localY: event.nativeEvent.locationY,\n measuredWidth: measured.width,\n measuredHeight: measured.height,\n zoneX: props.x ?? 0,\n zoneY: props.y ?? 0,\n zoneWidth: props.width ?? 100,\n zoneHeight: props.height ?? 100,\n });\n if (gameEvent !== undefined) runtime.dispatch(gameEvent);\n },\n [props.entityId, props.eventType, props.height, props.width, props.x, props.y, runtime],\n );\n\n const dispatchKeyboard = React.useCallback(\n (event: GameKeyboardInputEvent) => {\n const result = createGameKeyboardEvent({\n bindings: props.keyboardBindings ?? [],\n fallbackEventType: props.eventType,\n ...(props.entityId === undefined ? {} : { fallbackEntityId: props.entityId }),\n key: event.key,\n });\n if (result === undefined) return;\n if (result.preventDefault) event.preventDefault();\n runtime.dispatch(result.event);\n },\n [props.entityId, props.eventType, props.keyboardBindings, runtime],\n );\n\n return {\n dispatchKeyboard,\n dispatchPointer,\n handleLayout,\n shouldSetResponder: () => props.enabled ?? true,\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createGameBindingContext.d.ts","sourceRoot":"","sources":["../../../../src/features/game-presentation/composition/createGameBindingContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,kFAAkF;AAClF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"createGameBindingContext.d.ts","sourceRoot":"","sources":["../../../../src/features/game-presentation/composition/createGameBindingContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,kFAAkF;AAClF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOtF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createGameBindingContext.js","sourceRoot":"","sources":["../../../../src/features/game-presentation/composition/createGameBindingContext.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,MAAM,UAAU,wBAAwB,CAAC,OAAoB;IAC3D,OAAO;QACL,IAAI,EAAE;YACJ,OAAO;SACR;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { GameSession } from '@ankhorage/game';\n\n/*** Create the canonical Runtime context namespace for one local game session. */\nexport function createGameBindingContext(session: GameSession): Record<string, unknown> {\n return {\n game: {\n session,\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createGameBindingContext.js","sourceRoot":"","sources":["../../../../src/features/game-presentation/composition/createGameBindingContext.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,MAAM,UAAU,wBAAwB,CAAC,OAAoB;IAC3D,OAAO;QACL,IAAI,EAAE;YACJ,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;YACzC,OAAO;SACR;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { GameSession } from '@ankhorage/game';\n\n/*** Create the canonical Runtime context namespace for one local game session. */\nexport function createGameBindingContext(session: GameSession): Record<string, unknown> {\n return {\n game: {\n entities: Object.values(session.entities),\n session,\n },\n };\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export declare const gameInputZoneMeta: {
|
|
3
3
|
readonly name: "GameInputZone";
|
|
4
4
|
readonly category: "component";
|
|
5
|
-
readonly description: "Normalizes pointer
|
|
5
|
+
readonly description: "Normalizes pointer/touch positions and optional keyboard bindings into generic game events.";
|
|
6
6
|
readonly directManifestNode: true;
|
|
7
7
|
readonly allowedChildren: readonly [];
|
|
8
8
|
readonly blueprint: {
|
|
@@ -99,6 +99,57 @@ export declare const gameInputZoneMeta: {
|
|
|
99
99
|
readonly authority: "instance";
|
|
100
100
|
};
|
|
101
101
|
};
|
|
102
|
+
readonly keyboardBindings: {
|
|
103
|
+
readonly type: "array";
|
|
104
|
+
readonly category: "Input";
|
|
105
|
+
readonly label: "Keyboard bindings";
|
|
106
|
+
readonly default: readonly [];
|
|
107
|
+
readonly itemSchema: readonly [{
|
|
108
|
+
readonly key: "key";
|
|
109
|
+
readonly schema: {
|
|
110
|
+
readonly type: "string";
|
|
111
|
+
readonly category: "Input";
|
|
112
|
+
readonly label: "Key";
|
|
113
|
+
readonly authoring: {
|
|
114
|
+
readonly authority: "instance";
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
}, {
|
|
118
|
+
readonly key: "eventType";
|
|
119
|
+
readonly schema: {
|
|
120
|
+
readonly type: "string";
|
|
121
|
+
readonly category: "Input";
|
|
122
|
+
readonly label: "Event type";
|
|
123
|
+
readonly authoring: {
|
|
124
|
+
readonly authority: "instance";
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
}, {
|
|
128
|
+
readonly key: "entityId";
|
|
129
|
+
readonly schema: {
|
|
130
|
+
readonly type: "string";
|
|
131
|
+
readonly category: "Input";
|
|
132
|
+
readonly label: "Entity id";
|
|
133
|
+
readonly authoring: {
|
|
134
|
+
readonly authority: "instance";
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
}, {
|
|
138
|
+
readonly key: "preventDefault";
|
|
139
|
+
readonly schema: {
|
|
140
|
+
readonly type: "boolean";
|
|
141
|
+
readonly category: "Input";
|
|
142
|
+
readonly label: "Prevent browser default";
|
|
143
|
+
readonly default: false;
|
|
144
|
+
readonly authoring: {
|
|
145
|
+
readonly authority: "instance";
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
}];
|
|
149
|
+
readonly authoring: {
|
|
150
|
+
readonly authority: "instance";
|
|
151
|
+
};
|
|
152
|
+
};
|
|
102
153
|
readonly accessibilityLabel: {
|
|
103
154
|
readonly type: "string";
|
|
104
155
|
readonly category: "Accessibility";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gameInputZoneMeta.d.ts","sourceRoot":"","sources":["../../../../src/features/game-presentation/meta/gameInputZoneMeta.ts"],"names":[],"mappings":"AAEA,8FAA8F;AAC9F,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"gameInputZoneMeta.d.ts","sourceRoot":"","sources":["../../../../src/features/game-presentation/meta/gameInputZoneMeta.ts"],"names":[],"mappings":"AAEA,8FAA8F;AAC9F,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwIQ,CAAC"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export const gameInputZoneMeta = {
|
|
3
3
|
name: 'GameInputZone',
|
|
4
4
|
category: 'component',
|
|
5
|
-
description: 'Normalizes pointer
|
|
5
|
+
description: 'Normalizes pointer/touch positions and optional keyboard bindings into generic game events.',
|
|
6
6
|
directManifestNode: true,
|
|
7
7
|
allowedChildren: [],
|
|
8
8
|
blueprint: {
|
|
@@ -81,6 +81,52 @@ export const gameInputZoneMeta = {
|
|
|
81
81
|
default: true,
|
|
82
82
|
authoring: { authority: 'instance' },
|
|
83
83
|
},
|
|
84
|
+
keyboardBindings: {
|
|
85
|
+
type: 'array',
|
|
86
|
+
category: 'Input',
|
|
87
|
+
label: 'Keyboard bindings',
|
|
88
|
+
default: [],
|
|
89
|
+
itemSchema: [
|
|
90
|
+
{
|
|
91
|
+
key: 'key',
|
|
92
|
+
schema: {
|
|
93
|
+
type: 'string',
|
|
94
|
+
category: 'Input',
|
|
95
|
+
label: 'Key',
|
|
96
|
+
authoring: { authority: 'instance' },
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
key: 'eventType',
|
|
101
|
+
schema: {
|
|
102
|
+
type: 'string',
|
|
103
|
+
category: 'Input',
|
|
104
|
+
label: 'Event type',
|
|
105
|
+
authoring: { authority: 'instance' },
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
key: 'entityId',
|
|
110
|
+
schema: {
|
|
111
|
+
type: 'string',
|
|
112
|
+
category: 'Input',
|
|
113
|
+
label: 'Entity id',
|
|
114
|
+
authoring: { authority: 'instance' },
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
key: 'preventDefault',
|
|
119
|
+
schema: {
|
|
120
|
+
type: 'boolean',
|
|
121
|
+
category: 'Input',
|
|
122
|
+
label: 'Prevent browser default',
|
|
123
|
+
default: false,
|
|
124
|
+
authoring: { authority: 'instance' },
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
authoring: { authority: 'instance' },
|
|
129
|
+
},
|
|
84
130
|
accessibilityLabel: {
|
|
85
131
|
type: 'string',
|
|
86
132
|
category: 'Accessibility',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gameInputZoneMeta.js","sourceRoot":"","sources":["../../../../src/features/game-presentation/meta/gameInputZoneMeta.ts"],"names":[],"mappings":"AAEA,8FAA8F;AAC9F,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,eAAe;IACrB,QAAQ,EAAE,WAAW;IACrB,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"gameInputZoneMeta.js","sourceRoot":"","sources":["../../../../src/features/game-presentation/meta/gameInputZoneMeta.ts"],"names":[],"mappings":"AAEA,8FAA8F;AAC9F,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,eAAe;IACrB,QAAQ,EAAE,WAAW;IACrB,WAAW,EACT,6FAA6F;IAC/F,kBAAkB,EAAE,IAAI;IACxB,eAAe,EAAE,EAAE;IACnB,SAAS,EAAE;QACT,KAAK,EAAE,iBAAiB;QACxB,YAAY,EAAE;YACZ,SAAS,EAAE,cAAc;YACzB,CAAC,EAAE,CAAC;YACJ,CAAC,EAAE,CAAC;YACJ,KAAK,EAAE,GAAG;YACV,MAAM,EAAE,GAAG;YACX,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,IAAI;SACjB;KACF;IACD,KAAK,EAAE;QACL,SAAS,EAAE;YACT,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,iBAAiB;YACxB,OAAO,EAAE,cAAc;YACvB,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,WAAW;YAClB,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,CAAC,EAAE;YACD,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,CAAC,EAAE;YACD,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,GAAG;YACZ,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,YAAY;YACnB,OAAO,EAAE,GAAG;YACZ,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,OAAO,EAAE;YACP,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,UAAU,EAAE;YACV,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,uBAAuB;YAC9B,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,gBAAgB,EAAE;YAChB,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,mBAAmB;YAC1B,OAAO,EAAE,EAAE;YACX,UAAU,EAAE;gBACV;oBACE,GAAG,EAAE,KAAK;oBACV,MAAM,EAAE;wBACN,IAAI,EAAE,QAAQ;wBACd,QAAQ,EAAE,OAAO;wBACjB,KAAK,EAAE,KAAK;wBACZ,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;qBACrC;iBACF;gBACD;oBACE,GAAG,EAAE,WAAW;oBAChB,MAAM,EAAE;wBACN,IAAI,EAAE,QAAQ;wBACd,QAAQ,EAAE,OAAO;wBACjB,KAAK,EAAE,YAAY;wBACnB,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;qBACrC;iBACF;gBACD;oBACE,GAAG,EAAE,UAAU;oBACf,MAAM,EAAE;wBACN,IAAI,EAAE,QAAQ;wBACd,QAAQ,EAAE,OAAO;wBACjB,KAAK,EAAE,WAAW;wBAClB,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;qBACrC;iBACF;gBACD;oBACE,GAAG,EAAE,gBAAgB;oBACrB,MAAM,EAAE;wBACN,IAAI,EAAE,SAAS;wBACf,QAAQ,EAAE,OAAO;wBACjB,KAAK,EAAE,yBAAyB;wBAChC,OAAO,EAAE,KAAK;wBACd,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;qBACrC;iBACF;aACF;YACD,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,kBAAkB,EAAE;YAClB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,eAAe;YACzB,KAAK,EAAE,qBAAqB;YAC5B,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;KACF;CACmC,CAAC","sourcesContent":["import type { ZoraComponentMeta } from '@ankhorage/zora/metadata';\n\n/*** Describe a field-relative pointer/touch input adapter for one embeddable Game session. */\nexport const gameInputZoneMeta = {\n name: 'GameInputZone',\n category: 'component',\n description:\n 'Normalizes pointer/touch positions and optional keyboard bindings into generic game events.',\n directManifestNode: true,\n allowedChildren: [],\n blueprint: {\n label: 'Game input zone',\n defaultProps: {\n eventType: 'game.pointer',\n x: 0,\n y: 0,\n width: 100,\n height: 100,\n zIndex: 1,\n enabled: true,\n continuous: true,\n },\n },\n props: {\n eventType: {\n type: 'string',\n category: 'Input',\n label: 'Game event type',\n default: 'game.pointer',\n authoring: { authority: 'instance' },\n },\n entityId: {\n type: 'string',\n category: 'Input',\n label: 'Entity id',\n authoring: { authority: 'instance' },\n },\n x: {\n type: 'number',\n category: 'Position',\n label: 'X (%)',\n default: 0,\n authoring: { authority: 'instance' },\n },\n y: {\n type: 'number',\n category: 'Position',\n label: 'Y (%)',\n default: 0,\n authoring: { authority: 'instance' },\n },\n width: {\n type: 'number',\n category: 'Size',\n label: 'Width (%)',\n default: 100,\n authoring: { authority: 'instance' },\n },\n height: {\n type: 'number',\n category: 'Size',\n label: 'Height (%)',\n default: 100,\n authoring: { authority: 'instance' },\n },\n zIndex: {\n type: 'number',\n category: 'Position',\n label: 'Z index',\n default: 1,\n authoring: { authority: 'instance' },\n },\n enabled: {\n type: 'boolean',\n category: 'State',\n label: 'Enabled',\n default: true,\n authoring: { authority: 'instance' },\n },\n continuous: {\n type: 'boolean',\n category: 'Input',\n label: 'Dispatch while moving',\n default: true,\n authoring: { authority: 'instance' },\n },\n keyboardBindings: {\n type: 'array',\n category: 'Input',\n label: 'Keyboard bindings',\n default: [],\n itemSchema: [\n {\n key: 'key',\n schema: {\n type: 'string',\n category: 'Input',\n label: 'Key',\n authoring: { authority: 'instance' },\n },\n },\n {\n key: 'eventType',\n schema: {\n type: 'string',\n category: 'Input',\n label: 'Event type',\n authoring: { authority: 'instance' },\n },\n },\n {\n key: 'entityId',\n schema: {\n type: 'string',\n category: 'Input',\n label: 'Entity id',\n authoring: { authority: 'instance' },\n },\n },\n {\n key: 'preventDefault',\n schema: {\n type: 'boolean',\n category: 'Input',\n label: 'Prevent browser default',\n default: false,\n authoring: { authority: 'instance' },\n },\n },\n ],\n authoring: { authority: 'instance' },\n },\n accessibilityLabel: {\n type: 'string',\n category: 'Accessibility',\n label: 'Accessibility label',\n authoring: { authority: 'instance' },\n },\n },\n} as const satisfies ZoraComponentMeta;\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { GameEntityProps, GameFieldProps, GameInputZoneProps, GameOverlayPlacement, GameOverlayProps, GamePointerEvents, GameProps, } from '../../types/gamePresentation';
|
|
1
|
+
export type { GameEntityProps, GameFieldProps, GameInputZoneProps, GameKeyboardBinding, GameOverlayPlacement, GameOverlayProps, GamePointerEvents, GameProps, } from '../../types/gamePresentation';
|
|
2
2
|
export { Game } from './adapters/inbound/Game';
|
|
3
3
|
export { GameEntity } from './adapters/inbound/GameEntity';
|
|
4
4
|
export { GameField } from './adapters/inbound/GameField';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/game-presentation/public.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,GACV,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC"}
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/game-presentation/public.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,GACV,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/game-presentation/public.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/game-presentation/public.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC","sourcesContent":["export type {\n GameEntityProps,\n GameFieldProps,\n GameInputZoneProps,\n GameKeyboardBinding,\n GameOverlayPlacement,\n GameOverlayProps,\n GamePointerEvents,\n GameProps,\n} from '../../types/gamePresentation';\nexport { Game } from './adapters/inbound/Game';\nexport { GameEntity } from './adapters/inbound/GameEntity';\nexport { GameField } from './adapters/inbound/GameField';\nexport { GameInputZone } from './adapters/inbound/GameInputZone';\nexport { GameOverlay } from './adapters/inbound/GameOverlay';\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { GameEntityProps, GameFieldProps, GameInputZoneProps, GameOverlayPlacement, GameOverlayProps, GamePointerEvents, GameProps, } from './features/game-presentation/public';
|
|
1
|
+
export type { GameEntityProps, GameFieldProps, GameInputZoneProps, GameKeyboardBinding, GameOverlayPlacement, GameOverlayProps, GamePointerEvents, GameProps, } from './features/game-presentation/public';
|
|
2
2
|
export { Game, GameEntity, GameField, GameInputZone, GameOverlay, } from './features/game-presentation/public';
|
|
3
3
|
export { ZORA_GAME_PLUGIN } from './ZORA_GAME_PLUGIN';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,GACV,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,IAAI,EACJ,UAAU,EACV,SAAS,EACT,aAAa,EACb,WAAW,GACZ,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,GACV,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,IAAI,EACJ,UAAU,EACV,SAAS,EACT,aAAa,EACb,WAAW,GACZ,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,IAAI,EACJ,UAAU,EACV,SAAS,EACT,aAAa,EACb,WAAW,GACZ,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export type {\n GameEntityProps,\n GameFieldProps,\n GameInputZoneProps,\n GameKeyboardBinding,\n GameOverlayPlacement,\n GameOverlayProps,\n GamePointerEvents,\n GameProps,\n} from './features/game-presentation/public';\nexport {\n Game,\n GameEntity,\n GameField,\n GameInputZone,\n GameOverlay,\n} from './features/game-presentation/public';\nexport { ZORA_GAME_PLUGIN } from './ZORA_GAME_PLUGIN';\n"]}
|
|
@@ -26,6 +26,12 @@ export interface GameEntityProps {
|
|
|
26
26
|
readonly accessibilityLabel?: string;
|
|
27
27
|
readonly testID?: string;
|
|
28
28
|
}
|
|
29
|
+
export interface GameKeyboardBinding {
|
|
30
|
+
readonly key: string;
|
|
31
|
+
readonly eventType?: string;
|
|
32
|
+
readonly entityId?: string;
|
|
33
|
+
readonly preventDefault?: boolean;
|
|
34
|
+
}
|
|
29
35
|
export interface GameInputZoneProps {
|
|
30
36
|
readonly eventType: string;
|
|
31
37
|
readonly entityId?: string;
|
|
@@ -36,6 +42,7 @@ export interface GameInputZoneProps {
|
|
|
36
42
|
readonly zIndex?: number;
|
|
37
43
|
readonly enabled?: boolean;
|
|
38
44
|
readonly continuous?: boolean;
|
|
45
|
+
readonly keyboardBindings?: readonly GameKeyboardBinding[];
|
|
39
46
|
readonly accessibilityLabel?: string;
|
|
40
47
|
readonly testID?: string;
|
|
41
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gamePresentation.d.ts","sourceRoot":"","sources":["../../src/types/gamePresentation.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gamePresentation.d.ts","sourceRoot":"","sources":["../../src/types/gamePresentation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gamePresentation.js","sourceRoot":"","sources":["../../src/types/gamePresentation.ts"],"names":[],"mappings":"","sourcesContent":["import type { GameDefinition, GameInput, GameOutput } from '@ankhorage/game';\nimport type React from 'react';\n\ntype GameOverlayCornerPlacement = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n\nexport type GamePointerEvents = 'auto' | 'box-none' | 'box-only' | 'none';\nexport type GameOverlayPlacement =\n 'fill' | 'center' | 'top' | 'bottom' | GameOverlayCornerPlacement;\n\nexport interface GameFieldProps {\n readonly children?: React.ReactNode;\n readonly aspectRatio?: number;\n readonly minHeight?: number;\n readonly clip?: boolean;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameEntityProps {\n readonly children?: React.ReactNode;\n readonly x?: number;\n readonly y?: number;\n readonly width?: number;\n readonly height?: number;\n readonly opacity?: number;\n readonly scale?: number;\n readonly rotation?: number;\n readonly zIndex?: number;\n readonly hidden?: boolean;\n readonly pointerEvents?: GamePointerEvents;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameInputZoneProps {\n readonly eventType: string;\n readonly entityId?: string;\n readonly x?: number;\n readonly y?: number;\n readonly width?: number;\n readonly height?: number;\n readonly zIndex?: number;\n readonly enabled?: boolean;\n readonly continuous?: boolean;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameOverlayProps {\n readonly children?: React.ReactNode;\n readonly placement?: GameOverlayPlacement;\n readonly blocking?: boolean;\n readonly padding?: number;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameProps extends GameFieldProps {\n readonly definition: GameDefinition;\n readonly input?: GameInput;\n readonly seed?: number;\n readonly resetKey?: string;\n readonly autoAdvanceTime?: boolean;\n readonly onOutput?: (output: GameOutput) => void;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"gamePresentation.js","sourceRoot":"","sources":["../../src/types/gamePresentation.ts"],"names":[],"mappings":"","sourcesContent":["import type { GameDefinition, GameInput, GameOutput } from '@ankhorage/game';\nimport type React from 'react';\n\ntype GameOverlayCornerPlacement = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n\nexport type GamePointerEvents = 'auto' | 'box-none' | 'box-only' | 'none';\nexport type GameOverlayPlacement =\n 'fill' | 'center' | 'top' | 'bottom' | GameOverlayCornerPlacement;\n\nexport interface GameFieldProps {\n readonly children?: React.ReactNode;\n readonly aspectRatio?: number;\n readonly minHeight?: number;\n readonly clip?: boolean;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameEntityProps {\n readonly children?: React.ReactNode;\n readonly x?: number;\n readonly y?: number;\n readonly width?: number;\n readonly height?: number;\n readonly opacity?: number;\n readonly scale?: number;\n readonly rotation?: number;\n readonly zIndex?: number;\n readonly hidden?: boolean;\n readonly pointerEvents?: GamePointerEvents;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameKeyboardBinding {\n readonly key: string;\n readonly eventType?: string;\n readonly entityId?: string;\n readonly preventDefault?: boolean;\n}\n\nexport interface GameInputZoneProps {\n readonly eventType: string;\n readonly entityId?: string;\n readonly x?: number;\n readonly y?: number;\n readonly width?: number;\n readonly height?: number;\n readonly zIndex?: number;\n readonly enabled?: boolean;\n readonly continuous?: boolean;\n readonly keyboardBindings?: readonly GameKeyboardBinding[];\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameOverlayProps {\n readonly children?: React.ReactNode;\n readonly placement?: GameOverlayPlacement;\n readonly blocking?: boolean;\n readonly padding?: number;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameProps extends GameFieldProps {\n readonly definition: GameDefinition;\n readonly input?: GameInput;\n readonly seed?: number;\n readonly resetKey?: string;\n readonly autoAdvanceTime?: boolean;\n readonly onOutput?: (output: GameOutput) => void;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora-game",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Generic game presentation primitives for React Native and React Native Web apps built on ZORA.",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/zora-game#readme",
|
|
@@ -22,16 +22,6 @@ describe('ZORA game plugin metadata', () => {
|
|
|
22
22
|
expect(game.allowedChildren).toContain('GameOverlay');
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
test('keeps Game input zones scoped to runtime-owning Game parents', () => {
|
|
26
|
-
const catalog = composeZoraPluginMetadata([ZORA_CORE_PLUGIN_METADATA, ZORA_PLUGIN_METADATA]);
|
|
27
|
-
const gameInputZone = readComponentMeta(catalog.componentMeta.GameInputZone, 'GameInputZone');
|
|
28
|
-
|
|
29
|
-
expect(gameInputZone.props.eventType?.type).toBe('string');
|
|
30
|
-
expect(gameInputZone.props.continuous?.type).toBe('boolean');
|
|
31
|
-
expect(catalog.componentMeta.Game?.allowedChildren).toContain('GameInputZone');
|
|
32
|
-
expect(catalog.componentMeta.GameField?.allowedChildren).not.toContain('GameInputZone');
|
|
33
|
-
});
|
|
34
|
-
|
|
35
25
|
test('describes bindable Game inputs and domain-neutral outputs', () => {
|
|
36
26
|
const catalog = composeZoraPluginMetadata([ZORA_CORE_PLUGIN_METADATA, ZORA_PLUGIN_METADATA]);
|
|
37
27
|
const game = readComponentMeta(catalog.componentMeta.Game, 'Game');
|
|
@@ -60,6 +50,25 @@ describe('ZORA game plugin metadata', () => {
|
|
|
60
50
|
});
|
|
61
51
|
});
|
|
62
52
|
|
|
53
|
+
describe('ZORA game input zone metadata', () => {
|
|
54
|
+
test('keeps input zones scoped to runtime-owning Game parents', () => {
|
|
55
|
+
const catalog = composeZoraPluginMetadata([ZORA_CORE_PLUGIN_METADATA, ZORA_PLUGIN_METADATA]);
|
|
56
|
+
const gameInputZone = readComponentMeta(catalog.componentMeta.GameInputZone, 'GameInputZone');
|
|
57
|
+
|
|
58
|
+
expect(gameInputZone.props.eventType?.type).toBe('string');
|
|
59
|
+
expect(gameInputZone.props.continuous?.type).toBe('boolean');
|
|
60
|
+
expect(gameInputZone.props.keyboardBindings?.type).toBe('array');
|
|
61
|
+
expect(gameInputZone.props.keyboardBindings?.itemSchema?.map(({ key }) => key)).toEqual([
|
|
62
|
+
'key',
|
|
63
|
+
'eventType',
|
|
64
|
+
'entityId',
|
|
65
|
+
'preventDefault',
|
|
66
|
+
]);
|
|
67
|
+
expect(catalog.componentMeta.Game?.allowedChildren).toContain('GameInputZone');
|
|
68
|
+
expect(catalog.componentMeta.GameField?.allowedChildren).not.toContain('GameInputZone');
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
63
72
|
/*** Require one composed component metadata entry for focused assertions. */
|
|
64
73
|
function readComponentMeta<TValue>(value: TValue | undefined, name: string): TValue {
|
|
65
74
|
if (value === undefined) throw new Error(`Missing composed component metadata for ${name}.`);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { StyleSheet, View, type ViewStyle } from 'react-native';
|
|
1
|
+
import { Platform, StyleSheet, View, type ViewStyle } from 'react-native';
|
|
2
2
|
|
|
3
3
|
import type { GameInputZoneProps } from '../../../../types/gamePresentation';
|
|
4
4
|
import { toGamePercentage } from '../../utils/toGamePercentage';
|
|
5
5
|
import { useGameInputZoneResponder } from './useGameInputZoneResponder';
|
|
6
6
|
|
|
7
|
-
/*** Capture pointer/touch geometry and
|
|
7
|
+
/*** Capture pointer/touch geometry and optional keyboard input as normalized generic Game events. */
|
|
8
8
|
export function GameInputZone({
|
|
9
9
|
x = 0,
|
|
10
10
|
y = 0,
|
|
@@ -13,22 +13,31 @@ export function GameInputZone({
|
|
|
13
13
|
zIndex = 0,
|
|
14
14
|
enabled = true,
|
|
15
15
|
continuous = true,
|
|
16
|
+
keyboardBindings,
|
|
16
17
|
accessibilityLabel,
|
|
17
18
|
testID,
|
|
18
19
|
...inputProps
|
|
19
20
|
}: GameInputZoneProps) {
|
|
20
|
-
const { dispatchPointer, handleLayout, shouldSetResponder } =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
const { dispatchKeyboard, dispatchPointer, handleLayout, shouldSetResponder } =
|
|
22
|
+
useGameInputZoneResponder({
|
|
23
|
+
...inputProps,
|
|
24
|
+
x,
|
|
25
|
+
y,
|
|
26
|
+
width,
|
|
27
|
+
height,
|
|
28
|
+
enabled,
|
|
29
|
+
continuous,
|
|
30
|
+
...(keyboardBindings === undefined ? {} : { keyboardBindings }),
|
|
31
|
+
});
|
|
32
|
+
const keyboardProps = createGameInputZoneKeyboardProps({
|
|
33
|
+
dispatchKeyboard,
|
|
26
34
|
enabled,
|
|
27
|
-
|
|
35
|
+
keyboardBindings,
|
|
28
36
|
});
|
|
29
37
|
|
|
30
38
|
return (
|
|
31
39
|
<View
|
|
40
|
+
{...keyboardProps}
|
|
32
41
|
{...(accessibilityLabel === undefined ? {} : { accessibilityLabel })}
|
|
33
42
|
{...(testID === undefined ? {} : { testID })}
|
|
34
43
|
{...(continuous
|
|
@@ -43,6 +52,24 @@ export function GameInputZone({
|
|
|
43
52
|
);
|
|
44
53
|
}
|
|
45
54
|
|
|
55
|
+
interface GameInputZoneKeyboardPropsInput {
|
|
56
|
+
readonly dispatchKeyboard: (event: { readonly key: string; preventDefault(): void }) => void;
|
|
57
|
+
readonly enabled: boolean;
|
|
58
|
+
readonly keyboardBindings: GameInputZoneProps['keyboardBindings'];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/*** Add a focusable web keyboard target only when the input zone owns key bindings. */
|
|
62
|
+
function createGameInputZoneKeyboardProps({
|
|
63
|
+
dispatchKeyboard,
|
|
64
|
+
enabled,
|
|
65
|
+
keyboardBindings,
|
|
66
|
+
}: GameInputZoneKeyboardPropsInput) {
|
|
67
|
+
if (Platform.OS !== 'web' || !enabled || keyboardBindings === undefined) return {};
|
|
68
|
+
if (keyboardBindings.length === 0) return {};
|
|
69
|
+
|
|
70
|
+
return { onKeyDown: dispatchKeyboard, tabIndex: 0 as const };
|
|
71
|
+
}
|
|
72
|
+
|
|
46
73
|
interface InputZoneStyleInput {
|
|
47
74
|
readonly x: number;
|
|
48
75
|
readonly y: number;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import { createGameKeyboardEvent } from './createGameKeyboardEvent';
|
|
4
|
+
|
|
5
|
+
describe('createGameKeyboardEvent', () => {
|
|
6
|
+
test('maps a configured key through fallback event and entity values', () => {
|
|
7
|
+
expect(
|
|
8
|
+
createGameKeyboardEvent({
|
|
9
|
+
bindings: [{ key: 'ArrowLeft', preventDefault: true }],
|
|
10
|
+
fallbackEventType: 'player.move',
|
|
11
|
+
fallbackEntityId: 'player',
|
|
12
|
+
key: 'ArrowLeft',
|
|
13
|
+
}),
|
|
14
|
+
).toEqual({
|
|
15
|
+
event: {
|
|
16
|
+
type: 'player.move',
|
|
17
|
+
entityId: 'player',
|
|
18
|
+
payload: { key: 'ArrowLeft' },
|
|
19
|
+
},
|
|
20
|
+
preventDefault: true,
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('allows one key binding to override the event target', () => {
|
|
25
|
+
expect(
|
|
26
|
+
createGameKeyboardEvent({
|
|
27
|
+
bindings: [{ key: ' ', eventType: 'player.action', entityId: 'actor' }],
|
|
28
|
+
fallbackEventType: 'player.move',
|
|
29
|
+
fallbackEntityId: 'player',
|
|
30
|
+
key: ' ',
|
|
31
|
+
}),
|
|
32
|
+
).toEqual({
|
|
33
|
+
event: {
|
|
34
|
+
type: 'player.action',
|
|
35
|
+
entityId: 'actor',
|
|
36
|
+
payload: { key: ' ' },
|
|
37
|
+
},
|
|
38
|
+
preventDefault: false,
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('ignores keys without a binding', () => {
|
|
43
|
+
expect(
|
|
44
|
+
createGameKeyboardEvent({
|
|
45
|
+
bindings: [{ key: 'ArrowLeft' }],
|
|
46
|
+
fallbackEventType: 'player.move',
|
|
47
|
+
key: 'ArrowRight',
|
|
48
|
+
}),
|
|
49
|
+
).toBeUndefined();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { GameEvent } from '@ankhorage/game';
|
|
2
|
+
|
|
3
|
+
import type { GameKeyboardBinding } from '../../../../types/gamePresentation';
|
|
4
|
+
|
|
5
|
+
interface CreateGameKeyboardEventInput {
|
|
6
|
+
readonly bindings: readonly GameKeyboardBinding[];
|
|
7
|
+
readonly fallbackEventType: string;
|
|
8
|
+
readonly fallbackEntityId?: string;
|
|
9
|
+
readonly key: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface GameKeyboardEventResult {
|
|
13
|
+
readonly event: GameEvent;
|
|
14
|
+
readonly preventDefault: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/*** Map one configured keyboard key into a generic Game event. */
|
|
18
|
+
export function createGameKeyboardEvent(
|
|
19
|
+
input: CreateGameKeyboardEventInput,
|
|
20
|
+
): GameKeyboardEventResult | undefined {
|
|
21
|
+
const binding = input.bindings.find((candidate) => candidate.key === input.key);
|
|
22
|
+
if (binding === undefined) return undefined;
|
|
23
|
+
|
|
24
|
+
const entityId = binding.entityId ?? input.fallbackEntityId;
|
|
25
|
+
return {
|
|
26
|
+
event: {
|
|
27
|
+
type: binding.eventType ?? input.fallbackEventType,
|
|
28
|
+
...(entityId === undefined ? {} : { entityId }),
|
|
29
|
+
payload: { key: input.key },
|
|
30
|
+
},
|
|
31
|
+
preventDefault: binding.preventDefault ?? false,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -3,8 +3,14 @@ import type { GestureResponderEvent, LayoutChangeEvent } from 'react-native';
|
|
|
3
3
|
|
|
4
4
|
import type { GameInputZoneProps } from '../../../../types/gamePresentation';
|
|
5
5
|
import { GameRuntimeContext } from '../../composition/GameRuntimeContext';
|
|
6
|
+
import { createGameKeyboardEvent } from './createGameKeyboardEvent';
|
|
6
7
|
import { createGamePointerEvent } from './createGamePointerEvent';
|
|
7
8
|
|
|
9
|
+
interface GameKeyboardInputEvent {
|
|
10
|
+
readonly key: string;
|
|
11
|
+
preventDefault(): void;
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
interface MeasuredSize {
|
|
9
15
|
readonly width: number;
|
|
10
16
|
readonly height: number;
|
|
@@ -41,7 +47,23 @@ export function useGameInputZoneResponder(props: GameInputZoneProps) {
|
|
|
41
47
|
[props.entityId, props.eventType, props.height, props.width, props.x, props.y, runtime],
|
|
42
48
|
);
|
|
43
49
|
|
|
50
|
+
const dispatchKeyboard = React.useCallback(
|
|
51
|
+
(event: GameKeyboardInputEvent) => {
|
|
52
|
+
const result = createGameKeyboardEvent({
|
|
53
|
+
bindings: props.keyboardBindings ?? [],
|
|
54
|
+
fallbackEventType: props.eventType,
|
|
55
|
+
...(props.entityId === undefined ? {} : { fallbackEntityId: props.entityId }),
|
|
56
|
+
key: event.key,
|
|
57
|
+
});
|
|
58
|
+
if (result === undefined) return;
|
|
59
|
+
if (result.preventDefault) event.preventDefault();
|
|
60
|
+
runtime.dispatch(result.event);
|
|
61
|
+
},
|
|
62
|
+
[props.entityId, props.eventType, props.keyboardBindings, runtime],
|
|
63
|
+
);
|
|
64
|
+
|
|
44
65
|
return {
|
|
66
|
+
dispatchKeyboard,
|
|
45
67
|
dispatchPointer,
|
|
46
68
|
handleLayout,
|
|
47
69
|
shouldSetResponder: () => props.enabled ?? true,
|
|
@@ -15,6 +15,11 @@ const session: GameSession = {
|
|
|
15
15
|
templateId: 'actor',
|
|
16
16
|
state: { x: 42, y: 73, label: 'Player' },
|
|
17
17
|
},
|
|
18
|
+
shot: {
|
|
19
|
+
id: 'shot',
|
|
20
|
+
templateId: 'projectile',
|
|
21
|
+
state: { x: 50, y: 60, label: 'A' },
|
|
22
|
+
},
|
|
18
23
|
},
|
|
19
24
|
scheduled: [],
|
|
20
25
|
elapsedMs: 120,
|
|
@@ -39,9 +44,23 @@ describe('createGameBindingContext', () => {
|
|
|
39
44
|
).toBe(80);
|
|
40
45
|
});
|
|
41
46
|
|
|
47
|
+
test('exposes current entities as a repeatable array with stable ids', () => {
|
|
48
|
+
const context = createGameBindingContext(session);
|
|
49
|
+
const entities = resolveRuntimeBindingValueSync(
|
|
50
|
+
{ source: { kind: 'context', path: 'game.entities' } },
|
|
51
|
+
{ context },
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
expect(Array.isArray(entities)).toBe(true);
|
|
55
|
+
expect(entities).toEqual(Object.values(session.entities));
|
|
56
|
+
});
|
|
57
|
+
|
|
42
58
|
test('owns only the local game namespace', () => {
|
|
43
59
|
expect(createGameBindingContext(session)).toEqual({
|
|
44
|
-
game: {
|
|
60
|
+
game: {
|
|
61
|
+
entities: Object.values(session.entities),
|
|
62
|
+
session,
|
|
63
|
+
},
|
|
45
64
|
});
|
|
46
65
|
});
|
|
47
66
|
});
|
|
@@ -5,7 +5,7 @@ export const gameInputZoneMeta = {
|
|
|
5
5
|
name: 'GameInputZone',
|
|
6
6
|
category: 'component',
|
|
7
7
|
description:
|
|
8
|
-
'Normalizes pointer
|
|
8
|
+
'Normalizes pointer/touch positions and optional keyboard bindings into generic game events.',
|
|
9
9
|
directManifestNode: true,
|
|
10
10
|
allowedChildren: [],
|
|
11
11
|
blueprint: {
|
|
@@ -84,6 +84,52 @@ export const gameInputZoneMeta = {
|
|
|
84
84
|
default: true,
|
|
85
85
|
authoring: { authority: 'instance' },
|
|
86
86
|
},
|
|
87
|
+
keyboardBindings: {
|
|
88
|
+
type: 'array',
|
|
89
|
+
category: 'Input',
|
|
90
|
+
label: 'Keyboard bindings',
|
|
91
|
+
default: [],
|
|
92
|
+
itemSchema: [
|
|
93
|
+
{
|
|
94
|
+
key: 'key',
|
|
95
|
+
schema: {
|
|
96
|
+
type: 'string',
|
|
97
|
+
category: 'Input',
|
|
98
|
+
label: 'Key',
|
|
99
|
+
authoring: { authority: 'instance' },
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
key: 'eventType',
|
|
104
|
+
schema: {
|
|
105
|
+
type: 'string',
|
|
106
|
+
category: 'Input',
|
|
107
|
+
label: 'Event type',
|
|
108
|
+
authoring: { authority: 'instance' },
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
key: 'entityId',
|
|
113
|
+
schema: {
|
|
114
|
+
type: 'string',
|
|
115
|
+
category: 'Input',
|
|
116
|
+
label: 'Entity id',
|
|
117
|
+
authoring: { authority: 'instance' },
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
key: 'preventDefault',
|
|
122
|
+
schema: {
|
|
123
|
+
type: 'boolean',
|
|
124
|
+
category: 'Input',
|
|
125
|
+
label: 'Prevent browser default',
|
|
126
|
+
default: false,
|
|
127
|
+
authoring: { authority: 'instance' },
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
authoring: { authority: 'instance' },
|
|
132
|
+
},
|
|
87
133
|
accessibilityLabel: {
|
|
88
134
|
type: 'string',
|
|
89
135
|
category: 'Accessibility',
|
package/src/index.ts
CHANGED
|
@@ -32,6 +32,13 @@ export interface GameEntityProps {
|
|
|
32
32
|
readonly testID?: string;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
export interface GameKeyboardBinding {
|
|
36
|
+
readonly key: string;
|
|
37
|
+
readonly eventType?: string;
|
|
38
|
+
readonly entityId?: string;
|
|
39
|
+
readonly preventDefault?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
35
42
|
export interface GameInputZoneProps {
|
|
36
43
|
readonly eventType: string;
|
|
37
44
|
readonly entityId?: string;
|
|
@@ -42,6 +49,7 @@ export interface GameInputZoneProps {
|
|
|
42
49
|
readonly zIndex?: number;
|
|
43
50
|
readonly enabled?: boolean;
|
|
44
51
|
readonly continuous?: boolean;
|
|
52
|
+
readonly keyboardBindings?: readonly GameKeyboardBinding[];
|
|
45
53
|
readonly accessibilityLabel?: string;
|
|
46
54
|
readonly testID?: string;
|
|
47
55
|
}
|