@furystack/shades
Version:
A lightweight UI framework for FuryStack with JSX support
52 lines • 2.17 kB
JavaScript
import { defineService } from '@furystack/inject';
import { ObservableValue } from '@furystack/utils';
/**
* Available screen size breakpoint identifiers, ordered from smallest to largest.
*/
export const ScreenSizes = ['xs', 'sm', 'md', 'lg', 'xl'];
export const ScreenService = defineService({
name: '@furystack/shades/ScreenService',
lifetime: 'singleton',
factory: ({ onDispose }) => {
const getOrientation = () => window.matchMedia?.('(orientation:landscape').matches ? 'landscape' : 'portrait';
const breakpoints = {
xl: { minSize: 1920 },
lg: { minSize: 1280 },
md: { minSize: 960 },
sm: { minSize: 600 },
xs: { minSize: 0 },
};
const screenSizeAtLeast = (size) => window.innerWidth >= breakpoints[size].minSize;
const atLeast = {
xs: new ObservableValue(screenSizeAtLeast('xs')),
sm: new ObservableValue(screenSizeAtLeast('sm')),
md: new ObservableValue(screenSizeAtLeast('md')),
lg: new ObservableValue(screenSizeAtLeast('lg')),
xl: new ObservableValue(screenSizeAtLeast('xl')),
};
const orientation = new ObservableValue(getOrientation());
const refreshValues = () => {
orientation.setValue(getOrientation());
for (const size of ScreenSizes) {
atLeast[size].setValue(screenSizeAtLeast(size));
}
};
const onResizeListener = () => {
refreshValues();
};
window.addEventListener('resize', onResizeListener);
refreshValues();
onDispose(() => {
window.removeEventListener('resize', onResizeListener);
// eslint-disable-next-line furystack/prefer-using-wrapper -- Disposal is deferred to the injector's onDispose hook.
orientation[Symbol.dispose]();
Object.values(atLeast).forEach((observable) => observable[Symbol.dispose]());
});
return {
breakpoints,
screenSize: { atLeast },
orientation,
};
},
});
//# sourceMappingURL=screen-service.js.map