@supermousejs/core 2.2.0 → 2.3.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 +11 -0
- package/dist/index.d.ts +36 -17
- package/dist/index.mjs +91 -72
- package/dist/index.umd.js +2 -2
- package/package.json +1 -1
- package/src/Supermouse.ts +731 -708
- package/src/__tests__/setup.ts +13 -0
- package/src/__tests__/supermouse.test.ts +19 -0
- package/src/types.ts +27 -12
- package/vitest.config.ts +10 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Object.defineProperty(window, "matchMedia", {
|
|
2
|
+
writable: true,
|
|
3
|
+
value: (query: string) => ({
|
|
4
|
+
matches: false,
|
|
5
|
+
media: query,
|
|
6
|
+
onchange: null,
|
|
7
|
+
addListener: () => {},
|
|
8
|
+
removeListener: () => {},
|
|
9
|
+
addEventListener: () => {},
|
|
10
|
+
removeEventListener: () => {},
|
|
11
|
+
dispatchEvent: () => false
|
|
12
|
+
})
|
|
13
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { Supermouse } from "../Supermouse";
|
|
3
|
+
|
|
4
|
+
describe("Supermouse core", () => {
|
|
5
|
+
it("registers and looks up plugins by name", () => {
|
|
6
|
+
const app = new Supermouse();
|
|
7
|
+
|
|
8
|
+
const plugin = {
|
|
9
|
+
name: "test-plugin",
|
|
10
|
+
install() {},
|
|
11
|
+
update() {}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
app.use(plugin);
|
|
15
|
+
|
|
16
|
+
expect(app.getPlugin("test-plugin")).toBe(plugin);
|
|
17
|
+
expect(app.getPlugin("missing-plugin")).toBeUndefined();
|
|
18
|
+
});
|
|
19
|
+
});
|
package/src/types.ts
CHANGED
|
@@ -32,21 +32,21 @@ export interface InteractionState {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export interface MouseState {
|
|
35
|
-
/** The raw position
|
|
35
|
+
/** The raw position from the latest pointer event, before smoothing is applied. */
|
|
36
36
|
pointer: MousePosition;
|
|
37
|
-
/** The
|
|
37
|
+
/** The current goal position that the core loop is driving toward. */
|
|
38
38
|
target: MousePosition;
|
|
39
39
|
/** The smoothed/interpolated position used for rendering. */
|
|
40
40
|
smooth: MousePosition;
|
|
41
|
-
/** The current
|
|
41
|
+
/** The current movement vector derived from the smoothed state. */
|
|
42
42
|
velocity: MousePosition;
|
|
43
|
-
/** The
|
|
43
|
+
/** The current movement angle in degrees, derived from velocity. */
|
|
44
44
|
angle: number;
|
|
45
45
|
/** Whether the pointer is currently pressed down. */
|
|
46
46
|
isDown: boolean;
|
|
47
47
|
/** Whether the pointer is currently hovering over a registered interactive element. */
|
|
48
48
|
isHover: boolean;
|
|
49
|
-
/** Whether the
|
|
49
|
+
/** Whether the runtime has temporarily restored the native cursor due to native-input heuristics. */
|
|
50
50
|
isNative: boolean;
|
|
51
51
|
/**
|
|
52
52
|
* If set, this overrides all auto-detection logic.
|
|
@@ -95,20 +95,24 @@ export interface SupermouseOptions {
|
|
|
95
95
|
autoDisableOnMobile?: boolean;
|
|
96
96
|
/**
|
|
97
97
|
* Strategy for detecting when to fallback to the native cursor.
|
|
98
|
-
* - `
|
|
98
|
+
* - `'auto'`: Checks both HTML tags and CSS cursor styles (Accurate but slower).
|
|
99
99
|
* - `'tag'`: Checks only semantic tags like <input>, <textarea> (Fastest, prevents layout thrashing).
|
|
100
100
|
* - `'css'`: Checks only computed CSS cursor styles (Slow, triggers reflow).
|
|
101
|
-
* - `
|
|
101
|
+
* - `null`: Never fallback to native cursor.
|
|
102
|
+
*
|
|
102
103
|
* @default 'auto'
|
|
103
104
|
*/
|
|
104
|
-
ignoreOnNative?:
|
|
105
|
+
ignoreOnNative?: NativeIgnoreStrategy | null;
|
|
105
106
|
/**
|
|
106
|
-
* Whether to hide the native cursor via
|
|
107
|
+
* Whether to hide the native cursor via scoped CSS injection on the container.
|
|
108
|
+
* When enabled, the stage toggles `cursor: none` on the configured container and
|
|
109
|
+
* on registered hover targets.
|
|
107
110
|
* @default true
|
|
108
111
|
*/
|
|
109
112
|
hideCursor?: boolean;
|
|
110
113
|
/**
|
|
111
|
-
* Whether to hide the custom cursor when the
|
|
114
|
+
* Whether to hide the custom cursor when the pointer leaves the browser viewport.
|
|
115
|
+
* When enabled the runtime clears the cursor back to an off-screen position to avoid stale hover state.
|
|
112
116
|
* @default true
|
|
113
117
|
*/
|
|
114
118
|
hideOnLeave?: boolean;
|
|
@@ -128,18 +132,29 @@ export interface SupermouseOptions {
|
|
|
128
132
|
autoStart?: boolean;
|
|
129
133
|
/**
|
|
130
134
|
* Semantic rules mapping CSS selectors to interaction state.
|
|
135
|
+
* Rules are evaluated against hovered elements and merged into `state.interaction`.
|
|
136
|
+
* Matching data attributes on the same element are also read and can override or enrich the final object.
|
|
131
137
|
* @example { 'button': { icon: 'pointer' } }
|
|
132
138
|
*/
|
|
133
139
|
rules?: Record<string, InteractionState>;
|
|
134
140
|
/**
|
|
135
141
|
* Custom strategy to resolve interaction state from a hovered element.
|
|
136
|
-
*
|
|
142
|
+
* When provided, this callback bypasses the default `rules` + `data-[prefix]-*` scraping and
|
|
143
|
+
* returns the interaction payload directly for the current hover target.
|
|
137
144
|
*/
|
|
138
145
|
resolveInteraction?: (target: HTMLElement) => InteractionState;
|
|
146
|
+
/**
|
|
147
|
+
* The prefix used for data attributes to store hover metadata.
|
|
148
|
+
* For example, if dataPrefix is "supermouse", then the attribute would be "data-supermouse-*".
|
|
149
|
+
* This allows for multiple instances of Supermouse to coexist without conflicting data attributes.
|
|
150
|
+
* @default "supermouse"
|
|
151
|
+
*/
|
|
152
|
+
dataPrefix?: string;
|
|
139
153
|
}
|
|
140
154
|
|
|
141
155
|
/**
|
|
142
156
|
* Allows a property to be a static value or a function that returns the value based on state.
|
|
157
|
+
* This is primarily useful for plugin option definitions that should react to the current runtime state.
|
|
143
158
|
*/
|
|
144
159
|
export type ValueOrGetter<T> = T | ((state: MouseState) => T);
|
|
145
160
|
|
|
@@ -156,7 +171,7 @@ export interface SupermousePlugin {
|
|
|
156
171
|
|
|
157
172
|
/** Called when `app.use()` is executed. */
|
|
158
173
|
install?: (instance: Supermouse) => void;
|
|
159
|
-
/** Called on every animation frame. */
|
|
174
|
+
/** Called on every animation frame with the frame delta time in milliseconds. */
|
|
160
175
|
update?: (instance: Supermouse, deltaTime: number) => void;
|
|
161
176
|
/** Called when the plugin is removed or the app is destroyed. */
|
|
162
177
|
destroy?: (instance: Supermouse) => void;
|