Skip to content

Commit

Permalink
Merge pull request #1645 from didi/feat-rn-component-common-style
Browse files Browse the repository at this point in the history
Feat rn component common style
  • Loading branch information
hiyuki authored Oct 22, 2024
2 parents 578e7e1 + bb31cec commit b4ca1c4
Show file tree
Hide file tree
Showing 25 changed files with 943 additions and 684 deletions.
122 changes: 59 additions & 63 deletions packages/webpack-plugin/lib/runtime/components/react/mpx-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,20 @@
* ✔ bindtap
*/
import { useEffect, useRef, useState, ReactNode, forwardRef, useContext, JSX } from 'react'

import {
View,
Text,
StyleSheet,
ViewStyle,
TextStyle,
Animated,
Easing,
NativeSyntheticEvent
} from 'react-native'
import { splitStyle, isText, every, splitProps, throwReactWarning } from './utils'
import { warn } from '@mpxjs/utils'
import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren } from './utils'
import useInnerProps, { getCustomEvent } from './getInnerListeners'
import useNodesRef, { HandlerRef } from './useNodesRef'
import { FormContext } from './context'
import { isEmptyObject } from '@mpxjs/utils'

export type Type = 'default' | 'primary' | 'warn'

Expand All @@ -76,6 +74,11 @@ export interface ButtonProps {
'open-type'?: OpenType
'form-type'?: 'submit' | 'reset'
'enable-offset'?: boolean,
'enable-var'?: boolean
'external-var-context'?: Record<string, any>
'parent-font-size'?: number
'parent-width'?: number
'parent-height'?: number
style?: ViewStyle & TextStyle & Record<string, any>
children: ReactNode
bindgetuserinfo?: (userInfo: any) => void
Expand Down Expand Up @@ -127,18 +130,18 @@ const styles = StyleSheet.create({

const getOpenTypeEvent = (openType: OpenType) => {
if (!global.__mpx?.config?.rnConfig) {
throwReactWarning('[Mpx runtime warn]: Environment not supported')
warn('Environment not supported')
return
}
const eventName = OpenTypeEventsMap.get(openType)
if (!eventName) {
throwReactWarning(`[Mpx runtime warn]: open-type not support ${openType}`)
warn(`open-type not support ${openType}`)
return
}

const event = global.__mpx.config.rnConfig.openTypeHandler?.[eventName]
if (!event) {
throwReactWarning(`[Mpx runtime warn]: Unregistered ${eventName} event`)
warn(`Unregistered ${eventName} event`)
return
}

Expand Down Expand Up @@ -180,7 +183,9 @@ const Loading = ({ alone = false }: { alone: boolean }): JSX.Element => {
return <Animated.Image testID="loading" style={loadingStyle} source={{ uri: LOADING_IMAGE_URI }} />
}

const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((props, ref): JSX.Element => {
const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((buttonProps, ref): JSX.Element => {
const { textProps, innerProps: props = {} } = splitProps(buttonProps)

const {
size = 'default',
type = 'default',
Expand All @@ -192,8 +197,12 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((props, re
'hover-start-time': hoverStartTime = 20,
'hover-stay-time': hoverStayTime = 70,
'open-type': openType,
'enable-offset': enableOffset,
'form-type': formType,
'enable-var': enableVar,
'external-var-context': externalVarContext,
'parent-font-size': parentFontSize,
'parent-width': parentWidth,
'parent-height': parentHeight,
style = {},
children,
bindgetuserinfo,
Expand All @@ -220,22 +229,12 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((props, re
hoverStayTimer: undefined
})

const layoutRef = useRef({})

const [isHover, setIsHover] = useState(false)

const isMiniSize = size === 'mini'

const applyHoverEffect = isHover && hoverClass !== 'none'

const { textStyle, imageStyle, innerStyle } = splitStyle(style)

const { textStyle: hoverTextStyle, imageStyle: hoverImageStyle, innerStyle: hoverInnerStyle } = splitStyle(hoverStyle)

if (imageStyle || hoverImageStyle) {
throwReactWarning('[Mpx runtime warn]: Button does not support background image-related styles!')
}

const [color, hoverColor, plainColor, disabledColor] = TypeColorMap[type]

const normalBackgroundColor = disabled ? disabledColor : applyHoverEffect || loading ? hoverColor : color
Expand Down Expand Up @@ -278,6 +277,36 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((props, re
color: plain ? plainTextColor : normalTextColor
}

const defaultStyle = {
...defaultViewStyle,
...defaultTextStyle
}

const styleObj = {
...defaultStyle,
...style,
...(applyHoverEffect && hoverStyle)
}

const {
hasSelfPercent,
normalStyle,
hasVarDec,
varContextRef,
setWidth,
setHeight
} = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })

const { nodeRef } = useNodesRef(props, ref, { defaultStyle })

const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })

const { textStyle, backgroundStyle, innerStyle } = splitStyle(normalStyle)

if (backgroundStyle) {
warn('Button does not support background image-related styles!')
}

const handleOpenTypeEvent = (evt: NativeSyntheticEvent<TouchEvent>) => {
if (!openType) return
const handleEvent = getOpenTypeEvent(openType)
Expand Down Expand Up @@ -334,75 +363,42 @@ const Button = forwardRef<HandlerRef<View, ButtonProps>, ButtonProps>((props, re
resetFn && resetFn()
}
}

const onTap = (evt: NativeSyntheticEvent<TouchEvent>) => {
if (disabled) return
bindtap && bindtap(getCustomEvent('tap', evt, { layoutRef }, props))
handleOpenTypeEvent(evt)
handleFormTypeFn()
}

function wrapChildren (children: ReactNode, defaultTextStyle: Record<string, any>, textStyle: Record<string, any>) {
if (!children) return children
const hasTextStyle = !isEmptyObject(textStyle)
const { textProps } = splitProps(props)

if (every(children, (child) => isText(child))) {
children = <Text key='buttonTextWrap' style={{ ...defaultTextStyle, ...textStyle }} {...(textProps || {})}>{children}</Text>
} else {
if (hasTextStyle) throwReactWarning('[Mpx runtime warn]: Text style will be ignored unless every child of the Button is Text node!')
}

return children
}

const { nodeRef } = useNodesRef(props, ref, {
defaultStyle: {
...defaultViewStyle,
...defaultTextStyle,
...textStyle
}
})

const onLayout = () => {
nodeRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
})
}

const innerProps = useInnerProps(
props,
{
ref: nodeRef,
style: { ...innerStyle, ...layoutStyle },
...layoutProps,
bindtouchstart: onTouchStart,
bindtouchend: onTouchEnd,
bindtap: onTap,
...(enableOffset ? { onLayout } : {})
bindtap: onTap
},
[
'enable-offset'
],
[],
{
layoutRef,
disableTap: disabled
}
)

return (
<View
{...innerProps}
style={{
...defaultViewStyle,
...innerStyle,
...(applyHoverEffect && hoverInnerStyle)
} as ViewStyle}>
<View {...innerProps}>
{loading && <Loading alone={!children} />}
{
wrapChildren(
children,
defaultTextStyle,
props,
{
...textStyle,
...(applyHoverEffect && hoverTextStyle)
hasVarDec,
varContext: varContextRef.current,
textStyle,
textProps
}
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
/**
* ✔ bindchange
*/
import {
JSX,
useRef,
forwardRef,
ReactNode,
useContext
} from 'react'
import {
View,
NativeSyntheticEvent,
ViewStyle
} from 'react-native'
import { JSX, useRef, forwardRef, ReactNode, useContext } from 'react'
import { View, NativeSyntheticEvent, ViewStyle } from 'react-native'
import { warn } from '@mpxjs/utils'
import { FormContext, FormFieldValue, CheckboxGroupContext, GroupValue } from './context'
import useInnerProps, { getCustomEvent } from './getInnerListeners'
import useNodesRef, { HandlerRef } from './useNodesRef'
import { throwReactWarning } from './utils'
import { useLayout, useTransformStyle, wrapChildren } from './utils'

export interface CheckboxGroupProps {
name: string
style?: ViewStyle & Record<string, any>
'enable-offset'?: boolean
'enable-var'?: boolean
'external-var-context'?: Record<string, any>
'parent-font-size'?: number
'parent-width'?: number
'parent-height'?: number
children: ReactNode
bindchange?: (evt: NativeSyntheticEvent<TouchEvent> | unknown) => void
}
Expand All @@ -32,12 +28,14 @@ const CheckboxGroup = forwardRef<
>((props, ref): JSX.Element => {
const {
style = {},
'enable-offset': enableOffset,
children,
'enable-var': enableVar,
'external-var-context': externalVarContext,
'parent-font-size': parentFontSize,
'parent-width': parentWidth,
'parent-height': parentHeight,
bindchange
} = props

const layoutRef = useRef({})
const formContext = useContext(FormContext)

let formValuesMap: Map<string, FormFieldValue> | undefined
Expand All @@ -50,28 +48,27 @@ const CheckboxGroup = forwardRef<

const defaultStyle = {
flexDirection: 'row',
flexWrap: 'wrap',
...style
flexWrap: 'wrap'
}
const { nodeRef } = useNodesRef(props, ref, {
defaultStyle
})

const onLayout = () => {
nodeRef.current?.measure(
(
x: number,
y: number,
width: number,
height: number,
offsetLeft: number,
offsetTop: number
) => {
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
}
)

const styleObj = {
...defaultStyle,
...style
}

const {
hasSelfPercent,
normalStyle,
hasVarDec,
varContextRef,
setWidth,
setHeight
} = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })

const { nodeRef } = useNodesRef(props, ref, { defaultStyle })

const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })

const getSelectionValue = (): string[] => {
const arr: string[] = []
for (const key in groupValue) {
Expand All @@ -95,7 +92,7 @@ const CheckboxGroup = forwardRef<

if (formValuesMap) {
if (!props.name) {
throwReactWarning('[Mpx runtime warn]: If a form component is used, the name attribute is required.')
warn('If a form component is used, the name attribute is required.')
} else {
formValuesMap.set(props.name, { getValue, resetValue })
}
Expand Down Expand Up @@ -124,10 +121,10 @@ const CheckboxGroup = forwardRef<
props,
{
ref: nodeRef,
style: defaultStyle,
...(enableOffset ? { onLayout } : {})
style: { ...normalStyle, ...layoutStyle },
...layoutProps
},
['enable-offset'],
[],
{
layoutRef
}
Expand All @@ -136,7 +133,15 @@ const CheckboxGroup = forwardRef<
return (
<View {...innerProps}>
<CheckboxGroupContext.Provider value={{ groupValue, notifyChange }}>
{children}
{
wrapChildren(
props,
{
hasVarDec,
varContext: varContextRef.current
}
)
}
</CheckboxGroupContext.Provider>
</View>
)
Expand Down
Loading

0 comments on commit b4ca1c4

Please sign in to comment.