ngx-mq 2.11.2 → 3.0.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/LICENSE +1 -1
- package/README.md +187 -109
- package/fesm2022/ngx-mq.mjs +430 -10
- package/fesm2022/ngx-mq.mjs.map +1 -1
- package/index.d.ts +427 -3
- package/package.json +20 -5
package/fesm2022/ngx-mq.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { InjectionToken, inject, isDevMode, signal, DestroyRef, assertInInjectionContext } from '@angular/core';
|
|
2
|
-
import { createComputed, SIGNAL } from '@angular/core/primitives/signals';
|
|
1
|
+
import { InjectionToken, inject, isDevMode, signal, DestroyRef, computed, assertInInjectionContext } from '@angular/core';
|
|
3
2
|
|
|
4
3
|
const TAILWIND_BREAKPOINTS = {
|
|
5
4
|
sm: 640,
|
|
@@ -23,11 +22,29 @@ const MATERIAL_BREAKPOINTS = {
|
|
|
23
22
|
};
|
|
24
23
|
const DEFAULT_BREAKPOINT_EPSILON = 0.02;
|
|
25
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Holds the active {@link MqBreakpoints} map. Has no default: configure it with
|
|
27
|
+
* {@link provideBreakpoints} or a preset. Inject it to read breakpoints directly.
|
|
28
|
+
*
|
|
29
|
+
* @category Injection Tokens
|
|
30
|
+
*/
|
|
26
31
|
const MQ_BREAKPOINTS = new InjectionToken('MQ_BREAKPOINTS');
|
|
32
|
+
/**
|
|
33
|
+
* Holds the epsilon used for exclusive upper bounds. Set it with
|
|
34
|
+
* {@link provideBreakpointEpsilon}; defaults to `0.02`.
|
|
35
|
+
*
|
|
36
|
+
* @category Injection Tokens
|
|
37
|
+
*/
|
|
27
38
|
const MQ_BREAKPOINT_EPSILON = new InjectionToken('MQ_BREAKPOINT_EPSILON', {
|
|
28
39
|
providedIn: 'root',
|
|
29
40
|
factory: () => DEFAULT_BREAKPOINT_EPSILON,
|
|
30
41
|
});
|
|
42
|
+
/**
|
|
43
|
+
* Holds the value query signals report during SSR. Set it with
|
|
44
|
+
* {@link provideSsrValue}; defaults to `false`.
|
|
45
|
+
*
|
|
46
|
+
* @category Injection Tokens
|
|
47
|
+
*/
|
|
31
48
|
const NGX_MQ_SSR_VALUE = new InjectionToken('NGX_MQ_SSR_VALUE', {
|
|
32
49
|
providedIn: 'root',
|
|
33
50
|
factory: () => false,
|
|
@@ -52,7 +69,7 @@ function assertBreakpointExists(bp, breakpoints) {
|
|
|
52
69
|
}
|
|
53
70
|
function resolveBreakpoint(bp) {
|
|
54
71
|
const breakpoints = assertBreakpointsProvided();
|
|
55
|
-
return assertBreakpointExists(bp, breakpoints);
|
|
72
|
+
return assertBreakpointExists(bp.trim(), breakpoints);
|
|
56
73
|
}
|
|
57
74
|
function normalizeBreakpoints(bps) {
|
|
58
75
|
const out = {};
|
|
@@ -76,7 +93,7 @@ function validateEpsilon(epsilon) {
|
|
|
76
93
|
}
|
|
77
94
|
}
|
|
78
95
|
function applyMaxEpsilon(value) {
|
|
79
|
-
const epsilon = inject(MQ_BREAKPOINT_EPSILON
|
|
96
|
+
const epsilon = inject(MQ_BREAKPOINT_EPSILON);
|
|
80
97
|
return value - epsilon;
|
|
81
98
|
}
|
|
82
99
|
|
|
@@ -167,11 +184,9 @@ function createConsumer(query, options) {
|
|
|
167
184
|
const defaultSsrValue = inject(NGX_MQ_SSR_VALUE);
|
|
168
185
|
const effectiveSsrValue = options?.ssrValue ?? defaultSsrValue;
|
|
169
186
|
const querySignal = retainUntilDestroy(query, effectiveSsrValue);
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
return getter;
|
|
187
|
+
return computed(() => querySignal(), {
|
|
188
|
+
debugName: isDevMode() ? options?.debugName : undefined,
|
|
189
|
+
});
|
|
175
190
|
}
|
|
176
191
|
function createConsumerLabel(descriptor) {
|
|
177
192
|
return `[NgxMq Signal: ${descriptor}]`;
|
|
@@ -181,6 +196,29 @@ function normalizeQuery(value) {
|
|
|
181
196
|
return value.trim().replace(/\s+/g, ' ').toLowerCase();
|
|
182
197
|
}
|
|
183
198
|
|
|
199
|
+
/**
|
|
200
|
+
* Tracks whether the viewport width is **at or above** a breakpoint.
|
|
201
|
+
*
|
|
202
|
+
* Builds a `(min-width: <bp>px)` query from the value registered for `bp` via
|
|
203
|
+
* {@link provideBreakpoints} (or a preset like {@link provideTailwindBreakpoints}).
|
|
204
|
+
*
|
|
205
|
+
* @param bp - Name of a configured breakpoint, e.g. `'md'`.
|
|
206
|
+
* @param options - Optional per-call settings ({@link CreateMediaQueryOptions}).
|
|
207
|
+
* @returns A `Signal<boolean>` that is `true` while the viewport width is `>=` the breakpoint.
|
|
208
|
+
*
|
|
209
|
+
* @remarks Must be called within an Angular
|
|
210
|
+
* [injection context](https://angular.dev/guide/di/dependency-injection-context).
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```ts
|
|
214
|
+
* export class LayoutComponent {
|
|
215
|
+
* readonly isDesktop = up('lg');
|
|
216
|
+
* }
|
|
217
|
+
* ```
|
|
218
|
+
*
|
|
219
|
+
* @see {@link down} and {@link between} for the complementary ranges.
|
|
220
|
+
* @category Breakpoints
|
|
221
|
+
*/
|
|
184
222
|
function up(bp, options) {
|
|
185
223
|
isDevMode() && assertInInjectionContext(up);
|
|
186
224
|
const query = normalizeQuery(`(min-width: ${resolveBreakpoint(bp)}px)`);
|
|
@@ -188,6 +226,29 @@ function up(bp, options) {
|
|
|
188
226
|
consumer.toString = () => createConsumerLabel(`up(${bp})`);
|
|
189
227
|
return consumer;
|
|
190
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* Tracks whether the viewport width is **below** a breakpoint.
|
|
231
|
+
*
|
|
232
|
+
* Builds a `(max-width: <bp - epsilon>px)` query. The upper bound is **exclusive**:
|
|
233
|
+
* a small epsilon is subtracted so `down('md')` and {@link up}`('md')` never overlap.
|
|
234
|
+
*
|
|
235
|
+
* @param bp - Name of a configured breakpoint, e.g. `'md'`.
|
|
236
|
+
* @param options - Optional per-call settings ({@link CreateMediaQueryOptions}).
|
|
237
|
+
* @returns A `Signal<boolean>` that is `true` while the viewport width is `<` the breakpoint.
|
|
238
|
+
*
|
|
239
|
+
* @remarks Must be called within an Angular
|
|
240
|
+
* [injection context](https://angular.dev/guide/di/dependency-injection-context).
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```ts
|
|
244
|
+
* export class NavComponent {
|
|
245
|
+
* readonly isMobile = down('md');
|
|
246
|
+
* }
|
|
247
|
+
* ```
|
|
248
|
+
*
|
|
249
|
+
* @see {@link provideBreakpointEpsilon} to tune the exclusive-bound epsilon.
|
|
250
|
+
* @category Breakpoints
|
|
251
|
+
*/
|
|
191
252
|
function down(bp, options) {
|
|
192
253
|
isDevMode() && assertInInjectionContext(down);
|
|
193
254
|
const query = normalizeQuery(`(max-width: ${applyMaxEpsilon(resolveBreakpoint(bp))}px)`);
|
|
@@ -195,6 +256,29 @@ function down(bp, options) {
|
|
|
195
256
|
consumer.toString = () => createConsumerLabel(`down(${bp})`);
|
|
196
257
|
return consumer;
|
|
197
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* Tracks whether the viewport width falls within the range `[minBp, maxBp)`.
|
|
261
|
+
*
|
|
262
|
+
* Combines `min-width` and `max-width` into a single query. The lower bound is
|
|
263
|
+
* inclusive and the upper bound is **exclusive** (epsilon is subtracted from `maxBp`).
|
|
264
|
+
*
|
|
265
|
+
* @param minBp - Name of the lower (inclusive) breakpoint.
|
|
266
|
+
* @param maxBp - Name of the upper (exclusive) breakpoint.
|
|
267
|
+
* @param options - Optional per-call settings ({@link CreateMediaQueryOptions}).
|
|
268
|
+
* @returns A `Signal<boolean>` that is `true` while the width is in `[minBp, maxBp)`.
|
|
269
|
+
*
|
|
270
|
+
* @remarks Must be called within an Angular
|
|
271
|
+
* [injection context](https://angular.dev/guide/di/dependency-injection-context).
|
|
272
|
+
*
|
|
273
|
+
* @example
|
|
274
|
+
* ```ts
|
|
275
|
+
* export class GridComponent {
|
|
276
|
+
* readonly isTablet = between('md', 'lg');
|
|
277
|
+
* }
|
|
278
|
+
* ```
|
|
279
|
+
*
|
|
280
|
+
* @category Breakpoints
|
|
281
|
+
*/
|
|
198
282
|
function between(minBp, maxBp, options) {
|
|
199
283
|
isDevMode() && assertInInjectionContext(between);
|
|
200
284
|
const minPx = resolveBreakpoint(minBp);
|
|
@@ -204,6 +288,24 @@ function between(minBp, maxBp, options) {
|
|
|
204
288
|
consumer.toString = () => createConsumerLabel(`between(${minBp}, ${maxBp})`);
|
|
205
289
|
return consumer;
|
|
206
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Tracks the screen orientation via the `(orientation: ...)` media feature.
|
|
293
|
+
*
|
|
294
|
+
* @param value - `'portrait'` (height `>=` width) or `'landscape'` (width `>` height).
|
|
295
|
+
* @param options - Optional per-call settings ({@link CreateMediaQueryOptions}).
|
|
296
|
+
* @returns A `Signal<boolean>` that is `true` while the orientation matches `value`.
|
|
297
|
+
*
|
|
298
|
+
* @remarks Must be called within an Angular
|
|
299
|
+
* [injection context](https://angular.dev/guide/di/dependency-injection-context).
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```ts
|
|
303
|
+
* readonly isLandscape = orientation('landscape');
|
|
304
|
+
* ```
|
|
305
|
+
*
|
|
306
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@media/orientation | MDN: orientation}
|
|
307
|
+
* @category Media Features
|
|
308
|
+
*/
|
|
207
309
|
function orientation(value, options) {
|
|
208
310
|
isDevMode() && assertInInjectionContext(orientation);
|
|
209
311
|
const query = normalizeQuery(`(orientation: ${value})`);
|
|
@@ -211,6 +313,24 @@ function orientation(value, options) {
|
|
|
211
313
|
consumer.toString = () => createConsumerLabel(`orientation(${value})`);
|
|
212
314
|
return consumer;
|
|
213
315
|
}
|
|
316
|
+
/**
|
|
317
|
+
* Tracks the user's preferred color scheme via `(prefers-color-scheme: ...)`.
|
|
318
|
+
*
|
|
319
|
+
* @param value - `'light'` or `'dark'`.
|
|
320
|
+
* @param options - Optional per-call settings ({@link CreateMediaQueryOptions}).
|
|
321
|
+
* @returns A `Signal<boolean>` that is `true` while the system scheme matches `value`.
|
|
322
|
+
*
|
|
323
|
+
* @remarks Must be called within an Angular
|
|
324
|
+
* [injection context](https://angular.dev/guide/di/dependency-injection-context).
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* ```ts
|
|
328
|
+
* readonly isDark = colorScheme('dark');
|
|
329
|
+
* ```
|
|
330
|
+
*
|
|
331
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme | MDN: prefers-color-scheme}
|
|
332
|
+
* @category Media Features
|
|
333
|
+
*/
|
|
214
334
|
function colorScheme(value, options) {
|
|
215
335
|
isDevMode() && assertInInjectionContext(colorScheme);
|
|
216
336
|
const query = normalizeQuery(`(prefers-color-scheme: ${value})`);
|
|
@@ -218,6 +338,25 @@ function colorScheme(value, options) {
|
|
|
218
338
|
consumer.toString = () => createConsumerLabel(`colorScheme(${value})`);
|
|
219
339
|
return consumer;
|
|
220
340
|
}
|
|
341
|
+
/**
|
|
342
|
+
* Tracks how the app is being displayed via the `(display-mode: ...)` feature,
|
|
343
|
+
* useful for detecting installed PWAs.
|
|
344
|
+
*
|
|
345
|
+
* @param value - One of {@link DisplayModeOption}, e.g. `'standalone'`.
|
|
346
|
+
* @param options - Optional per-call settings ({@link CreateMediaQueryOptions}).
|
|
347
|
+
* @returns A `Signal<boolean>` that is `true` while the display mode matches `value`.
|
|
348
|
+
*
|
|
349
|
+
* @remarks Must be called within an Angular
|
|
350
|
+
* [injection context](https://angular.dev/guide/di/dependency-injection-context).
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* ```ts
|
|
354
|
+
* readonly isInstalledPwa = displayMode('standalone');
|
|
355
|
+
* ```
|
|
356
|
+
*
|
|
357
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@media/display-mode | MDN: display-mode}
|
|
358
|
+
* @category Media Features
|
|
359
|
+
*/
|
|
221
360
|
function displayMode(value, options) {
|
|
222
361
|
isDevMode() && assertInInjectionContext(displayMode);
|
|
223
362
|
const query = normalizeQuery(`(display-mode: ${value})`);
|
|
@@ -225,6 +364,24 @@ function displayMode(value, options) {
|
|
|
225
364
|
consumer.toString = () => createConsumerLabel(`displayMode(${value})`);
|
|
226
365
|
return consumer;
|
|
227
366
|
}
|
|
367
|
+
/**
|
|
368
|
+
* Tracks whether the user has requested reduced motion via
|
|
369
|
+
* `(prefers-reduced-motion: reduce)`.
|
|
370
|
+
*
|
|
371
|
+
* @param options - Optional per-call settings ({@link CreateMediaQueryOptions}).
|
|
372
|
+
* @returns A `Signal<boolean>` that is `true` while reduced motion is preferred.
|
|
373
|
+
*
|
|
374
|
+
* @remarks Must be called within an Angular
|
|
375
|
+
* [injection context](https://angular.dev/guide/di/dependency-injection-context).
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```ts
|
|
379
|
+
* readonly reduceMotion = reducedMotion();
|
|
380
|
+
* ```
|
|
381
|
+
*
|
|
382
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion | MDN: prefers-reduced-motion}
|
|
383
|
+
* @category Media Features
|
|
384
|
+
*/
|
|
228
385
|
function reducedMotion(options) {
|
|
229
386
|
isDevMode() && assertInInjectionContext(reducedMotion);
|
|
230
387
|
const query = normalizeQuery('(prefers-reduced-motion: reduce)');
|
|
@@ -232,6 +389,24 @@ function reducedMotion(options) {
|
|
|
232
389
|
consumer.toString = () => createConsumerLabel('reducedMotion');
|
|
233
390
|
return consumer;
|
|
234
391
|
}
|
|
392
|
+
/**
|
|
393
|
+
* Tracks whether the **primary** input device can hover via `(hover: hover)`.
|
|
394
|
+
*
|
|
395
|
+
* @param options - Optional per-call settings ({@link CreateMediaQueryOptions}).
|
|
396
|
+
* @returns A `Signal<boolean>` that is `true` while the primary pointer supports hover.
|
|
397
|
+
*
|
|
398
|
+
* @remarks Must be called within an Angular
|
|
399
|
+
* [injection context](https://angular.dev/guide/di/dependency-injection-context).
|
|
400
|
+
*
|
|
401
|
+
* @example
|
|
402
|
+
* ```ts
|
|
403
|
+
* readonly canHover = hover();
|
|
404
|
+
* ```
|
|
405
|
+
*
|
|
406
|
+
* @see {@link anyHover} to test **any** available input device.
|
|
407
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@media/hover | MDN: hover}
|
|
408
|
+
* @category Media Features
|
|
409
|
+
*/
|
|
235
410
|
function hover(options) {
|
|
236
411
|
isDevMode() && assertInInjectionContext(hover);
|
|
237
412
|
const query = normalizeQuery('(hover: hover)');
|
|
@@ -239,6 +414,24 @@ function hover(options) {
|
|
|
239
414
|
consumer.toString = () => createConsumerLabel('hover');
|
|
240
415
|
return consumer;
|
|
241
416
|
}
|
|
417
|
+
/**
|
|
418
|
+
* Tracks whether **any** available input device can hover via `(any-hover: hover)`.
|
|
419
|
+
*
|
|
420
|
+
* @param options - Optional per-call settings ({@link CreateMediaQueryOptions}).
|
|
421
|
+
* @returns A `Signal<boolean>` that is `true` while at least one pointer supports hover.
|
|
422
|
+
*
|
|
423
|
+
* @remarks Must be called within an Angular
|
|
424
|
+
* [injection context](https://angular.dev/guide/di/dependency-injection-context).
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* ```ts
|
|
428
|
+
* readonly anyCanHover = anyHover();
|
|
429
|
+
* ```
|
|
430
|
+
*
|
|
431
|
+
* @see {@link hover} to test only the primary input device.
|
|
432
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@media/any-hover | MDN: any-hover}
|
|
433
|
+
* @category Media Features
|
|
434
|
+
*/
|
|
242
435
|
function anyHover(options) {
|
|
243
436
|
isDevMode() && assertInInjectionContext(anyHover);
|
|
244
437
|
const query = normalizeQuery('(any-hover: hover)');
|
|
@@ -246,6 +439,25 @@ function anyHover(options) {
|
|
|
246
439
|
consumer.toString = () => createConsumerLabel('anyHover');
|
|
247
440
|
return consumer;
|
|
248
441
|
}
|
|
442
|
+
/**
|
|
443
|
+
* Tracks the accuracy of the **primary** pointer via `(pointer: ...)`.
|
|
444
|
+
*
|
|
445
|
+
* @param value - `'fine'` (mouse/stylus), `'coarse'` (touch), or `'none'`.
|
|
446
|
+
* @param options - Optional per-call settings ({@link CreateMediaQueryOptions}).
|
|
447
|
+
* @returns A `Signal<boolean>` that is `true` while the primary pointer matches `value`.
|
|
448
|
+
*
|
|
449
|
+
* @remarks Must be called within an Angular
|
|
450
|
+
* [injection context](https://angular.dev/guide/di/dependency-injection-context).
|
|
451
|
+
*
|
|
452
|
+
* @example
|
|
453
|
+
* ```ts
|
|
454
|
+
* readonly isTouch = pointer('coarse');
|
|
455
|
+
* ```
|
|
456
|
+
*
|
|
457
|
+
* @see {@link anyPointer} to test **any** available input device.
|
|
458
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer | MDN: pointer}
|
|
459
|
+
* @category Media Features
|
|
460
|
+
*/
|
|
249
461
|
function pointer(value, options) {
|
|
250
462
|
isDevMode() && assertInInjectionContext(pointer);
|
|
251
463
|
const query = normalizeQuery(`(pointer: ${value})`);
|
|
@@ -253,6 +465,25 @@ function pointer(value, options) {
|
|
|
253
465
|
consumer.toString = () => createConsumerLabel(`pointer(${value})`);
|
|
254
466
|
return consumer;
|
|
255
467
|
}
|
|
468
|
+
/**
|
|
469
|
+
* Tracks the accuracy of **any** available pointer via `(any-pointer: ...)`.
|
|
470
|
+
*
|
|
471
|
+
* @param value - `'fine'` (mouse/stylus), `'coarse'` (touch), or `'none'`.
|
|
472
|
+
* @param options - Optional per-call settings ({@link CreateMediaQueryOptions}).
|
|
473
|
+
* @returns A `Signal<boolean>` that is `true` while at least one pointer matches `value`.
|
|
474
|
+
*
|
|
475
|
+
* @remarks Must be called within an Angular
|
|
476
|
+
* [injection context](https://angular.dev/guide/di/dependency-injection-context).
|
|
477
|
+
*
|
|
478
|
+
* @example
|
|
479
|
+
* ```ts
|
|
480
|
+
* readonly hasFinePointer = anyPointer('fine');
|
|
481
|
+
* ```
|
|
482
|
+
*
|
|
483
|
+
* @see {@link pointer} to test only the primary input device.
|
|
484
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@media/any-pointer | MDN: any-pointer}
|
|
485
|
+
* @category Media Features
|
|
486
|
+
*/
|
|
256
487
|
function anyPointer(value, options) {
|
|
257
488
|
isDevMode() && assertInInjectionContext(anyPointer);
|
|
258
489
|
const query = normalizeQuery(`(any-pointer: ${value})`);
|
|
@@ -260,6 +491,24 @@ function anyPointer(value, options) {
|
|
|
260
491
|
consumer.toString = () => createConsumerLabel(`anyPointer(${value})`);
|
|
261
492
|
return consumer;
|
|
262
493
|
}
|
|
494
|
+
/**
|
|
495
|
+
* Tracks the approximate color gamut of the display via `(color-gamut: ...)`.
|
|
496
|
+
*
|
|
497
|
+
* @param value - `'srgb'`, `'p3'`, or `'rec2020'` (ordered by increasing range).
|
|
498
|
+
* @param options - Optional per-call settings ({@link CreateMediaQueryOptions}).
|
|
499
|
+
* @returns A `Signal<boolean>` that is `true` while the display covers `value`.
|
|
500
|
+
*
|
|
501
|
+
* @remarks Must be called within an Angular
|
|
502
|
+
* [injection context](https://angular.dev/guide/di/dependency-injection-context).
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* ```ts
|
|
506
|
+
* readonly isWideGamut = colorGamut('p3');
|
|
507
|
+
* ```
|
|
508
|
+
*
|
|
509
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/@media/color-gamut | MDN: color-gamut}
|
|
510
|
+
* @category Media Features
|
|
511
|
+
*/
|
|
263
512
|
function colorGamut(value, options) {
|
|
264
513
|
isDevMode() && assertInInjectionContext(colorGamut);
|
|
265
514
|
const query = normalizeQuery(`(color-gamut: ${value})`);
|
|
@@ -267,6 +516,27 @@ function colorGamut(value, options) {
|
|
|
267
516
|
consumer.toString = () => createConsumerLabel(`colorGamut(${value})`);
|
|
268
517
|
return consumer;
|
|
269
518
|
}
|
|
519
|
+
/**
|
|
520
|
+
* Tracks an arbitrary, raw CSS media query.
|
|
521
|
+
*
|
|
522
|
+
* Use this escape hatch for any feature not covered by the dedicated helpers.
|
|
523
|
+
* The query is normalized (trimmed, collapsed whitespace, lower-cased) before use.
|
|
524
|
+
*
|
|
525
|
+
* @param query - A valid CSS media query, e.g. `'(min-resolution: 2dppx)'`.
|
|
526
|
+
* @param options - Optional per-call settings ({@link CreateMediaQueryOptions}).
|
|
527
|
+
* @returns A `Signal<boolean>` that reflects the live result of the query.
|
|
528
|
+
*
|
|
529
|
+
* @remarks Must be called within an Angular
|
|
530
|
+
* [injection context](https://angular.dev/guide/di/dependency-injection-context).
|
|
531
|
+
*
|
|
532
|
+
* @example
|
|
533
|
+
* ```ts
|
|
534
|
+
* readonly isRetina = matchMediaSignal('(min-resolution: 2dppx)');
|
|
535
|
+
* ```
|
|
536
|
+
*
|
|
537
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries | MDN: CSS media queries}
|
|
538
|
+
* @category Custom Queries
|
|
539
|
+
*/
|
|
270
540
|
function matchMediaSignal(query, options) {
|
|
271
541
|
isDevMode() && assertInInjectionContext(matchMediaSignal);
|
|
272
542
|
const media = normalizeQuery(query);
|
|
@@ -275,30 +545,180 @@ function matchMediaSignal(query, options) {
|
|
|
275
545
|
return consumer;
|
|
276
546
|
}
|
|
277
547
|
|
|
548
|
+
const LABEL_RE = /^\[NgxMq Signal: (.+)]$/;
|
|
549
|
+
/** Extracts the inner descriptor from an ngx-mq signal label, or falls back to its raw toString(). */
|
|
550
|
+
function describe(condition) {
|
|
551
|
+
const raw = condition.toString();
|
|
552
|
+
const match = LABEL_RE.exec(raw);
|
|
553
|
+
return match ? match[1] : raw;
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Combines boolean signals with logical **AND**.
|
|
557
|
+
*
|
|
558
|
+
* Composition happens at the signal level, so the underlying media-query
|
|
559
|
+
* listeners stay shared and are still cleaned up automatically.
|
|
560
|
+
*
|
|
561
|
+
* @param conditions - Boolean signals to combine. An empty call returns a
|
|
562
|
+
* signal that is always `true` (vacuous truth).
|
|
563
|
+
* @returns A `Signal<boolean>` that is `true` only when **every** condition is `true`.
|
|
564
|
+
*
|
|
565
|
+
* @example
|
|
566
|
+
* ```ts
|
|
567
|
+
* readonly isLandscapeDesktop = and(up('lg'), orientation('landscape'), hover());
|
|
568
|
+
* ```
|
|
569
|
+
*
|
|
570
|
+
* @see {@link or} and {@link not}.
|
|
571
|
+
* @category Combining Signals
|
|
572
|
+
*/
|
|
573
|
+
function and(...conditions) {
|
|
574
|
+
const result = computed(() => conditions.every((condition) => condition()), ...(ngDevMode ? [{ debugName: "result" }] : []));
|
|
575
|
+
result.toString = () => createConsumerLabel(`and(${conditions.map(describe).join(', ')})`);
|
|
576
|
+
return result;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Combines boolean signals with logical **OR**.
|
|
580
|
+
*
|
|
581
|
+
* Composition happens at the signal level, so the underlying media-query
|
|
582
|
+
* listeners stay shared and are still cleaned up automatically.
|
|
583
|
+
*
|
|
584
|
+
* @param conditions - Boolean signals to combine. An empty call returns a
|
|
585
|
+
* signal that is always `false`.
|
|
586
|
+
* @returns A `Signal<boolean>` that is `true` when **at least one** condition is `true`.
|
|
587
|
+
*
|
|
588
|
+
* @example
|
|
589
|
+
* ```ts
|
|
590
|
+
* readonly prefersSimpleUi = or(down('md'), reducedMotion());
|
|
591
|
+
* ```
|
|
592
|
+
*
|
|
593
|
+
* @see {@link and} and {@link not}.
|
|
594
|
+
* @category Combining Signals
|
|
595
|
+
*/
|
|
596
|
+
function or(...conditions) {
|
|
597
|
+
const result = computed(() => conditions.some((condition) => condition()), ...(ngDevMode ? [{ debugName: "result" }] : []));
|
|
598
|
+
result.toString = () => createConsumerLabel(`or(${conditions.map(describe).join(', ')})`);
|
|
599
|
+
return result;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Negates a boolean signal.
|
|
603
|
+
*
|
|
604
|
+
* Useful for features that have no direct inverse helper, such as
|
|
605
|
+
* "devices without hover": `not(hover())`.
|
|
606
|
+
*
|
|
607
|
+
* @param condition - The boolean signal to invert.
|
|
608
|
+
* @returns A `Signal<boolean>` that is `true` when `condition` is `false`, and vice versa.
|
|
609
|
+
*
|
|
610
|
+
* @example
|
|
611
|
+
* ```ts
|
|
612
|
+
* readonly isTouchLike = not(hover());
|
|
613
|
+
* ```
|
|
614
|
+
*
|
|
615
|
+
* @see {@link and} and {@link or}.
|
|
616
|
+
* @category Combining Signals
|
|
617
|
+
*/
|
|
618
|
+
function not(condition) {
|
|
619
|
+
const result = computed(() => !condition(), ...(ngDevMode ? [{ debugName: "result" }] : []));
|
|
620
|
+
result.toString = () => createConsumerLabel(`not(${describe(condition)})`);
|
|
621
|
+
return result;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Registers a custom breakpoint map, enabling {@link up}, {@link down} and {@link between}.
|
|
626
|
+
*
|
|
627
|
+
* Provide once at bootstrap, or at any injector level to scope/override breakpoints.
|
|
628
|
+
*
|
|
629
|
+
* @param bps - A {@link MqBreakpoints} map of names to minimum widths in pixels.
|
|
630
|
+
* @returns An Angular {@link Provider}.
|
|
631
|
+
*
|
|
632
|
+
* @example
|
|
633
|
+
* ```ts
|
|
634
|
+
* bootstrapApplication(AppComponent, {
|
|
635
|
+
* providers: [provideBreakpoints({ sm: 640, md: 768, lg: 1024 })],
|
|
636
|
+
* });
|
|
637
|
+
* ```
|
|
638
|
+
*
|
|
639
|
+
* @category Providers
|
|
640
|
+
*/
|
|
278
641
|
function provideBreakpoints(bps) {
|
|
279
642
|
return { provide: MQ_BREAKPOINTS, useValue: normalizeBreakpoints(bps) };
|
|
280
643
|
}
|
|
644
|
+
/**
|
|
645
|
+
* Registers the default Tailwind CSS breakpoints:
|
|
646
|
+
* `sm: 640, md: 768, lg: 1024, xl: 1280, 2xl: 1536`.
|
|
647
|
+
*
|
|
648
|
+
* @returns An Angular {@link Provider}.
|
|
649
|
+
* @category Providers
|
|
650
|
+
*/
|
|
281
651
|
function provideTailwindBreakpoints() {
|
|
282
652
|
return provideBreakpoints(TAILWIND_BREAKPOINTS);
|
|
283
653
|
}
|
|
654
|
+
/**
|
|
655
|
+
* Registers the default Bootstrap breakpoints:
|
|
656
|
+
* `sm: 576, md: 768, lg: 992, xl: 1200, xxl: 1400`.
|
|
657
|
+
*
|
|
658
|
+
* @returns An Angular {@link Provider}.
|
|
659
|
+
* @category Providers
|
|
660
|
+
*/
|
|
284
661
|
function provideBootstrapBreakpoints() {
|
|
285
662
|
return provideBreakpoints(BOOTSTRAP_BREAKPOINTS);
|
|
286
663
|
}
|
|
664
|
+
/**
|
|
665
|
+
* Registers the default Material 2 breakpoints:
|
|
666
|
+
* `sm: 600, md: 905, lg: 1240, xl: 1440`.
|
|
667
|
+
*
|
|
668
|
+
* @returns An Angular {@link Provider}.
|
|
669
|
+
* @category Providers
|
|
670
|
+
*/
|
|
287
671
|
function provideMaterialBreakpoints() {
|
|
288
672
|
return provideBreakpoints(MATERIAL_BREAKPOINTS);
|
|
289
673
|
}
|
|
674
|
+
/**
|
|
675
|
+
* Sets the epsilon subtracted from exclusive upper bounds in {@link down} and
|
|
676
|
+
* {@link between}, preventing adjacent ranges from overlapping.
|
|
677
|
+
*
|
|
678
|
+
* @param epsilon - A value in the range `(0, 1]`. Defaults to `0.02`.
|
|
679
|
+
* @returns An Angular {@link Provider}.
|
|
680
|
+
*
|
|
681
|
+
* @example
|
|
682
|
+
* ```ts
|
|
683
|
+
* provideBreakpointEpsilon(0.02);
|
|
684
|
+
* ```
|
|
685
|
+
*
|
|
686
|
+
* @category Providers
|
|
687
|
+
*/
|
|
290
688
|
function provideBreakpointEpsilon(epsilon = DEFAULT_BREAKPOINT_EPSILON) {
|
|
291
689
|
if (isDevMode())
|
|
292
690
|
validateEpsilon(epsilon);
|
|
293
691
|
return { provide: MQ_BREAKPOINT_EPSILON, useValue: epsilon };
|
|
294
692
|
}
|
|
693
|
+
/**
|
|
694
|
+
* Sets the app-wide value query signals report during server-side rendering,
|
|
695
|
+
* where `matchMedia` is unavailable. A per-call `ssrValue` overrides this.
|
|
696
|
+
*
|
|
697
|
+
* @param value - The boolean returned by every signal on the server.
|
|
698
|
+
* @returns An Angular {@link Provider}.
|
|
699
|
+
*
|
|
700
|
+
* @example
|
|
701
|
+
* ```ts
|
|
702
|
+
* provideSsrValue(true);
|
|
703
|
+
* ```
|
|
704
|
+
*
|
|
705
|
+
* @category Providers
|
|
706
|
+
*/
|
|
295
707
|
function provideSsrValue(value) {
|
|
296
708
|
return { provide: NGX_MQ_SSR_VALUE, useValue: value };
|
|
297
709
|
}
|
|
298
710
|
|
|
711
|
+
/**
|
|
712
|
+
* @packageDocumentation
|
|
713
|
+
*
|
|
714
|
+
* @document ../guides/getting-started.md
|
|
715
|
+
* @document ../guides/ssr.md
|
|
716
|
+
* @document ../guides/recipes.md
|
|
717
|
+
*/
|
|
718
|
+
|
|
299
719
|
/**
|
|
300
720
|
* Generated bundle index. Do not edit.
|
|
301
721
|
*/
|
|
302
722
|
|
|
303
|
-
export { MQ_BREAKPOINTS, MQ_BREAKPOINT_EPSILON, NGX_MQ_SSR_VALUE, anyHover, anyPointer, between, colorGamut, colorScheme, displayMode, down, hover, matchMediaSignal, orientation, pointer, provideBootstrapBreakpoints, provideBreakpointEpsilon, provideBreakpoints, provideMaterialBreakpoints, provideSsrValue, provideTailwindBreakpoints, reducedMotion, up };
|
|
723
|
+
export { MQ_BREAKPOINTS, MQ_BREAKPOINT_EPSILON, NGX_MQ_SSR_VALUE, and, anyHover, anyPointer, between, colorGamut, colorScheme, displayMode, down, hover, matchMediaSignal, not, or, orientation, pointer, provideBootstrapBreakpoints, provideBreakpointEpsilon, provideBreakpoints, provideMaterialBreakpoints, provideSsrValue, provideTailwindBreakpoints, reducedMotion, up };
|
|
304
724
|
//# sourceMappingURL=ngx-mq.mjs.map
|