@nrg-ui/ember-media
v0.2.1
Published
An Ember addon for safe media query handling
Downloads
9
Readme
@nrg-ui/ember-media
An Ember addon for safe media query handling.
Compatibility
- Ember.js v5.12 or above
- Embroider or ember-auto-import v2
Installation
ember install @nrg-ui/ember-mediaUsage
Breakpoints
There are 6 breakpoints available, with the following media queries:
| Breakpoint | Media Query |
| ---------- | --------------------------------------------- |
| xsmall | (min-width: 0px) and (max-width: 575px) |
| small | (min-width: 576px) and (max-width: 767px) |
| medium | (min-width: 768px) and (max-width: 991px) |
| large | (min-width: 992px) and (max-width: 1199px) |
| xlarge | (min-width: 1200px) and (max-width: 1399px) |
| xxlarge | (min-width: 1400px) |
There is a corresponding property on the media service for each breakpoint, e.g. isSmall, isMedium, etc.
The queries can be adjusted via the Embroider build config, if needed:
// ember-cli-build.js
module.exports = function (defaults) {
let app = new EmberApp(defaults, {
'@embroider/macros': {
setConfig: {
'@nrg-ui/ember-media': {
breakpoints: {
small: '(min-width: 600px) and (max-width: 799px)',
// other breakpoints...
},
},
},
},
});
return app;
};Accessing Custom Breakpoints
You can add arbitrary custom breakpoints via the Embroider build config:
// ember-cli-build.js
module.exports = function (defaults) {
let app = new EmberApp(defaults, {
'@embroider/macros': {
setConfig: {
'@nrg-ui/ember-media': {
breakpoints: {
short: '(min-height: 0px) and (max-height: 320px)',
},
},
},
},
});
return app;
};Custom breakpoints like short in the example above do not have convenience properties (i.e. there is no media.isShort). However, you can use the media.matches TrackedSet to access custom breakpoints:
export default class MyComponent extends Component {
@service
declare media: MediaService;
get isShortScreen() {
return this.media.matches.has('short');
}
}Events
The media service emits a change event whenever the matched media queries change. You can listen for this event to react to changes in screen size.
export default class MyComponent extends Component {
@service
declare media: MediaService;
constructor(owner: Owner, args: unknown) {
super(owner, args);
this.media.on('change', () => {
console.log('Matched media queries:', Array.from(this.media.matches));
});
}
}Testing
When testing components or services that depend on the media service, you can use the provided test helpers to simulate different screen sizes.
import { setupRenderingTest } from 'ember-qunit';
import { module, test } from 'qunit';
import { setBreakpoint } from '@nrg-ui/ember-media/test-support';
module('Integration | Component | my-component', function (hooks) {
setupRenderingTest(hooks);
test('my test', async function (assert) {
const service = this.owner.lookup('service:media');
await setBreakpoint('small');
// ...
});
});Example
Inject the media service into your component, controller, or route:
import Component from '@glimmer/component';
import { service } from '@ember/service';
import type { Owner } from '@ember/owner';
import type MediaService from '@nrg-ui/ember-media/services/media';
export default class MyComponent extends Component {
@service
declare media: MediaService;
constructor(owner: unknown, args: unknown) {
super(owner, args);
this.media.on('change', this.handleMediaChange);
}
onClick = () => {
if (this.media.isLarge) {
// Do something for large screens
}
};
handleMediaChange = () => {
console.log('Matched media queries:', Array.from(this.media.matches));
};
}Contributing
See the Contributing guide for details.
License
This project is licensed under the MIT License.
