responsive-media 1.2.1 → 1.2.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/README.md +252 -130
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,47 +4,71 @@
|
|
|
4
4
|
</h1>
|
|
5
5
|
<img
|
|
6
6
|
src="https://s3.twcstorage.ru/c9a2cc89-780f97fd-311d-4a1a-b86f-c25665c9dc46/images/npm/responsive-media.webp"
|
|
7
|
-
alt="
|
|
7
|
+
alt="responsive-media"
|
|
8
8
|
style="max-width:100%;width:auto;height:300px;border-radius:12px"
|
|
9
9
|
/>
|
|
10
10
|
</div>
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Reactive boolean state from CSS media queries and element dimensions for Vanilla JS, Vue 3, and React 18+ — AND/OR conditions, container queries, ordered breakpoint helpers, rich subscription API, CSS vars sync, SSR-safe — with no required peer dependencies.
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Contents
|
|
17
|
+
|
|
18
|
+
- [Features](#features)
|
|
19
|
+
- [Installation](#installation)
|
|
20
|
+
- [Quick start](#quick-start)
|
|
21
|
+
- [Config format — MediaQueryConfig](#config-format--mediaqueryconfig)
|
|
22
|
+
- [Global singleton](#global-singleton)
|
|
23
|
+
- [createResponsiveState — isolated instances](#createresponsivestate--isolated-instances)
|
|
24
|
+
- [ContainerState — element container queries](#containerstate--element-container-queries)
|
|
25
|
+
- [Subscription API](#subscription-api)
|
|
26
|
+
- [Ordered breakpoint helpers](#ordered-breakpoint-helpers)
|
|
27
|
+
- [Utilities](#utilities)
|
|
28
|
+
- [Presets](#presets)
|
|
29
|
+
- [Vue 3 integration](#vue-3-integration)
|
|
30
|
+
- [React 18+ integration](#react-18-integration)
|
|
31
|
+
- [TypeScript helpers](#typescript-helpers)
|
|
32
|
+
- [SSR / hydration](#ssr--hydration)
|
|
33
|
+
- [Architecture](#architecture)
|
|
34
|
+
- [Bundle size & peer dependencies](#bundle-size--peer-dependencies)
|
|
35
|
+
- [Exported API reference](#exported-api-reference)
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Features
|
|
40
|
+
|
|
41
|
+
- **Framework-agnostic core** — `ReactiveResponsiveState` and `ContainerState` work with Vanilla JS, any signals library, or any framework; Vue and React are optional peer dependencies
|
|
42
|
+
- **Viewport breakpoints** — backed by `window.matchMedia`; conditions combined with AND (flat array) or OR (nested array); raw media type support for `print`, `screen`, etc.
|
|
43
|
+
- **Full condition vocabulary** — `min/max-width`, `min/max-height`, `orientation`, `aspect-ratio`, `prefers-color-scheme`, `prefers-reduced-motion`, `prefers-contrast`, `hover`, `pointer`, `forced-colors`, `resolution`, `display-mode`, and `raw`
|
|
44
|
+
- **Container queries (JS-side)** — `ContainerState` tracks an element's dimensions via `ResizeObserver` and evaluates breakpoint conditions in JavaScript; identical API to viewport state
|
|
45
|
+
- **Rich subscription API** — `subscribe`, `on`, `onEnter`, `onLeave`, `once`, `onNextChange`, `onBreakpointChange`, `waitFor`; optional debounce for `subscribe`; per-key listeners are never debounced
|
|
46
|
+
- **Ordered breakpoint helpers** — `current`, `isAbove()`, `isBelow()`, `between()` for semantic viewport comparisons; order derived from config key insertion or explicit `order` option
|
|
47
|
+
- **Utilities** — `syncCSSVars` (CSS custom properties), `emitDOMEvents` (DOM CustomEvents), `toSignal` (any signals library — Preact, Angular, SolidJS, Vue), `match` (pick value by first active breakpoint), `subscribeMediaQuery` (raw single query)
|
|
48
|
+
- **Vue 3 adapter** — `useResponsive`, `useBreakpoints`, `useMediaQuery`, `useContainerState`; fully reactive in templates and `computed`; `ResponsivePlugin` for global config
|
|
49
|
+
- **React 18+ adapter** — same four hooks; `useSyncExternalStore` for safe concurrent rendering; SSR-safe (`false` on server)
|
|
50
|
+
- **Presets** — `TailwindPreset`, `BootstrapPreset`, `AccessibilityPreset` out of the box; user-preference queries (`dark`, `reducedMotion`, `highContrast`, `print`, …)
|
|
51
|
+
- **SSR-safe** — all APIs check for `window` / `matchMedia` / `ResizeObserver` before use; `hydrate()` prevents layout shift on the client
|
|
52
|
+
- **TypeScript** — full generics; `ConfigToState<T>` infers a boolean-state type from any config object
|
|
53
|
+
|
|
54
|
+
---
|
|
19
55
|
|
|
20
56
|
## Installation
|
|
21
57
|
|
|
22
|
-
```
|
|
58
|
+
```bash
|
|
23
59
|
npm install responsive-media
|
|
24
60
|
```
|
|
25
61
|
|
|
26
|
-
|
|
62
|
+
No required peer dependencies. Vue and React adapters are available automatically when the respective package is installed:
|
|
27
63
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
3. [Global singleton](#global-singleton)
|
|
33
|
-
4. [createResponsiveState — isolated instances](#createresponsivestate--isolated-instances)
|
|
34
|
-
5. [ContainerState — element container queries](#containerstate--element-container-queries)
|
|
35
|
-
6. [Subscription API](#subscription-api)
|
|
36
|
-
7. [Ordered breakpoint helpers](#ordered-breakpoint-helpers)
|
|
37
|
-
8. [Utilities](#utilities)
|
|
38
|
-
9. [Presets](#presets)
|
|
39
|
-
10. [Vue 3 integration](#vue-3-integration)
|
|
40
|
-
11. [React 18+ integration](#react-18-integration)
|
|
41
|
-
12. [TypeScript helpers](#typescript-helpers)
|
|
42
|
-
13. [SSR / hydration](#ssr--hydration)
|
|
43
|
-
14. [Exported API reference](#exported-api-reference)
|
|
64
|
+
```bash
|
|
65
|
+
npm install vue@>=3.3 # for Vue composables
|
|
66
|
+
npm install react@>=18 # for React hooks
|
|
67
|
+
```
|
|
44
68
|
|
|
45
69
|
---
|
|
46
70
|
|
|
47
|
-
## Quick
|
|
71
|
+
## Quick start
|
|
48
72
|
|
|
49
73
|
```ts
|
|
50
74
|
import { responsiveState, setResponsiveConfig } from 'responsive-media';
|
|
@@ -71,7 +95,7 @@ stop();
|
|
|
71
95
|
|
|
72
96
|
## Config format — MediaQueryConfig
|
|
73
97
|
|
|
74
|
-
Each breakpoint is described by a `MediaQueryConfig` — an array of conditions
|
|
98
|
+
Each breakpoint is described by a `MediaQueryConfig` — an array of conditions combined with **AND**, or a nested array of groups combined with **OR**.
|
|
75
99
|
|
|
76
100
|
### AND (flat array)
|
|
77
101
|
|
|
@@ -107,24 +131,23 @@ Use `type: 'raw'` to insert a value verbatim — useful for media types like `pr
|
|
|
107
131
|
|
|
108
132
|
### Supported condition types
|
|
109
133
|
|
|
110
|
-
| `type`
|
|
111
|
-
|
|
112
|
-
| `min-width`
|
|
113
|
-
| `max-width`
|
|
114
|
-
| `min-height`
|
|
115
|
-
| `max-height`
|
|
116
|
-
| `orientation`
|
|
117
|
-
| `aspect-ratio`
|
|
118
|
-
| `prefers-color-scheme`
|
|
119
|
-
| `prefers-reduced-motion
|
|
120
|
-
| `prefers-contrast`
|
|
121
|
-
| `hover`
|
|
122
|
-
| `pointer`
|
|
123
|
-
| `forced-colors`
|
|
124
|
-
| `resolution`
|
|
125
|
-
| `display-mode`
|
|
126
|
-
| `raw`
|
|
127
|
-
| … and more | | |
|
|
134
|
+
| `type` | Example value | Generated query |
|
|
135
|
+
|--------------------------|----------------|------------------------------------|
|
|
136
|
+
| `min-width` | `768` | `(min-width: 768px)` |
|
|
137
|
+
| `max-width` | `1023` | `(max-width: 1023px)` |
|
|
138
|
+
| `min-height` | `600` | `(min-height: 600px)` |
|
|
139
|
+
| `max-height` | `900` | `(max-height: 900px)` |
|
|
140
|
+
| `orientation` | `'portrait'` | `(orientation: portrait)` |
|
|
141
|
+
| `aspect-ratio` | `'16/9'` | `(aspect-ratio: 16/9)` |
|
|
142
|
+
| `prefers-color-scheme` | `'dark'` | `(prefers-color-scheme: dark)` |
|
|
143
|
+
| `prefers-reduced-motion` | `'reduce'` | `(prefers-reduced-motion: reduce)` |
|
|
144
|
+
| `prefers-contrast` | `'more'` | `(prefers-contrast: more)` |
|
|
145
|
+
| `hover` | `'none'` | `(hover: none)` |
|
|
146
|
+
| `pointer` | `'coarse'` | `(pointer: coarse)` |
|
|
147
|
+
| `forced-colors` | `'active'` | `(forced-colors: active)` |
|
|
148
|
+
| `resolution` | `'2dppx'` | `(resolution: 2dppx)` |
|
|
149
|
+
| `display-mode` | `'standalone'` | `(display-mode: standalone)` |
|
|
150
|
+
| `raw` | `'print'` | `print` *(verbatim)* |
|
|
128
151
|
|
|
129
152
|
---
|
|
130
153
|
|
|
@@ -142,15 +165,15 @@ setResponsiveConfig(
|
|
|
142
165
|
lg: [{ type: 'min-width', value: 1024 }],
|
|
143
166
|
},
|
|
144
167
|
{
|
|
145
|
-
order:
|
|
146
|
-
debounce: 50,
|
|
168
|
+
order: ['sm', 'lg'], // for isAbove / isBelow / between
|
|
169
|
+
debounce: 50, // ms — throttle subscribe() listeners
|
|
147
170
|
}
|
|
148
171
|
);
|
|
149
172
|
|
|
150
|
-
// Read
|
|
173
|
+
// Read a stable snapshot
|
|
151
174
|
const { sm, lg } = responsiveState.getState();
|
|
152
175
|
|
|
153
|
-
//
|
|
176
|
+
// Live proxy access (never debounced)
|
|
154
177
|
console.log(responsiveState.proxy.sm);
|
|
155
178
|
|
|
156
179
|
// Get the generated CSS strings
|
|
@@ -370,12 +393,10 @@ const stop = state.syncCSSVars({ element: document.body, prefix: '--bp-' });
|
|
|
370
393
|
stop(); // cleanup
|
|
371
394
|
```
|
|
372
395
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
|
376
|
-
|
|
377
|
-
| `element` | `document.documentElement` | Target HTML element |
|
|
378
|
-
| `prefix` | `'--responsive-'` | CSS custom property name prefix |
|
|
396
|
+
| Option | Default | Description |
|
|
397
|
+
|-----------|----------------------------|----------------------------------|
|
|
398
|
+
| `element` | `document.documentElement` | Target HTML element |
|
|
399
|
+
| `prefix` | `'--responsive-'` | CSS custom property name prefix |
|
|
379
400
|
|
|
380
401
|
### `emitDOMEvents(target?, options?)` → stop
|
|
381
402
|
|
|
@@ -395,8 +416,6 @@ document.addEventListener('bp:desktop:leave', () => destroyDesktopChart());
|
|
|
395
416
|
stop();
|
|
396
417
|
```
|
|
397
418
|
|
|
398
|
-
**Options:**
|
|
399
|
-
|
|
400
419
|
| Option | Default | Description |
|
|
401
420
|
|----------|-----------------|--------------------------|
|
|
402
421
|
| `prefix` | `'responsive:'` | Custom event name prefix |
|
|
@@ -442,7 +461,6 @@ Returns the configured breakpoint order array (or empty array if not set).
|
|
|
442
461
|
Sets initial state from a server-side snapshot to prevent layout shift. Only updates keys that exist in the current config.
|
|
443
462
|
|
|
444
463
|
```ts
|
|
445
|
-
// On the server, serialize state and pass to the client:
|
|
446
464
|
state.hydrate({ mobile: false, tablet: false, desktop: true });
|
|
447
465
|
```
|
|
448
466
|
|
|
@@ -472,9 +490,9 @@ Returns the first value in `map` whose key is `true` in `state`. Priority follow
|
|
|
472
490
|
import { match } from 'responsive-media';
|
|
473
491
|
import { responsiveState } from 'responsive-media';
|
|
474
492
|
|
|
475
|
-
const cols
|
|
476
|
-
const View
|
|
477
|
-
const label
|
|
493
|
+
const cols = match(responsiveState.proxy, { mobile: 1, tablet: 2, desktop: 4 });
|
|
494
|
+
const View = match(responsiveState.proxy, { mobile: MobileMenu, desktop: DesktopNav });
|
|
495
|
+
const label = match(responsiveState.proxy, { sm: 'Compact', lg: 'Full' }, 'Default');
|
|
478
496
|
```
|
|
479
497
|
|
|
480
498
|
### `subscribeMediaQuery(query, callback)` — standalone utility
|
|
@@ -508,14 +526,14 @@ Import from `responsive-media/presets` or from the main entry point.
|
|
|
508
526
|
|
|
509
527
|
Mutually exclusive Tailwind CSS v3/v4 breakpoints:
|
|
510
528
|
|
|
511
|
-
| Key | Range
|
|
512
|
-
|
|
513
|
-
| `xs` | ≤ 639px
|
|
514
|
-
| `sm` | 640 – 767px
|
|
515
|
-
| `md` | 768 – 1023px
|
|
516
|
-
| `lg` | 1024 – 1279px
|
|
517
|
-
| `xl` | 1280 – 1535px
|
|
518
|
-
| `2xl` | ≥ 1536px
|
|
529
|
+
| Key | Range |
|
|
530
|
+
|-------|---------------|
|
|
531
|
+
| `xs` | ≤ 639px |
|
|
532
|
+
| `sm` | 640 – 767px |
|
|
533
|
+
| `md` | 768 – 1023px |
|
|
534
|
+
| `lg` | 1024 – 1279px |
|
|
535
|
+
| `xl` | 1280 – 1535px |
|
|
536
|
+
| `2xl` | ≥ 1536px |
|
|
519
537
|
|
|
520
538
|
```ts
|
|
521
539
|
import { createResponsiveState, TailwindPreset, TailwindOrder } from 'responsive-media';
|
|
@@ -546,17 +564,17 @@ const state = createResponsiveState(BootstrapPreset, { order: [...BootstrapOrder
|
|
|
546
564
|
|
|
547
565
|
User-preference media queries. Multiple keys can be `true` simultaneously.
|
|
548
566
|
|
|
549
|
-
| Key | Matches when …
|
|
550
|
-
|
|
551
|
-
| `dark` | `prefers-color-scheme: dark`
|
|
552
|
-
| `light` | `prefers-color-scheme: light`
|
|
553
|
-
| `reducedMotion` | `prefers-reduced-motion: reduce`
|
|
554
|
-
| `highContrast` | `prefers-contrast: more`
|
|
555
|
-
| `lowContrast` | `prefers-contrast: less`
|
|
556
|
-
| `noHover` | `hover: none` (touch / stylus devices)
|
|
557
|
-
| `coarsePointer` | `pointer: coarse` (finger-sized input)
|
|
558
|
-
| `forcedColors` | `forced-colors: active` (Windows HCM)
|
|
559
|
-
| `print` | `print` media type
|
|
567
|
+
| Key | Matches when … |
|
|
568
|
+
|-----------------|----------------------------------------|
|
|
569
|
+
| `dark` | `prefers-color-scheme: dark` |
|
|
570
|
+
| `light` | `prefers-color-scheme: light` |
|
|
571
|
+
| `reducedMotion` | `prefers-reduced-motion: reduce` |
|
|
572
|
+
| `highContrast` | `prefers-contrast: more` |
|
|
573
|
+
| `lowContrast` | `prefers-contrast: less` |
|
|
574
|
+
| `noHover` | `hover: none` (touch / stylus devices) |
|
|
575
|
+
| `coarsePointer` | `pointer: coarse` (finger-sized input) |
|
|
576
|
+
| `forcedColors` | `forced-colors: active` (Windows HCM) |
|
|
577
|
+
| `print` | `print` media type |
|
|
560
578
|
|
|
561
579
|
```ts
|
|
562
580
|
import { createResponsiveState, AccessibilityPreset } from 'responsive-media';
|
|
@@ -572,7 +590,7 @@ a11y.onEnter('print', () => hideNonPrintable());
|
|
|
572
590
|
|
|
573
591
|
## Vue 3 integration
|
|
574
592
|
|
|
575
|
-
|
|
593
|
+
Vue composables are included in the main bundle and are activated when Vue is installed as a peer dependency.
|
|
576
594
|
|
|
577
595
|
### Plugin registration
|
|
578
596
|
|
|
@@ -655,7 +673,7 @@ Tracks an element's dimensions and returns a reactive state object. Sets up and
|
|
|
655
673
|
import { useTemplateRef } from 'vue';
|
|
656
674
|
import { useContainerState } from 'responsive-media';
|
|
657
675
|
|
|
658
|
-
const cardRef
|
|
676
|
+
const cardRef = useTemplateRef('card');
|
|
659
677
|
const cardState = useContainerState(cardRef, {
|
|
660
678
|
compact: [{ type: 'max-width', value: 300 }],
|
|
661
679
|
wide: [{ type: 'min-width', value: 600 }],
|
|
@@ -791,9 +809,14 @@ const state = useResponsive<AppState>();
|
|
|
791
809
|
|
|
792
810
|
## SSR / hydration
|
|
793
811
|
|
|
794
|
-
All APIs are SSR-safe — they check for `window` and `
|
|
812
|
+
All APIs are SSR-safe — they check for `window`, `matchMedia`, and `ResizeObserver` availability before use and fall back to `false` on the server.
|
|
795
813
|
|
|
796
|
-
|
|
814
|
+
| Scenario | Behaviour |
|
|
815
|
+
|---|---|
|
|
816
|
+
| `typeof window === 'undefined'` | All listeners skip setup; `proxy` / `getState()` return `false` for all keys |
|
|
817
|
+
| `useCookie` on server (Nuxt) | Not applicable — use `useCookie` from `@vueuse/core` or Nuxt built-ins |
|
|
818
|
+
| React SSR | `useMediaQuery` returns `false`; `useResponsive` returns the server-side snapshot |
|
|
819
|
+
| Hydration mismatch | Call `hydrate()` with the server snapshot before first render |
|
|
797
820
|
|
|
798
821
|
```ts
|
|
799
822
|
// Server: serialize the expected initial state
|
|
@@ -806,63 +829,146 @@ responsiveState.hydrate(initialState);
|
|
|
806
829
|
|
|
807
830
|
---
|
|
808
831
|
|
|
832
|
+
## Architecture
|
|
833
|
+
|
|
834
|
+
```
|
|
835
|
+
responsive-media
|
|
836
|
+
│
|
|
837
|
+
├── BaseResponsiveState (abstract)
|
|
838
|
+
│ Proxy over a plain Record<string, boolean>
|
|
839
|
+
│ Batched updates — all matchMedia/ResizeObserver callbacks collected
|
|
840
|
+
│ before a single notify() fires
|
|
841
|
+
│ Subscription registry: global listeners + per-key listeners
|
|
842
|
+
│ Debounce for subscribe(); key listeners never debounced
|
|
843
|
+
│ Ordered breakpoint helpers: current / isAbove / isBelow / between
|
|
844
|
+
│ Utilities: syncCSSVars / emitDOMEvents / toSignal / hydrate / destroy
|
|
845
|
+
│
|
|
846
|
+
├── ReactiveResponsiveState extends BaseResponsiveState
|
|
847
|
+
│ setupSources() → window.matchMedia per config key
|
|
848
|
+
│ Generated media query string stored in mediaQueries map
|
|
849
|
+
│ Batches all MediaQueryList 'change' events, then flushes
|
|
850
|
+
│ setConfig() / destroy() cleanupSources() removes matchMedia handlers
|
|
851
|
+
│
|
|
852
|
+
├── ContainerState extends BaseResponsiveState
|
|
853
|
+
│ setupSources() → single ResizeObserver on the target element
|
|
854
|
+
│ Evaluates width/height/orientation/aspect-ratio conditions in JS
|
|
855
|
+
│ Reconnects observer when config changes; teardown on destroy()
|
|
856
|
+
│
|
|
857
|
+
├── createResponsiveState(config, options)
|
|
858
|
+
│ Factory — returns a new ReactiveResponsiveState instance
|
|
859
|
+
│
|
|
860
|
+
├── responsiveState (global singleton)
|
|
861
|
+
│ Pre-configured with default ResponsiveConfig (mobile/tablet/desktop)
|
|
862
|
+
│ setResponsiveConfig() / getResponsiveState() / getResponsiveMediaQueries()
|
|
863
|
+
│ delegate to this instance
|
|
864
|
+
│
|
|
865
|
+
├── toMediaQueryString(conditions)
|
|
866
|
+
│ Converts MediaQueryConfig → CSS string
|
|
867
|
+
│ AND: flat array → joined with ' and '
|
|
868
|
+
│ OR: nested array → groups joined with ', '
|
|
869
|
+
│ Numeric values get 'px' suffix (except raw / orientation / …)
|
|
870
|
+
│
|
|
871
|
+
├── match(state, map, fallback?)
|
|
872
|
+
│ First-match lookup — returns mapped value for first true key in map
|
|
873
|
+
│
|
|
874
|
+
├── subscribeMediaQuery(query, callback)
|
|
875
|
+
│ Thin wrapper around window.matchMedia + addEventListener('change')
|
|
876
|
+
│ Returns cleanup function
|
|
877
|
+
│
|
|
878
|
+
├── Vue adapter (vue-responsive.ts)
|
|
879
|
+
│ ResponsivePlugin — app.use(); calls setResponsiveConfig
|
|
880
|
+
│ useResponsive() — returns shallowReactive mirror; subscribe() syncs it
|
|
881
|
+
│ useBreakpoints() — returns { current, isAbove, isBelow, between }
|
|
882
|
+
│ all methods read from the reactive mirror
|
|
883
|
+
│ useMediaQuery() — wraps subscribeMediaQuery in a ref + onUnmounted
|
|
884
|
+
│ useContainerState() — watchEffect over templateRef; creates/destroys
|
|
885
|
+
│ ContainerState; returns shallowReactive mirror
|
|
886
|
+
│
|
|
887
|
+
├── React adapter (react-responsive.ts)
|
|
888
|
+
│ useResponsive() — useSyncExternalStore(subscribe, getState, getState)
|
|
889
|
+
│ useBreakpoints() — useSyncExternalStore + wraps ordered helpers
|
|
890
|
+
│ useMediaQuery() — useSyncExternalStore over subscribeMediaQuery
|
|
891
|
+
│ useContainerState() — useEffect creates ContainerState; useState mirror
|
|
892
|
+
│
|
|
893
|
+
└── Presets (presets.ts)
|
|
894
|
+
ResponsiveConfig — default mobile/tablet/desktop
|
|
895
|
+
TailwindPreset / TailwindOrder
|
|
896
|
+
BootstrapPreset / BootstrapOrder
|
|
897
|
+
AccessibilityPreset
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
---
|
|
901
|
+
|
|
902
|
+
## Bundle size & peer dependencies
|
|
903
|
+
|
|
904
|
+
| Entry point | Peer deps | Notes |
|
|
905
|
+
|-----------------------------|----------------------|-------|
|
|
906
|
+
| `responsive-media` | *(none required)* | Core + Vue composables (tree-shaken when Vue absent) |
|
|
907
|
+
| `responsive-media/react` | `react ^18` | React hooks only |
|
|
908
|
+
| `responsive-media/presets` | *(none)* | Preset configs only — add to any instance |
|
|
909
|
+
| `responsive-media/container`| *(none)* | `ContainerState` class + factory only |
|
|
910
|
+
|
|
911
|
+
The package ships as tree-shakeable ESM and CommonJS. Vue composables (`ResponsivePlugin`, `useResponsive`, etc.) are included in the main bundle but resolve to no-ops when Vue is not installed, so the core footprint stays minimal in non-Vue projects. The React entry point is code-split and never imported by the main bundle.
|
|
912
|
+
|
|
913
|
+
---
|
|
914
|
+
|
|
809
915
|
## Exported API reference
|
|
810
916
|
|
|
811
917
|
### Main entry (`responsive-media`)
|
|
812
918
|
|
|
813
|
-
| Export
|
|
814
|
-
|
|
815
|
-
| `responsiveState`
|
|
816
|
-
| `setResponsiveConfig`
|
|
817
|
-
| `getResponsiveState`
|
|
818
|
-
| `getResponsiveMediaQueries
|
|
819
|
-
| `createResponsiveState`
|
|
820
|
-
| `createContainerState`
|
|
821
|
-
| `toMediaQueryString`
|
|
822
|
-
| `match`
|
|
823
|
-
| `subscribeMediaQuery`
|
|
824
|
-
| `ResponsiveConfig`
|
|
825
|
-
| `BaseResponsiveState`
|
|
826
|
-
| `ReactiveResponsiveState`
|
|
827
|
-
| `ContainerState`
|
|
828
|
-
| `ResponsivePlugin`
|
|
829
|
-
| `useResponsive`
|
|
830
|
-
| `useBreakpoints`
|
|
831
|
-
| `useMediaQuery`
|
|
832
|
-
| `useContainerState`
|
|
833
|
-
| `ConfigToState`
|
|
834
|
-
| `MediaQueryConfig`
|
|
835
|
-
| `MediaQueryCondition`
|
|
836
|
-
| `ResponsiveState`
|
|
837
|
-
| `SetConfigOptions`
|
|
838
|
-
| `BreakpointHelpers`
|
|
919
|
+
| Export | Type | Description |
|
|
920
|
+
|----------------------------|---------------------------|--------------------------------------------------------|
|
|
921
|
+
| `responsiveState` | `ReactiveResponsiveState` | Global singleton, default `ResponsiveConfig` |
|
|
922
|
+
| `setResponsiveConfig` | function | Reconfigure the global singleton |
|
|
923
|
+
| `getResponsiveState` | function | Get state snapshot from global singleton |
|
|
924
|
+
| `getResponsiveMediaQueries`| function | Get CSS query strings from global singleton |
|
|
925
|
+
| `createResponsiveState` | function | Create an isolated `ReactiveResponsiveState` instance |
|
|
926
|
+
| `createContainerState` | function | Create a `ContainerState` for an element |
|
|
927
|
+
| `toMediaQueryString` | function | Convert `MediaQueryConfig` to CSS string |
|
|
928
|
+
| `match` | function | Pick a value by first matching breakpoint key |
|
|
929
|
+
| `subscribeMediaQuery` | function | Subscribe to a raw CSS media query string |
|
|
930
|
+
| `ResponsiveConfig` | const | Default mobile / tablet / desktop breakpoints |
|
|
931
|
+
| `BaseResponsiveState` | class | Abstract base (for extension) |
|
|
932
|
+
| `ReactiveResponsiveState` | class | Viewport state (`matchMedia`-backed) |
|
|
933
|
+
| `ContainerState` | class | Element container state (`ResizeObserver`-backed) |
|
|
934
|
+
| `ResponsivePlugin` | Vue plugin | Vue app plugin |
|
|
935
|
+
| `useResponsive` | Vue composable | Reactive state object |
|
|
936
|
+
| `useBreakpoints` | Vue composable | Ordered breakpoint helpers |
|
|
937
|
+
| `useMediaQuery` | Vue composable | Single raw media query |
|
|
938
|
+
| `useContainerState` | Vue composable | Element container queries |
|
|
939
|
+
| `ConfigToState` | type | Derives state type from config |
|
|
940
|
+
| `MediaQueryConfig` | type | Config entry type |
|
|
941
|
+
| `MediaQueryCondition` | type | Single condition type |
|
|
942
|
+
| `ResponsiveState` | type | `Record<string, boolean>` |
|
|
943
|
+
| `SetConfigOptions` | type | Options for `setConfig` / `createResponsiveState` |
|
|
944
|
+
| `BreakpointHelpers` | type | Return type of `useBreakpoints` |
|
|
839
945
|
|
|
840
946
|
### React entry (`responsive-media/react`)
|
|
841
947
|
|
|
842
|
-
| Export | Description
|
|
843
|
-
|
|
844
|
-
| `useResponsive` | State hook (useSyncExternalStore)
|
|
845
|
-
| `useBreakpoints` | Ordered breakpoint helpers hook
|
|
846
|
-
| `useMediaQuery` | Single raw media query hook
|
|
847
|
-
| `useContainerState` | Element container queries hook
|
|
848
|
-
| `BreakpointHelpers` | Type for `useBreakpoints` return value
|
|
948
|
+
| Export | Description |
|
|
949
|
+
|---------------------|-----------------------------------------------|
|
|
950
|
+
| `useResponsive` | State hook (`useSyncExternalStore`) |
|
|
951
|
+
| `useBreakpoints` | Ordered breakpoint helpers hook |
|
|
952
|
+
| `useMediaQuery` | Single raw media query hook |
|
|
953
|
+
| `useContainerState` | Element container queries hook |
|
|
954
|
+
| `BreakpointHelpers` | Type for `useBreakpoints` return value |
|
|
849
955
|
|
|
850
956
|
### Presets entry (`responsive-media/presets`)
|
|
851
957
|
|
|
852
|
-
| Export
|
|
853
|
-
|
|
854
|
-
| `TailwindPreset`
|
|
855
|
-
| `TailwindOrder`
|
|
856
|
-
| `BootstrapPreset`
|
|
857
|
-
| `BootstrapOrder`
|
|
858
|
-
| `AccessibilityPreset
|
|
958
|
+
| Export | Description |
|
|
959
|
+
|-----------------------|------------------------------------------|
|
|
960
|
+
| `TailwindPreset` | Tailwind CSS v3/v4 breakpoints |
|
|
961
|
+
| `TailwindOrder` | Ordered key array for `TailwindPreset` |
|
|
962
|
+
| `BootstrapPreset` | Bootstrap 5 breakpoints |
|
|
963
|
+
| `BootstrapOrder` | Ordered key array for `BootstrapPreset` |
|
|
964
|
+
| `AccessibilityPreset` | User-preference media queries |
|
|
859
965
|
|
|
860
966
|
### Container entry (`responsive-media/container`)
|
|
861
967
|
|
|
862
|
-
| Export
|
|
863
|
-
|
|
864
|
-
| `ContainerState`
|
|
865
|
-
| `createContainerState
|
|
968
|
+
| Export | Description |
|
|
969
|
+
|------------------------|------------------------------------------|
|
|
970
|
+
| `ContainerState` | Class for element container queries |
|
|
971
|
+
| `createContainerState` | Factory function |
|
|
866
972
|
|
|
867
973
|
---
|
|
868
974
|
|
|
@@ -870,8 +976,24 @@ responsiveState.hydrate(initialState);
|
|
|
870
976
|
|
|
871
977
|
MIT
|
|
872
978
|
|
|
979
|
+
---
|
|
980
|
+
|
|
873
981
|
## Author
|
|
874
982
|
|
|
875
|
-
Danil Lisin aka Macrulez
|
|
983
|
+
Danil Lisin Vladimirovich aka Macrulez
|
|
984
|
+
|
|
985
|
+
GitHub: [macrulezru](https://github.com/macrulezru) · Website: [macrulez.ru/en](https://macrulez.ru/en)
|
|
986
|
+
|
|
987
|
+
Bugs and questions — [issues](https://github.com/macrulezru/responsive-media/issues)
|
|
988
|
+
|
|
989
|
+
---
|
|
990
|
+
|
|
991
|
+
## 💖 Support the project
|
|
992
|
+
|
|
993
|
+
Open source takes time and effort. If my work saves you time or brings value, consider supporting further development.
|
|
994
|
+
|
|
995
|
+
<a href="https://donate.cryptocloud.plus/M6O34NIN" target="_blank">
|
|
996
|
+
<img src="https://img.shields.io/badge/Donate-CryptoCloud-8A2BE2?style=for-the-badge&logo=cryptocurrency&logoColor=white" alt="Donate via CryptoCloud">
|
|
997
|
+
</a>
|
|
876
998
|
|
|
877
|
-
|
|
999
|
+
Thank you for being part of this journey. ❤️
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "responsive-media",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "A utility for reactive state based on CSS media queries. Includes integration with Vue 3 (Composition API) and React 18+.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|