@mmstack/primitives 19.2.0 → 19.2.2
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 +121 -3
- package/fesm2022/mmstack-primitives.mjs +282 -10
- package/fesm2022/mmstack-primitives.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/element-visibility.d.ts +66 -0
- package/lib/sensors/index.d.ts +2 -0
- package/lib/sensors/mouse-position.d.ts +5 -0
- package/lib/sensors/scroll-position.d.ts +84 -0
- package/lib/sensors/sensor.d.ts +20 -0
- package/lib/sensors/window-size.d.ts +75 -0
- package/lib/until.d.ts +2 -1
- package/package.json +2 -2
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ElementRef, // Used for SSR fallback
|
|
2
|
+
type Signal } from '@angular/core';
|
|
3
|
+
/**
|
|
4
|
+
* Represents the scroll position.
|
|
5
|
+
*/
|
|
6
|
+
export type ScrollPosition = {
|
|
7
|
+
/** The horizontal scroll position (pixels from the left). */
|
|
8
|
+
readonly x: number;
|
|
9
|
+
/** The vertical scroll position (pixels from the top). */
|
|
10
|
+
readonly y: number;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Options for configuring the `scrollPosition` sensor.
|
|
14
|
+
*/
|
|
15
|
+
export type ScrollPositionOptions = {
|
|
16
|
+
/**
|
|
17
|
+
* The target to listen for scroll events on.
|
|
18
|
+
* Can be `window` (for page scroll) or an `HTMLElement`/`ElementRef<HTMLElement>`.
|
|
19
|
+
* @default window
|
|
20
|
+
*/
|
|
21
|
+
target?: Window | HTMLElement | ElementRef<HTMLElement>;
|
|
22
|
+
/**
|
|
23
|
+
* Optional delay in milliseconds to throttle the updates.
|
|
24
|
+
* Scroll events can fire very rapidly.
|
|
25
|
+
* @default 100 // A common default for scroll throttling
|
|
26
|
+
*/
|
|
27
|
+
throttle?: number;
|
|
28
|
+
/** Optional debug name for the internal signal. */
|
|
29
|
+
debugName?: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* A specialized Signal that tracks scroll position.
|
|
33
|
+
* It's a throttled signal of the scroll coordinates with an attached `unthrottled` signal.
|
|
34
|
+
*/
|
|
35
|
+
export type ScrollPositionSignal = Signal<ScrollPosition> & {
|
|
36
|
+
/** A signal providing the raw, unthrottled scroll position. */
|
|
37
|
+
readonly unthrottled: Signal<ScrollPosition>;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Creates a read-only signal that tracks the scroll position (x, y) of the window
|
|
41
|
+
* or a specified HTML element.
|
|
42
|
+
*
|
|
43
|
+
* Updates are throttled by default to optimize performance. An `unthrottled`
|
|
44
|
+
* property is available on the returned signal for direct access to raw updates.
|
|
45
|
+
* The primitive is SSR-safe and automatically cleans up its event listeners.
|
|
46
|
+
*
|
|
47
|
+
* @param options Optional configuration for the scroll sensor.
|
|
48
|
+
* @returns A `ScrollPositionSignal`. On the server, it returns a static
|
|
49
|
+
* signal with `{ x: 0, y: 0 }`.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* import { Component, effect, ElementRef, viewChild } from '@angular/core';
|
|
54
|
+
* import { scrollPosition } from '@mmstack/primitives';
|
|
55
|
+
*
|
|
56
|
+
* @Component({
|
|
57
|
+
* selector: 'app-scroll-tracker',
|
|
58
|
+
* template: `
|
|
59
|
+
* <p>Window Scroll: X: {{ windowScroll().x }}, Y: {{ windowScroll().y }}</p>
|
|
60
|
+
* <div #scrollableDiv style="height: 200px; width: 200px; overflow: auto; border: 1px solid black;">
|
|
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
|
+
* }
|
|
66
|
+
* `
|
|
67
|
+
* })
|
|
68
|
+
* export class ScrollTrackerComponent {
|
|
69
|
+
* readonly windowScroll = scrollPosition(); // Defaults to window
|
|
70
|
+
* readonly scrollableDiv = viewChild<ElementRef<HTMLDivElement>>('scrollableDiv');
|
|
71
|
+
* readonly divScroll = scrollPosition({ target: this.scrollableDiv() }); // Example with element target
|
|
72
|
+
*
|
|
73
|
+
* 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
|
+
* });
|
|
80
|
+
* }
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export declare function scrollPosition(opt?: ScrollPositionOptions): ScrollPositionSignal;
|
package/lib/sensors/sensor.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Signal } from '@angular/core';
|
|
2
2
|
import { MousePositionOptions, MousePositionSignal } from './mouse-position';
|
|
3
3
|
import { NetworkStatusSignal } from './network-status';
|
|
4
|
+
import { ScrollPositionOptions, ScrollPositionSignal } from './scroll-position';
|
|
5
|
+
import { WindowSizeOptions, WindowSizeSignal } from './window-size';
|
|
4
6
|
/**
|
|
5
7
|
* Creates a sensor signal that tracks the mouse cursor's position.
|
|
6
8
|
* @param type Must be `'mousePosition'`.
|
|
@@ -54,3 +56,21 @@ export declare function sensor(type: 'dark-mode', options?: {
|
|
|
54
56
|
export declare function sensor(type: 'reduced-motion', options?: {
|
|
55
57
|
debugName?: string;
|
|
56
58
|
}): Signal<boolean>;
|
|
59
|
+
/**
|
|
60
|
+
* Creates a sensor signal that tracks the browser window's inner dimensions (width and height).
|
|
61
|
+
* @param type Must be `'windowSize'`.
|
|
62
|
+
* @param options Optional configuration for the window size sensor, including `throttle` and `debugName`.
|
|
63
|
+
* @returns A `WindowSizeSignal` that tracks window dimensions and provides an unthrottled version.
|
|
64
|
+
* @see {windowSize} for detailed documentation and examples.
|
|
65
|
+
* @example const size = sensor('windowSize', { throttle: 200 });
|
|
66
|
+
*/
|
|
67
|
+
export declare function sensor(type: 'windowSize', options?: WindowSizeOptions): WindowSizeSignal;
|
|
68
|
+
/**
|
|
69
|
+
* Creates a sensor signal that tracks the scroll position (x, y) of the window or a specified element.
|
|
70
|
+
* @param type Must be `'scrollPosition'`.
|
|
71
|
+
* @param options Optional configuration for the scroll position sensor, including `target`, `throttle`, and `debugName`.
|
|
72
|
+
* @returns A `ScrollPositionSignal` that tracks scroll coordinates and provides an unthrottled version.
|
|
73
|
+
* @see {scrollPosition} for detailed documentation and examples.
|
|
74
|
+
* @example const pageScroll = sensor('scrollPosition', { throttle: 150 });
|
|
75
|
+
*/
|
|
76
|
+
export declare function sensor(type: 'scrollPosition', options?: ScrollPositionOptions): ScrollPositionSignal;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Signal } from '@angular/core';
|
|
2
|
+
/**
|
|
3
|
+
* Represents the dimensions of the window.
|
|
4
|
+
*/
|
|
5
|
+
export type WindowSize = {
|
|
6
|
+
/** The current inner width of the window in pixels. */
|
|
7
|
+
readonly width: number;
|
|
8
|
+
/** The current inner height of the window in pixels. */
|
|
9
|
+
readonly height: number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Options for configuring the `mousePosition` sensor.
|
|
13
|
+
*/
|
|
14
|
+
export type WindowSizeOptions = {
|
|
15
|
+
/**
|
|
16
|
+
* Optional debug name for the internal signal.
|
|
17
|
+
*/
|
|
18
|
+
debugName?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Optional delay in milliseconds to throttle the updates.
|
|
21
|
+
* @default 100
|
|
22
|
+
*/
|
|
23
|
+
throttle?: number;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* A specialized Signal that tracks window size.
|
|
27
|
+
* It's a throttled signal of the window.innerHeight/innerWidth properties
|
|
28
|
+
* with an attached `unthrottled` signal.
|
|
29
|
+
*/
|
|
30
|
+
export type WindowSizeSignal = Signal<WindowSize> & {
|
|
31
|
+
/** A signal providing the raw, unthrottled window size. */
|
|
32
|
+
readonly unthrottled: Signal<WindowSize>;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Creates a read-only signal that tracks the browser window's inner dimensions (width and height).
|
|
36
|
+
*
|
|
37
|
+
* Updates are throttled by default (100ms) to optimize performance during resize events.
|
|
38
|
+
* An `unthrottled` property is available on the returned signal for direct access to raw updates.
|
|
39
|
+
* The primitive is SSR-safe (returns a default size on the server) and automatically
|
|
40
|
+
* cleans up its event listeners.
|
|
41
|
+
*
|
|
42
|
+
* @param opt Optional configuration, including `throttle` (ms) and `debugName`.
|
|
43
|
+
* @returns A `WindowSizeSignal` (a `Signal<WindowSize>` with an `unthrottled` property).
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* import { Component, effect } from '@angular/core';
|
|
48
|
+
* import { windowSize } from '@mmstack/primitives';
|
|
49
|
+
*
|
|
50
|
+
* @Component({
|
|
51
|
+
* selector: 'app-responsive-header',
|
|
52
|
+
* template: `
|
|
53
|
+
* <header>
|
|
54
|
+
* Current Window Size: {{ size().width }}px x {{ size().height }}px
|
|
55
|
+
* @if (isMobile()) {
|
|
56
|
+
* <p>Mobile Menu</p>
|
|
57
|
+
* } @else {
|
|
58
|
+
* <p>Desktop Menu</p>
|
|
59
|
+
* }
|
|
60
|
+
* </header>
|
|
61
|
+
* `
|
|
62
|
+
* })
|
|
63
|
+
* export class ResponsiveHeaderComponent {
|
|
64
|
+
* readonly size = windowSize();
|
|
65
|
+
* readonly isMobile = computed(() => this.size().width < 768);
|
|
66
|
+
*
|
|
67
|
+
* constructor() {
|
|
68
|
+
* effect(() => {
|
|
69
|
+
* console.log('Window resized to:', this.size());
|
|
70
|
+
* });
|
|
71
|
+
* }
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export declare function windowSize(opt?: WindowSizeOptions): WindowSizeSignal;
|
package/lib/until.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DestroyRef, Signal } from '@angular/core';
|
|
1
|
+
import { DestroyRef, Injector, Signal } from '@angular/core';
|
|
2
2
|
export type UntilOptions = {
|
|
3
3
|
/**
|
|
4
4
|
* Optional timeout in milliseconds. If the condition is not met
|
|
@@ -11,6 +11,7 @@ export type UntilOptions = {
|
|
|
11
11
|
* If not provided, it will attempt to inject one if called in an injection context.
|
|
12
12
|
*/
|
|
13
13
|
destroyRef?: DestroyRef;
|
|
14
|
+
injector?: Injector;
|
|
14
15
|
};
|
|
15
16
|
/**
|
|
16
17
|
* Creates a Promise that resolves when a signal's value satisfies a given predicate.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmstack/primitives",
|
|
3
|
-
"version": "19.2.
|
|
3
|
+
"version": "19.2.2",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"angular",
|
|
6
6
|
"signals",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"homepage": "https://github.com/mihajm/mmstack/blob/master/packages/primitives",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@mmstack/object": "^19.
|
|
18
|
+
"@mmstack/object": "^19.2.0",
|
|
19
19
|
"tslib": "^2.3.0"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|