feat: 小程序菜单按钮安全区域适配工具

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-24 18:39:28 +08:00
parent 6e5a379bef
commit fc14051073
@@ -0,0 +1,62 @@
import { computed, ref } from 'vue'
export const useMenuButtonSafeArea = ({ extraRightRpx = 20, extraTopPx = 8 } = {}) => {
const windowWidth = ref(uni.getStorageSync('windowWidth') || 375)
const safeAreaTop = ref(uni.getStorageSync('safeAreaTop') || 20)
const menuButton = ref(uni.getStorageSync('menuButtonRect') || null)
const readSafeArea = () => {
try {
const windowInfo = uni.getWindowInfo ? uni.getWindowInfo() : uni.getSystemInfoSync()
windowWidth.value = windowInfo.windowWidth || windowWidth.value
safeAreaTop.value = windowInfo.safeAreaInsets?.top || windowInfo.statusBarHeight || safeAreaTop.value
if (uni.getMenuButtonBoundingClientRect) {
menuButton.value = uni.getMenuButtonBoundingClientRect()
}
} catch (error) {
menuButton.value = uni.getStorageSync('menuButtonRect') || menuButton.value
}
}
readSafeArea()
const pxToRpx = (px) => Math.ceil((Number(px) || 0) * 750 / (windowWidth.value || 375))
const capsuleRightReserveRpx = computed(() => {
const rect = menuButton.value
if (!rect?.left) return 32
return pxToRpx((windowWidth.value - rect.left) + extraTopPx) + extraRightRpx
})
const capsuleTopReservePx = computed(() => {
const rect = menuButton.value
if (!rect?.bottom) return safeAreaTop.value + extraTopPx
return Math.max(safeAreaTop.value + extraTopPx, rect.bottom + extraTopPx)
})
const navStyle = computed(() => ({
paddingTop: `${capsuleTopReservePx.value}px`,
paddingRight: `${capsuleRightReserveRpx.value}rpx`
}))
const topbarStyle = computed(() => ({
paddingRight: `${capsuleRightReserveRpx.value}rpx`
}))
const floatingTopStyle = computed(() => ({
paddingTop: `${capsuleTopReservePx.value}px`,
paddingRight: `${capsuleRightReserveRpx.value}rpx`
}))
return {
safeAreaTop,
capsuleRightReserveRpx,
capsuleTopReservePx,
navStyle,
topbarStyle,
floatingTopStyle,
readSafeArea
}
}
export default useMenuButtonSafeArea