wux-weapp
Version:
一套组件化、可复用、易扩展的微信小程序 UI 组件库
115 lines (111 loc) • 3.69 kB
JavaScript
import baseComponent from '../helpers/baseComponent'
import classNames from '../helpers/libs/classNames'
import styleToCssString from '../helpers/libs/styleToCssString'
import safeAreaBehavior from '../helpers/mixins/safeAreaBehavior'
import { getSafeAreaInset } from '../helpers/hooks/useSafeArea'
/**
* css var prefix
*/
const cssVarPattern = /^--/
baseComponent({
behaviors: [safeAreaBehavior],
properties: {
prefixCls: {
type: String,
value: 'wux-safe-area',
},
multiple: {
type: Number,
value: 1,
},
wrapStyle: {
type: [String, Object],
value: '',
},
forceRender: {
type: Boolean,
value: false,
},
supports: {
type: Boolean,
value: false,
},
},
data: {
extStyle: '',
},
computed: {
classes: ['prefixCls, forceRender, supports, safeAreaConfig, isIPhoneX', function(prefixCls, forceRender, supports, safeAreaConfig, isIPhoneX) {
const wrap = classNames(prefixCls, {
[`${prefixCls}--position-bottom`]: (forceRender || isIPhoneX) && safeAreaConfig.bottom,
[`${prefixCls}--position-top`]: (forceRender || isIPhoneX) && !safeAreaConfig.bottom,
[`${prefixCls}--supports`]: (forceRender || isIPhoneX) && supports,
})
return {
wrap,
}
}],
},
observers: {
['safeAreaConfig, safeAreaStyle, isIPhoneX, multiple, wrapStyle, forceRender, supports'](...args) {
const [
safeAreaConfig,
safeAreaStyle,
isIPhoneX,
multiple,
wrapStyle,
forceRender,
supports,
] = args
this.updateStyle({
safeAreaConfig,
safeAreaStyle,
isIPhoneX,
multiple,
wrapStyle,
forceRender,
supports,
})
},
},
methods: {
updateStyle(props) {
const {
safeAreaConfig,
safeAreaStyle,
isIPhoneX,
multiple,
wrapStyle,
forceRender,
supports,
} = props
const position = safeAreaConfig.bottom ? 'bottom' : safeAreaConfig.top ? 'top' : 'none'
const normalStyle = {}
const varStyle = {
['--safe-area-multiple']: multiple,
}
if (
(forceRender || isIPhoneX) &&
!supports &&
['bottom', 'top'].includes(position)
) {
const safeAreaInset = getSafeAreaInset(safeAreaStyle)
const property = position === 'bottom' ? 'paddingBottom' : 'paddingTop'
normalStyle[property] = `calc(${safeAreaInset[position]}PX * ${multiple})`
varStyle[`--safe-area-inset-${position}`] = `${safeAreaInset[position]}PX`
varStyle[property] = `calc(var(--safe-area-inset-${position}) * var(--safe-area-multiple))`
}
const extStyle = styleToCssString(
styleToCssString(normalStyle) + styleToCssString(varStyle, { exclude: cssVarPattern }) + styleToCssString(wrapStyle)
)
if (extStyle !== this.data.extStyle) {
this.setData({
extStyle,
})
}
},
},
attached() {
this.updateStyle(this.data)
},
})