npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vue-screen-utils

v1.0.0-beta.13

Published

A dependency-free collection of screen utility functions in Vue 3.

Downloads

491,857

Readme

vue-screen-utils

A dependency-free collection of screen utility functions in Vue 3, written completely in TypeScript.

  • Use Screens: Use function for mapping screen sizes to media query strings, arrays and custom values
  • Screens Plugin: Same useScreens goodness but applied application-wide in a Vue plugin.
  • Use Media Query: Use function for evaluating simple media query strings.
  • Use Resize Observer: Use function for evaluating changes made to an ref element's content rect.
  • Use Dark Mode: Use function for observing dark mode using manual, class or system preference strategies.

Install package

npm install vue-screen-utils

Use Screens

Step 1. Import and call useScreens

Import and call the useScreens function within a parent component, passing a config object that maps custom screen size keys to media query values.

<!--ParentComponent.vue-->
<script setup>
  import { useScreens } from 'vue-screen-utils';

  useScreens(
    // Order from smallest to largest
    {
      xs: '0px', // (min-width: 0px)
      sm: '640px',
      md: '768px',
      lg: '1024px',
      xl: '1280px',
    }
    // {
    //   injectKey: $sq, (Optional custom inject key)
    // }
  );
</script>

The useScreens function accepts a config object with screen size keys mapped to query values. A simple pixel value of '640px' will get mapped to 'min-width: 640px'. It is recommended to map a mobile-first key with a '0px' value followed by larger sizes.

The query value may be in a variety of formats.

useScreens(['0px', '100px', '200px']); // Raw strings
useScreens({ xs: '0px', sm: '100px', md: '200px' }); // Object with string values
useScreens({ xs: { min: '0px' }, sm: { min: '100px' }, md: { min: '100px' } }); // Object with object values
useScreens({ xs: [{ min: '0px' }, { max: '100px' }] }); // Object with object array (multiple values)

The useScreens function will return an object with a collection of utility properties and functions. This object will also get injected into the parent's child components as $screens (or custom injectKey).

See notes about cleanup.

Step 2. Inject the $screens object into nested components.

<!--ChildComponent.vue-->
<script setup>
  import { inject } from 'vue';
  // Desctructure utilities needed
  const { matches, list, mapList, current, mapCurrent } = inject('$screens');
</script>

Matches Object

The value of matches in the example above is a reactive object of size keys mapped to the match status of their respective media query.

// Viewport is 800px wide
console.log(matches.value); // { xs: true, sm: true, md: true, lg: false, xl: false }

Current Screen

The current computed property returns the current max screen size key.

console.log(current.value); // 'md'

The mapCurrent() function returns a computed value mapped to the current key.

const current = mapCurrent({ xs: 0, sm: 1, md: 2, lg: 3, xl: 4 });
console.log(current.value); // 2

Pass an optional default value that gets returned when no screen sizes are matched.

const current = mapCurrent({ lg: 3 }, 0);
console.log(current.value); // 0

List Matching Screens

The list computed property returns a list of media-matched screen size keys.

console.log(list.value); // ['xs', 'sm', 'md']

The mapList() function returns a computed property list of custom values mapped to the current matched size keys.

const value = mapList({ xs: 0, sm: 1, md: 2, lg: 3, xl: 4 });
console.log(value.value); // [0, 1, 2]

Cleanup

Event cleanup happens automatically when the parent component is unmounted, but can be manually called if needed.

// <!--ParentComponent.vue-->
const { cleanup } = useScreens({...});
cleanup();

Screens Plugin

The screens plugin is exactly like the useScreens method above, but allows for a screen configuration to be used application-wide. Also, a global property will be created for easy access to $screens within templates.

Step 1. Import the plugin.

// main.js
import { screens } from 'vue-screen-utils';

// Use plugin with optional config
app.use(screens, {
  mobile: '0px',
  tablet: '640px',
  laptop: '1024px',
  desktop: '1280px',
});

Step 2. Repeat step 2 from the Use Screens method above.

Step 3. Quick reference from component templates

<template>
  <GridComponent :columns="$screens.mapCurrent({ tablet: 2 }, 1)" />
</template>

Use Media Query

Import and use the useMediaQuery function to evaluate simple media query strings. The function returns a matches computed property with the media query match status and an optional cleanup() function.

If you wish to receive a callback of the raw media query event, provide the callback function as the second argument.

Event cleanup happens automatically when the component is unmounted, but can be manually called via the cleanup() function.

<template>
  <div>
    <p class="high-dpi"><strong>High-DPI</strong>: {{ matches }}</p>
    <button @click="cleanup">Cleanup</button>
  </div>
</template>
<script setup>
  import { useMediaQuery } from 'vue-screen-utils';

  const { matches, cleanup } = useMediaQuery(`@media only screen and (-moz-min-device-pixel-ratio: 2),
  only screen and (-o-min-device-pixel-ratio: 2/1),
  only screen and (-webkit-min-device-pixel-ratio: 2),
  only screen and (min-device-pixel-ratio: 2)`);
</script>

Use Resize Observer

Import and use the useResizeObserver function to evaluate changes made to an ref element's content rect. The function returns a reactive content rect object. It also returns an optional cleanup() function.

If you wish to receive a callback of the raw resize observer event, provide the callback function as the second argument.

The backing event is cleaned up when the component is unmounted, but cleanup() can be called manually.

<template>
  <div>
    <!-- Resizable text area element -->
    <textarea ref="textRef">{{ rect }}</textarea>
    <!-- Component refs also supported -->
    <!-- <MyComponent ref="componentRef" /> -->
    <button @click="cleanup">Cleanup</button>
  </div>
</template>
<script setup>
  import { ref } from 'vue';
  import { useResizeObserver } from 'vue-screen-utils';

  const textRef = ref(null);
  const { rect, cleanup } = useResizeObserver(textRef);
</script>

Use Dark Mode

Import and use the useDarkMode function to evaluate dark mode using a variety of strategies, based on the argument provided.

declare function useDarkMode(config: Ref<boolean | 'system' | Partial<DarkModeClassConfig>>): {
  isDark: Ref<boolean>;
  displayMode: ComputedRef<'dark' | 'light'>;
  cleanup: () => void;
};

Manual Strategy

Pass a boolean value for isDark to set the dark mode manually.

<template>
  <div>Dark Mode Active: {{ isDark ? 'Yes' : 'No' }}</div>
</template>

<script setup>
  import { useDarkMode } from 'vue-screen-utils';

  const configRef = ref(false);
  const isDark = useDarkMode(configRef);
</script>

System Preference Strategy

Pass the system string to use the Window.matchMedia() API to read the user's system preference. This setting is continually watched to detect future changes made by the user.

For example, to view the effect on the Mac, you can navigate to System Preferences › General and switch the Appearance setting between Light, Dark and Auto.

<template>
  <div>Dark Mode Active: {{ isDark ? 'Yes' : 'No' }}</div>
</template>

<script setup>
  import { useDarkMode } from 'vue-screen-utils';

  const configRef = ref('system');
  const isDark = useDarkMode(configRef);
</script>

Class Strategy

To use the class strategy, pass an object with the element selector and darkClass to check against.

interface DarkModeClassConfig {
  selector: string;
  darkClass: string;
}

Any class updates made on the element are watched with a MutationObserver to detect future changes made by the user.

<template>
  <div>Dark Mode Active: {{ isDark ? 'Yes' : 'No' }}</div>
</template>

<script setup>
  import { useDarkMode } from 'vue-screen-utils';

  const configRef = ref({ selector: ':root', darkClass: 'dark' });
  const isDark = useDarkMode(configRef);
</script>

Because :root and dark are the default selector and darkClass, respectively, a simple object could be passed to achieve the same effect.

<script setup>
  import { useDarkMode } from 'vue-screen-utils';

  const configRef = ref({});
  const isDark = useDarkMode(configRef);
</script>