Skip to content

useMatchMedia ​

useMatchMedia tracks if the window matches the given media query strings.

It adds three new behaviors to your Stimulus controller for each media query string you specify:

  • is[Name] triggered when the media query string matches.
  • not[Name] triggered when the media query string doesn't match.
  • [name]Changed triggered when the media query changes.

Reference ​

javascript
useMatchMedia(controller, options)

controller : a Stimulus Controller (usually 'this')

options :

OptionDescription           Default value               
mediaQueriesAn object of media queries where the key is the name of the query and the value is a media query string. Make sure you wrap the whole query with parenthesis.{}
eventPrefixWhether to prefix the emitted event. Can be a boolean or a string.
- true prefix the event with the controller identifier users:is:small
- my-prefix prefix the event with the given string my-prefix:is:small
- false to remove prefix is:small
true
debugWhether to log debug information. See debug for more information on the debugging toolsfalse
dispatchEventWhether to dispatch a event.true

Usage ​

js
import { Controller } from '@hotwired/stimulus'
import { useMatchMedia } from 'stimulus-use'

export default class extends Controller {
  connect() {
    useMatchMedia(this, {
      mediaQueries: {
        small: '(min-width: 320px) and (max-width: 769px)',
        tall: '(min-height: 1000px)',
        light: '(prefers-color-scheme: light)',
        landscape: '(orientation: landscape)',
      }
    })
  }

  smallChanged({ name, media, matches, event }) {
    console.log("small media query changed")
  }

  isSmall({ name, media, matches, event }) {
    console.log("small media query matches")
  }

  notSmall({ name, media, matches, event }) {
    console.log("small media query doesn't match")
  }

  // The same for
  // tall      => tallChanged()      // isTall()      // notTall()
  // light     => lightChanged()     // isLight()     // notLight()
  // landscape => landscapeChanged() // isLandscape() // notLandscape()
}

Events ​

When dispatchEvent is enabled (the default), this module dispatches three events for each media query you define, where [name] is the key of the media query (all prefixed by the controller identifier by default, e.g. users:small:changed):

  • [name]:changed dispatched when the media query changes.
  • is:[name] dispatched when the media query matches.
  • not:[name] dispatched when the media query doesn't match.

Each event carries event.detail = { name, media, matches, event }.

See events for more information on the event prefix behavior.

html
<div
  data-controller="users"
  data-action="users:small:changed@window->users#smallChanged users:is:small@window->users#isSmall users:not:small@window->users#notSmall"
>
  ...
</div>