Skip to content

feat(nvue-styler): 调整 uvue 中 flex-flow 拆分、支持 ::v-deep #5495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 30, 2025
Merged
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
61 changes: 61 additions & 0 deletions packages/uni-nvue-styler/__tests__/parse-nvue.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -690,4 +690,65 @@ border-top-style: solid;
})
expect(messages.length).toBe(1)
})
test('flex-flow', async () => {
const { json, messages } = await objectifierRule(`
.a {
flex-flow: row nowrap;
}
.b {
flex-flow: row wrap;
}
`)
expect(json).toEqual({
a: {
'': {
flexDirection: 'row',
flexWrap: 'nowrap',
},
},
b: {
'': {
flexDirection: 'row',
flexWrap: 'wrap',
},
},
})
expect(messages.length).toBe(2)
expect(messages[0].text).toBe(
'NOTE: property value `nowrap` is the DEFAULT value for `flex-wrap` (could be removed)'
)
expect(messages[1].text).toBe(
'NOTE: the flex-wrap property may have compatibility problem on native'
)
})
test('nvue 不支持 ::v-deep 和 :deep()', async () => {
// 多个空格
const { json, messages } = await objectifierRule(`
.a .b{
color: #ff0000;
}
.a ::v-deep .b{
color: #00ff00;
}
.a ::v-deep .b ::v-deep .c{
color: #ff00ff;
}
.a :deep(.b){

color: #0000ff;
}
`)
expect(json).toEqual({
b: { '.a ': { color: '#ff0000' } },
})
// console.log(messages)
expect(messages.length).toBe(3)
expect(
messages.every((i) =>
i.text.includes(
'is not supported. nvue only support classname selector'
)
)
).toEqual(true)
})
})
33 changes: 16 additions & 17 deletions packages/uni-nvue-styler/__tests__/uvueNormalize-android.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,12 +459,12 @@ flexBasis: fill;
.foo {
margin: 100px;
padding: 50px;
flexFlow: row nowrap;
flex-flow: row nowrap;
}
.bar {
margin:
10px auto;
flexFlow: row;
flex-flow: row;
padding: 10px auto;
}
.baz {
Expand Down Expand Up @@ -502,7 +502,8 @@ flexBasis: fill;
paddingRight: 50,
paddingTop: 50,
paddingBottom: 50,
flexFlow: 'row nowrap',
flexDirection: 'row',
flexWrap: 'nowrap',
},
},
bar: {
Expand All @@ -513,7 +514,8 @@ flexBasis: fill;
marginRight: 'auto',
paddingBottom: 10,
paddingTop: 10,
flexFlow: 'row',
flexDirection: 'row',
flexWrap: 'nowrap',
},
},
baz: {
Expand All @@ -534,52 +536,49 @@ flexBasis: fill;
},
},
})
expect(messages.length).toEqual(9)

expect(messages[0]).toEqual(
expect.objectContaining({
text: 'ERROR: property value `row` is not supported for `flex-flow` (both property values must be explicitly defined)',
})
)
expect(messages[1]).toEqual(
expect.objectContaining({
text: 'ERROR: property value `min-content` is not supported for `flex` (supported values are: `number`|`pixel`|`initial`|`auto`|`none`)',
})
)
expect(messages[2]).toEqual(
expect(messages[1]).toEqual(
expect.objectContaining({
text: 'ERROR: property value `2 unset` is not supported for `flex` (supported values are: `number`|`pixel`|`initial`|`auto`|`none`)',
})
)
expect(messages[3]).toEqual(
expect(messages[2]).toEqual(
expect.objectContaining({
text: 'ERROR: property value `1 abc 100px` is not supported for `flex` (supported values are: `number`|`pixel`|`initial`|`auto`|`none`)',
})
)
expect(messages[4]).toEqual(
expect(messages[3]).toEqual(
expect.objectContaining({
text: 'ERROR: property value `auto` is not supported for `padding-right` (supported values are: `number`|`pixel`|`percent`)',
})
)
expect(messages[5]).toEqual(
expect(messages[4]).toEqual(
expect.objectContaining({
text: 'ERROR: property value `auto` is not supported for `padding-left` (supported values are: `number`|`pixel`|`percent`)',
})
)
expect(messages[6]).toEqual(
expect(messages[5]).toEqual(
expect.objectContaining({
text: 'ERROR: property value `abc` is not supported for `margin-top` (supported values are: `number`|`pixel`|`percent`|`auto`)',
})
)
expect(messages[7]).toEqual(
expect(messages[6]).toEqual(
expect.objectContaining({
text: 'ERROR: property value `abc` is not supported for `margin-right` (supported values are: `number`|`pixel`|`percent`|`auto`)',
})
)
expect(messages[8]).toEqual(
expect(messages[7]).toEqual(
expect.objectContaining({
text: 'ERROR: property value `abc` is not supported for `margin-bottom` (supported values are: `number`|`pixel`|`percent`|`auto`)',
})
)
expect(messages[9]).toEqual(
expect(messages[8]).toEqual(
expect.objectContaining({
text: 'ERROR: property value `abc` is not supported for `margin-left` (supported values are: `number`|`pixel`|`percent`|`auto`)',
})
Expand Down
95 changes: 95 additions & 0 deletions packages/uni-nvue-styler/__tests__/uvueNormalize-ios.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -656,4 +656,99 @@ border-color: var(--default-border);
},
})
})

test('多次出现 border 不同形式,保证最后一个生效', async () => {
const { json } = await objectifierRule(`
.test {
border-left-color: red;
}

.test {
width: 100px;
height: 100px;
border-width: 1px;
border-color: blue;
/* border-left-color: blue;border-top-color: blue;border-bottom-color: blue;border-right-color: blue; */
border-style: solid;
}
`)
expect(json).toEqual({
test: {
'': {
borderTopColor: '#0000FF',
borderRightColor: '#0000FF',
borderBottomColor: '#0000FF',
borderLeftColor: '#0000FF',
borderTopStyle: 'solid',
borderRightStyle: 'solid',
borderBottomStyle: 'solid',
borderLeftStyle: 'solid',
borderTopWidth: 1,
borderRightWidth: 1,
borderBottomWidth: 1,
borderLeftWidth: 1,
height: 100,
width: 100,
},
},
})
})

test('测试 ::v-deep 的样式', async () => {
const { json, messages } = await objectifierRule(`
.box ::v-deep .text1 {
color: #fff000;
}
.box1 ::v-deep .box2 ::v-deep .box3 {
color: #000000;
}
`)
// console.log(messages)
expect(messages.length).toBe(0)
expect(json).toEqual({
text1: {
'.box ': {
color: '#fff000',
},
},
box3: {
'.box1 .box2 ': {
color: '#000000',
},
},
})
})

test('测试 ::v-deep(.xxx) 的样式', async () => {
const { json, messages } = await objectifierRule(`
.box :deep(.text1) {
color: #fff000;
}
.box :deep(.box2 .text2) {
color: #000000;
}
.box .box3 .text3 {
color: #000000;
}

`)
expect(messages.length).toBe(0)
expect(json).toEqual({
text1: {
'.box ': {
color: '#fff000',
},
},
text2: {
'.box .box2 ': {
color: '#000000',
},
},
text3: {
'.box .box3 ': {
color: '#000000',
},
},
})
})
})
8 changes: 2 additions & 6 deletions packages/uni-nvue-styler/src/expand/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,8 @@ function getDeclTransforms(
// margin,padding继续展开,确保样式的优先级
margin: transformMargin,
padding: transformPadding,
/* eslint-disable no-restricted-syntax */
...(options.type !== 'uvue'
? {
flexFlow: transformFlexFlow,
}
: {}),

flexFlow: transformFlexFlow,
}
let result: Record<string, TransformDecl> = {}
if (__NODE_JS__) {
Expand Down
16 changes: 15 additions & 1 deletion packages/uni-nvue-styler/src/normalize/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,23 @@ function createRuleProcessor(opts: NormalizeOptions = {}) {
}
rule.selector = rule.selectors
.map((selector) => {
const isUvue = opts.type === 'uvue'
if (isUvue) {
// 特殊处理 ::v-deep 选择器 和 ::v-deep(.xxx) 写法
const hasVDeep = selector.includes('::v-deep')
const hasDeepMethod = selector.includes(':deep(')
if (hasVDeep) {
selector = selector.replace(/::v-deep/g, '')
}
if (hasDeepMethod) {
selector = selector.replace(/:deep\(([^)]+)\)/g, '$1')
}
}
// 移除组合符周围的空格,合并多个空格
selector = selector
.replace(/\s*([\+\~\>])\s*/g, '$1')
.replace(/\s+/, ' ')
.replace(/\s+/g, ' ')
// 组合符号
if (COMBINATORS_RE.test(selector)) {
return selector
}
Expand Down
Loading