@supermousejs/core 2.4.3 → 2.5.0-beta.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 CHANGED
@@ -1,5 +1,45 @@
1
1
  # @supermousejs/core
2
2
 
3
+ ## 2.5.0-beta.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 0af4732: Architecture rewrite for v2.5. This is a beta, therefore expect API surface churn before the stable release.
8
+
9
+ **Scopes.** A single instance can now own multiple scopes. Pass them at construction or add them at runtime:
10
+
11
+ ```ts
12
+ const mouse = new Supermouse({
13
+ scopes: [{ name: "sidebar", container: sidebarEl, cursor: "native" }]
14
+ });
15
+
16
+ const handle = mouse.addScope({ container: modalEl, cursor: "custom" });
17
+ handle.setCursor("auto");
18
+ handle.remove();
19
+ ```
20
+
21
+ The innermost scope whose container contains the pointer is the active one. Plugin installation, cursor mode, hover selectors, and native-cursor state are all managed per scope.
22
+
23
+ **Cursor policy.** `NATIVE_TAGS` and the old `Stage.selectors` are unified into a single `CursorPolicy`. Pass a custom policy via `cursorPolicy` at the top level or per scope. `DEFAULT_CURSOR_POLICY` is exported for spreading.
24
+
25
+ **Ancestor-chain interaction.** `data-supermouse-*` attributes and `rules` now cascade from ancestors to the hovered element, ensuring the closest ancestor wins. This fixes the tag-inside-a-tag class of bugs. Disable with `inheritDataAttributes: false`.
26
+
27
+ **Lifecycle.** `onBeforeDisable` (and its `definePlugin` equivalent, `beforeDisable`) is now scope-aware: when a scope deactivates, each of its plugins runs `onBeforeDisable`, and the core waits for any returned Promise before hiding the element and calling `onDisable`.
28
+
29
+ **Changed.**
30
+ - `disable()` no longer resets physics. Call `disable({ reset: true })` for the old behavior.
31
+ - `suspend()` and `resume()` are removed. Use scopes.
32
+ - `registerHoverTarget` now mutates the active scope's selector set. It's still available for raw-object plugins, but `definePlugin`'s `selector` option is preferred.
33
+ - Stage no longer owns an individual `<style>` tag. All scopes share a single engine-level stylesheet.
34
+
35
+ **Removed.**
36
+ - `NATIVE_TAGS`, `SUPERMOUSE_CURSORS` internal constants (moved into policy).
37
+ - `Stage.addSelector` / `Stage.addSelectors` no-ops.
38
+
39
+ ### Patch Changes
40
+
41
+ - 1325a9c: Reorganized Supermouse core for better tree-shaking and module isolation
42
+
3
43
  ## 2.4.3
4
44
 
5
45
  ### Patch Changes
package/README.md CHANGED
@@ -1,158 +1,158 @@
1
- # Supermouse.js - TypeScript cursor engine
2
-
3
- [![npm version](https://img.shields.io/npm/v/@supermousejs/core.svg?style=flat-square)](https://www.npmjs.com/package/@supermousejs/core)
4
- [![npm downloads](https://img.shields.io/npm/dm/@supermousejs/core.svg?style=flat-square)](https://www.npmjs.com/package/@supermousejs/core)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
6
- ![npm bundle size](https://img.shields.io/bundlephobia/minzip/%40supermousejs%2Fcore?label=minzip)
7
-
8
- Supermouse is a headless, physics‑based cursor engine for the web written in TypeScript. It provides pointer tracking, state, physics, and a plugin lifecycle. You install plugins (or write your own) to render custom cursors and effects. The core is zero‑dependency and TypeScript‑first.
9
-
10
- **Documentation:** [supermouse.js.org](https://supermouse.js.org)
11
-
12
- ## Installation
13
-
14
- ```bash
15
- pnpm add @supermousejs/core
16
- npm install @supermousejs/core
17
- ```
18
-
19
- Install plugins you need:
20
-
21
- ```bash
22
- pnpm add @supermousejs/dot @supermousejs/ring
23
- npm install @supermousejs/dot @supermousejs/ring
24
- ```
25
-
26
- ## Quick Start
27
-
28
- ```ts
29
- import { Supermouse } from "@supermousejs/core";
30
- import { Dot } from "@supermousejs/dot";
31
-
32
- const mouse = new Supermouse({
33
- plugins: [Dot({ size: 8 })]
34
- });
35
- ```
36
-
37
- Or use the plugin interface directly:
38
-
39
- ```ts
40
- import { Supermouse } from "@supermousejs/core";
41
-
42
- const dot = document.createElement("div");
43
- // ... style dot ...
44
-
45
- const redDot = {
46
- name: "red-dot",
47
- install(app) {
48
- app.stage.appendChild(dot);
49
- },
50
- update(app) {
51
- const { smooth } = app.state;
52
- dot.style.transform = `translate3d(${smooth.x}px, ${smooth.y}px, 0)`;
53
- },
54
- destroy() {
55
- dot.remove();
56
- }
57
- };
58
-
59
- const mouse = new Supermouse({ plugins: [redDot] });
60
- ```
61
-
62
- ## Options
63
-
64
- | Option | Default | Description |
65
- | --------------------- | ----------------------------------------------------------------------- | --------------------------------------------- |
66
- | `smoothness` | `0.15` | Lower = smoother cursor follow |
67
- | `hoverSelectors` | `["a", "button", "input", "textarea", "[data-hover]", "[data-cursor]"]` | Selectors that set `state.isHover` |
68
- | `enableTouch` | `false` | Allow touch events to move cursor |
69
- | `autoDisableOnMobile` | `true` | Disable on coarse‑pointer devices |
70
- | `cursor` | `"auto"` | `"auto"`, `"custom"`, `"native"`, or `"both"` |
71
- | `hideOnLeave` | `true` | Hide when pointer leaves window |
72
- | `container` | `document.body` | Scoping container |
73
- | `zIndex` | `9999` | Stage stacking order |
74
- | `dataPrefix` | `"supermouse"` | Prefix for data attributes |
75
- | `rules` | — | Map of selectors to interaction data |
76
- | `plugins` | — | Plugins to install at creation |
77
- | `autoStart` | `true` | Set `false` and call `.start()` manually |
78
-
79
- ## Cursor Modes
80
-
81
- - `"auto"` – native cursor on interactive elements, custom elsewhere.
82
- - `"custom"` – always custom, hide native.
83
- - `"native"` – always native, hide custom.
84
- - `"both"` – show both native and custom together.
85
-
86
- Change at runtime with `mouse.setCursor("both")`.
87
-
88
- ## Containers & Multiple Instances
89
-
90
- Scope an instance to a container:
91
-
92
- ```ts
93
- const modal = document.getElementById("modal");
94
- const mouse = new Supermouse({ container: modal, cursor: "custom" });
95
- ```
96
-
97
- Multiple instances can coexist; CSS rules are scoped automatically.
98
-
99
- ## Native Cursor Fallback
100
-
101
- In `"auto"` mode, add `data-supermouse-ignore` to force the native cursor on an element and its descendants.
102
-
103
- ```html
104
- <div data-supermouse-ignore>Native cursor here</div>
105
- ```
106
-
107
- ## Data Attributes
108
-
109
- Plugins can react to `data-*` attributes, e.g. `data-supermouse-color`. The prefix is configurable via `dataPrefix`.
110
-
111
- ## Rules
112
-
113
- Define interaction data without writing many attributes:
114
-
115
- ```ts
116
- const mouse = new Supermouse({
117
- rules: {
118
- ".primary-action": { magnetic: true, color: "red" }
119
- }
120
- });
121
- ```
122
-
123
- HTML `data-*` attributes override rule values per property.
124
-
125
- ## API
126
-
127
- ```ts
128
- mouse.state; // current MouseState
129
- mouse.options; // resolved options
130
- mouse.stage; // DOM element plugins render into
131
- mouse.isEnabled; // boolean
132
-
133
- mouse.enable(); // start input, hide native cursor
134
- mouse.disable(); // stop input, show native cursor, reset
135
- mouse.suspend(); // pause non‑destructively
136
- mouse.resume(); // resume from suspend
137
-
138
- mouse.setCursor(mode); // "auto" | "custom" | "native" | "both"
139
-
140
- mouse.use(plugin); // install plugin
141
- mouse.getPlugin(name); // retrieve plugin
142
- mouse.enablePlugin(name); // enable plugin
143
- mouse.disablePlugin(name); // disable plugin
144
- mouse.togglePlugin(name); // toggle plugin
145
-
146
- mouse.registerHoverTarget(sel); // add hover selector at runtime
147
- mouse.start(); // start animation loop
148
- mouse.step(time); // advance one frame manually
149
- mouse.destroy(); // destroy instance and plugins
150
- ```
151
-
152
- ## Browser Support
153
-
154
- All modern browsers.
155
-
156
- ## License
157
-
158
- MIT
1
+ # Supermouse.js - TypeScript cursor engine
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@supermousejs/core.svg?style=flat-square)](https://www.npmjs.com/package/@supermousejs/core)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@supermousejs/core.svg?style=flat-square)](https://www.npmjs.com/package/@supermousejs/core)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
6
+ ![npm bundle size](https://img.shields.io/bundlephobia/minzip/%40supermousejs%2Fcore?label=minzip)
7
+
8
+ Supermouse is a headless, physics‑based cursor engine for the web written in TypeScript. It provides pointer tracking, state, physics, and a plugin lifecycle. You install plugins (or write your own) to render custom cursors and effects. The core is zero‑dependency and TypeScript‑first.
9
+
10
+ **Documentation:** [supermouse.js.org](https://supermouse.js.org)
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ pnpm add @supermousejs/core
16
+ npm install @supermousejs/core
17
+ ```
18
+
19
+ Install plugins you need:
20
+
21
+ ```bash
22
+ pnpm add @supermousejs/dot @supermousejs/ring
23
+ npm install @supermousejs/dot @supermousejs/ring
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ```ts
29
+ import { Supermouse } from "@supermousejs/core";
30
+ import { Dot } from "@supermousejs/dot";
31
+
32
+ const mouse = new Supermouse({
33
+ plugins: [Dot({ size: 8 })]
34
+ });
35
+ ```
36
+
37
+ Or use the plugin interface directly:
38
+
39
+ ```ts
40
+ import { Supermouse } from "@supermousejs/core";
41
+
42
+ const dot = document.createElement("div");
43
+ // ... style dot ...
44
+
45
+ const redDot = {
46
+ name: "red-dot",
47
+ install(app) {
48
+ app.stage.appendChild(dot);
49
+ },
50
+ update(app) {
51
+ const { smooth } = app.state;
52
+ dot.style.transform = `translate3d(${smooth.x}px, ${smooth.y}px, 0)`;
53
+ },
54
+ destroy() {
55
+ dot.remove();
56
+ }
57
+ };
58
+
59
+ const mouse = new Supermouse({ plugins: [redDot] });
60
+ ```
61
+
62
+ ## Options
63
+
64
+ | Option | Default | Description |
65
+ | --------------------- | ----------------------------------------------------------------------- | --------------------------------------------- |
66
+ | `smoothness` | `0.15` | Lower = smoother cursor follow |
67
+ | `hoverSelectors` | `["a", "button", "input", "textarea", "[data-hover]", "[data-cursor]"]` | Selectors that set `state.isHover` |
68
+ | `enableTouch` | `false` | Allow touch events to move cursor |
69
+ | `autoDisableOnMobile` | `true` | Disable on coarse‑pointer devices |
70
+ | `cursor` | `"auto"` | `"auto"`, `"custom"`, `"native"`, or `"both"` |
71
+ | `hideOnLeave` | `true` | Hide when pointer leaves window |
72
+ | `container` | `document.body` | Scoping container |
73
+ | `zIndex` | `9999` | Stage stacking order |
74
+ | `dataPrefix` | `"supermouse"` | Prefix for data attributes |
75
+ | `rules` | — | Map of selectors to interaction data |
76
+ | `plugins` | — | Plugins to install at creation |
77
+ | `autoStart` | `true` | Set `false` and call `.start()` manually |
78
+
79
+ ## Cursor Modes
80
+
81
+ - `"auto"` – native cursor on interactive elements, custom elsewhere.
82
+ - `"custom"` – always custom, hide native.
83
+ - `"native"` – always native, hide custom.
84
+ - `"both"` – show both native and custom together.
85
+
86
+ Change at runtime with `mouse.setCursor("both")`.
87
+
88
+ ## Containers & Multiple Instances
89
+
90
+ Scope an instance to a container:
91
+
92
+ ```ts
93
+ const modal = document.getElementById("modal");
94
+ const mouse = new Supermouse({ container: modal, cursor: "custom" });
95
+ ```
96
+
97
+ Multiple instances can coexist; CSS rules are scoped automatically.
98
+
99
+ ## Native Cursor Fallback
100
+
101
+ In `"auto"` mode, add `data-supermouse-ignore` to force the native cursor on an element and its descendants.
102
+
103
+ ```html
104
+ <div data-supermouse-ignore>Native cursor here</div>
105
+ ```
106
+
107
+ ## Data Attributes
108
+
109
+ Plugins can react to `data-*` attributes, e.g. `data-supermouse-color`. The prefix is configurable via `dataPrefix`.
110
+
111
+ ## Rules
112
+
113
+ Define interaction data without writing many attributes:
114
+
115
+ ```ts
116
+ const mouse = new Supermouse({
117
+ rules: {
118
+ ".primary-action": { magnetic: true, color: "red" }
119
+ }
120
+ });
121
+ ```
122
+
123
+ HTML `data-*` attributes override rule values per property.
124
+
125
+ ## API
126
+
127
+ ```ts
128
+ mouse.state; // current MouseState
129
+ mouse.options; // resolved options
130
+ mouse.stage; // DOM element plugins render into
131
+ mouse.isEnabled; // boolean
132
+
133
+ mouse.enable(); // start input, hide native cursor
134
+ mouse.disable(); // stop input, show native cursor, reset
135
+ mouse.suspend(); // pause non‑destructively
136
+ mouse.resume(); // resume from suspend
137
+
138
+ mouse.setCursor(mode); // "auto" | "custom" | "native" | "both"
139
+
140
+ mouse.use(plugin); // install plugin
141
+ mouse.getPlugin(name); // retrieve plugin
142
+ mouse.enablePlugin(name); // enable plugin
143
+ mouse.disablePlugin(name); // disable plugin
144
+ mouse.togglePlugin(name); // toggle plugin
145
+
146
+ mouse.registerHoverTarget(sel); // add hover selector at runtime
147
+ mouse.start(); // start animation loop
148
+ mouse.step(time); // advance one frame manually
149
+ mouse.destroy(); // destroy instance and plugins
150
+ ```
151
+
152
+ ## Browser Support
153
+
154
+ All modern browsers.
155
+
156
+ ## License
157
+
158
+ MIT
package/dist/index.d.ts CHANGED
@@ -1,7 +1,42 @@
1
- /** Default selectors that trigger `state.isHover`. Override with `hoverSelectors`. */
2
- export declare const DEFAULT_HOVER_SELECTORS: string[];
1
+ /** Overall cursor mode. */
2
+ export declare type CursorMode = "auto" | "custom" | "native" | "both";
3
+
4
+ export declare interface CursorPolicy {
5
+ rules: CursorTargetRule[];
6
+ }
7
+
8
+ /** Shorthand form accepted at the public API boundary. */
9
+ export declare type CursorPolicyInput = CursorPolicy | {
10
+ native?: string[];
11
+ hide?: string[];
12
+ };
13
+
14
+ /**
15
+ * A single rule that ties a CSS selector to native-cursor behaviour
16
+ * and/or native-cursor CSS suppression.
17
+ */
18
+ export declare interface CursorTargetRule {
19
+ /** CSS selector to match. */
20
+ selector: string;
21
+ /**
22
+ * In `"auto"` cursor mode, an element matching this selector yields to the
23
+ * OS cursor.
24
+ * @default true
25
+ */
26
+ native?: boolean;
27
+ /**
28
+ * Generate a `cursor: none !important` rule for this selector when the
29
+ * custom cursor is active. Needed for elements whose UA stylesheet sets a
30
+ * cursor value (e.g. `a { cursor: pointer }`) that would otherwise override
31
+ * the container's inherited `cursor: none`.
32
+ * @default true
33
+ */
34
+ hide?: boolean;
35
+ }
36
+
37
+ export declare const DEFAULT_CURSOR_POLICY: CursorPolicy;
3
38
 
4
- /* Excluded from this release type: Input */
39
+ export declare const DEFAULT_HOVER_SELECTORS: string[];
5
40
 
6
41
  /**
7
42
  * Interaction state consumed by plugins.
@@ -45,7 +80,7 @@ export declare interface MouseState {
45
80
  /** Native cursor temporarily restored due to native-input heuristics. */
46
81
  isNative: boolean;
47
82
  /** Current cursor mode: auto, custom, native, or both. */
48
- cursorMode: "auto" | "custom" | "native" | "both";
83
+ cursorMode: CursorMode;
49
84
  /** Currently hovered DOM element, if any. */
50
85
  hoverTarget: HTMLElement | null;
51
86
  /** User has `prefers-reduced-motion` enabled. */
@@ -58,11 +93,7 @@ export declare interface MouseState {
58
93
  interaction: InteractionState;
59
94
  }
60
95
 
61
- /**
62
- * The subset of `SupermouseOptions` guaranteed to have a concrete value once
63
- * the constructor has merged user input over the defaults.
64
- */
65
- declare type ResolvedOptions = SupermouseOptions & Required<Pick<SupermouseOptions, "smoothness" | "enableTouch" | "autoDisableOnMobile" | "cursor" | "hideOnLeave" | "autoStart" | "container" | "dataPrefix" | "zIndex">>;
96
+ declare type ResolvedOptions = SupermouseOptions & Required<Pick<SupermouseOptions, "smoothness" | "enableTouch" | "autoDisableOnMobile" | "cursor" | "hideOnLeave" | "autoStart" | "container" | "dataPrefix" | "zIndex" | "inheritDataAttributes">>;
66
97
 
67
98
  export declare type RuleDefinition = RuleSet | ((el: HTMLElement) => RuleSet);
68
99
 
@@ -70,71 +101,91 @@ export declare type RuleSet = Record<string, RuleValue | ((el: HTMLElement) => R
70
101
 
71
102
  export declare type RuleValue = string | boolean | number;
72
103
 
104
+ /**
105
+ * Configuration for a single scope. A scope owns a container, its cursor
106
+ * mode, its hover selectors, and its plugin set. Scopes stack: the innermost
107
+ * scope whose container contains the pointer is the active one.
108
+ */
109
+ export declare interface ScopeConfig {
110
+ /** Optional identifier for `getScope(name)` lookups. */
111
+ name?: string;
112
+ /** The element this scope is bound to. */
113
+ container: HTMLElement;
114
+ /** Cursor mode for this scope. Inherits from top-level if omitted. */
115
+ cursor?: CursorMode;
116
+ /** Hover selectors for this scope. Inherits from top-level if omitted. */
117
+ hoverSelectors?: string[];
118
+ /** Custom cursor policy for this scope. Inherits from top-level if omitted. */
119
+ cursorPolicy?: CursorPolicyInput;
120
+ /** Plugins installed when this scope activates. */
121
+ plugins?: SupermousePlugin[];
122
+ /**
123
+ * Whether data attributes and rules on ancestors cascade to the hovered
124
+ * element. Inherits from top-level if omitted.
125
+ * @default true
126
+ */
127
+ inheritDataAttributes?: boolean;
128
+ /** Stage z-index for this scope. Inherits from top-level if omitted. */
129
+ zIndex?: number;
130
+ }
131
+
132
+ export declare interface ScopeHandle {
133
+ readonly name: string | undefined;
134
+ readonly container: HTMLElement;
135
+ remove(): void;
136
+ setCursor(mode: CursorMode): void;
137
+ }
138
+
73
139
  export declare interface ShapeState {
74
140
  width: number;
75
141
  height: number;
76
142
  borderRadius: number;
77
143
  }
78
144
 
79
- /* Excluded from this release type: Stage */
80
-
81
- /**
82
- * Orchestrates state, animation loop, and plugin lifecycle.
83
- */
84
145
  export declare class Supermouse {
85
146
  static readonly version: string;
86
147
  readonly version: string;
87
148
  state: MouseState;
88
- /** Configuration options, fully resolved with defaults applied. */
89
149
  options: ResolvedOptions;
90
- private plugins;
91
- private _stage;
150
+ private _scopes;
151
+ private _activeScope;
152
+ private _installingScope;
153
+ private scopeByContainer;
92
154
  private input;
93
155
  private rafId;
94
156
  private lastTime;
95
- private isRunning;
96
- private isSuspended;
97
157
  private visibilityAbortController;
98
- private hoverSelectors;
99
- private hoverSelectorString;
100
158
  private crashedPlugins;
101
159
  constructor(options?: SupermouseOptions);
102
- /** Look up a registered plugin by name. */
103
- getPlugin(name: string): SupermousePlugin | undefined;
104
- /** Whether the instance is not disabled/suspended and is processing input. */
160
+ get container(): HTMLElement;
161
+ get stage(): HTMLDivElement;
105
162
  get isEnabled(): boolean;
106
- /** Enable a plugin by name. */
163
+ get isRunning(): boolean;
164
+ use(plugin: SupermousePlugin): this;
165
+ getPlugin(name: string): SupermousePlugin | undefined;
107
166
  enablePlugin(name: string): void;
108
- /** Disable a plugin by name and hide its element. */
109
167
  disablePlugin(name: string): void;
110
- /** Toggle a plugin's enabled state by name. */
111
168
  togglePlugin(name: string): void;
112
- /** Add a selector to hover detection and cursor suppression. */
113
- registerHoverTarget(selector: string): void;
114
- /** The DOM element the instance is scoped to. */
115
- get container(): HTMLElement;
116
- /** The stage element that plugins append their visuals into. */
117
- get stage(): HTMLDivElement;
118
- /** Set the current cursor mode. */
119
- setCursor(mode: "auto" | "custom" | "native" | "both"): void;
120
- private init;
121
- /** Re‑enable input processing and re‑apply cursor state. */
169
+ setCursor(mode: CursorMode): void;
170
+ addScope(config: ScopeConfig): ScopeHandle;
122
171
  enable(): void;
123
- /** Disable input processing and restore native cursor. */
124
- disable(): void;
125
- /** Temporarily yield to a scoped instance. */
126
- suspend(): void;
127
- /** Resume from `suspend()`. */
128
- resume(): void;
129
- /** Register a new plugin. */
130
- use(plugin: SupermousePlugin): this;
131
- /** Reset physics; optionally clear all input state. */
132
- private reset;
133
- private startLoop;
134
- /** Start the animation loop. */
172
+ disable(opts?: {
173
+ reset?: boolean;
174
+ }): void;
175
+ reset(): void;
135
176
  start(): void;
136
- /** Manually step the animation loop. */
137
177
  step(time: number): void;
178
+ destroy(): void;
179
+ private _running;
180
+ private createScope;
181
+ private removeScope;
182
+ private setScopeCursor;
183
+ private installPlugins;
184
+ private installPlugin;
185
+ private handleActiveScopeChange;
186
+ private activatePlugin;
187
+ private deactivatePlugin;
188
+ private rebuildStylesheet;
138
189
  private runPluginSafe;
139
190
  private cleanupCrashedPlugins;
140
191
  private resolveStageVisibility;
@@ -142,10 +193,24 @@ export declare class Supermouse {
142
193
  private resetMotion;
143
194
  private update;
144
195
  private tick;
145
- /** Pause rAF loop when tab hidden; resume on visible. */
146
196
  private bindVisibilityHandling;
147
- /** Destroy the instance, freeing all resources. */
148
- destroy(): void;
197
+ private startLoop;
198
+ /**
199
+ * @deprecated Prefer setting `hoverSelectors` at scope creation, or use
200
+ * `definePlugin`'s `selector` option. This method is kept for raw-object
201
+ * plugins and runtime extension; it mutates the active scope's selector set.
202
+ */
203
+ registerHoverTarget(selector: string): void;
204
+ /**
205
+ * @deprecated Read from the active scope instead. Exposed for tests and
206
+ * debugging only.
207
+ */
208
+ get hoverSelectors(): Set<string>;
209
+ /**
210
+ * @deprecated Read from the active scope instead. Exposed for tests and
211
+ * debugging only.
212
+ */
213
+ get plugins(): SupermousePlugin[];
149
214
  }
150
215
 
151
216
  export declare type SupermouseInstance = Supermouse;
@@ -180,7 +245,23 @@ export declare interface SupermouseOptions {
180
245
  * - `"both"`: always show custom cursor **and** native cursor together (no suppression).
181
246
  * @default "auto"
182
247
  */
183
- cursor?: "auto" | "custom" | "native" | "both";
248
+ cursor?: CursorMode;
249
+ /**
250
+ * Custom cursor policy. Defaults to `DEFAULT_CURSOR_POLICY` from `./policy`.
251
+ */
252
+ cursorPolicy?: CursorPolicyInput;
253
+ /**
254
+ * Additional scopes registered at construction. The primary scope is
255
+ * created from the top-level `container` / `hoverSelectors` / `plugins`
256
+ * options; these are appended after it.
257
+ */
258
+ scopes?: ScopeConfig[];
259
+ /**
260
+ * Whether data attributes and rules on ancestors cascade to the hovered
261
+ * element. Applies to the primary scope; individual scopes can override.
262
+ * @default true
263
+ */
264
+ inheritDataAttributes?: boolean;
184
265
  /**
185
266
  * Whether to hide the custom cursor when the pointer leaves the browser viewport.
186
267
  * @default true
@@ -239,7 +320,8 @@ export declare interface SupermousePlugin {
239
320
  /** Called when plugin disabled via `.disablePlugin()`. */
240
321
  onDisable?: (instance: SupermouseInstance) => void;
241
322
  /**
242
- * Called before the plugin is disabled.
323
+ * Called before the plugin is disabled. Return a Promise to delay hiding
324
+ * until an exit animation completes.
243
325
  */
244
326
  onBeforeDisable?(instance: SupermouseInstance): void | Promise<void>;
245
327
  }