@supermousejs/core 2.5.0-beta.1 → 2.5.0-beta.3
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 +41 -0
- package/dist/index.d.ts +143 -45
- package/dist/index.mjs +443 -261
- package/dist/index.umd.js +2 -2
- package/package.json +8 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @supermousejs/core
|
|
2
2
|
|
|
3
|
+
## 2.5.0-beta.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 264bcbd: Beta.3 fixes and internal refactors.
|
|
8
|
+
|
|
9
|
+
**Fixed**
|
|
10
|
+
- Logic plugins (`priority < 0`) now correctly override `state.target` before physics. The update loop was reordering `target = pointer` after plugin execution, silently clobbering Magnetic, Stick, and any plugin that pins the cursor.
|
|
11
|
+
- Cursor state now applies synchronously on `mouseover`, `setCursor()`, and `handle.deactivate()`. Previously the cursor and stage visibility only updated on the next animation frame, causing a one-frame flash of the native cursor when entering a scope whose cursor mode differs from the previous one.
|
|
12
|
+
- Nested scope containers no longer inherit `cursor: none` from an outer scope. An engine-level `:where(.supermouse-scope .supermouse-scope) { cursor: auto }` rule cuts the inheritance without beating any authored cursor rule. Verified in Chromium and Firefox.
|
|
13
|
+
- `disablePlugin` on a plugin whose scope is inactive no longer re-fires `onBeforeDisable` and `onDisable`. Those hooks already ran when the scope went inactive. Semantics: `isEnabled` is user intent; lifecycle hooks fire on transitions of `(isEnabled && scopeIsActive)`.
|
|
14
|
+
- Deactivated eager scopes no longer orphan. The previous resolution model deleted the map entry on deactivation and never re-added it, so `handle.activate()` followed by a hover couldn't reactivate.
|
|
15
|
+
- Detached scope containers no longer pin stale bindings.
|
|
16
|
+
- `handle.activate()` is now eager when the pointer is already inside the container — fixes modals that mount under a stationary pointer.
|
|
17
|
+
|
|
18
|
+
**Changed**
|
|
19
|
+
- `ScopeHandle.remove()` renamed to `ScopeHandle.destroy()`.
|
|
20
|
+
- `ScopeHandle.disable()` / `ScopeHandle.enable()` renamed to `ScopeHandle.deactivate()` / `ScopeHandle.activate()`.
|
|
21
|
+
- `ScopeHandle.disabled` renamed to `ScopeHandle.active` (inverted).
|
|
22
|
+
- `CursorPolicy` is now `{ native: string[], hide: string[] }`. The previous `{ rules: CursorTargetRule[] }` shape is removed; `CursorTargetRule` is no longer exported.
|
|
23
|
+
- `ScopeConfig.container` accepts `HTMLElement | string`. A string is a CSS selector for lazy resolution. The scope stays dormant until an element matching the selector appears and the pointer enters it.
|
|
24
|
+
- `Stage.setNativeCursor` no longer writes inline `cursor` on the container. Cursor suppression is class-driven.
|
|
25
|
+
|
|
26
|
+
**Removed**
|
|
27
|
+
- `ViewportManager` module. Container rect reads are now direct `getBoundingClientRect()` calls in `Input.applyPointerToState`. Fixes stale-rect behavior after enter animations.
|
|
28
|
+
- Internal `scopeByContainer` map. Replaced with an ancestor walk using `Scope.match(el)`.
|
|
29
|
+
|
|
30
|
+
**Internal**
|
|
31
|
+
- Build target raised to `es2022`.
|
|
32
|
+
- `sideEffects: false` added to package.json.
|
|
33
|
+
- Size budget enforced at 6 kB gzip / 5.5 kB brotli via `size-limit`.
|
|
34
|
+
|
|
35
|
+
- e9431a5: Renamed `disable` and `enable` to `deactivate` and `activate` for clarify of function and implement lazy loading of containers
|
|
36
|
+
|
|
37
|
+
## 2.5.0-beta.2
|
|
38
|
+
|
|
39
|
+
### Patch Changes
|
|
40
|
+
|
|
41
|
+
- ff288b4: Fixed Logic Plugins not have effect from wrong ordering of target overwrite
|
|
42
|
+
- 18b57de: Fixed CSS stylesheets being destroyed erroneously from a lack of a primary owner and plugins being activated all at once by the `States` plugin when re-entering previously exited scope
|
|
43
|
+
|
|
3
44
|
## 2.5.0-beta.1
|
|
4
45
|
|
|
5
46
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,39 +1,32 @@
|
|
|
1
1
|
/** Overall cursor mode. */
|
|
2
2
|
export declare type CursorMode = "auto" | "custom" | "native" | "both";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* A cursor policy maps two independent concerns to flat selector lists.
|
|
6
|
+
*
|
|
7
|
+
* - `native`: selectors whose elements yield to the OS cursor when the
|
|
8
|
+
* cursor mode is `"auto"`. Hovering them temporarily shows the native
|
|
9
|
+
* cursor and hides the custom one.
|
|
10
|
+
*
|
|
11
|
+
* - `hide`: selectors that receive `cursor: none !important` when the
|
|
12
|
+
* custom cursor is active. Needed for elements whose UA stylesheet sets
|
|
13
|
+
* a cursor (`a { cursor: pointer }`) that would otherwise override the
|
|
14
|
+
* inherited suppression.
|
|
15
|
+
*/
|
|
4
16
|
export declare interface CursorPolicy {
|
|
5
|
-
|
|
17
|
+
native: string[];
|
|
18
|
+
hide: string[];
|
|
6
19
|
}
|
|
7
20
|
|
|
8
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Shorthand accepted at the public API boundary. `{ native?: [...], hide?: [...] }`
|
|
23
|
+
* normalizes to the full `CursorPolicy` shape with missing keys defaulting to `[]`.
|
|
24
|
+
*/
|
|
9
25
|
export declare type CursorPolicyInput = CursorPolicy | {
|
|
10
26
|
native?: string[];
|
|
11
27
|
hide?: string[];
|
|
12
28
|
};
|
|
13
29
|
|
|
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
30
|
export declare const DEFAULT_CURSOR_POLICY: CursorPolicy;
|
|
38
31
|
|
|
39
32
|
export declare const DEFAULT_HOVER_SELECTORS: string[];
|
|
@@ -91,6 +84,11 @@ export declare interface MouseState {
|
|
|
91
84
|
shape: ShapeState | null;
|
|
92
85
|
/** Centralized store for hover metadata from data attributes and rules. */
|
|
93
86
|
interaction: InteractionState;
|
|
87
|
+
/** The currently active scope's identity, or null when none is active. */
|
|
88
|
+
scope: {
|
|
89
|
+
name: string | undefined;
|
|
90
|
+
container: HTMLElement;
|
|
91
|
+
} | null;
|
|
94
92
|
}
|
|
95
93
|
|
|
96
94
|
declare type ResolvedOptions = SupermouseOptions & Required<Pick<SupermouseOptions, "smoothness" | "enableTouch" | "autoDisableOnMobile" | "cursor" | "hideOnLeave" | "autoStart" | "container" | "dataPrefix" | "zIndex" | "inheritDataAttributes">>;
|
|
@@ -109,8 +107,11 @@ export declare type RuleValue = string | boolean | number;
|
|
|
109
107
|
export declare interface ScopeConfig {
|
|
110
108
|
/** Optional identifier for `getScope(name)` lookups. */
|
|
111
109
|
name?: string;
|
|
112
|
-
/**
|
|
113
|
-
|
|
110
|
+
/**
|
|
111
|
+
* The container this scope is bound to. Pass an element reference for
|
|
112
|
+
* eager binding, or a CSS selector string for lazy resolution.
|
|
113
|
+
*/
|
|
114
|
+
container: HTMLElement | string;
|
|
114
115
|
/** Cursor mode for this scope. Inherits from top-level if omitted. */
|
|
115
116
|
cursor?: CursorMode;
|
|
116
117
|
/** Hover selectors for this scope. Inherits from top-level if omitted. */
|
|
@@ -119,6 +120,12 @@ export declare interface ScopeConfig {
|
|
|
119
120
|
cursorPolicy?: CursorPolicyInput;
|
|
120
121
|
/** Plugins installed when this scope activates. */
|
|
121
122
|
plugins?: SupermousePlugin[];
|
|
123
|
+
/**
|
|
124
|
+
* Rules evaluated against hovered elements inside this scope. If omitted,
|
|
125
|
+
* the scope inherits the primary scope's rules. If provided, the scope
|
|
126
|
+
* uses only its own rules.
|
|
127
|
+
*/
|
|
128
|
+
rules?: Record<string, RuleDefinition>;
|
|
122
129
|
/**
|
|
123
130
|
* Whether data attributes and rules on ancestors cascade to the hovered
|
|
124
131
|
* element. Inherits from top-level if omitted.
|
|
@@ -131,9 +138,34 @@ export declare interface ScopeConfig {
|
|
|
131
138
|
|
|
132
139
|
export declare interface ScopeHandle {
|
|
133
140
|
readonly name: string | undefined;
|
|
134
|
-
|
|
135
|
-
|
|
141
|
+
/**
|
|
142
|
+
* The scope's container element, or `null` if the scope is
|
|
143
|
+
* selector-based and has not yet been resolved to a live element.
|
|
144
|
+
*/
|
|
145
|
+
readonly container: HTMLElement | null;
|
|
146
|
+
readonly active: boolean;
|
|
147
|
+
/** True for eager scopes and for selector scopes that have resolved. */
|
|
148
|
+
readonly resolved: boolean;
|
|
149
|
+
destroy(): void;
|
|
136
150
|
setCursor(mode: CursorMode): void;
|
|
151
|
+
/**
|
|
152
|
+
* Marks the scope as eligible for activation.
|
|
153
|
+
*
|
|
154
|
+
* Activation is lazy: the scope becomes active on the next `mouseover`
|
|
155
|
+
* inside its container, not immediately. If you need to force the scope
|
|
156
|
+
* active while the pointer is already inside it, this will not work
|
|
157
|
+
* until the pointer moves. Deactivation, by contrast, is eager.
|
|
158
|
+
*/
|
|
159
|
+
activate(): void;
|
|
160
|
+
/**
|
|
161
|
+
* Marks the scope as ineligible. If it was the active scope, control
|
|
162
|
+
* yields immediately to the nearest active ancestor scope, or to
|
|
163
|
+
* nothing if none exists.
|
|
164
|
+
*/
|
|
165
|
+
deactivate(): void;
|
|
166
|
+
use(plugin: SupermousePlugin): ScopeHandle;
|
|
167
|
+
removePlugin(name: string): void;
|
|
168
|
+
getPlugin(name: string): SupermousePlugin | undefined;
|
|
137
169
|
}
|
|
138
170
|
|
|
139
171
|
export declare interface ShapeState {
|
|
@@ -150,8 +182,10 @@ export declare class Supermouse {
|
|
|
150
182
|
private _scopes;
|
|
151
183
|
private _activeScope;
|
|
152
184
|
private _installingScope;
|
|
153
|
-
private
|
|
185
|
+
private scopeByName;
|
|
186
|
+
private scopeHandles;
|
|
154
187
|
private input;
|
|
188
|
+
private styleOwner;
|
|
155
189
|
private rafId;
|
|
156
190
|
private lastTime;
|
|
157
191
|
private visibilityAbortController;
|
|
@@ -161,11 +195,42 @@ export declare class Supermouse {
|
|
|
161
195
|
get stage(): HTMLDivElement;
|
|
162
196
|
get isEnabled(): boolean;
|
|
163
197
|
get isRunning(): boolean;
|
|
198
|
+
/**
|
|
199
|
+
* Installs a plugin into the primary scope.
|
|
200
|
+
*
|
|
201
|
+
* In multi-scope mode, prefer `handle.use(plugin)` to target a specific
|
|
202
|
+
* scope. This method always installs to the primary scope, regardless of
|
|
203
|
+
* which scope is currently active.
|
|
204
|
+
*/
|
|
164
205
|
use(plugin: SupermousePlugin): this;
|
|
206
|
+
/**
|
|
207
|
+
* Searches every scope and returns the first plugin matching `name`.
|
|
208
|
+
* Scopes are searched in registration order (primary first).
|
|
209
|
+
*/
|
|
165
210
|
getPlugin(name: string): SupermousePlugin | undefined;
|
|
211
|
+
getScope(name: string): ScopeHandle | undefined;
|
|
212
|
+
/**
|
|
213
|
+
* Enables a plugin by name, wherever it lives.
|
|
214
|
+
*
|
|
215
|
+
* If the plugin's scope is currently active, the activation lifecycle
|
|
216
|
+
* runs immediately. If the scope is inactive, `isEnabled` is set but
|
|
217
|
+
* hooks do not fire until the scope next activates.
|
|
218
|
+
*/
|
|
166
219
|
enablePlugin(name: string): void;
|
|
220
|
+
/**
|
|
221
|
+
* Disables a plugin by name, wherever it lives.
|
|
222
|
+
*
|
|
223
|
+
* If the plugin's scope is currently active, the deactivation lifecycle
|
|
224
|
+
* runs immediately. If the scope is inactive, `isEnabled` is set but
|
|
225
|
+
* hooks do not fire — they already ran when the scope went inactive.
|
|
226
|
+
*/
|
|
167
227
|
disablePlugin(name: string): void;
|
|
168
228
|
togglePlugin(name: string): void;
|
|
229
|
+
/**
|
|
230
|
+
* Sets the cursor mode on the *active* scope.
|
|
231
|
+
*
|
|
232
|
+
* To set the mode on a specific scope, use `handle.setCursor(mode)`.
|
|
233
|
+
*/
|
|
169
234
|
setCursor(mode: CursorMode): void;
|
|
170
235
|
addScope(config: ScopeConfig): ScopeHandle;
|
|
171
236
|
enable(): void;
|
|
@@ -178,13 +243,55 @@ export declare class Supermouse {
|
|
|
178
243
|
destroy(): void;
|
|
179
244
|
private _running;
|
|
180
245
|
private createScope;
|
|
181
|
-
private
|
|
246
|
+
private buildScopeHandle;
|
|
247
|
+
private destroyScope;
|
|
182
248
|
private setScopeCursor;
|
|
249
|
+
/**
|
|
250
|
+
* Marks the scope ineligible for activation and, if it was active, yields
|
|
251
|
+
* immediately to the nearest active ancestor scope (or nothing).
|
|
252
|
+
*/
|
|
253
|
+
private deactivateScope;
|
|
254
|
+
/**
|
|
255
|
+
* Marks the scope eligible for activation.
|
|
256
|
+
*
|
|
257
|
+
* If the pointer is already inside the scope's container, the scope
|
|
258
|
+
* becomes active immediately. Otherwise it activates on the next
|
|
259
|
+
* `mouseover` inside the container. Deactivation is always eager.
|
|
260
|
+
*/
|
|
261
|
+
private activateScope;
|
|
262
|
+
/**
|
|
263
|
+
* Called by `Input` on every `mouseover`, and internally when the active
|
|
264
|
+
* scope is removed or deactivated. Walks from `node` up the ancestor
|
|
265
|
+
* chain, returning the innermost active scope whose `match` succeeds
|
|
266
|
+
* for an ancestor. The matched scope is bound to that ancestor before
|
|
267
|
+
* return.
|
|
268
|
+
*
|
|
269
|
+
* The walk order is what enforces "innermost wins": the first ancestor
|
|
270
|
+
* matching any active scope is, by construction, the closest one to the
|
|
271
|
+
* event target. Detached containers can never be ancestors of a live
|
|
272
|
+
* event target, so no cleanup of stale bindings is required here.
|
|
273
|
+
*/
|
|
274
|
+
private resolveScopeForNode;
|
|
275
|
+
/**
|
|
276
|
+
* Synchronously writes the current cursor and stage visibility for the
|
|
277
|
+
* active scope. Called after hover state settles, on cursor mode changes,
|
|
278
|
+
* and on programmatic scope transitions. The `update()` rAF path calls
|
|
279
|
+
* the same writers as a backstop.
|
|
280
|
+
*/
|
|
281
|
+
private applyCursorNow;
|
|
282
|
+
private findScopeForPlugin;
|
|
183
283
|
private installPlugins;
|
|
184
284
|
private installPlugin;
|
|
285
|
+
private removePluginFromScope;
|
|
185
286
|
private handleActiveScopeChange;
|
|
186
|
-
private activatePlugin;
|
|
187
287
|
private deactivatePlugin;
|
|
288
|
+
/**
|
|
289
|
+
* Runs the deactivation lifecycle for a plugin whose owning scope just
|
|
290
|
+
* became inactive. Does NOT flip `plugin.isEnabled`, so user intent
|
|
291
|
+
* (e.g. States disabling a plugin) survives the scope round-trip.
|
|
292
|
+
*/
|
|
293
|
+
private scopeDeactivatePlugin;
|
|
294
|
+
private scopeActivatePlugin;
|
|
188
295
|
private rebuildStylesheet;
|
|
189
296
|
private runPluginSafe;
|
|
190
297
|
private cleanupCrashedPlugins;
|
|
@@ -196,21 +303,12 @@ export declare class Supermouse {
|
|
|
196
303
|
private bindVisibilityHandling;
|
|
197
304
|
private startLoop;
|
|
198
305
|
/**
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
306
|
+
* Adds one or more hover selectors to the current scope. Intended for
|
|
307
|
+
* raw-object plugins during `install`. Plugins written with `definePlugin`
|
|
308
|
+
* should use the `selector` option instead, and consumers setting up a
|
|
309
|
+
* scope should prefer the `hoverSelectors` option at construction.
|
|
202
310
|
*/
|
|
203
311
|
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[];
|
|
214
312
|
}
|
|
215
313
|
|
|
216
314
|
export declare type SupermouseInstance = Supermouse;
|