Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(theme-default): optimizing css variable acquisition #1322

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 15 additions & 16 deletions ecosystem/theme-default/src/client/components/Navbar.vue
Expand Up @@ -3,8 +3,12 @@ import NavbarBrand from '@theme/NavbarBrand.vue'
import NavbarItems from '@theme/NavbarItems.vue'
import ToggleColorModeButton from '@theme/ToggleColorModeButton.vue'
import ToggleSidebarButton from '@theme/ToggleSidebarButton.vue'
import { computed, onMounted, ref } from 'vue'
import { useThemeLocaleData } from '../composables/index.js'
import { computed, ref } from 'vue'
import {
DeviceType,
useThemeLocaleData,
useUpdateDeviceStatus,
} from '../composables/index.js'

defineEmits(['toggle-sidebar'])

Expand All @@ -23,16 +27,14 @@ const linksWrapperStyle = computed(() => {
}
})

// avoid overlapping of long title and long navbar links
onMounted(() => {
// TODO: migrate to css var
// refer to _variables.scss
const MOBILE_DESKTOP_BREAKPOINT = 719
const navbarHorizontalPadding =
getCssValue(navbar.value, 'paddingLeft') +
getCssValue(navbar.value, 'paddingRight')
const handleLinksWrapWidth = (): void => {
if (window.innerWidth < MOBILE_DESKTOP_BREAKPOINT) {
useUpdateDeviceStatus(
DeviceType.MOBILE,
(mobileDesktopBreakpoint: number): void => {
// avoid overlapping of long title and long navbar links
const navbarHorizontalPadding =
getCssValue(navbar.value, 'paddingLeft') +
getCssValue(navbar.value, 'paddingRight')
if (window.innerWidth < mobileDesktopBreakpoint) {
linksWrapperMaxWidth.value = 0
} else {
linksWrapperMaxWidth.value =
Expand All @@ -41,10 +43,7 @@ onMounted(() => {
(navbarBrand.value?.offsetWidth || 0)
}
}
handleLinksWrapWidth()
window.addEventListener('resize', handleLinksWrapWidth, false)
window.addEventListener('orientationchange', handleLinksWrapWidth, false)
})
)

function getCssValue(el: HTMLElement | null, property: string): number {
// NOTE: Known bug, will return 'auto' if style value is 'auto'
Expand Down
27 changes: 13 additions & 14 deletions ecosystem/theme-default/src/client/components/NavbarItems.vue
Expand Up @@ -3,15 +3,20 @@ import AutoLink from '@theme/AutoLink.vue'
import NavbarDropdown from '@theme/NavbarDropdown.vue'
import { useRouteLocale, useSiteLocaleData } from '@vuepress/client'
import { isLinkHttp, isString } from '@vuepress/shared'
import { computed, onMounted, ref } from 'vue'
import { computed, ref } from 'vue'
import type { ComputedRef } from 'vue'
import { useRouter } from 'vue-router'
import type {
NavbarGroup,
NavbarItem,
ResolvedNavbarItem,
} from '../../shared/index.js'
import { useNavLink, useThemeLocaleData } from '../composables/index.js'
import {
DeviceType,
useNavLink,
useThemeLocaleData,
useUpdateDeviceStatus,
} from '../composables/index.js'
import { resolveRepoType } from '../utils/index.js'

/**
Expand Down Expand Up @@ -152,23 +157,17 @@ const navbarLinks = computed(() => [
...navbarRepo.value,
])

// avoid overlapping of long title and long navbar links
onMounted(() => {
// TODO: migrate to css var
// refer to _variables.scss
const MOBILE_DESKTOP_BREAKPOINT = 719

const handleMobile = (): void => {
if (window.innerWidth < MOBILE_DESKTOP_BREAKPOINT) {
useUpdateDeviceStatus(
DeviceType.MOBILE,
(mobileDesktopBreakpoint: number): void => {
// avoid overlapping of long title and long navbar links
if (window.innerWidth < mobileDesktopBreakpoint) {
isMobile.value = true
} else {
isMobile.value = false
}
}
handleMobile()
window.addEventListener('resize', handleMobile, false)
window.addEventListener('orientationchange', handleMobile, false)
})
)
</script>

<template>
Expand Down
1 change: 1 addition & 0 deletions ecosystem/theme-default/src/client/composables/index.ts
Expand Up @@ -4,3 +4,4 @@ export * from './useResolveRouteWithRedirect.js'
export * from './useScrollPromise.js'
export * from './useSidebarItems.js'
export * from './useThemeData.js'
export * from './useUpdateDeviceStatus.js'
@@ -0,0 +1,30 @@
import { onMounted } from 'vue'
import cssVars from '../styles/_variables.module.scss?module'

export enum DeviceType {
MOBILE = 'mobile',
}

const DeviceTypeMap = {
[DeviceType.MOBILE]: Number.parseInt(cssVars.mobile?.replace('px', ''), 10),
}

/**
* add listener to detect screen though device type
*/
export const useUpdateDeviceStatus = (
deviceType: DeviceType,
callback: (width: number) => void
): void => {
const width = DeviceTypeMap[deviceType]
if (!Number.isInteger(width)) {
if (__VUEPRESS_DEV__) throw new Error('device width must be a integer')
return
}

onMounted(() => {
callback(width)
window.addEventListener('resize', () => callback(width), false)
window.addEventListener('orientationchange', () => callback(width), false)
})
}
5 changes: 5 additions & 0 deletions ecosystem/theme-default/src/client/shim.d.ts
Expand Up @@ -3,3 +3,8 @@ declare module '*.vue' {
const comp: ComponentOptions
export default comp
}

declare module '*.module.scss?module' {
const cssVars: Record<string, string>
export default cssVars
}
@@ -0,0 +1,5 @@
@import '_variables';

:export {
mobile: $MQMobile;
}