From e5f1fb04b2af515d5b96569e364ab0ceb94f43fb Mon Sep 17 00:00:00 2001 From: hiyuki <674883329@qq.com> Date: Fri, 11 Oct 2024 16:39:01 +0800 Subject: [PATCH] RN: support hairlineWidth && fix var() parse --- .../platform/builtInMixins/styleHelperMixin.ios.js | 10 ++++++---- .../webpack-plugin/lib/platform/style/wx/index.js | 6 +++--- packages/webpack-plugin/lib/react/style-helper.js | 6 +++++- .../lib/runtime/components/react/utils.ts | 11 ++++++----- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js b/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js index e6bb196376..f8421b6ab7 100644 --- a/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js +++ b/packages/core/src/platform/builtInMixins/styleHelperMixin.ios.js @@ -1,5 +1,5 @@ import { isObject, isArray, dash2hump, isFunction, cached } from '@mpxjs/utils' -import { Dimensions } from 'react-native' +import { Dimensions, StyleSheet } from 'react-native' function rpx (value) { const { width } = Dimensions.get('screen') @@ -9,6 +9,7 @@ function rpx (value) { } global.__rpx = rpx +global.__hairlineWidth = StyleSheet.hairlineWidth const escapeReg = /[()[\]{}#!.:,%'"+$]/g const escapeMap = { @@ -81,7 +82,8 @@ const listDelimiter = /;(?![^(]*[)])/g const propertyDelimiter = /:(.+)/ const rpxRegExp = /^\s*(-?\d+(\.\d+)?)rpx\s*$/ const pxRegExp = /^\s*(-?\d+(\.\d+)?)(px)?\s*$/ -const varRegExp = /^--.*/ +const hairlineRegExp = /^\s*hairlineWidth\s*$/ +const varRegExp = /^--/ const parseStyleText = cached((cssText = '') => { const res = {} @@ -123,15 +125,15 @@ function transformStyleObj (styleObj) { const keys = Object.keys(styleObj) const transformed = {} keys.forEach((prop) => { - // todo 检测不支持的prop let value = styleObj[prop] let matched if ((matched = pxRegExp.exec(value))) { value = +matched[1] } else if ((matched = rpxRegExp.exec(value))) { value = rpx(+matched[1]) + } else if (hairlineRegExp.test(value)) { + value = StyleSheet.hairlineWidth } - // todo 检测不支持的value transformed[prop] = value }) return transformed diff --git a/packages/webpack-plugin/lib/platform/style/wx/index.js b/packages/webpack-plugin/lib/platform/style/wx/index.js index 008bc9e1f0..5a1183d7c6 100644 --- a/packages/webpack-plugin/lib/platform/style/wx/index.js +++ b/packages/webpack-plugin/lib/platform/style/wx/index.js @@ -9,7 +9,7 @@ module.exports = function getSpec ({ warn, error }) { // React Native android 不支持的 CSS property android: /^(text-decoration-style|text-decoration-color|shadow-offset|shadow-opacity|shadow-radius)$/ } - const cssVariableExp = /var\((.*?)\)/ + const cssVariableExp = /^var\((.+)\)$/ // 不支持的属性提示 const unsupportedPropError = ({ prop, mode }) => { error(`Property [${prop}] is not supported in React Native ${mode} environment!`) @@ -91,7 +91,7 @@ module.exports = function getSpec ({ warn, error }) { // css variable 类型校验 const newVal = (value.match(cssVariableExp)?.[1] || '').split(',') const variable = newVal?.[0] - if (!variable || !/^--.+$/.test(variable)) { + if (!variable || !/^--/.test(variable)) { tips(`The css variable [${prop}:${value}] is invalid, please check again`) return false } @@ -99,7 +99,7 @@ module.exports = function getSpec ({ warn, error }) { } const namedColor = ['transparent', 'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'grey', 'honeydew', 'hotpink', 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategrey', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'rebeccapurple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen'] const valueExp = { - number: /^(-?\d+(\.\d+)?)(rpx|px|%)?$/, + number: /^((-?\d+(\.\d+)?)(rpx|px|%)?|hairlineWidth)$/, color: new RegExp(('^(' + namedColor.join('|') + ')$') + '|(^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$)|^(rgb|rgba|hsl|hsla|hwb)\\(.+\\)$') } const type = getValueType(prop) diff --git a/packages/webpack-plugin/lib/react/style-helper.js b/packages/webpack-plugin/lib/react/style-helper.js index d067f87b24..6ce8790841 100644 --- a/packages/webpack-plugin/lib/react/style-helper.js +++ b/packages/webpack-plugin/lib/react/style-helper.js @@ -4,7 +4,8 @@ const getRulesRunner = require('../platform/index') const dash2hump = require('../utils/hump-dash').dash2hump const rpxRegExp = /^\s*(-?\d+(\.\d+)?)rpx\s*$/ const pxRegExp = /^\s*(-?\d+(\.\d+)?)(px)?\s*$/ -const varRegExp = /^--.*/ +const hairlineRegExp = /^\s*hairlineWidth\s*$/ +const varRegExp = /^--/ const cssPrefixExp = /^-(webkit|moz|ms|o)-/ function getClassMap ({ content, filename, mode, srcMode, warn, error }) { const classMap = {} @@ -22,6 +23,9 @@ function getClassMap ({ content, filename, mode, srcMode, warn, error }) { } else if ((matched = rpxRegExp.exec(value))) { value = `global.__rpx(${matched[1]})` needStringify = false + } else if (hairlineRegExp.test(value)) { + value = `global.__hairlineWidth` + needStringify = false } return needStringify ? JSON.stringify(value) : value } diff --git a/packages/webpack-plugin/lib/runtime/components/react/utils.ts b/packages/webpack-plugin/lib/runtime/components/react/utils.ts index ef22aac502..e7c7e05795 100644 --- a/packages/webpack-plugin/lib/runtime/components/react/utils.ts +++ b/packages/webpack-plugin/lib/runtime/components/react/utils.ts @@ -1,5 +1,5 @@ import { useEffect, useRef, ReactNode, ReactElement, FunctionComponent, isValidElement, useContext, useState } from 'react' -import { TextStyle, Dimensions } from 'react-native' +import { TextStyle, Dimensions, StyleSheet } from 'react-native' import { isObject, hasOwn, diffAndCloneA, noop } from '@mpxjs/utils' import { VarContext } from './context' @@ -8,8 +8,8 @@ export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/ export const BACKGROUND_REGEX = /^background(Image|Size|Repeat|Position)$/ export const TEXT_PROPS_REGEX = /ellipsizeMode|numberOfLines/ export const VAR_DEC_REGEX = /^--.*/ -export const VAR_USE_REGEX = /var\(([^,]+)(?:,([^)]+))?\)/ -export const URL_REGEX = /url\(["']?(.*?)["']?\)/ +export const VAR_USE_REGEX = /^\s*var\(([^,]+)(?:,(.+))?\)\s*$/ +export const URL_REGEX = /^\s*url\(["']?(.*?)["']?\)\s*$/ export const DEFAULT_FONT_SIZE = 16 export function rpx (value: number) { @@ -21,6 +21,7 @@ export function rpx (value: number) { const rpxRegExp = /^\s*(-?\d+(\.\d+)?)rpx\s*$/ const pxRegExp = /^\s*(-?\d+(\.\d+)?)(px)?\s*$/ +const hairlineRegExp = /^\s*hairlineWidth\s*$/ export function formatValue (value: string) { let matched @@ -28,6 +29,8 @@ export function formatValue (value: string) { return +matched[1] } else if ((matched = rpxRegExp.exec(value))) { return rpx(+matched[1]) + } else if (hairlineRegExp.test(value)) { + return StyleSheet.hairlineWidth } return value } @@ -79,9 +82,7 @@ export const parseInlineStyle = (inlineStyle = ''): Record => { export const parseUrl = (cssUrl = '') => { if (!cssUrl) return - const match = cssUrl.match(URL_REGEX) - return match?.[1] }