Skip to content

Commit

Permalink
Merge branch 'master' into fix-selectcomponent-web
Browse files Browse the repository at this point in the history
  • Loading branch information
hiyuki authored Oct 18, 2024
2 parents ed5a7e0 + 59a1a05 commit 74dce1c
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 51 deletions.
1 change: 1 addition & 0 deletions packages/core/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ Mpx.config = {
ignoreProxyWhiteList: ['id', 'dataset', 'data'],
observeClassInstance: false,
errorHandler: null,
warnHandler: null,
proxyEventHandler: null,
setDataHandler: null,
forceFlushSync: false,
Expand Down
8 changes: 7 additions & 1 deletion packages/utils/src/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ export function warn (msg, location, e) {
} else if (condition instanceof RegExp) {
ignore = condition.test(msg)
}
if (!ignore) return log('warn', msg, location, e)
if (!ignore) {
const warnHandler = global.__mpx?.config.warnHandler
if (isFunction(warnHandler)) {
warnHandler(msg, location, e)
}
return log('warn', msg, location, e)
}
}

export function error (msg, location, e) {
Expand Down
4 changes: 1 addition & 3 deletions packages/webpack-plugin/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1812,7 +1812,6 @@ try {
}

if (isWeb(mpx.mode)) {
const mpxStyleOptions = queryObj.mpxStyleOptions
const firstLoader = loaders[0] ? toPosix(loaders[0].loader) : ''
const isPitcherRequest = firstLoader.includes('node_modules/vue-loader/lib/loaders/pitcher')
let cssLoaderIndex = -1
Expand All @@ -1837,8 +1836,7 @@ try {
}
if (loaderIndex > -1) {
loaders.splice(loaderIndex + 1, 0, {
loader: styleCompilerPath,
options: (mpxStyleOptions && JSON.parse(mpxStyleOptions)) || {}
loader: styleCompilerPath
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export const getCustomEvent = (
const useInnerProps = (
props: Props = {},
additionalProps: AdditionalProps = {},
removeProps: RemoveProps = [],
userRemoveProps: RemoveProps = [],
rawConfig?: UseInnerPropsConfig
) => {
const ref = useRef<InnerRef>({
Expand All @@ -130,6 +130,17 @@ const useInnerProps = (
const propsRef = useRef<Record<string, any>>({})
const eventConfig: { [key: string]: string[] } = {}
const config = rawConfig || { layoutRef: { current: {} }, disableTouch: false, disableTap: false }
const removeProps = [
'children',
'enable-background',
'enable-offset',
'enable-var',
'external-var-context',
'parent-font-size',
'parent-width',
'parent-height',
...userRemoveProps
]

propsRef.current = { ...props, ...additionalProps }

Expand Down
58 changes: 43 additions & 15 deletions packages/webpack-plugin/lib/runtime/components/react/mpx-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@
* ✔ bindreset
*/

import { View, LayoutChangeEvent } from 'react-native'
import { View } from 'react-native'
import { JSX, useRef, forwardRef, ReactNode } from 'react'
import useNodesRef, { HandlerRef } from './useNodesRef'
import useInnerProps, { getCustomEvent } from './getInnerListeners'
import { FormContext } from './context'

import { useTransformStyle, splitProps, splitStyle, useLayout, wrapChildren } from './utils'
interface FormProps {
style?: Record<string, any>;
children: ReactNode;
'enable-offset'?: boolean;
'enable-var'?: boolean
'external-var-context'?: Record<string, any>;
'parent-font-size'?: number;
'parent-width'?: number;
'parent-height'?: number;
bindsubmit?: (evt: {
detail: {
value: any;
Expand All @@ -22,18 +28,32 @@ interface FormProps {
bindreset?: () => void;
}

const _Form = forwardRef<HandlerRef<View, FormProps>, FormProps>((props: FormProps, ref): JSX.Element => {
const { children, style } = props
const layoutRef = useRef({})
const _Form = forwardRef<HandlerRef<View, FormProps>, FormProps>((fromProps: FormProps, ref): JSX.Element => {
const { textProps, innerProps: props = {} } = splitProps(fromProps)
const formValuesMap = useRef(new Map()).current
const {
style,
'enable-var': enableVar,
'external-var-context': externalVarContext,
'parent-font-size': parentFontSize,
'parent-width': parentWidth,
'parent-height': parentHeight
} = props

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

const { textStyle, innerStyle } = splitStyle(normalStyle)

const { nodeRef: formRef } = useNodesRef(props, ref)

const onLayout = (e: LayoutChangeEvent) => {
formRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
})
}
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: formRef })

const submit = () => {
const { bindsubmit } = props
Expand Down Expand Up @@ -63,12 +83,10 @@ const _Form = forwardRef<HandlerRef<View, FormProps>, FormProps>((props: FormPro
}

const innerProps = useInnerProps(props, {
style: { ...innerStyle, ...layoutStyle },
ref: formRef,
style,
onLayout
...layoutProps
}, [
'children',
'style',
'bindsubmit',
'bindreset'
], { layoutRef })
Expand All @@ -78,7 +96,17 @@ const _Form = forwardRef<HandlerRef<View, FormProps>, FormProps>((props: FormPro
{...innerProps}
>
<FormContext.Provider value={{ formValuesMap, submit, reset }}>
{children}
{
wrapChildren(
props,
{
hasVarDec,
varContext: varContextRef.current,
textStyle,
textProps
}
)
}
</FormContext.Provider>
</View>
)
Expand Down
16 changes: 4 additions & 12 deletions packages/webpack-plugin/lib/runtime/components/react/mpx-text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,25 +65,17 @@ const _Text = forwardRef<HandlerRef<Text, _TextProps>, _TextProps>((props, ref):
const { nodeRef } = useNodesRef<Text, _TextProps>(props, ref)

const innerProps = useInnerProps(props, {
ref: nodeRef
ref: nodeRef,
style: normalStyle,
selectable: !!selectable || !!userSelect
}, [
'style',
'children',
'selectable',
'user-select',
'enable-var',
'external-var-context',
'parent-font-size',
'parent-width',
'parent-height'
'user-select'
], {
layoutRef
})

return (
<Text
style={normalStyle}
selectable={!!selectable || !!userSelect}
{...innerProps}
>
{
Expand Down
15 changes: 3 additions & 12 deletions packages/webpack-plugin/lib/runtime/components/react/mpx-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ function wrapImage (imageStyle?: ExtendedViewStyle) {
}
}

return <View key='viewBgImg' {...needLayout ? { onLayout } : null} style={{ ...StyleSheet.absoluteFillObject, width: '100%', height: '100%', overflow: 'hidden' }}>
return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...StyleSheet.absoluteFillObject, width: '100%', height: '100%', overflow: 'hidden' }}>
{show && <Image {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} />}
</View>
}
Expand Down Expand Up @@ -539,33 +539,24 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((props, ref):

const innerProps = useInnerProps(props, {
ref: nodeRef,
style: innerStyle,
...needLayout ? { onLayout } : null,
...(hoverStyle && {
bindtouchstart: onTouchStart,
bindtouchend: onTouchEnd
})
}, [
'style',
'children',
'hover-start-time',
'hover-stay-time',
'hover-style',
'hover-class',
'enable-offset',
'enable-background-image',
'enable-var',
'external-var-context',
'parent-font-size',
'parent-width',
'parent-height'
'hover-class'
], {
layoutRef
})

return (
<View
{...innerProps}
style={innerStyle}
>
{
wrapChildren(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useRef, ReactNode, ReactElement, FunctionComponent, isValidElement, useContext, useState } from 'react'
import { Dimensions, StyleSheet } from 'react-native'
import { useEffect, useRef, ReactNode, ReactElement, FunctionComponent, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement } from 'react'
import { Dimensions, StyleSheet, LayoutChangeEvent, TextStyle } from 'react-native'
import { isObject, hasOwn, diffAndCloneA, error, warn } from '@mpxjs/utils'
import { VarContext } from './context'
import { ExpressionParser, parseFunc, ReplaceSource } from './parser'
Expand All @@ -10,6 +10,9 @@ export const URL_REGEX = /^\s*url\(["']?(.*?)["']?\)\s*$/
export const BACKGROUND_REGEX = /^background(Image|Size|Repeat|Position)$/
export const TEXT_PROPS_REGEX = /ellipsizeMode|numberOfLines/
export const DEFAULT_FONT_SIZE = 16
export const DEFAULT_UNLAY_STYLE = {
opacity: 0
}

export const throwReactWarning = (message: string) => {
setTimeout(() => {
Expand Down Expand Up @@ -426,3 +429,65 @@ export function splitProps<T extends Record<string, any>> (props: T) {
}
})
}

interface LayoutConfig {
props: Record<string, any>
hasSelfPercent: boolean
setWidth: Dispatch<SetStateAction<number>>
setHeight: Dispatch<SetStateAction<number>>
onLayout?: (event?: LayoutChangeEvent) => void
nodeRef: React.RefObject<any>
}
export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout, nodeRef }:LayoutConfig) => {
const layoutRef = useRef({})
const hasLayoutRef = useRef(false)
const layoutStyle: Record<string, any> = hasLayoutRef.current ? {} : DEFAULT_UNLAY_STYLE
const layoutProps: Record<string, any> = {}
const enableOffset = props['enable-offset']
if (hasSelfPercent || onLayout || enableOffset) {
layoutProps.onLayout = (e: LayoutChangeEvent) => {
hasLayoutRef.current = true
if (hasSelfPercent) {
const { width, height } = e?.nativeEvent?.layout || {}
setWidth(width || 0)
setHeight(height || 0)
}
if (enableOffset) {
nodeRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
})
}
onLayout && onLayout(e)
props.onLayout && props.onLayout(e)
}
}
return {
layoutRef,
layoutStyle,
layoutProps
}
}

export interface WrapChildrenConfig {
hasVarDec: boolean
varContext?: Record<string, any>
textStyle?: TextStyle
textProps?: Record<string, any>
}

export function wrapChildren (props: Record<string, any> = {}, { hasVarDec, varContext, textStyle, textProps }: WrapChildrenConfig) {
let { children } = props
if (textStyle || textProps) {
children = Children.map(children, (child) => {
if (isText(child)) {
const style = { ...textStyle, ...child.props.style }
return cloneElement(child, { ...textProps, style })
}
return child
})
}
if (hasVarDec && varContext) {
children = <VarContext.Provider value={varContext} key='varContextWrap'>{children}</VarContext.Provider>
}
return children
}
7 changes: 2 additions & 5 deletions packages/webpack-plugin/lib/web/processStyles.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ module.exports = function (styles, options, callback) {
attrs (style) {
const attrs = Object.assign({}, style.attrs)
if (options.autoScope) attrs.scoped = true
attrs.mpxStyleOptions = JSON.stringify({
// scoped: !!options.autoScope,
// query中包含module字符串会被新版vue-cli中的默认rules当做css-module处理
mid: options.moduleId
})
// query中包含module字符串会被新版vue-cli中的默认rules当做css-module处理
attrs.mid = options.moduleId
return attrs
}
})
Expand Down

0 comments on commit 74dce1c

Please sign in to comment.