Sign In

@solid-primitives/media

Package Overview
Dependencies
Maintainers
3
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@solid-primitives/media - npm Package Compare versions

Comparing version
4.0.0-next.0
to
4.0.0-next.1
+90
-87
dist/index.d.ts

@@ -1,95 +0,98 @@

import { type Accessor } from "solid-js";
/* @ts-self-types="./index.d.ts" */
import { Accessor } from "solid-js";
//#region src/index.d.ts
/**
* attaches a MediaQuery listener to window, listeneing to changes to provided query
* @param query Media query to listen for
* @param callback function called every time the media match changes
* @returns function removing the listener
* @example
* const clear = makeMediaQueryListener("(max-width: 767px)", e => {
* console.log(e.matches)
* });
* // remove listeners (will happen also on cleanup)
* clear()
*/
export declare function makeMediaQueryListener(query: string | MediaQueryList, callback: (e: MediaQueryListEvent) => void): VoidFunction;
* attaches a MediaQuery listener to window, listeneing to changes to provided query
* @param query Media query to listen for
* @param callback function called every time the media match changes
* @returns function removing the listener
* @example
* const clear = makeMediaQueryListener("(max-width: 767px)", e => {
* console.log(e.matches)
* });
* // remove listeners (will happen also on cleanup)
* clear()
*/
declare function makeMediaQueryListener(query: string | MediaQueryList, callback: (e: MediaQueryListEvent) => void): VoidFunction;
/**
* Creates a very simple and straightforward media query monitor.
*
* @param query Media query to listen for
* @param fallbackState Server fallback state *(Defaults to `false`)*
* @returns Boolean value if media query is met or not
*
* @example
* ```ts
* const isSmall = createMediaQuery("(max-width: 767px)");
* console.log(isSmall());
* ```
*/
export declare function createMediaQuery(query: string, serverFallback?: boolean): () => boolean;
* Creates a very simple and straightforward media query monitor.
*
* @param query Media query to listen for
* @param fallbackState Server fallback state *(Defaults to `false`)*
* @returns Boolean value if media query is met or not
*
* @example
* ```ts
* const isSmall = createMediaQuery("(max-width: 767px)");
* console.log(isSmall());
* ```
*/
declare function createMediaQuery(query: string, serverFallback?: boolean): Accessor<boolean>;
/**
* Provides a signal indicating if the user has requested dark color theme. The setting is being watched with a [Media Query](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme).
*
* @param serverFallback value that should be returned on the server — defaults to `false`
*
* @returns a boolean signal
* @example
* const prefersDark = usePrefersDark();
* createEffect(() => {
* prefersDark() // => boolean
* });
*/
export declare function createPrefersDark(serverFallback?: boolean): () => boolean;
* Provides a signal indicating if the user has requested dark color theme. The setting is being watched with a [Media Query](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme).
*
* @param serverFallback value that should be returned on the server — defaults to `false`
*
* @returns a boolean signal
* @example
* const prefersDark = usePrefersDark();
* createEffect(() => {
* prefersDark() // => boolean
* });
*/
declare function createPrefersDark(serverFallback?: boolean): Accessor<boolean>;
/**
* Provides a signal indicating if the user has requested dark color theme. The setting is being watched with a [Media Query](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme).
*
* This is a [singleton root primitive](https://github.com/solidjs-community/solid-primitives/tree/main/packages/rootless#createSingletonRoot) except if during hydration.
*
* @returns a boolean signal
* @example
* const prefersDark = usePrefersDark();
* createEffect(() => {
* prefersDark() // => boolean
* });
*/
export declare const usePrefersDark: () => Accessor<boolean>;
export type Breakpoints = Record<string, string>;
export type Matches<T extends Breakpoints> = {
readonly [K in keyof T]: K extends "key" ? never : boolean;
} & {
key: keyof T;
* Provides a signal indicating if the user has requested dark color theme. The setting is being watched with a [Media Query](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme).
*
* This is a [singleton root primitive](https://github.com/solidjs-community/solid-primitives/tree/main/packages/rootless#createSingletonRoot) except if during hydration.
*
* @returns a boolean signal
* @example
* const prefersDark = usePrefersDark();
* createEffect(() => {
* prefersDark() // => boolean
* });
*/
declare const usePrefersDark: () => Accessor<boolean>;
type Breakpoints = Record<string, string>;
type Matches<T extends Breakpoints> = { readonly [K in keyof T]: K extends "key" ? never : boolean } & {
key: keyof T;
};
export interface BreakpointOptions<T extends Breakpoints> {
/** If true watches changes and reports state reactively */
watchChange?: boolean;
/** Default value of `match` when `window.matchMedia` is not available like during SSR & legacy browsers */
fallbackState?: Matches<T>;
/** Use `min-width` media query for mobile first or `max-width` for desktop first. Defaults to `min-width` */
mediaFeature?: string;
interface BreakpointOptions<T extends Breakpoints> {
/** If true watches changes and reports state reactively */
watchChange?: boolean;
/** Default value of `match` when `window.matchMedia` is not available like during SSR & legacy browsers */
fallbackState?: Matches<T>;
/** Use `min-width` media query for mobile first or `max-width` for desktop first. Defaults to `min-width` */
mediaFeature?: string;
}
/**
* Creates a multi-breakpoint monitor to make responsive components easily.
*
* @param breakpoints Map of breakpoint names and their widths
* @param options Options to customize watch, fallback, responsive mode.
* @returns map of currently matching breakpoints.
*
* @example
* ```ts
* const breakpoints = {
sm: "640px",
lg: "1024px",
xl: "1280px",
};
* const matches = createBreakpoints(breakpoints);
* console.log(matches.lg);
* ```
*/
export declare function createBreakpoints<T extends Breakpoints>(breakpoints: T, options?: BreakpointOptions<T>): Matches<T>;
* Creates a multi-breakpoint monitor to make responsive components easily.
*
* @param breakpoints Map of breakpoint names and their widths
* @param options Options to customize watch, fallback, responsive mode.
* @returns map of currently matching breakpoints.
*
* @example
* ```ts
* const breakpoints = {
sm: "640px",
lg: "1024px",
xl: "1280px",
};
* const matches = createBreakpoints(breakpoints);
* console.log(matches.lg);
* ```
*/
declare function createBreakpoints<T extends Breakpoints>(breakpoints: T, options?: BreakpointOptions<T>): Matches<T>;
/**
* Creates a sorted copy of the Breakpoints Object
* If you want to use the result of `createBreakpoints()` with string coercion:
* ```ts
* createBreakpoints(sortBreakpoints({ tablet: "980px", mobile: "640px" }))
* ```
*/
export declare function sortBreakpoints(breakpoints: Breakpoints): Breakpoints;
* Creates a sorted copy of the Breakpoints Object
* If you want to use the result of `createBreakpoints()` with string coercion:
* ```ts
* createBreakpoints(sortBreakpoints({ tablet: "980px", mobile: "640px" }))
* ```
*/
declare function sortBreakpoints(breakpoints: Breakpoints): Breakpoints;
//#endregion
export { BreakpointOptions, Breakpoints, Matches, createBreakpoints, createMediaQuery, createPrefersDark, makeMediaQueryListener, sortBreakpoints, usePrefersDark };

@@ -1,134 +0,133 @@

import {} from "solid-js";
/* @ts-self-types="./index.d.ts" */
import "solid-js";
import { isServer } from "@solidjs/web";
import { makeEventListener } from "@solid-primitives/event-listener";
import { entries, noop, createHydratableSignal } from "@solid-primitives/utils";
import { createHydratableSignal, entries, noop } from "@solid-primitives/utils";
import { createHydratableStaticStore } from "@solid-primitives/static-store";
import { createHydratableSingletonRoot } from "@solid-primitives/rootless";
//#region src/index.ts
/**
* attaches a MediaQuery listener to window, listeneing to changes to provided query
* @param query Media query to listen for
* @param callback function called every time the media match changes
* @returns function removing the listener
* @example
* const clear = makeMediaQueryListener("(max-width: 767px)", e => {
* console.log(e.matches)
* });
* // remove listeners (will happen also on cleanup)
* clear()
*/
export function makeMediaQueryListener(query, callback) {
if (isServer) {
return noop;
}
const mql = typeof query === "string" ? window.matchMedia(query) : query;
return makeEventListener(mql, "change", callback);
* attaches a MediaQuery listener to window, listeneing to changes to provided query
* @param query Media query to listen for
* @param callback function called every time the media match changes
* @returns function removing the listener
* @example
* const clear = makeMediaQueryListener("(max-width: 767px)", e => {
* console.log(e.matches)
* });
* // remove listeners (will happen also on cleanup)
* clear()
*/
function makeMediaQueryListener(query, callback) {
if (isServer) return noop;
return makeEventListener(typeof query === "string" ? window.matchMedia(query) : query, "change", callback);
}
/**
* Creates a very simple and straightforward media query monitor.
*
* @param query Media query to listen for
* @param fallbackState Server fallback state *(Defaults to `false`)*
* @returns Boolean value if media query is met or not
*
* @example
* ```ts
* const isSmall = createMediaQuery("(max-width: 767px)");
* console.log(isSmall());
* ```
*/
export function createMediaQuery(query, serverFallback = false) {
if (isServer) {
return () => serverFallback;
}
const mql = window.matchMedia(query);
const [state, setState] = createHydratableSignal(serverFallback, () => mql.matches);
const update = () => setState(mql.matches);
makeEventListener(mql, "change", update);
return state;
* Creates a very simple and straightforward media query monitor.
*
* @param query Media query to listen for
* @param fallbackState Server fallback state *(Defaults to `false`)*
* @returns Boolean value if media query is met or not
*
* @example
* ```ts
* const isSmall = createMediaQuery("(max-width: 767px)");
* console.log(isSmall());
* ```
*/
function createMediaQuery(query, serverFallback = false) {
if (isServer) return () => serverFallback;
const mql = window.matchMedia(query);
const [state, setState] = createHydratableSignal(serverFallback, () => mql.matches);
const update = () => setState(mql.matches);
makeEventListener(mql, "change", update);
return state;
}
/**
* Provides a signal indicating if the user has requested dark color theme. The setting is being watched with a [Media Query](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme).
*
* @param serverFallback value that should be returned on the server — defaults to `false`
*
* @returns a boolean signal
* @example
* const prefersDark = usePrefersDark();
* createEffect(() => {
* prefersDark() // => boolean
* });
*/
export function createPrefersDark(serverFallback) {
return createMediaQuery("(prefers-color-scheme: dark)", serverFallback);
* Provides a signal indicating if the user has requested dark color theme. The setting is being watched with a [Media Query](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme).
*
* @param serverFallback value that should be returned on the server — defaults to `false`
*
* @returns a boolean signal
* @example
* const prefersDark = usePrefersDark();
* createEffect(() => {
* prefersDark() // => boolean
* });
*/
function createPrefersDark(serverFallback) {
return createMediaQuery("(prefers-color-scheme: dark)", serverFallback);
}
/**
* Provides a signal indicating if the user has requested dark color theme. The setting is being watched with a [Media Query](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme).
*
* This is a [singleton root primitive](https://github.com/solidjs-community/solid-primitives/tree/main/packages/rootless#createSingletonRoot) except if during hydration.
*
* @returns a boolean signal
* @example
* const prefersDark = usePrefersDark();
* createEffect(() => {
* prefersDark() // => boolean
* });
*/
export const usePrefersDark = /*#__PURE__*/ createHydratableSingletonRoot(createPrefersDark.bind(void 0, false));
* Provides a signal indicating if the user has requested dark color theme. The setting is being watched with a [Media Query](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme).
*
* This is a [singleton root primitive](https://github.com/solidjs-community/solid-primitives/tree/main/packages/rootless#createSingletonRoot) except if during hydration.
*
* @returns a boolean signal
* @example
* const prefersDark = usePrefersDark();
* createEffect(() => {
* prefersDark() // => boolean
* });
*/
const usePrefersDark = /*#__PURE__*/ createHydratableSingletonRoot(createPrefersDark.bind(void 0, false));
const getEmptyMatchesFromBreakpoints = (breakpoints) => entries(breakpoints).reduce((matches, [key]) => {
matches[key] = false;
return matches;
matches[key] = false;
return matches;
}, {});
/**
* Creates a multi-breakpoint monitor to make responsive components easily.
*
* @param breakpoints Map of breakpoint names and their widths
* @param options Options to customize watch, fallback, responsive mode.
* @returns map of currently matching breakpoints.
*
* @example
* ```ts
* const breakpoints = {
sm: "640px",
lg: "1024px",
xl: "1280px",
};
* const matches = createBreakpoints(breakpoints);
* console.log(matches.lg);
* ```
*/
export function createBreakpoints(breakpoints, options = {}) {
const fallback = Object.defineProperty(options.fallbackState ?? getEmptyMatchesFromBreakpoints(breakpoints), "key", { enumerable: false, get: () => Object.keys(breakpoints).pop() });
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (isServer || !window.matchMedia)
return fallback;
const { mediaFeature = "min-width", watchChange = true } = options;
const [matches, setMatches] = createHydratableStaticStore(fallback, () => {
const matches = {};
entries(breakpoints).forEach(([token, width]) => {
const mql = window.matchMedia(`(${mediaFeature}: ${width})`);
matches[token] = mql.matches;
if (watchChange)
makeEventListener(mql, "change", (e) => setMatches(token, e.matches));
});
return matches;
});
return Object.defineProperty(matches, "key", {
enumerable: false,
get: () => Object.keys(matches).findLast(token => matches[token]),
});
* Creates a multi-breakpoint monitor to make responsive components easily.
*
* @param breakpoints Map of breakpoint names and their widths
* @param options Options to customize watch, fallback, responsive mode.
* @returns map of currently matching breakpoints.
*
* @example
* ```ts
* const breakpoints = {
sm: "640px",
lg: "1024px",
xl: "1280px",
};
* const matches = createBreakpoints(breakpoints);
* console.log(matches.lg);
* ```
*/
function createBreakpoints(breakpoints, options = {}) {
const fallback = Object.defineProperty(options.fallbackState ?? getEmptyMatchesFromBreakpoints(breakpoints), "key", {
enumerable: false,
get: () => Object.keys(breakpoints).pop()
});
if (isServer || !window.matchMedia) return fallback;
const { mediaFeature = "min-width", watchChange = true } = options;
const [matches, setMatches] = createHydratableStaticStore(fallback, () => {
const matches = {};
entries(breakpoints).forEach(([token, width]) => {
const mql = window.matchMedia(`(${mediaFeature}: ${width})`);
matches[token] = mql.matches;
if (watchChange) makeEventListener(mql, "change", (e) => setMatches(token, e.matches));
});
return matches;
});
return Object.defineProperty(matches, "key", {
enumerable: false,
get: () => Object.keys(matches).findLast((token) => matches[token])
});
}
/**
* Creates a sorted copy of the Breakpoints Object
* If you want to use the result of `createBreakpoints()` with string coercion:
* ```ts
* createBreakpoints(sortBreakpoints({ tablet: "980px", mobile: "640px" }))
* ```
*/
export function sortBreakpoints(breakpoints) {
const sorted = entries(breakpoints);
sorted.sort((x, y) => parseInt(x[1], 10) - parseInt(y[1], 10));
return sorted.reduce((obj, [key, value]) => {
obj[key] = value;
return obj;
}, {});
* Creates a sorted copy of the Breakpoints Object
* If you want to use the result of `createBreakpoints()` with string coercion:
* ```ts
* createBreakpoints(sortBreakpoints({ tablet: "980px", mobile: "640px" }))
* ```
*/
function sortBreakpoints(breakpoints) {
const sorted = entries(breakpoints);
sorted.sort((x, y) => parseInt(x[1], 10) - parseInt(y[1], 10));
return sorted.reduce((obj, [key, value]) => {
obj[key] = value;
return obj;
}, {});
}
//#endregion
export { createBreakpoints, createMediaQuery, createPrefersDark, makeMediaQueryListener, sortBreakpoints, usePrefersDark };
{
"name": "@solid-primitives/media",
"version": "4.0.0-next.0",
"version": "4.0.0-next.1",
"description": "Primitives for media query and device features",

@@ -31,3 +31,3 @@ "author": "David Di Biase <dave@solidjs.com>",

"category": "Display & Media",
"gzip": 1285
"gzip": 1290
},

@@ -59,20 +59,24 @@ "keywords": [

},
"tsdown": {
"entry": "src/**/*.{ts,tsx}",
"outDir": "dist"
},
"dependencies": {
"@solid-primitives/event-listener": "^3.0.0-next.0",
"@solid-primitives/rootless": "^2.0.0-next.0",
"@solid-primitives/static-store": "^1.0.0-next.0",
"@solid-primitives/utils": "^7.0.0-next.0"
"@solid-primitives/event-listener": "^3.0.0-next.2",
"@solid-primitives/rootless": "^2.0.0-next.1",
"@solid-primitives/static-store": "^1.0.0-next.1",
"@solid-primitives/utils": "^7.0.0-next.2"
},
"peerDependencies": {
"@solidjs/web": "^2.0.0-beta.15",
"solid-js": "^2.0.0-beta.15"
"@solidjs/web": "^2.0.0-beta.20",
"solid-js": "^2.0.0-beta.20"
},
"typesVersions": {},
"devDependencies": {
"@solidjs/web": "2.0.0-beta.15",
"solid-js": "2.0.0-beta.15"
"@solidjs/web": "2.0.0-beta.20",
"solid-js": "2.0.0-beta.20"
},
"scripts": {
"dev": "node --import=@nothing-but/node-resolve-ts --experimental-transform-types ../../scripts/dev.ts",
"build": "node --import=@nothing-but/node-resolve-ts --experimental-transform-types ../../scripts/build.ts",
"build": "pnpm -w build",
"vitest": "vitest -c ../../configs/vitest.config.ts",

@@ -79,0 +83,0 @@ "test": "pnpm run vitest",

@@ -7,3 +7,3 @@ <p>

[![size](https://img.shields.io/badge/size-1.28_kB-blue?style=for-the-badge)](https://bundlephobia.com/package/@solid-primitives/media)
[![size](https://img.shields.io/badge/size-1.29_kB-blue?style=for-the-badge)](https://bundlephobia.com/package/@solid-primitives/media)
[![size](https://img.shields.io/npm/v/@solid-primitives/media?style=for-the-badge)](https://www.npmjs.com/package/@solid-primitives/media)

@@ -10,0 +10,0 @@ [![stage](https://img.shields.io/endpoint?style=for-the-badge&url=https%3A%2F%2Fraw.githubusercontent.com%2Fsolidjs-community%2Fsolid-primitives%2Fmain%2Fassets%2Fbadges%2Fstage-3.json)](https://github.com/solidjs-community/solid-primitives#contribution-process)