@supermousejs/core 2.5.0-beta.2 → 2.5.0-beta.4
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 +54 -0
- package/dist/index.d.ts +122 -47
- package/dist/index.mjs +394 -287
- package/dist/index.umd.js +2 -2
- package/package.json +8 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
# @supermousejs/core
|
|
2
2
|
|
|
3
|
+
## 2.5.0-beta.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- cb9bf9a: Beta.4
|
|
8
|
+
|
|
9
|
+
**Added**
|
|
10
|
+
- `state.authoredCursor` — the cursor value the page intends at the element under the pointer, resolved as if Supermouse's suppression were not active. Populated on every pointerTarget change, in all cursor modes. Read this to know what the page wants (`canvas { cursor: crosshair }`, `.drag-handle { cursor: grab }`, `[disabled] { cursor: not-allowed }`) rather than just whether the OS cursor should be shown (`state.isNative`).
|
|
11
|
+
- `state.pointerTarget` — the raw element under the pointer, regardless of hover selectors. Distinct from `state.hoverTarget`, which reports the nearest ancestor matching a hover selector.
|
|
12
|
+
|
|
13
|
+
**Fixed**
|
|
14
|
+
- Cursor detection in `auto` mode no longer reads its own suppression output. The previous implementation called `getComputedStyle(target).cursor` while the scope's hide class was active, so it always saw `"none"` and never triggered native fallback for authored exotic cursors. A probe attribute (`data-sm-probe`) is now excluded from every generated suppression rule, so the read sees the page's intended value.
|
|
15
|
+
|
|
16
|
+
**Changed**
|
|
17
|
+
- `@supermousejs/labs`: `SmartIcon` now reads `state.pointerTarget` and `state.authoredCursor` instead of relying on a broad hover-selector sweep. Hovering a `<p>` no longer sets `state.isHover` on the primary scope.
|
|
18
|
+
- `@supermousejs/labs`: `SmartIconOptions.useSemanticTags` renamed to `useSemanticDetection`. The old name referred to a `registerHoverTarget` sweep that no longer runs.
|
|
19
|
+
|
|
20
|
+
**Internal**
|
|
21
|
+
- Size budget raised to 6.5 kB gzip / 5.75 kB brotli to accommodate the beta.4 surface. Will be re-tightened once the shape settles.
|
|
22
|
+
|
|
23
|
+
## 2.5.0-beta.3
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- 264bcbd: Beta.3 fixes and internal refactors.
|
|
28
|
+
|
|
29
|
+
**Fixed**
|
|
30
|
+
- 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.
|
|
31
|
+
- 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.
|
|
32
|
+
- 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.
|
|
33
|
+
- `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)`.
|
|
34
|
+
- 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.
|
|
35
|
+
- Detached scope containers no longer pin stale bindings.
|
|
36
|
+
- `handle.activate()` is now eager when the pointer is already inside the container — fixes modals that mount under a stationary pointer.
|
|
37
|
+
|
|
38
|
+
**Changed**
|
|
39
|
+
- `ScopeHandle.remove()` renamed to `ScopeHandle.destroy()`.
|
|
40
|
+
- `ScopeHandle.disable()` / `ScopeHandle.enable()` renamed to `ScopeHandle.deactivate()` / `ScopeHandle.activate()`.
|
|
41
|
+
- `ScopeHandle.disabled` renamed to `ScopeHandle.active` (inverted).
|
|
42
|
+
- `CursorPolicy` is now `{ native: string[], hide: string[] }`. The previous `{ rules: CursorTargetRule[] }` shape is removed; `CursorTargetRule` is no longer exported.
|
|
43
|
+
- `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.
|
|
44
|
+
- `Stage.setNativeCursor` no longer writes inline `cursor` on the container. Cursor suppression is class-driven.
|
|
45
|
+
|
|
46
|
+
**Removed**
|
|
47
|
+
- `ViewportManager` module. Container rect reads are now direct `getBoundingClientRect()` calls in `Input.applyPointerToState`. Fixes stale-rect behavior after enter animations.
|
|
48
|
+
- Internal `scopeByContainer` map. Replaced with an ancestor walk using `Scope.match(el)`.
|
|
49
|
+
|
|
50
|
+
**Internal**
|
|
51
|
+
- Build target raised to `es2022`.
|
|
52
|
+
- `sideEffects: false` added to package.json.
|
|
53
|
+
- Size budget enforced at 6 kB gzip / 5.5 kB brotli via `size-limit`.
|
|
54
|
+
|
|
55
|
+
- e9431a5: Renamed `disable` and `enable` to `deactivate` and `activate` for clarify of function and implement lazy loading of containers
|
|
56
|
+
|
|
3
57
|
## 2.5.0-beta.2
|
|
4
58
|
|
|
5
59
|
### 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[];
|
|
@@ -81,6 +74,16 @@ export declare interface MouseState {
|
|
|
81
74
|
isNative: boolean;
|
|
82
75
|
/** Current cursor mode: auto, custom, native, or both. */
|
|
83
76
|
cursorMode: CursorMode;
|
|
77
|
+
/**
|
|
78
|
+
* The raw element currently under the pointer, regardless of whether it
|
|
79
|
+
* matches any hover selector.
|
|
80
|
+
*/
|
|
81
|
+
pointerTarget: HTMLElement | null;
|
|
82
|
+
/**
|
|
83
|
+
* The authored cursor value at `pointerTarget`, resolved as if
|
|
84
|
+
* Supermouse's suppression were not active.
|
|
85
|
+
*/
|
|
86
|
+
authoredCursor: string | null;
|
|
84
87
|
/** Currently hovered DOM element, if any. */
|
|
85
88
|
hoverTarget: HTMLElement | null;
|
|
86
89
|
/** User has `prefers-reduced-motion` enabled. */
|
|
@@ -114,8 +117,11 @@ export declare type RuleValue = string | boolean | number;
|
|
|
114
117
|
export declare interface ScopeConfig {
|
|
115
118
|
/** Optional identifier for `getScope(name)` lookups. */
|
|
116
119
|
name?: string;
|
|
117
|
-
/**
|
|
118
|
-
|
|
120
|
+
/**
|
|
121
|
+
* The container this scope is bound to. Pass an element reference for
|
|
122
|
+
* eager binding, or a CSS selector string for lazy resolution.
|
|
123
|
+
*/
|
|
124
|
+
container: HTMLElement | string;
|
|
119
125
|
/** Cursor mode for this scope. Inherits from top-level if omitted. */
|
|
120
126
|
cursor?: CursorMode;
|
|
121
127
|
/** Hover selectors for this scope. Inherits from top-level if omitted. */
|
|
@@ -142,12 +148,31 @@ export declare interface ScopeConfig {
|
|
|
142
148
|
|
|
143
149
|
export declare interface ScopeHandle {
|
|
144
150
|
readonly name: string | undefined;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
151
|
+
/**
|
|
152
|
+
* The scope's container element, or `null` if the scope is
|
|
153
|
+
* selector-based and has not yet been resolved to a live element.
|
|
154
|
+
*/
|
|
155
|
+
readonly container: HTMLElement | null;
|
|
156
|
+
readonly active: boolean;
|
|
157
|
+
/** True for eager scopes and for selector scopes that have resolved. */
|
|
158
|
+
readonly resolved: boolean;
|
|
159
|
+
destroy(): void;
|
|
148
160
|
setCursor(mode: CursorMode): void;
|
|
149
|
-
|
|
150
|
-
|
|
161
|
+
/**
|
|
162
|
+
* Marks the scope as eligible for activation.
|
|
163
|
+
*
|
|
164
|
+
* Activation is lazy: the scope becomes active on the next `mouseover`
|
|
165
|
+
* inside its container, not immediately. If you need to force the scope
|
|
166
|
+
* active while the pointer is already inside it, this will not work
|
|
167
|
+
* until the pointer moves. Deactivation, by contrast, is eager.
|
|
168
|
+
*/
|
|
169
|
+
activate(): void;
|
|
170
|
+
/**
|
|
171
|
+
* Marks the scope as ineligible. If it was the active scope, control
|
|
172
|
+
* yields immediately to the nearest active ancestor scope, or to
|
|
173
|
+
* nothing if none exists.
|
|
174
|
+
*/
|
|
175
|
+
deactivate(): void;
|
|
151
176
|
use(plugin: SupermousePlugin): ScopeHandle;
|
|
152
177
|
removePlugin(name: string): void;
|
|
153
178
|
getPlugin(name: string): SupermousePlugin | undefined;
|
|
@@ -167,7 +192,6 @@ export declare class Supermouse {
|
|
|
167
192
|
private _scopes;
|
|
168
193
|
private _activeScope;
|
|
169
194
|
private _installingScope;
|
|
170
|
-
private scopeByContainer;
|
|
171
195
|
private scopeByName;
|
|
172
196
|
private scopeHandles;
|
|
173
197
|
private input;
|
|
@@ -181,12 +205,42 @@ export declare class Supermouse {
|
|
|
181
205
|
get stage(): HTMLDivElement;
|
|
182
206
|
get isEnabled(): boolean;
|
|
183
207
|
get isRunning(): boolean;
|
|
208
|
+
/**
|
|
209
|
+
* Installs a plugin into the primary scope.
|
|
210
|
+
*
|
|
211
|
+
* In multi-scope mode, prefer `handle.use(plugin)` to target a specific
|
|
212
|
+
* scope. This method always installs to the primary scope, regardless of
|
|
213
|
+
* which scope is currently active.
|
|
214
|
+
*/
|
|
184
215
|
use(plugin: SupermousePlugin): this;
|
|
216
|
+
/**
|
|
217
|
+
* Searches every scope and returns the first plugin matching `name`.
|
|
218
|
+
* Scopes are searched in registration order (primary first).
|
|
219
|
+
*/
|
|
185
220
|
getPlugin(name: string): SupermousePlugin | undefined;
|
|
186
221
|
getScope(name: string): ScopeHandle | undefined;
|
|
222
|
+
/**
|
|
223
|
+
* Enables a plugin by name, wherever it lives.
|
|
224
|
+
*
|
|
225
|
+
* If the plugin's scope is currently active, the activation lifecycle
|
|
226
|
+
* runs immediately. If the scope is inactive, `isEnabled` is set but
|
|
227
|
+
* hooks do not fire until the scope next activates.
|
|
228
|
+
*/
|
|
187
229
|
enablePlugin(name: string): void;
|
|
230
|
+
/**
|
|
231
|
+
* Disables a plugin by name, wherever it lives.
|
|
232
|
+
*
|
|
233
|
+
* If the plugin's scope is currently active, the deactivation lifecycle
|
|
234
|
+
* runs immediately. If the scope is inactive, `isEnabled` is set but
|
|
235
|
+
* hooks do not fire — they already ran when the scope went inactive.
|
|
236
|
+
*/
|
|
188
237
|
disablePlugin(name: string): void;
|
|
189
238
|
togglePlugin(name: string): void;
|
|
239
|
+
/**
|
|
240
|
+
* Sets the cursor mode on the *active* scope.
|
|
241
|
+
*
|
|
242
|
+
* To set the mode on a specific scope, use `handle.setCursor(mode)`.
|
|
243
|
+
*/
|
|
190
244
|
setCursor(mode: CursorMode): void;
|
|
191
245
|
addScope(config: ScopeConfig): ScopeHandle;
|
|
192
246
|
enable(): void;
|
|
@@ -200,11 +254,42 @@ export declare class Supermouse {
|
|
|
200
254
|
private _running;
|
|
201
255
|
private createScope;
|
|
202
256
|
private buildScopeHandle;
|
|
203
|
-
private
|
|
257
|
+
private destroyScope;
|
|
204
258
|
private setScopeCursor;
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
259
|
+
/**
|
|
260
|
+
* Marks the scope ineligible for activation and, if it was active, yields
|
|
261
|
+
* immediately to the nearest active ancestor scope (or nothing).
|
|
262
|
+
*/
|
|
263
|
+
private deactivateScope;
|
|
264
|
+
/**
|
|
265
|
+
* Marks the scope eligible for activation.
|
|
266
|
+
*
|
|
267
|
+
* If the pointer is already inside the scope's container, the scope
|
|
268
|
+
* becomes active immediately. Otherwise it activates on the next
|
|
269
|
+
* `mouseover` inside the container. Deactivation is always eager.
|
|
270
|
+
*/
|
|
271
|
+
private activateScope;
|
|
272
|
+
/**
|
|
273
|
+
* Called by `Input` on every `mouseover`, and internally when the active
|
|
274
|
+
* scope is removed or deactivated. Walks from `node` up the ancestor
|
|
275
|
+
* chain, returning the innermost active scope whose `match` succeeds
|
|
276
|
+
* for an ancestor. The matched scope is bound to that ancestor before
|
|
277
|
+
* return.
|
|
278
|
+
*
|
|
279
|
+
* The walk order is what enforces "innermost wins": the first ancestor
|
|
280
|
+
* matching any active scope is, by construction, the closest one to the
|
|
281
|
+
* event target. Detached containers can never be ancestors of a live
|
|
282
|
+
* event target, so no cleanup of stale bindings is required here.
|
|
283
|
+
*/
|
|
284
|
+
private resolveScopeForNode;
|
|
285
|
+
/**
|
|
286
|
+
* Synchronously writes the current cursor and stage visibility for the
|
|
287
|
+
* active scope. Called after hover state settles, on cursor mode changes,
|
|
288
|
+
* and on programmatic scope transitions. The `update()` rAF path calls
|
|
289
|
+
* the same writers as a backstop.
|
|
290
|
+
*/
|
|
291
|
+
private applyCursorNow;
|
|
292
|
+
private findScopeForPlugin;
|
|
208
293
|
private installPlugins;
|
|
209
294
|
private installPlugin;
|
|
210
295
|
private removePluginFromScope;
|
|
@@ -227,16 +312,6 @@ export declare class Supermouse {
|
|
|
227
312
|
private tick;
|
|
228
313
|
private bindVisibilityHandling;
|
|
229
314
|
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
315
|
/**
|
|
241
316
|
* Adds one or more hover selectors to the current scope. Intended for
|
|
242
317
|
* raw-object plugins during `install`. Plugins written with `definePlugin`
|