Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs-vitepress/guide/rn/component.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,17 @@
| ----------------------- | ------- | ------------- | ---------------------------------------------------------- |
| user-select | boolean | `false` | 文本是否可选。 |
| is-simple | - | - | RN环境特有标记,设置后将使用简单版本的 text 组件渲染,该组件不包含 css var、calc、ref 等拓展功能,但性能更优,请根据实际情况设置 |
| enable-max-lines | number | - | 跨平台属性,开启后 web/小程序/rn 环境均生效。用于限制文本最大行数, 文本溢出仅支持尾部打点模式|
| enable-android-align-center | boolean | `false` | RN环境特有属性,开启后 Text 组件样式将默认增加 includeFontPadding: false 与 textAlignVertical: 'center' 配置 |
| enable-add-space | boolean | `false` | RN环境特有属性,开启后将在文本尾部补一个空格字符,用于规避小米 HyperOS2 系统下 RN Text 组件出现“吞字”问题 |
| space-font-size | number | - | RN环境特有属性,用于设置空格大小,与 `enable-add-space` 配合使用 |



> [!tip] 注意
> - 未包裹 text 标签的文本,会自动包裹 text 标签。
> - text 组件开启 enable-offset 后,offsetLeft、offsetWidth 获取时机仅为组件首次渲染阶段
> - enable-add-space、enable-android-align-center、space-font-size 仅 text 组件支持,使用 view 组件直接包裹文本的场景不支持

### scroll-view
可滚动视图区域。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ module.exports = function ({ print }) {
qa: qaPropLog
},
{
test: /^(space|decode)$/,
test: /^(space)$/,
ios: iosPropLog,
android: androidPropLog,
harmony: harmonyPropLog
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
import { Text, TextProps } from 'react-native'
import { JSX, createElement } from 'react'
import { Text, TextProps, TextStyle } from 'react-native'
import { JSX, createElement, ReactNode } from 'react'
import useInnerProps from './getInnerListeners'
import { extendObject } from './utils'
import { extendObject, useAddSpace } from './utils'

const SimpleText = (props: TextProps): JSX.Element => {
interface _TextProps extends TextProps {
style?: TextStyle
children?: ReactNode
'enable-android-align-center'?: boolean
'enable-add-space'?: boolean
'space-font-size'?: number
}

const SimpleText = (props: _TextProps): JSX.Element => {
const {
allowFontScaling = false,
children
'enable-android-align-center': enableAndroidAlignCenter,
'enable-add-space': enableAddSpace,
'space-font-size': spaceFontSize
} = props

const extendStyle = enableAndroidAlignCenter ? { includeFontPadding: false, textAlignVertical: 'center' } : null

const innerProps = useInnerProps(
extendObject(
{},
props,
{
allowFontScaling
allowFontScaling,
style: extendStyle ? extendObject({}, props.style, extendStyle) : props.style
}
)
),
['enable-android-align-center', 'enable-add-space', 'space-font-size']
)

const children = useAddSpace(props.children, { enableAddSpace, spaceFontSize })

return createElement(Text, innerProps, children)
}

Expand Down
25 changes: 19 additions & 6 deletions packages/webpack-plugin/lib/runtime/components/react/mpx-text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useRef, forwardRef, ReactNode, JSX, createElement, Children } from 'rea
import Portal from './mpx-portal'
import useInnerProps from './getInnerListeners'
import useNodesRef, { HandlerRef } from './useNodesRef' // 引入辅助函数
import { useTransformStyle, wrapChildren, extendObject } from './utils'
import { useTransformStyle, wrapChildren, extendObject, useAddSpace } from './utils'

const decodeMap = {
'&lt;': '<',
Expand Down Expand Up @@ -41,35 +41,43 @@ interface _TextProps extends TextProps {
style?: TextStyle
children?: ReactNode
selectable?: boolean
decode?: boolean
'user-select'?: boolean
'enable-var'?: boolean
'external-var-context'?: Record<string, any>
'parent-font-size'?: number
'parent-width'?: number
'parent-height'?: number
decode?: boolean
'enable-android-align-center'?: boolean
'enable-add-space'?: boolean
'space-font-size'?: number
}

const _Text = forwardRef<HandlerRef<Text, _TextProps>, _TextProps>((props, ref): JSX.Element => {
const {
style = {},
allowFontScaling = false,
selectable,
decode,
'enable-var': enableVar,
'external-var-context': externalVarContext,
'enable-android-align-center': enableAndroidAlignCenter,
'user-select': userSelect,
'parent-font-size': parentFontSize,
'parent-width': parentWidth,
'parent-height': parentHeight,
decode
'enable-add-space': enableAddSpace,
'space-font-size': spaceFontSize
} = props

const extendStyle = enableAndroidAlignCenter ? { includeFontPadding: false, textAlignVertical: 'center' } : null

const {
normalStyle,
hasVarDec,
varContextRef,
hasPositionFixed
} = useTransformStyle(style, {
} = useTransformStyle(extendStyle ? extendObject({}, style, extendStyle) : style, {
enableVar,
externalVarContext,
parentFontSize,
Expand All @@ -95,11 +103,16 @@ const _Text = forwardRef<HandlerRef<Text, _TextProps>, _TextProps>((props, ref):
),
[
'user-select',
'decode'
'decode',
'enable-android-align-center',
'enable-add-space',
'space-font-size'
]
)

const children = decode ? getDecodedChildren(props.children) : props.children
let children = decode ? getDecodedChildren(props.children) : props.children

children = useAddSpace(children, { enableAddSpace, spaceFontSize })

let finalComponent:JSX.Element = createElement(Text, innerProps, wrapChildren(
extendObject({}, props, {
Expand Down
13 changes: 12 additions & 1 deletion packages/webpack-plugin/lib/runtime/components/react/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useCallback, useMemo, useRef, ReactNode, ReactElement, isValidElement, useContext, useState, Dispatch, SetStateAction, Children, cloneElement, createElement, MutableRefObject } from 'react'
import { LayoutChangeEvent, TextStyle, ImageProps, Image } from 'react-native'
import { LayoutChangeEvent, TextStyle, ImageProps, Image, Text } from 'react-native'
import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn } from '@mpxjs/utils'
import { VarContext, ScrollViewContext, RouteContext } from './context'
import { ExpressionParser, parseFunc, ReplaceSource } from './parser'
Expand Down Expand Up @@ -832,3 +832,14 @@ export function useRunOnJSCallback (callbackMapRef: MutableRefObject<Record<stri

return invokeCallback
}

export function useAddSpace (children: ReactNode, { enableAddSpace, spaceFontSize }: { enableAddSpace?: boolean, spaceFontSize?: number }) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个不是个hook不应该叫use

if (!enableAddSpace) return children
const spaceNode = createElement(Text,
spaceFontSize
? { key: '__mpx_text_space__', style: { fontSize: spaceFontSize } }
: { key: '__mpx_text_space__' },
' '
)
return Array.isArray(children) ? children.concat(spaceNode) : [children, spaceNode]
}
35 changes: 33 additions & 2 deletions packages/webpack-plugin/lib/template-compiler/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const { isNonPhrasingTag } = require('../utils/dom-tag-config')
const setBaseWxml = require('../runtime-render/base-wxml')
const { parseExp } = require('./parse-exps')
const shallowStringify = require('../utils/shallow-stringify')
const { isReact, isWeb, isNoMode } = require('../utils/env')
const { isReact, isWeb, isNoMode, isMiniProgram } = require('../utils/env')
const { capitalToHyphen } = require('../utils/string')

const no = function () {
Expand Down Expand Up @@ -2303,7 +2303,7 @@ function processText (el, options, meta) {
}

// RN中裸文字需被Text包裹
// 为了批量修改Text默认属性,如allowFontScaling,使用mpx-simple-text进行包裹
// 为了批量修改Text默认属性,如allowFontScaling,使用mpx-inline-text进行包裹
function processWrapTextReact (el, options, meta) {
const parent = el.parent
const parentTag = parent.tag
Expand Down Expand Up @@ -2932,6 +2932,34 @@ function processMpxTagName (el) {
}
}

function processTextMaxLines (el) {
if (el.tag !== 'text') return
const maxLinesAttr = getAndRemoveAttr(el, 'enable-max-lines')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

processTextMaxLines,只处理Text节点

if (!maxLinesAttr.val) return

const parsed = parseMustacheWithContext(maxLinesAttr.val)

const singleLineStyleStr = '"display:inline-block;max-width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;"'
const multiLineStyleStr = `"display:-webkit-box;max-width:100%;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:" + (${parsed.result}) + ";"`
const linesStyleStr = `((${parsed.result}) <= 1 ? ${singleLineStyleStr} : ${multiLineStyleStr})`
const { val: styleAttrVal } = getAndRemoveAttr(el, 'style')
const styleVal = styleAttrVal ? parseMustacheWithContext(styleAttrVal).result : ''
const mergedStyleStr = styleVal ? `${linesStyleStr} + ';' + (${styleVal})` : linesStyleStr

if (isReact(mode)) {
// iOS/Android 环境:转换为 numberOfLines
addAttrs(el, [{ name: 'numberOfLines', value: maxLinesAttr.val }])
} else {
if (isMiniProgram()) {
addAttrs(el, [{ name: 'max-lines', value: maxLinesAttr.val }, { name: 'overflow', value: 'ellipsis' }])
}
addAttrs(el, [{
name: 'style',
value: `{{${mergedStyleStr}}}`
}])
}
}

function processElement (el, root, options, meta) {
processAtMode(el)
// 如果已经标记了这个元素要被清除,直接return跳过后续处理步骤
Expand All @@ -2941,6 +2969,9 @@ function processElement (el, root, options, meta) {

processMpxTagName(el)

// 处理 enable-max-lines 跨平台属性(在平台规则处理之前)
processTextMaxLines(el)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

放在平台规则处理之后,支持overflow属性,同时平台规则处理可以校验overfolow属性

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

继续放在平台转换之前,函数名统一改为preProcessXXX


if (runtimeCompile && options.dynamicTemplateRuleRunner) {
options.dynamicTemplateRuleRunner(el, options, config[mode])
}
Expand Down