UNPKG

@empathyco/x-components

Version:
128 lines (125 loc) 4.1 kB
import { defineComponent, ref, computed, watch, onMounted } from 'vue'; import { GlobalEvents } from 'vue-global-events'; import { useXBus } from '../../../composables/use-x-bus.js'; import { throttle } from '../../../utils/throttle.js'; import { deviceXModule } from '../x-module.js'; /** * This component helps to detect or setting a device, that can be used later to create * different layouts optimized for different devices. This detected device is available under * the {@link XComponentAliasAPI.device} property. * * @public */ var _sfc_main = defineComponent({ name: 'DeviceDetector', xModule: deviceXModule.name, components: { GlobalEvents }, props: { /** * Record of the device name, that can be whatever you want `xs`, `mobile`, `big`... And * the max width in pixels for that device. * * @public */ breakpoints: { type: Object, default: () => ({}), }, /** * Forces a device, ignoring the breakpoints prop. * * @public */ force: String, /** * Time in milliseconds to throttle the resize events used to detect the device. * * @public */ throttleMs: { type: Number, default: 100, }, }, setup(props) { const xBus = useXBus(); /** * The width in pixels of the window where the app is being rendered. * * @internal */ const windowWidthPx = ref(null); /** * Stores the window width in {@link DeviceDetector.windowWidthPx}. * * @internal */ const storeWindowWidth = () => { windowWidthPx.value = window.innerWidth; }; /** * Throttled version of {@link DeviceDetector.storeWindowWidth} function. * * @internal */ let throttledStoreWindowWidth = storeWindowWidth; /** * List of each of the entries of the breakpoints sorted from the smallest to the biggest * max width. * * @returns A list of the breakpoints sorted by its max width in ascending order. * * @internal */ const sortedBreakpoints = computed(() => Object.entries(props.breakpoints).sort(([, aWidth], [, bWidth]) => aWidth - bWidth)); /** * The device detected by this component, or the value provided in {@link DeviceDetector.force} * prop. * * @returns The detected device, or the value provided in {@link DeviceDetector.force} * prop. * * @internal */ const detectedDevice = computed(() => { if (props.force) { return props.force; } else if (windowWidthPx.value === null) { return null; } else { return (sortedBreakpoints.value.find(([, width]) => windowWidthPx.value <= width)?.[0] ?? null); } }); watch(detectedDevice, device => { xBus.emit('DeviceProvided', device); }, { immediate: true }); /** * Updates {@link DeviceDetector.throttledStoreWindowWidth} with the throttle time at * {@link DeviceDetector.throttleMs}. * * @param throttleMs - The new duration in milliseconds for the throttle. * * @internal */ watch(() => props.throttleMs, throttleMs => { throttledStoreWindowWidth = throttle(storeWindowWidth, throttleMs); }, { immediate: true }); /** * Initialises the store window width. * * @remarks This is done this way to ensure SSR compatibility. * * @internal */ onMounted(() => { storeWindowWidth(); }); return { throttledStoreWindowWidth, }; }, }); export { _sfc_main as default }; //# sourceMappingURL=device-detector.vue2.js.map