@mmstack/primitives 19.4.1 → 19.5.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/README.md +2 -0
- package/fesm2022/mmstack-primitives.mjs +570 -245
- package/fesm2022/mmstack-primitives.mjs.map +1 -1
- package/index.d.ts +2 -2
- package/lib/chunked.d.ts +2 -2
- package/lib/concurrent/pausable.d.ts +3 -2
- package/lib/concurrent/start-transition.d.ts +5 -0
- package/lib/concurrent/transaction.d.ts +5 -0
- package/lib/concurrent/transition-scope.d.ts +15 -1
- package/lib/effect/index.d.ts +1 -0
- package/lib/effect/nested-effect.d.ts +2 -2
- package/lib/get-signal-equality.d.ts +1 -1
- package/lib/mutable.d.ts +1 -1
- package/lib/pipeable/{pipeble.d.ts → pipeable.d.ts} +1 -1
- package/lib/pipeable/public_api.d.ts +1 -1
- package/lib/pipeable/types.d.ts +1 -1
- package/lib/sensors/battery-status.d.ts +2 -1
- package/lib/sensors/clipboard.d.ts +2 -1
- package/lib/sensors/element-size.d.ts +2 -4
- package/lib/sensors/element-visibility.d.ts +2 -4
- package/lib/sensors/focus-within.d.ts +2 -1
- package/lib/sensors/geolocation.d.ts +2 -3
- package/lib/sensors/idle.d.ts +6 -4
- package/lib/sensors/index.d.ts +1 -0
- package/lib/sensors/media-query.d.ts +4 -3
- package/lib/sensors/mouse-position.d.ts +6 -7
- package/lib/sensors/network-status.d.ts +8 -3
- package/lib/sensors/orientation.d.ts +9 -2
- package/lib/sensors/page-visibility.d.ts +4 -2
- package/lib/sensors/scroll-position.d.ts +10 -18
- package/lib/sensors/sensor-options.d.ts +25 -0
- package/lib/sensors/sensor.d.ts +15 -30
- package/lib/sensors/window-size.d.ts +3 -6
- package/lib/store/store.d.ts +4 -4
- package/lib/stored.d.ts +4 -3
- package/lib/{tabSync.d.ts → tab-sync.d.ts} +9 -4
- package/lib/throttled.d.ts +2 -0
- package/lib/to-writable.d.ts +4 -0
- package/package.json +2 -2
package/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export * from './lib/chunked';
|
|
|
2
2
|
export * from './lib/concurrent';
|
|
3
3
|
export * from './lib/debounced';
|
|
4
4
|
export * from './lib/derived';
|
|
5
|
-
export { nestedEffect } from './lib/effect';
|
|
5
|
+
export { nestedEffect, type Frame } from './lib/effect';
|
|
6
6
|
export * from './lib/keep-previous';
|
|
7
7
|
export * from './lib/mappers';
|
|
8
8
|
export * from './lib/mutable';
|
|
@@ -11,7 +11,7 @@ export * from './lib/pooled';
|
|
|
11
11
|
export * from './lib/sensors';
|
|
12
12
|
export * from './lib/store/public_api';
|
|
13
13
|
export * from './lib/stored';
|
|
14
|
-
export { tabSync } from './lib/
|
|
14
|
+
export { tabSync } from './lib/tab-sync';
|
|
15
15
|
export * from './lib/throttled';
|
|
16
16
|
export * from './lib/to-writable';
|
|
17
17
|
export * from './lib/until';
|
package/lib/chunked.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export type CreateChunkedOptions<T> = {
|
|
|
22
22
|
/**
|
|
23
23
|
* Creates a new `Signal` that processes an array of items in time-sliced chunks. This is useful for handling large lists without blocking the main thread.
|
|
24
24
|
*
|
|
25
|
-
* The returned signal will initially contain the first `chunkSize` items from the source array. It will then schedule updates to include additional chunks of items based on the specified `
|
|
25
|
+
* The returned signal will initially contain the first `chunkSize` items from the source array. It will then schedule updates to include additional chunks of items based on the specified `delay`.
|
|
26
26
|
*
|
|
27
27
|
* @template T The type of items in the array.
|
|
28
28
|
* @param source A `Signal` or a function that returns an array of items to be processed in chunks.
|
|
@@ -31,6 +31,6 @@ export type CreateChunkedOptions<T> = {
|
|
|
31
31
|
*
|
|
32
32
|
* @example
|
|
33
33
|
* const largeList = signal(Array.from({ length: 1000 }, (_, i) => i));
|
|
34
|
-
* const chunkedList = chunked(largeList, { chunkSize: 100,
|
|
34
|
+
* const chunkedList = chunked(largeList, { chunkSize: 100, delay: 100 });
|
|
35
35
|
*/
|
|
36
36
|
export declare function chunked<T>(source: Signal<T[]> | (() => T[]), options?: CreateChunkedOptions<T>): Signal<T[]>;
|
|
@@ -46,8 +46,9 @@ export declare function pausableEffect(effectFn: (registerCleanup: EffectCleanup
|
|
|
46
46
|
/**
|
|
47
47
|
* Like `signal`, but pausable. While paused, READS hold the last value; writes still land on the
|
|
48
48
|
* underlying signal and surface on resume. Built on the `keepPrevious`/`hold` shape — a
|
|
49
|
-
* `linkedSignal` gated on the pause predicate, with `set`/`update
|
|
50
|
-
*
|
|
49
|
+
* `linkedSignal` gated on the pause predicate, with `set`/`update` forwarded to the source signal.
|
|
50
|
+
* `asReadonly()` returns the held (gated) view, so both views of the signal agree while paused.
|
|
51
|
+
* With no `pause` option it defaults to the ambient `PAUSED_CONTEXT`; `pause: false`
|
|
51
52
|
* makes it a plain `signal` — no `linkedSignal` is created.
|
|
52
53
|
*
|
|
53
54
|
* NOTE: while paused, `set(x)` followed by a read returns the *held* (pre-pause) value, not `x` — the
|
|
@@ -16,5 +16,10 @@ export type TransitionRef = {
|
|
|
16
16
|
*
|
|
17
17
|
* Must be called in an injection context. This is the *async* generalization (Tier 2): it adds
|
|
18
18
|
* no rendering cost and needs no fork — holding direct/sync readers is a separate, deferred tier.
|
|
19
|
+
*
|
|
20
|
+
* Caveat: work must go in flight by the first post-write render to be awaited. A loader that
|
|
21
|
+
* starts later (a debounced request signal, a chained/deferred resource) is not attributable to
|
|
22
|
+
* this transition — the no-async fallback will have already resolved `done`. Trigger such work
|
|
23
|
+
* eagerly inside `fn`, or coordinate it separately.
|
|
19
24
|
*/
|
|
20
25
|
export declare function injectStartTransition(): (fn: () => void) => TransitionRef;
|
|
@@ -32,5 +32,10 @@ export type TransactionRef = {
|
|
|
32
32
|
* The writes land on LIVE state immediately (so derived variables and connector requests see the
|
|
33
33
|
* new values and refetch); only the *display* is held, via `scope.hold`. Must run in an injection
|
|
34
34
|
* context.
|
|
35
|
+
*
|
|
36
|
+
* Caveat: work must go in flight by the first post-write render to be part of the transaction. A
|
|
37
|
+
* loader that starts later (a debounced request signal, a chained/deferred resource) is not
|
|
38
|
+
* attributable to it — the no-async fallback will have already committed and released the hold,
|
|
39
|
+
* after which `abort()` is a no-op. Trigger such work eagerly inside `fn`.
|
|
35
40
|
*/
|
|
36
41
|
export declare function injectStartTransaction(): (fn: () => void) => TransactionRef;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Provider, type ResourceRef, type Signal } from '@angular/core';
|
|
1
|
+
import { type Injector, type Provider, type ResourceRef, type Signal } from '@angular/core';
|
|
2
2
|
/**
|
|
3
3
|
* What "not ready" means for first-load suspense:
|
|
4
4
|
* - `'value'`: the resource has no value yet (`!hasValue()`). With `keepPrevious`,
|
|
@@ -64,6 +64,20 @@ export declare function createTransitionScope(): TransitionScope;
|
|
|
64
64
|
/** Provide a fresh transition scope at a boundary so its subtree's resources are tracked independently. */
|
|
65
65
|
export declare function provideTransitionScope(): Provider;
|
|
66
66
|
export declare function injectTransitionScope(): TransitionScope;
|
|
67
|
+
/**
|
|
68
|
+
* A transition scope that can be re-pointed at a delegate target at runtime. Reads and
|
|
69
|
+
* commit/hold follow the current target; `add`/`remove` pin to the target that was current
|
|
70
|
+
* at add-time, so re-pointing between a resource's registration and its destroy-time removal
|
|
71
|
+
* never strands it in the wrong scope. With no target it behaves as a plain own-scope.
|
|
72
|
+
*/
|
|
73
|
+
export type ForwardingTransitionScope = TransitionScope & {
|
|
74
|
+
setTarget(target: TransitionScope | null): void;
|
|
75
|
+
};
|
|
76
|
+
export declare function createForwardingScope(): ForwardingTransitionScope;
|
|
77
|
+
/** Provide a forwarding transition scope at a boundary (used by the transition outlet). */
|
|
78
|
+
export declare function provideForwardingTransitionScope(): Provider;
|
|
79
|
+
/** Read the transition scope reachable from `injector`, or null if none is provided there. */
|
|
80
|
+
export declare function getTransitionScope(injector: Injector): TransitionScope | null;
|
|
67
81
|
/**
|
|
68
82
|
* Returns a register function bound to the nearest transition scope: it adds a resource
|
|
69
83
|
* to the scope and removes it when the caller's injection context is destroyed. Pass any
|
package/lib/effect/index.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ import { type Frame } from './frame-stack';
|
|
|
43
43
|
* ]);
|
|
44
44
|
*
|
|
45
45
|
* // The fine-grained mapped list
|
|
46
|
-
* const mappedUsers =
|
|
46
|
+
* const mappedUsers = indexArray(
|
|
47
47
|
* users,
|
|
48
48
|
* (userSignal, index) => {
|
|
49
49
|
* // 1. Create a fine-grained SIDE EFFECT for *this item*
|
|
@@ -64,7 +64,7 @@ import { type Frame } from './frame-stack';
|
|
|
64
64
|
* };
|
|
65
65
|
* },
|
|
66
66
|
* {
|
|
67
|
-
* // 3. Tell
|
|
67
|
+
* // 3. Tell indexArray HOW to clean up when an item is removed, this needs to be manual as it's not a nestedEffect itself
|
|
68
68
|
* onDestroy: (mappedItem) => {
|
|
69
69
|
* mappedItem.destroyEffect();
|
|
70
70
|
* }
|
package/lib/mutable.d.ts
CHANGED
|
@@ -92,4 +92,4 @@ export declare function mutable<T>(initial: T, opt?: CreateSignalOptions<T>): Mu
|
|
|
92
92
|
* myMutableSignal.mutate(x => x + 1); // This is safe.
|
|
93
93
|
* }
|
|
94
94
|
*/
|
|
95
|
-
export declare function isMutable<T =
|
|
95
|
+
export declare function isMutable<T = unknown>(value: WritableSignal<T>): value is MutableSignal<T>;
|
|
@@ -10,7 +10,7 @@ import type { PipeableSignal, SignalValue } from './types';
|
|
|
10
10
|
*/
|
|
11
11
|
export declare function pipeable<TSig extends Signal<any>>(signal: TSig): PipeableSignal<SignalValue<TSig>, TSig>;
|
|
12
12
|
/**
|
|
13
|
-
* Create a new **writable** signal and return it as a `
|
|
13
|
+
* Create a new **writable** signal and return it as a `PipeableSignal`.
|
|
14
14
|
*
|
|
15
15
|
* The returned value is a `WritableSignal<T>` with `.set`, `.update`, `.asReadonly`
|
|
16
16
|
* still available (via intersection type), plus a chainable `.pipe(...)`.
|
package/lib/pipeable/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Signal } from '@angular/core';
|
|
2
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
2
3
|
export type BatteryStatus = {
|
|
3
4
|
readonly level: number;
|
|
4
5
|
readonly charging: boolean;
|
|
@@ -20,4 +21,4 @@ export type BatteryStatus = {
|
|
|
20
21
|
* });
|
|
21
22
|
* ```
|
|
22
23
|
*/
|
|
23
|
-
export declare function batteryStatus(
|
|
24
|
+
export declare function batteryStatus(opt?: string | SensorRunOptions): Signal<BatteryStatus | null>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Signal } from '@angular/core';
|
|
2
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
2
3
|
export type ClipboardSignal = Signal<string> & {
|
|
3
4
|
/**
|
|
4
5
|
* Writes `value` to the system clipboard. Resolves once the write completes;
|
|
@@ -19,4 +20,4 @@ export type ClipboardSignal = Signal<string> & {
|
|
|
19
20
|
* in browsers that gate it. Errors from `navigator.clipboard.readText` are
|
|
20
21
|
* swallowed silently to keep the signal value stable.
|
|
21
22
|
*/
|
|
22
|
-
export declare function clipboard(
|
|
23
|
+
export declare function clipboard(opt?: string | SensorRunOptions): ClipboardSignal;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ElementRef, type Signal } from '@angular/core';
|
|
2
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
2
3
|
/**
|
|
3
4
|
* Represents the size of an element.
|
|
4
5
|
*/
|
|
@@ -9,10 +10,7 @@ export interface ElementSize {
|
|
|
9
10
|
/**
|
|
10
11
|
* Options for configuring the `elementSize` sensor.
|
|
11
12
|
*/
|
|
12
|
-
export type ElementSizeOptions = ResizeObserverOptions &
|
|
13
|
-
/** Optional debug name for the internal signal. */
|
|
14
|
-
debugName?: string;
|
|
15
|
-
};
|
|
13
|
+
export type ElementSizeOptions = ResizeObserverOptions & SensorRunOptions;
|
|
16
14
|
export type ElementSizeSignal = Signal<ElementSize | undefined>;
|
|
17
15
|
/**
|
|
18
16
|
* Creates a read-only signal that tracks the size of a target DOM element.
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { ElementRef, type Signal } from '@angular/core';
|
|
2
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
2
3
|
/**
|
|
3
4
|
* Options for configuring the `elementVisibility` sensor, extending
|
|
4
5
|
* standard `IntersectionObserverInit` options.
|
|
5
6
|
*/
|
|
6
|
-
export type ElementVisibilityOptions = IntersectionObserverInit &
|
|
7
|
-
/** Optional debug name for the internal signal. */
|
|
8
|
-
debugName?: string;
|
|
9
|
-
};
|
|
7
|
+
export type ElementVisibilityOptions = IntersectionObserverInit & SensorRunOptions;
|
|
10
8
|
export type ElementVisibilitySignal = Signal<IntersectionObserverEntry | undefined> & {
|
|
11
9
|
readonly visible: Signal<boolean>;
|
|
12
10
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ElementRef, type Signal } from '@angular/core';
|
|
2
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
2
3
|
type FocusWithinTarget = ElementRef<Element> | Element | Signal<ElementRef<Element> | Element | null>;
|
|
3
4
|
/**
|
|
4
5
|
* Creates a read-only signal that tracks whether the focused element is the
|
|
@@ -17,5 +18,5 @@ type FocusWithinTarget = ElementRef<Element> | Element | Signal<ElementRef<Eleme
|
|
|
17
18
|
* }
|
|
18
19
|
* ```
|
|
19
20
|
*/
|
|
20
|
-
export declare function focusWithin(target?: FocusWithinTarget): Signal<boolean>;
|
|
21
|
+
export declare function focusWithin(target?: FocusWithinTarget, opt?: SensorRunOptions): Signal<boolean>;
|
|
21
22
|
export {};
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { type Signal } from '@angular/core';
|
|
2
|
-
|
|
2
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
3
|
+
export type GeolocationOptions = PositionOptions & SensorRunOptions & {
|
|
3
4
|
/**
|
|
4
5
|
* If `true`, uses `navigator.geolocation.watchPosition` and updates the
|
|
5
6
|
* signal continuously. Otherwise a single `getCurrentPosition` call is made.
|
|
6
7
|
* @default false
|
|
7
8
|
*/
|
|
8
9
|
watch?: boolean;
|
|
9
|
-
/** Optional debug name for the produced signal. */
|
|
10
|
-
debugName?: string;
|
|
11
10
|
};
|
|
12
11
|
export type GeolocationSignal = Signal<GeolocationPosition | null> & {
|
|
13
12
|
readonly error: Signal<GeolocationPositionError | null>;
|
package/lib/sensors/idle.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Signal } from '@angular/core';
|
|
2
|
-
|
|
2
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
3
|
+
export type IdleOptions = SensorRunOptions & {
|
|
3
4
|
/**
|
|
4
5
|
* Milliseconds of user inactivity before the signal flips to `true`.
|
|
5
6
|
* @default 60_000
|
|
@@ -10,11 +11,12 @@ export type IdleOptions = {
|
|
|
10
11
|
* @default ['mousemove','keydown','touchstart','scroll','visibilitychange']
|
|
11
12
|
*/
|
|
12
13
|
events?: string[];
|
|
13
|
-
/** Optional debug name for the produced signal. */
|
|
14
|
-
debugName?: string;
|
|
15
14
|
};
|
|
16
15
|
export type IdleSignal = Signal<boolean> & {
|
|
17
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Timestamp of the last idle/active transition. Before any transition has occurred it
|
|
18
|
+
* holds the sensor's creation time, not an actual transition.
|
|
19
|
+
*/
|
|
18
20
|
readonly since: Signal<Date>;
|
|
19
21
|
};
|
|
20
22
|
/**
|
package/lib/sensors/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Signal } from '@angular/core';
|
|
2
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
2
3
|
/**
|
|
3
4
|
* Creates a read-only signal that reactively tracks whether a CSS media query
|
|
4
5
|
* string currently matches.
|
|
@@ -43,7 +44,7 @@ import { type Signal } from '@angular/core';
|
|
|
43
44
|
* }
|
|
44
45
|
* ```
|
|
45
46
|
*/
|
|
46
|
-
export declare function mediaQuery(query: string,
|
|
47
|
+
export declare function mediaQuery(query: string, opt?: string | SensorRunOptions): Signal<boolean>;
|
|
47
48
|
/**
|
|
48
49
|
* Creates a read-only signal that tracks the user's OS/browser preference
|
|
49
50
|
* for a dark color scheme using the `(prefers-color-scheme: dark)` media query.
|
|
@@ -65,7 +66,7 @@ export declare function mediaQuery(query: string, debugName?: string): Signal<bo
|
|
|
65
66
|
* });
|
|
66
67
|
* ```
|
|
67
68
|
*/
|
|
68
|
-
export declare function prefersDarkMode(
|
|
69
|
+
export declare function prefersDarkMode(opt?: string | SensorRunOptions): Signal<boolean>;
|
|
69
70
|
/**
|
|
70
71
|
* Creates a read-only signal that tracks the user's OS/browser preference
|
|
71
72
|
* for reduced motion using the `(prefers-reduced-motion: reduce)` media query.
|
|
@@ -91,4 +92,4 @@ export declare function prefersDarkMode(debugName?: string): Signal<boolean>;
|
|
|
91
92
|
* });
|
|
92
93
|
* ```
|
|
93
94
|
*/
|
|
94
|
-
export declare function prefersReducedMotion(
|
|
95
|
+
export declare function prefersReducedMotion(opt?: string | SensorRunOptions): Signal<boolean>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ElementRef, type Signal } from '@angular/core';
|
|
2
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
2
3
|
type MousePosition = {
|
|
3
4
|
x: number;
|
|
4
5
|
y: number;
|
|
@@ -6,13 +7,15 @@ type MousePosition = {
|
|
|
6
7
|
/**
|
|
7
8
|
* Options for configuring the `mousePosition` sensor.
|
|
8
9
|
*/
|
|
9
|
-
export type MousePositionOptions = {
|
|
10
|
+
export type MousePositionOptions = SensorRunOptions & {
|
|
10
11
|
/**
|
|
11
12
|
* The target element to listen for mouse movements on.
|
|
12
|
-
* Can be `window`, `document`, an `HTMLElement`,
|
|
13
|
+
* Can be `window`, `document`, an `HTMLElement`, an `ElementRef<HTMLElement>`, or a
|
|
14
|
+
* `Signal` resolving to one (e.g. a `viewChild` result) — listeners re-attach when the
|
|
15
|
+
* signal's element changes, and nothing is tracked while it is `null`/`undefined`.
|
|
13
16
|
* @default window
|
|
14
17
|
*/
|
|
15
|
-
target?: Window | Document | HTMLElement | ElementRef<HTMLElement>;
|
|
18
|
+
target?: Window | Document | HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement> | null | undefined>;
|
|
16
19
|
/**
|
|
17
20
|
* Defines the coordinate system for the reported position.
|
|
18
21
|
* - `'client'`: Coordinates relative to the viewport (`clientX`, `clientY`).
|
|
@@ -26,10 +29,6 @@ export type MousePositionOptions = {
|
|
|
26
29
|
* @default false
|
|
27
30
|
*/
|
|
28
31
|
touch?: boolean;
|
|
29
|
-
/**
|
|
30
|
-
* Optional debug name for the internal signal.
|
|
31
|
-
*/
|
|
32
|
-
debugName?: string;
|
|
33
32
|
/**
|
|
34
33
|
* Optional delay in milliseconds to throttle the updates.
|
|
35
34
|
* @default 100
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { type Signal } from '@angular/core';
|
|
2
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
2
3
|
/**
|
|
3
4
|
* A specialized Signal that tracks network status.
|
|
4
5
|
* It's a boolean signal with an attached `since` signal.
|
|
5
6
|
*/
|
|
6
7
|
export type NetworkStatusSignal = Signal<boolean> & {
|
|
7
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* A signal tracking the timestamp of the last status change. Before any change has
|
|
10
|
+
* occurred it holds the sensor's creation time, not an actual transition.
|
|
11
|
+
*/
|
|
8
12
|
readonly since: Signal<Date>;
|
|
9
13
|
};
|
|
10
14
|
/**
|
|
@@ -14,7 +18,8 @@ export type NetworkStatusSignal = Signal<boolean> & {
|
|
|
14
18
|
* An additional `since` signal is attached, tracking when the status last changed.
|
|
15
19
|
* It's SSR-safe and automatically cleans up its event listeners.
|
|
16
20
|
*
|
|
17
|
-
* @param
|
|
21
|
+
* @param opt Optional debug name for the signal, or a {@link SensorRunOptions} object
|
|
22
|
+
* (with an optional `injector` for creation outside an injection context).
|
|
18
23
|
* @returns A `NetworkStatusSignal` instance.
|
|
19
24
|
*
|
|
20
25
|
* @example
|
|
@@ -25,4 +30,4 @@ export type NetworkStatusSignal = Signal<boolean> & {
|
|
|
25
30
|
* });
|
|
26
31
|
* ```
|
|
27
32
|
*/
|
|
28
|
-
export declare function networkStatus(
|
|
33
|
+
export declare function networkStatus(opt?: string | SensorRunOptions): NetworkStatusSignal;
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { type Signal } from '@angular/core';
|
|
2
|
-
|
|
2
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
3
|
+
export type ScreenOrientationState = {
|
|
3
4
|
/** Angle in degrees relative to the natural orientation. */
|
|
4
5
|
readonly angle: number;
|
|
5
6
|
/** One of the four `OrientationType` strings. */
|
|
6
7
|
readonly type: OrientationType;
|
|
7
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Use {@link ScreenOrientationState} instead — this name shadows the DOM's global
|
|
11
|
+
* `ScreenOrientation` interface in any module that imports it, silently changing the meaning of
|
|
12
|
+
* `screen.orientation`-related typings there.
|
|
13
|
+
*/
|
|
14
|
+
export type ScreenOrientation = ScreenOrientationState;
|
|
8
15
|
/**
|
|
9
16
|
* Creates a read-only signal that tracks `screen.orientation`.
|
|
10
17
|
*
|
|
@@ -20,4 +27,4 @@ export type ScreenOrientation = {
|
|
|
20
27
|
* });
|
|
21
28
|
* ```
|
|
22
29
|
*/
|
|
23
|
-
export declare function orientation(
|
|
30
|
+
export declare function orientation(opt?: string | SensorRunOptions): Signal<ScreenOrientationState>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Signal } from '@angular/core';
|
|
2
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
2
3
|
/**
|
|
3
4
|
* Creates a read-only signal that tracks the page's visibility state.
|
|
4
5
|
*
|
|
@@ -7,7 +8,8 @@ import { type Signal } from '@angular/core';
|
|
|
7
8
|
* The primitive is SSR-safe and automatically cleans up its event listeners
|
|
8
9
|
* when the creating context is destroyed.
|
|
9
10
|
*
|
|
10
|
-
* @param
|
|
11
|
+
* @param opt Optional debug name for the signal, or a {@link SensorRunOptions} object
|
|
12
|
+
* (with an optional `injector` for creation outside an injection context).
|
|
11
13
|
* @returns A read-only `Signal<DocumentVisibilityState>`. On the server,
|
|
12
14
|
* it returns a static signal with a value of `'visible'`.
|
|
13
15
|
*
|
|
@@ -35,4 +37,4 @@ import { type Signal } from '@angular/core';
|
|
|
35
37
|
* }
|
|
36
38
|
* ```
|
|
37
39
|
*/
|
|
38
|
-
export declare function pageVisibility(
|
|
40
|
+
export declare function pageVisibility(opt?: string | SensorRunOptions): Signal<DocumentVisibilityState>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ElementRef, // Used for SSR fallback
|
|
2
2
|
type Signal } from '@angular/core';
|
|
3
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
3
4
|
/**
|
|
4
5
|
* Represents the scroll position.
|
|
5
6
|
*/
|
|
@@ -12,21 +13,21 @@ export type ScrollPosition = {
|
|
|
12
13
|
/**
|
|
13
14
|
* Options for configuring the `scrollPosition` sensor.
|
|
14
15
|
*/
|
|
15
|
-
export type ScrollPositionOptions = {
|
|
16
|
+
export type ScrollPositionOptions = SensorRunOptions & {
|
|
16
17
|
/**
|
|
17
18
|
* The target to listen for scroll events on.
|
|
18
|
-
* Can be `window` (for page scroll)
|
|
19
|
+
* Can be `window` (for page scroll), an `HTMLElement`/`ElementRef<HTMLElement>`, or a
|
|
20
|
+
* `Signal` resolving to one (e.g. a `viewChild` result) — listeners re-attach when the
|
|
21
|
+
* signal's element changes, and nothing is tracked while it is `null`/`undefined`.
|
|
19
22
|
* @default window
|
|
20
23
|
*/
|
|
21
|
-
target?: Window | HTMLElement | ElementRef<HTMLElement>;
|
|
24
|
+
target?: Window | HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement> | null | undefined>;
|
|
22
25
|
/**
|
|
23
26
|
* Optional delay in milliseconds to throttle the updates.
|
|
24
27
|
* Scroll events can fire very rapidly.
|
|
25
28
|
* @default 100 // A common default for scroll throttling
|
|
26
29
|
*/
|
|
27
30
|
throttle?: number;
|
|
28
|
-
/** Optional debug name for the internal signal. */
|
|
29
|
-
debugName?: string;
|
|
30
31
|
};
|
|
31
32
|
/**
|
|
32
33
|
* A specialized Signal that tracks scroll position.
|
|
@@ -57,26 +58,17 @@ export type ScrollPositionSignal = Signal<ScrollPosition> & {
|
|
|
57
58
|
* selector: 'app-scroll-tracker',
|
|
58
59
|
* template: `
|
|
59
60
|
* <p>Window Scroll: X: {{ windowScroll().x }}, Y: {{ windowScroll().y }}</p>
|
|
60
|
-
* <
|
|
61
|
-
* <div style="height: 400px; width: 400px;">Scroll me!</div>
|
|
62
|
-
* </div>
|
|
63
|
-
* @if (divScroll()) {
|
|
64
|
-
* <p>Div Scroll: X: {{ divScroll().x }}, Y: {{ divScroll().y }}</p>
|
|
65
|
-
* }
|
|
61
|
+
* <p>Host Scroll: X: {{ hostScroll().x }}, Y: {{ hostScroll().y }}</p>
|
|
66
62
|
* `
|
|
67
63
|
* })
|
|
68
64
|
* export class ScrollTrackerComponent {
|
|
69
65
|
* readonly windowScroll = scrollPosition(); // Defaults to window
|
|
66
|
+
* // Signal targets (e.g. viewChild) attach once the element exists:
|
|
70
67
|
* readonly scrollableDiv = viewChild<ElementRef<HTMLDivElement>>('scrollableDiv');
|
|
71
|
-
* readonly divScroll = scrollPosition({ target: this.scrollableDiv
|
|
68
|
+
* readonly divScroll = scrollPosition({ target: this.scrollableDiv });
|
|
72
69
|
*
|
|
73
70
|
* constructor() {
|
|
74
|
-
* effect(() =>
|
|
75
|
-
* console.log('Window scrolled to:', this.windowScroll());
|
|
76
|
-
* if (this.divScroll()) {
|
|
77
|
-
* console.log('Div scrolled to:', this.divScroll());
|
|
78
|
-
* }
|
|
79
|
-
* });
|
|
71
|
+
* effect(() => console.log('Window scrolled to:', this.windowScroll()));
|
|
80
72
|
* }
|
|
81
73
|
* }
|
|
82
74
|
* ```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type Injector } from '@angular/core';
|
|
2
|
+
/**
|
|
3
|
+
* Options shared by every sensor: an optional `debugName` for the produced signal(s) and an
|
|
4
|
+
* optional `Injector` that lifts the injection-context requirement.
|
|
5
|
+
*/
|
|
6
|
+
export type SensorRunOptions = {
|
|
7
|
+
/** Optional debug name for the produced signal(s). */
|
|
8
|
+
debugName?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Injector used to resolve the sensor's dependencies (`PLATFORM_ID`, `DestroyRef`, default
|
|
11
|
+
* `ElementRef` targets, ...). Provide it when creating the sensor outside an injection
|
|
12
|
+
* context — e.g. in `ngOnInit`, an event handler, or an effect body. When omitted, the
|
|
13
|
+
* sensor must be created in an injection context (a constructor / field initializer).
|
|
14
|
+
*/
|
|
15
|
+
injector?: Injector;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* @internal Run a sensor factory inside `injector` when provided, else in the ambient
|
|
19
|
+
* injection context. Keeps every sensor's escape hatch identical and in one place.
|
|
20
|
+
*/
|
|
21
|
+
export declare function runInSensorContext<T>(injector: Injector | undefined, fn: () => T): T;
|
|
22
|
+
/**
|
|
23
|
+
* @internal Normalize the legacy positional `debugName: string` form into {@link SensorRunOptions}.
|
|
24
|
+
*/
|
|
25
|
+
export declare function coerceSensorOptions(opt?: string | SensorRunOptions): SensorRunOptions;
|
package/lib/sensors/sensor.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ElementRef, type Signal } from '@angular/core';
|
|
2
|
+
import { type SensorRunOptions } from './sensor-options';
|
|
2
3
|
import { type BatteryStatus } from './battery-status';
|
|
3
4
|
import { type ClipboardSignal } from './clipboard';
|
|
4
5
|
import { type ElementSizeOptions as BaseElementSizeOptions, type ElementSizeSignal } from './element-size';
|
|
@@ -7,7 +8,7 @@ import { type GeolocationOptions, type GeolocationSignal } from './geolocation';
|
|
|
7
8
|
import { type IdleOptions, type IdleSignal } from './idle';
|
|
8
9
|
import { type MousePositionOptions, type MousePositionSignal } from './mouse-position';
|
|
9
10
|
import { type NetworkStatusSignal } from './network-status';
|
|
10
|
-
import { type
|
|
11
|
+
import { type ScreenOrientationState } from './orientation';
|
|
11
12
|
import { type ScrollPositionOptions, type ScrollPositionSignal } from './scroll-position';
|
|
12
13
|
import { type WindowSizeOptions, type WindowSizeSignal } from './window-size';
|
|
13
14
|
type SensorTypedOptions = {
|
|
@@ -28,27 +29,19 @@ type SensorTypedOptions = {
|
|
|
28
29
|
returnType: MousePositionSignal;
|
|
29
30
|
};
|
|
30
31
|
networkStatus: {
|
|
31
|
-
opt:
|
|
32
|
-
debugName?: string;
|
|
33
|
-
};
|
|
32
|
+
opt: SensorRunOptions;
|
|
34
33
|
returnType: NetworkStatusSignal;
|
|
35
34
|
};
|
|
36
35
|
pageVisibility: {
|
|
37
|
-
opt:
|
|
38
|
-
debugName?: string;
|
|
39
|
-
};
|
|
36
|
+
opt: SensorRunOptions;
|
|
40
37
|
returnType: Signal<DocumentVisibilityState>;
|
|
41
38
|
};
|
|
42
39
|
darkMode: {
|
|
43
|
-
opt:
|
|
44
|
-
debugName?: string;
|
|
45
|
-
};
|
|
40
|
+
opt: SensorRunOptions;
|
|
46
41
|
returnType: Signal<boolean>;
|
|
47
42
|
};
|
|
48
43
|
reducedMotion: {
|
|
49
|
-
opt:
|
|
50
|
-
debugName?: string;
|
|
51
|
-
};
|
|
44
|
+
opt: SensorRunOptions;
|
|
52
45
|
returnType: Signal<boolean>;
|
|
53
46
|
};
|
|
54
47
|
scrollPosition: {
|
|
@@ -60,9 +53,8 @@ type SensorTypedOptions = {
|
|
|
60
53
|
returnType: WindowSizeSignal;
|
|
61
54
|
};
|
|
62
55
|
mediaQuery: {
|
|
63
|
-
opt: {
|
|
56
|
+
opt: SensorRunOptions & {
|
|
64
57
|
query: string;
|
|
65
|
-
debugName?: string;
|
|
66
58
|
};
|
|
67
59
|
returnType: Signal<boolean>;
|
|
68
60
|
};
|
|
@@ -71,21 +63,15 @@ type SensorTypedOptions = {
|
|
|
71
63
|
returnType: GeolocationSignal;
|
|
72
64
|
};
|
|
73
65
|
clipboard: {
|
|
74
|
-
opt:
|
|
75
|
-
debugName?: string;
|
|
76
|
-
};
|
|
66
|
+
opt: SensorRunOptions;
|
|
77
67
|
returnType: ClipboardSignal;
|
|
78
68
|
};
|
|
79
69
|
orientation: {
|
|
80
|
-
opt:
|
|
81
|
-
|
|
82
|
-
};
|
|
83
|
-
returnType: Signal<ScreenOrientation>;
|
|
70
|
+
opt: SensorRunOptions;
|
|
71
|
+
returnType: Signal<ScreenOrientationState>;
|
|
84
72
|
};
|
|
85
73
|
batteryStatus: {
|
|
86
|
-
opt:
|
|
87
|
-
debugName?: string;
|
|
88
|
-
};
|
|
74
|
+
opt: SensorRunOptions;
|
|
89
75
|
returnType: Signal<BatteryStatus | null>;
|
|
90
76
|
};
|
|
91
77
|
idle: {
|
|
@@ -93,8 +79,7 @@ type SensorTypedOptions = {
|
|
|
93
79
|
returnType: IdleSignal;
|
|
94
80
|
};
|
|
95
81
|
focusWithin: {
|
|
96
|
-
opt: {
|
|
97
|
-
debugName?: string;
|
|
82
|
+
opt: SensorRunOptions & {
|
|
98
83
|
target?: ElementRef<Element> | Element | Signal<ElementRef<Element> | Element | null>;
|
|
99
84
|
};
|
|
100
85
|
returnType: Signal<boolean>;
|
|
@@ -166,12 +151,12 @@ export declare function sensor(type: 'reducedMotion' | 'reduced-motion', options
|
|
|
166
151
|
/**
|
|
167
152
|
* Creates a sensor signal that tracks the provided media query.
|
|
168
153
|
* @param type Must be `'mediaQuery'`.
|
|
169
|
-
* @param options
|
|
154
|
+
* @param options Required configuration for the media query sensor — `query` is mandatory, `debugName` optional.
|
|
170
155
|
* @returns A `Signal<boolean>` which is `true` if the media query currently matches.
|
|
171
156
|
* @see {mediaQuery} for detailed documentation and examples.
|
|
172
157
|
* @example const isDesktop = sensor('mediaQuery', { query: '(min-width: 1024px)' });
|
|
173
158
|
*/
|
|
174
|
-
export declare function sensor(type: 'mediaQuery', options
|
|
159
|
+
export declare function sensor(type: 'mediaQuery', options: SensorTypedOptions['mediaQuery']['opt']): Signal<boolean>;
|
|
175
160
|
/**
|
|
176
161
|
* Creates a sensor signal that tracks the browser window's inner dimensions (width and height).
|
|
177
162
|
* @param type Must be `'windowSize'`.
|
|
@@ -204,7 +189,7 @@ export declare function sensor(type: 'clipboard', options?: SensorTypedOptions['
|
|
|
204
189
|
* Creates a sensor signal tracking the screen orientation.
|
|
205
190
|
* @see {orientation}
|
|
206
191
|
*/
|
|
207
|
-
export declare function sensor(type: 'orientation', options?: SensorTypedOptions['orientation']['opt']): Signal<
|
|
192
|
+
export declare function sensor(type: 'orientation', options?: SensorTypedOptions['orientation']['opt']): Signal<ScreenOrientationState>;
|
|
208
193
|
/**
|
|
209
194
|
* Creates a sensor signal tracking the system battery status.
|
|
210
195
|
* @see {batteryStatus}
|