@rive-app/canvas-lite 2.37.7 → 2.38.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/rive.wasm CHANGED
Binary file
@@ -755,6 +755,18 @@ export interface RiveEventCustomProperties {
755
755
  [key: string]: number | boolean | string;
756
756
  }
757
757
 
758
+ /**
759
+ * Snapshot of the focus state returned by StateMachineInstance.focusState().
760
+ * Poll this each frame after advanceAndApply() to detect focus changes and
761
+ * determine whether a virtual keyboard should be shown or hidden.
762
+ */
763
+ export interface FocusState {
764
+ /** True if any element currently holds focus in this state machine's active focus manager. */
765
+ hasFocus: boolean;
766
+ /** True if the focused element accepts keyboard input (e.g. a TextInput node). */
767
+ expectsKeyboardInput: boolean;
768
+ }
769
+
758
770
  export declare class LinearAnimation {
759
771
  /**
760
772
  * The animation's loop type
@@ -877,6 +889,35 @@ export declare class StateMachineInstance {
877
889
  */
878
890
  pointerExit(x: number, y: number, id: number): void;
879
891
 
892
+ /**
893
+ * Returns true if this state machine has any focus nodes registered in its focus tree.
894
+ * Since the focus tree is unified across nested artboards, this covers the full scene.
895
+ * Use this to gate whether tab/focus traversal DOM listeners should be attached.
896
+ */
897
+ hasFocusNodes(): boolean;
898
+
899
+ /**
900
+ * Move focus to the next focusable node in the focus tree via the state machine's focus manager.
901
+ */
902
+ focusNext(): boolean;
903
+
904
+ /**
905
+ * Move focus to the previous focusable node in the focus tree via the state machine's focus manager.
906
+ */
907
+ focusPrevious(): boolean;
908
+
909
+ /**
910
+ * Clear focus from the Rive focus tree.
911
+ */
912
+ clearFocus(): void;
913
+
914
+ /**
915
+ * Returns metadata about current focus state:
916
+ * 1. Whether any node in the focus tree is currently focused
917
+ * 2. Whether the currently focused node expects keyboard input (i.e. keyboard/text input listener)
918
+ */
919
+ focusState(): FocusState;
920
+
880
921
  /**
881
922
  * Deletes the underlying instance created via the WASM. It's important to clean up this instance
882
923
  * when no longer in use
Binary file
@@ -35,7 +35,7 @@ declare class CustomFileAssetLoaderWrapper {
35
35
  assetLoader: rc.CustomFileAssetLoader;
36
36
  _assetLoaderCallback: AssetLoadCallbackWrapper;
37
37
  constructor(runtime: rc.RiveCanvas, loaderCallback: AssetLoadCallbackWrapper);
38
- loadContents(asset: rc.FileAsset, bytes: any): Boolean;
38
+ loadContents(asset: rc.FileAsset, bytes: any): false | Boolean;
39
39
  }
40
40
  /**
41
41
  * Rive class representing a FileAsset with relevant metadata fields to describe
package/utils/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export { registerTouchInteractions } from "./registerTouchInteractions";
2
+ export { KeyboardInteractions, FocusSessionState } from "./registerKeyboardInteractions";
3
+ export type { KeyboardInteractionsParams } from "./registerKeyboardInteractions";
2
4
  export { BLANK_URL, sanitizeUrl } from "./sanitizeUrl";
3
5
  export { Finalizable, ImageWrapper, AudioWrapper, FontWrapper, FileAssetWrapper, ImageAssetWrapper, AudioAssetWrapper, FontAssetWrapper, finalizationRegistry, CustomFileAssetLoaderWrapper, AssetLoadCallbackWrapper, FileFinalizer, createFinalization, } from "./finalizationRegistry";
4
6
  export { RiveFont } from "./riveFont";
@@ -0,0 +1,82 @@
1
+ import * as rc from "../rive_advanced.mjs";
2
+ export interface KeyboardInteractionsParams {
3
+ canvas: HTMLCanvasElement;
4
+ stateMachine: rc.StateMachineInstance;
5
+ /**
6
+ * Whether this canvas has focus nodes that should participate in tab traversal.
7
+ * When true, Tab/Shift+Tab will be intercepted and routed to the Rive focus manager.
8
+ * focusNext() returning false means no more traversable nodes — tab is released to the page.
9
+ */
10
+ hasFocusNodes: boolean;
11
+ }
12
+ /**
13
+ * Tracks the relationship between the canvas's DOM focus and Rive's internal focus for the
14
+ * current focus session.
15
+ *
16
+ * NotFocused — the canvas is not the active DOM element, or Rive entered and then released focus
17
+ * internally this session. Either way the next Tab should move on to the next page
18
+ * element, so Tab events are ignored.
19
+ * EntryPending — the canvas has DOM focus but Rive holds no active focus node yet, and the next Tab should enter
20
+ * the focus tree. This is the resting state for pointer-driven focus (a click on the
21
+ * canvas), or an edge case for keyboard focus where initial focus action did not land on a focus node.
22
+ * RiveFocused — a Rive node currently holds focus. Tab/Shift+Tab are routed to the Rive focus
23
+ * manager and trapped inside the canvas until Rive notifies focus has ended.
24
+ *
25
+ * When keyboard focus lands on the canvas, onCanvasFocus reads the direction focus came from and
26
+ * moves into the focus tree immediately, going straight to RiveFocused. EntryPending is only set via pointer focus (or keyboard focus
27
+ * where focusNext()/focusPrevious() return false but respects tabindex).
28
+ */
29
+ export declare enum FocusSessionState {
30
+ NotFocused = "notFocused",
31
+ EntryPending = "entryPending",
32
+ RiveFocused = "riveFocused"
33
+ }
34
+ /**
35
+ * Manages keyboard and DOM focus interactions for a Rive canvas.
36
+ *
37
+ * Tracks the canvas focus session state (focusSessionState) and routes
38
+ * Tab/Shift+Tab to the Rive state machine's focus manager. Exposes shared
39
+ * state as properties so the Rive render loop can read them directly.
40
+ */
41
+ export declare class KeyboardInteractions {
42
+ focusSessionState: FocusSessionState;
43
+ private canvas;
44
+ private mainSm;
45
+ private hasFocusNodes;
46
+ constructor({ canvas, stateMachine, hasFocusNodes }: KeyboardInteractionsParams);
47
+ /**
48
+ * Set the FocusSessionState. Useful for invoking a Rive "blur" without actually blurring from the <canvas>. This
49
+ * helps put the DOM focus state on the canvas rather than the <body>, so the user doesn't lose the spot in page navigation
50
+ *
51
+ * @param state FocusSessionState enum
52
+ */
53
+ setFocusSessionState(state: FocusSessionState): void;
54
+ /**
55
+ * Called by pollFocusState on the Rive instance when it observes hasFocus=true. Rive acquired
56
+ * focus internally (e.g. via a listener action or state transition) without a DOM focus event,
57
+ * so mark the session RiveFocused.
58
+ */
59
+ notifyRiveFocused(): void;
60
+ /**
61
+ * Handles the canvas gaining browser focus. The behavior differs based on how focus was gained -
62
+ *
63
+ * Pointer-driven focus: the canvas now has focus but Rive holds nothing yet, so we move to EntryPending — this lets the
64
+ * next Tab enter the focus tree even when the focus is pointer-driven
65
+ *
66
+ * Keyboard-driven focus: we enter the Rive focus tree immediately once canvas gains focus.
67
+ * The direction is inferred from where focus came from: an element before the canvas in DOM order
68
+ * means a forward Tab (focusNext), one after means a Shift+Tab (focusPrevious). :focus-visible
69
+ * gates this so a click doesn't yank Rive focus to the first node on the focus event itself.
70
+ */
71
+ onCanvasFocus: (event: FocusEvent) => void;
72
+ onCanvasBlur: (_event: FocusEvent) => void;
73
+ onKeyDown: (event: KeyboardEvent) => void;
74
+ /**
75
+ * Whether the canvas currently matches :focus-visible — the browser's heuristic for keyboard-
76
+ * (vs pointer-) driven focus. For older browser versions that don't support this selector, return false
77
+ * so that we don't incorrectly assume pointer vs keyboard focus. Next tab would enter the focus tree in those edge cases.
78
+ */
79
+ private isKeyboardDrivenFocus;
80
+ private cameFromBeforeCanvas;
81
+ cleanup(): void;
82
+ }
@@ -11,9 +11,10 @@ export interface TouchInteractionsParams {
11
11
  dispatchPointerExit?: boolean;
12
12
  enableMultiTouch?: boolean;
13
13
  layoutScaleFactor?: number;
14
+ advanceAndDrain: (elapsedTime: number) => void;
14
15
  }
15
16
  /**
16
17
  * Registers mouse move/up/down callback handlers on the canvas to send meaningful coordinates to
17
18
  * the state machine pointer move/up/down functions based on cursor interaction
18
19
  */
19
- export declare const registerTouchInteractions: ({ canvas, artboard, stateMachines, renderer, rive, fit, alignment, isTouchScrollEnabled, dispatchPointerExit, enableMultiTouch, layoutScaleFactor, }: TouchInteractionsParams) => () => void;
20
+ export declare const registerTouchInteractions: ({ canvas, artboard, stateMachines, renderer, rive, fit, alignment, isTouchScrollEnabled, dispatchPointerExit, enableMultiTouch, layoutScaleFactor, advanceAndDrain, }: TouchInteractionsParams) => () => void;