Skip to content

Commit

Permalink
WIP Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
thanksameeelian committed Sep 27, 2023
1 parent 23be829 commit 18ad4af
Showing 1 changed file with 115 additions and 113 deletions.
228 changes: 115 additions & 113 deletions lib/useKResponsiveWindow/index.js
Original file line number Diff line number Diff line change
@@ -1,132 +1,134 @@
import { computed, onBeforeUnmount, onMounted, ref } from '@vue/composition-api';
import { computed, onBeforeUnmount, onMounted, ref, watch } from '@vue/composition-api';
import useKWindowDimensions from '../useKWindowDimensions';
import MediaQuery from './MediaQuery';

/** Global variables */
const { windowWidth, windowHeight } = useKWindowDimensions();

/*
Implementing breakpoint controlled by watchers to work around
optimization issue: https://github.com/vuejs/vue/issues/10344
If that issue ever gets addressed, we should make them computed props.
*/
const windowBreakpoint = ref(null)

const windowIsPortrait = ref(false);
const windowIsLandscape = ref(false);
const windowGutter = ref(16);
const windowIsShort = ref(false);

const windowIsLarge = computed(() => windowBreakpoint.value > 2);
const windowIsMedium = computed(() => windowBreakpoint.value === 2);
const windowIsSmall = computed(() => windowBreakpoint.value < 2);

const usageCount = ref(0);

const orientationQuery = new MediaQuery('screen and (orientation: portrait)', event => {
updateOrientation(event.matches);
});
const heightQuery = new MediaQuery('screen and (max-height: 600px)', event => {
windowIsShort.value = event.matches;
});

/**
* Export window properties
* @returns {Object} Object with window properties
* Initialize window properties
*/
export default function useKResponsiveWindow() {
/** Window properties */
const { windowWidth, windowHeight } = useKWindowDimensions();
const windowBreakpoint = ref(null);
const windowIsPortrait = ref(false);
const windowIsLandscape = ref(false);
const windowGutter = ref(16);
const windowIsShort = ref(false);
const windowIsLarge = computed(() => windowBreakpoint.value > 2);
const windowIsMedium = computed(() => windowBreakpoint.value === 2);
const windowIsSmall = computed(() => windowBreakpoint.value < 2);

const orientationQuery = new MediaQuery('screen and (orientation: portrait)', event => {
updateOrientation(event.matches);
updateGutter();
});
function initProps() {
orientationQuery.eventHandler(orientationQuery.mediaQueryList);
heightQuery.eventHandler(heightQuery.mediaQueryList);
updateBreakPoint(); // ?
};

const heightQuery = new MediaQuery('screen and (max-height: 600px)', event => {
windowIsShort.value = event.matches;
});
initProps();

/**
* Generate width media queries
*/
const widthQueries = (() => {
const SCROLL_BAR = 16;
const queries = [
'(max-width: 480px)',
'(max-width: 600px)',
'(max-width: 840px)',
`(max-width: ${960 - SCROLL_BAR}px)`,
`(max-width: ${1280 - SCROLL_BAR}px)`,
`(max-width: ${1440 - SCROLL_BAR}px)`,
`(max-width: ${1600 - SCROLL_BAR}px)`,
'(min-width: 1601px)',
];

return queries.map(
(query, index) =>
new MediaQuery(`screen and ${query}`, () => {
windowBreakpoint.value = index;
updateGutter();
})
);
})();

/**
* Initialize window properties
*/
const initProps = () => {
orientationQuery.eventHandler(orientationQuery.mediaQueryList);
heightQuery.eventHandler(heightQuery.mediaQueryList);
for (const widthQuery of widthQueries) {
if (widthQuery.mediaQueryList.matches) {
widthQuery.eventHandler(widthQuery.mediaQueryList);
break;
}
}
};
/**
* Start listening to media query changes
*/
function startListening() {
orientationQuery.startListening();
heightQuery.startListening();
updateBreakPoint(); // ?
};

/**
* Start listening to media query changes
*/
const startListening = () => {
orientationQuery.startListening();
heightQuery.startListening();
for (const widthQuery of widthQueries) {
widthQuery.startListening();
}
};
/**
* Stop listening to media query changes
*/
function stopListening() {
orientationQuery.stopListening();
heightQuery.stopListening();
};

/**
* Stop listening to media query changes
*/
const stopListening = () => {
orientationQuery.stopListening();
heightQuery.stopListening();
for (const widthQuery of widthQueries) {
widthQuery.stopListening();
}
};

/**
* Update window gutter
*/
const updateGutter = () => {
if (windowIsSmall.value) {
windowGutter.value = 16;
} else if (smallestWindowDimensionIsLessThan(600)) {
windowGutter.value = 16;
} else {
windowGutter.value = 24;
}
};
function updateBreakPoint() {
const SCROLL_BAR = 16;
const widthBreakpoints = [
480, 600, 840, 960 - SCROLL_BAR, 1280 - SCROLL_BAR, 1440 - SCROLL_BAR, 1600 - SCROLL_BAR,
];

/**
* Check if the smallest window dimension(width or height) is smaller than the specified dimension
* @param {Number} dimension in px
* @returns {Boolean}
*/
const smallestWindowDimensionIsLessThan = dimension => {
return (
windowBreakpoint.value < 4 && Math.min(windowWidth.value, windowHeight.value) < dimension
);
};
// if windowWidth is null (upon initialization), breakpoint = 0
const firstMatchingWidthIndex = windowWidth.value
? widthBreakpoints.findIndex(matchingWidth => windowWidth.value < matchingWidth)
: 0;

// if windowWidth > 1585, breakpoint = 7
const matchingBreakpoint = firstMatchingWidthIndex >= 0
? firstMatchingWidthIndex
: 7;

windowBreakpoint.value = matchingBreakpoint;
updateGutter();
};

watch([windowWidth, windowHeight], updateBreakPoint);

/**
* Update window orientation
* @param {Boolean} portrait
*/
const updateOrientation = portrait => {
windowIsPortrait.value = portrait;
windowIsLandscape.value = !windowIsPortrait.value;
};

function updateGutter() {
if (windowIsSmall.value || smallestWindowDimensionIsLessThan(600)) {
windowGutter.value = 16;
} else {
windowGutter.value = 24;
}
};

/**
* Check if the smallest window dimension(width or height) is smaller than the specified dimension
* @param {Number} dimension in px
* @returns {Boolean}
*/
function smallestWindowDimensionIsLessThan(dimension) {
return (
windowBreakpoint.value < 4 && Math.min(windowWidth.value, windowHeight.value) < dimension
);
};

/**
* Update window orientation
* @param {Boolean} portrait
*/
function updateOrientation(portrait) {
windowIsPortrait.value = portrait;
windowIsLandscape.value = !windowIsPortrait.value;
};

/**
* Export window properties
* @returns {Object} Object with window properties
*/
export default function useKResponsiveWindow() {
onMounted(() => {
initProps();
startListening();
if (usageCount.value === 0) {
// No component is currently using this, so we need to initialize
startListening();
}
usageCount.value++;
});

onBeforeUnmount(() => {
stopListening();
usageCount.value--;
if (usageCount.value === 0) {
// No component is now using this, so we can clean up
stopListening();
}
});

return {
Expand Down

0 comments on commit 18ad4af

Please sign in to comment.