@supermousejs/core 2.5.0-beta.2 → 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 +34 -0
- package/dist/index.d.ts +112 -47
- package/dist/index.mjs +373 -279
- package/dist/index.umd.js +2 -2
- package/package.json +8 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
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
|
+
|
|
3
37
|
## 2.5.0-beta.2
|
|
4
38
|
|
|
5
39
|
### 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[];
|
|
@@ -114,8 +107,11 @@ export declare type RuleValue = string | boolean | number;
|
|
|
114
107
|
export declare interface ScopeConfig {
|
|
115
108
|
/** Optional identifier for `getScope(name)` lookups. */
|
|
116
109
|
name?: string;
|
|
117
|
-
/**
|
|
118
|
-
|
|
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;
|
|
119
115
|
/** Cursor mode for this scope. Inherits from top-level if omitted. */
|
|
120
116
|
cursor?: CursorMode;
|
|
121
117
|
/** Hover selectors for this scope. Inherits from top-level if omitted. */
|
|
@@ -142,12 +138,31 @@ export declare interface ScopeConfig {
|
|
|
142
138
|
|
|
143
139
|
export declare interface ScopeHandle {
|
|
144
140
|
readonly name: string | undefined;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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;
|
|
148
150
|
setCursor(mode: CursorMode): void;
|
|
149
|
-
|
|
150
|
-
|
|
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;
|
|
151
166
|
use(plugin: SupermousePlugin): ScopeHandle;
|
|
152
167
|
removePlugin(name: string): void;
|
|
153
168
|
getPlugin(name: string): SupermousePlugin | undefined;
|
|
@@ -167,7 +182,6 @@ export declare class Supermouse {
|
|
|
167
182
|
private _scopes;
|
|
168
183
|
private _activeScope;
|
|
169
184
|
private _installingScope;
|
|
170
|
-
private scopeByContainer;
|
|
171
185
|
private scopeByName;
|
|
172
186
|
private scopeHandles;
|
|
173
187
|
private input;
|
|
@@ -181,12 +195,42 @@ export declare class Supermouse {
|
|
|
181
195
|
get stage(): HTMLDivElement;
|
|
182
196
|
get isEnabled(): boolean;
|
|
183
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
|
+
*/
|
|
184
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
|
+
*/
|
|
185
210
|
getPlugin(name: string): SupermousePlugin | undefined;
|
|
186
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
|
+
*/
|
|
187
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
|
+
*/
|
|
188
227
|
disablePlugin(name: string): void;
|
|
189
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
|
+
*/
|
|
190
234
|
setCursor(mode: CursorMode): void;
|
|
191
235
|
addScope(config: ScopeConfig): ScopeHandle;
|
|
192
236
|
enable(): void;
|
|
@@ -200,11 +244,42 @@ export declare class Supermouse {
|
|
|
200
244
|
private _running;
|
|
201
245
|
private createScope;
|
|
202
246
|
private buildScopeHandle;
|
|
203
|
-
private
|
|
247
|
+
private destroyScope;
|
|
204
248
|
private setScopeCursor;
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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;
|
|
208
283
|
private installPlugins;
|
|
209
284
|
private installPlugin;
|
|
210
285
|
private removePluginFromScope;
|
|
@@ -227,16 +302,6 @@ export declare class Supermouse {
|
|
|
227
302
|
private tick;
|
|
228
303
|
private bindVisibilityHandling;
|
|
229
304
|
private startLoop;
|
|
230
|
-
/**
|
|
231
|
-
* @deprecated Read from the active scope instead.
|
|
232
|
-
* Exposed for tests and debugging.
|
|
233
|
-
*/
|
|
234
|
-
get hoverSelectors(): Set<string>;
|
|
235
|
-
/**
|
|
236
|
-
* @deprecated Read from the active scope instead.
|
|
237
|
-
* Exposed for tests and debugging.
|
|
238
|
-
*/
|
|
239
|
-
get plugins(): SupermousePlugin[];
|
|
240
305
|
/**
|
|
241
306
|
* Adds one or more hover selectors to the current scope. Intended for
|
|
242
307
|
* raw-object plugins during `install`. Plugins written with `definePlugin`
|