display.mjs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Utilities
  2. import { inject, reactive, shallowRef, toRefs, watchEffect } from 'vue';
  3. import { mergeDeep } from "../util/index.mjs";
  4. import { IN_BROWSER, SUPPORTS_TOUCH } from "../util/globals.mjs"; // Types
  5. export const breakpoints = ['sm', 'md', 'lg', 'xl', 'xxl']; // no xs
  6. export const DisplaySymbol = Symbol.for('vuetify:display');
  7. const defaultDisplayOptions = {
  8. mobileBreakpoint: 'lg',
  9. thresholds: {
  10. xs: 0,
  11. sm: 600,
  12. md: 960,
  13. lg: 1280,
  14. xl: 1920,
  15. xxl: 2560
  16. }
  17. };
  18. const parseDisplayOptions = function () {
  19. let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultDisplayOptions;
  20. return mergeDeep(defaultDisplayOptions, options);
  21. };
  22. function getClientWidth(ssr) {
  23. return IN_BROWSER && !ssr ? window.innerWidth : typeof ssr === 'object' && ssr.clientWidth || 0;
  24. }
  25. function getClientHeight(ssr) {
  26. return IN_BROWSER && !ssr ? window.innerHeight : typeof ssr === 'object' && ssr.clientHeight || 0;
  27. }
  28. function getPlatform(ssr) {
  29. const userAgent = IN_BROWSER && !ssr ? window.navigator.userAgent : 'ssr';
  30. function match(regexp) {
  31. return Boolean(userAgent.match(regexp));
  32. }
  33. const android = match(/android/i);
  34. const ios = match(/iphone|ipad|ipod/i);
  35. const cordova = match(/cordova/i);
  36. const electron = match(/electron/i);
  37. const chrome = match(/chrome/i);
  38. const edge = match(/edge/i);
  39. const firefox = match(/firefox/i);
  40. const opera = match(/opera/i);
  41. const win = match(/win/i);
  42. const mac = match(/mac/i);
  43. const linux = match(/linux/i);
  44. return {
  45. android,
  46. ios,
  47. cordova,
  48. electron,
  49. chrome,
  50. edge,
  51. firefox,
  52. opera,
  53. win,
  54. mac,
  55. linux,
  56. touch: SUPPORTS_TOUCH,
  57. ssr: userAgent === 'ssr'
  58. };
  59. }
  60. export function createDisplay(options, ssr) {
  61. const {
  62. thresholds,
  63. mobileBreakpoint
  64. } = parseDisplayOptions(options);
  65. const height = shallowRef(getClientHeight(ssr));
  66. const platform = shallowRef(getPlatform(ssr));
  67. const state = reactive({});
  68. const width = shallowRef(getClientWidth(ssr));
  69. function updateSize() {
  70. height.value = getClientHeight();
  71. width.value = getClientWidth();
  72. }
  73. function update() {
  74. updateSize();
  75. platform.value = getPlatform();
  76. }
  77. // eslint-disable-next-line max-statements
  78. watchEffect(() => {
  79. const xs = width.value < thresholds.sm;
  80. const sm = width.value < thresholds.md && !xs;
  81. const md = width.value < thresholds.lg && !(sm || xs);
  82. const lg = width.value < thresholds.xl && !(md || sm || xs);
  83. const xl = width.value < thresholds.xxl && !(lg || md || sm || xs);
  84. const xxl = width.value >= thresholds.xxl;
  85. const name = xs ? 'xs' : sm ? 'sm' : md ? 'md' : lg ? 'lg' : xl ? 'xl' : 'xxl';
  86. const breakpointValue = typeof mobileBreakpoint === 'number' ? mobileBreakpoint : thresholds[mobileBreakpoint];
  87. const mobile = width.value < breakpointValue;
  88. state.xs = xs;
  89. state.sm = sm;
  90. state.md = md;
  91. state.lg = lg;
  92. state.xl = xl;
  93. state.xxl = xxl;
  94. state.smAndUp = !xs;
  95. state.mdAndUp = !(xs || sm);
  96. state.lgAndUp = !(xs || sm || md);
  97. state.xlAndUp = !(xs || sm || md || lg);
  98. state.smAndDown = !(md || lg || xl || xxl);
  99. state.mdAndDown = !(lg || xl || xxl);
  100. state.lgAndDown = !(xl || xxl);
  101. state.xlAndDown = !xxl;
  102. state.name = name;
  103. state.height = height.value;
  104. state.width = width.value;
  105. state.mobile = mobile;
  106. state.mobileBreakpoint = mobileBreakpoint;
  107. state.platform = platform.value;
  108. state.thresholds = thresholds;
  109. });
  110. if (IN_BROWSER) {
  111. window.addEventListener('resize', updateSize, {
  112. passive: true
  113. });
  114. }
  115. return {
  116. ...toRefs(state),
  117. update,
  118. ssr: !!ssr
  119. };
  120. }
  121. export function useDisplay() {
  122. const display = inject(DisplaySymbol);
  123. if (!display) throw new Error('Could not find Vuetify display injection');
  124. return display;
  125. }
  126. //# sourceMappingURL=display.mjs.map