Skip to content

Commit 5e51a17

Browse files
authored
fix(define-stylex): use attrs() instead of props() (#990)
1 parent cbdaa39 commit 5e51a17

File tree

14 files changed

+253
-117
lines changed

14 files changed

+253
-117
lines changed

docs/macros/define-stylex.md

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@ Define and consume [StyleX](https://stylexjs.com/) styles in `<script setup>`.
1313

1414
## Setup
1515

16-
To use StyleX, you should install and configure StyleX first. The steps could change, you may want to check the [official documentation](https://stylexjs.com/) and the [documentation of vite-plugin-stylex](https://github.com/HorusGoul/vite-plugin-stylex) for the latest information.
16+
To use StyleX, you should install and configure StyleX first. The steps could change, you may want to check the [official document](https://stylexjs.com/) and the [document of StyleX bundler integrations](https://stylexjs.com/docs/learn/ecosystem/#third-party-bundler-integrations) for the latest information.
1717

1818
### Vite
1919

2020
```sh
21-
pnpm add @stylexjs/stylex vite-plugin-stylex
21+
pnpm add @stylexjs/stylex @stylex-extend/core @stylex-extend/vite -D
2222
```
2323

24-
```ts [vite.config.ts] {4,13}
24+
```ts [vite.config.ts] {1,13}
25+
import { stylex } from '@stylex-extend/vite'
2526
import Vue from '@vitejs/plugin-vue'
2627
import { defineConfig } from 'vite'
27-
import StyleX from 'vite-plugin-stylex'
2828
import VueMacros from 'vue-macros/vite'
2929

3030
export default defineConfig({
@@ -34,16 +34,14 @@ export default defineConfig({
3434
vue: Vue(),
3535
},
3636
}),
37-
StyleX(), // Must be placed after Vue Macros
37+
stylex(), // Must be placed after Vue Macros
3838
],
3939
})
4040
```
4141

42-
```vue [App.vue] {2-3}
43-
<style>
44-
/* import StyleX stylesheet, according to https://github.com/HorusGoul/vite-plugin-stylex */
45-
@stylex stylesheet;
46-
</style>
42+
```ts [main.ts] {2}
43+
// import StyleX stylesheet, according to https://nonzzz.github.io/stylex-extend/integrations/vite
44+
import 'virtual:stylex.css'
4745
```
4846

4947
## Basic Usage
@@ -79,12 +77,17 @@ import {
7977
create as _stylex_create,
8078
props as _stylex_props,
8179
} from '@stylexjs/stylex'
80+
// virtual module to provide runtime code
81+
// ---cut-start---
82+
// @ts-ignore
83+
// ---cut-end---
84+
import stylex_attrs from '/vue-macros/define-stylex/stylex-attrs'
8285
8386
// ...
8487
</script>
8588
8689
<template>
87-
<p v-bind="_stylex_props(styles.red)">Red</p>
90+
<p v-bind="stylex_attrs(_stylex_props(styles.red))">Red</p>
8891
</template>
8992
```
9093

@@ -127,12 +130,18 @@ import {
127130
create as _stylex_create,
128131
props as _stylex_props,
129132
} from '@stylexjs/stylex'
133+
// ---cut-start---
134+
// @ts-ignore
135+
// ---cut-end---
136+
import stylex_attrs from '/vue-macros/define-stylex/stylex-attrs'
130137
131138
defineProps<{ bold?: boolean }>()
132139
</script>
133140
134141
<template>
135-
<span v-bind="_stylex_props(styles.red, bold && styles.bold)">Red</span>
142+
<span v-bind="stylex_attrs(_stylex_props(styles.red, bold && styles.bold))"
143+
>Red</span
144+
>
136145
</template>
137146
```
138147

docs/zh-CN/macros/define-stylex.md

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@
1313

1414
## 配置
1515

16-
在使用这个宏之前,你需要先引入与配置 StyleX。步骤可能会有所变化,你可能需要查看 [StyleX 官方文档](https://stylexjs.com/) 以及 [vite-plugin-stylex](https://github.com/HorusGoul/vite-plugin-stylex) 的文档,以获取最新信息。
16+
在使用这个宏之前,你需要先引入与配置 StyleX。步骤可能会有所变化,你可能需要查看 [StyleX 官方文档](https://stylexjs.com/) 以及 [StyleX 的第三方插件列表](https://stylexjs.com/docs/learn/ecosystem/#third-party-bundler-integrations),以获取最新信息。
1717

1818
### Vite
1919

2020
```sh
21-
pnpm add @stylexjs/stylex vite-plugin-stylex
21+
pnpm add @stylexjs/stylex @stylex-extend/core @stylex-extend/vite -D
2222
```
2323

24-
```ts [vite.config.ts] {4,13}
24+
```ts [vite.config.ts] {1,13}
25+
import { stylex } from '@stylex-extend/vite'
2526
import Vue from '@vitejs/plugin-vue'
2627
import { defineConfig } from 'vite'
27-
import StyleX from 'vite-plugin-stylex'
2828
import VueMacros from 'vue-macros/vite'
2929

3030
export default defineConfig({
@@ -34,16 +34,14 @@ export default defineConfig({
3434
vue: Vue(),
3535
},
3636
}),
37-
StyleX(), // 必须放在 Vue Macros 插件后
37+
stylex(), // 必须放在 Vue Macros 插件后
3838
],
3939
})
4040
```
4141

42-
```vue [App.vue] {2-3}
43-
<style>
44-
/* 引入 StyleX 样式表, 参考: https://github.com/HorusGoul/vite-plugin-stylex */
45-
@stylex stylesheet;
46-
</style>
42+
```ts [main.ts] {2}
43+
// 引入 StyleX 样式表, 参考:https://nonzzz.github.io/stylex-extend/integrations/vite
44+
import 'virtual:stylex.css'
4745
```
4846

4947
## 基本用法
@@ -79,12 +77,17 @@ import {
7977
create as _stylex_create,
8078
props as _stylex_props,
8179
} from '@stylexjs/stylex'
80+
// 虚拟模块,提供运行时代码
81+
// ---cut-start---
82+
// @ts-ignore
83+
// ---cut-end---
84+
import stylex_attrs from '/vue-macros/define-stylex/stylex-attrs'
8285
8386
// ...
8487
</script>
8588
8689
<template>
87-
<p v-bind="_stylex_props(styles.red)">Red</p>
90+
<p v-bind="stylex_attrs(_stylex_props(styles.red))">Red</p>
8891
</template>
8992
```
9093

@@ -127,12 +130,18 @@ import {
127130
create as _stylex_create,
128131
props as _stylex_props,
129132
} from '@stylexjs/stylex'
133+
// ---cut-start---
134+
// @ts-ignore
135+
// ---cut-end---
136+
import stylex_attrs from '/vue-macros/define-stylex/stylex-attrs'
130137
131138
defineProps<{ bold?: boolean }>()
132139
</script>
133140
134141
<template>
135-
<span v-bind="_stylex_props(styles.red, bold && styles.bold)">Red</span>
142+
<span v-bind="stylex_attrs(_stylex_props(styles.red, bold && styles.bold))"
143+
>Red</span
144+
>
136145
</template>
137146
```
138147

packages/define-stylex/macros.d.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,20 @@
11
export declare const defineStyleX: (typeof import('@stylexjs/stylex'))['create']
22

33
type Styles =
4-
| (
5-
| null
6-
| undefined
7-
| import('@stylexjs/stylex/lib/StyleXTypes').CompiledStyles
8-
)
4+
| (null | undefined | import('@stylexjs/stylex').CompiledStyles)
95
| boolean
106
| Readonly<
117
[
12-
import('@stylexjs/stylex/lib/StyleXTypes').CompiledStyles,
13-
import('@stylexjs/stylex/lib/StyleXTypes').InlineStyles,
8+
import('@stylexjs/stylex').CompiledStyles,
9+
import('@stylexjs/stylex').InlineStyles,
1410
]
1511
>
1612

1713
declare module 'vue' {
1814
interface ComponentCustomProperties {
1915
vStylex: import('vue').Directive<
2016
any,
21-
| ReadonlyArray<
22-
import('@stylexjs/stylex/lib/StyleXTypes').StyleXArray<Styles>
23-
>
24-
| Styles
17+
ReadonlyArray<import('@stylexjs/stylex').StyleXArray<Styles>> | Styles
2518
>
2619
}
2720
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { VIRTUAL_ID_PREFIX } from '@vue-macros/common'
2+
3+
export const helperPrefix: '/vue-macros/define-stylex' = `${VIRTUAL_ID_PREFIX}/define-stylex`
4+
export const styleXAttrsId: string = `${helperPrefix}/stylex-attrs`
5+
export { default as styleXAttrsCode } from './stylex-attrs?raw'
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
interface AttrsReturn {
2+
class?: string
3+
style?: string
4+
'data-style-src'?: string
5+
}
6+
7+
/** StyleX removed the `attrs` api at [0.13.0](https://stylexjs.com/blog/v0.13.0/#breaking-changes).
8+
* Follow the [guide](https://stylexjs.com/docs/api/javascript/props/#not-using-react) to add it back.
9+
*/
10+
export default ({
11+
className,
12+
'data-style-src': dataStyleSrc,
13+
style,
14+
}: ReturnType<(typeof import('@stylexjs/stylex'))['props']>): AttrsReturn => {
15+
const result: AttrsReturn = {}
16+
// Convert className to class
17+
if (className != null && className !== '') {
18+
result.class = className
19+
}
20+
// Convert style object to string
21+
if (style != null && Object.keys(style).length > 0) {
22+
result.style = Object.keys(style)
23+
.map((key) => `${key}:${style[key]};`)
24+
.join('')
25+
}
26+
if (dataStyleSrc != null && dataStyleSrc !== '') {
27+
result['data-style-src'] = dataStyleSrc
28+
}
29+
return result
30+
}

packages/define-stylex/src/core/index.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
addNormalScript,
33
DEFINE_STYLEX,
44
generateTransform,
5+
importHelperFn,
56
isCallOf,
67
MagicStringAST,
78
parseSFC,
@@ -15,12 +16,20 @@ import {
1516
type NodeTransform,
1617
type NodeTypes,
1718
} from '@vue/compiler-dom'
19+
import { styleXAttrsId } from './helper'
1820
import type { CallExpression, Node } from '@babel/types'
1921

2022
const STYLEX_CREATE = '_stylex_create'
2123
const STYLEX_PROPS = '_stylex_props'
24+
const STYLEX_ATTRS = '_stylex_attrs'
2225

23-
function transformDirective(s: MagicStringAST): NodeTransform {
26+
const callStyleXAttrs = (s: MagicStringAST, setupOffset: number) =>
27+
importHelperFn(s, setupOffset, 'default', STYLEX_ATTRS, styleXAttrsId)
28+
29+
function transformDirective(
30+
s: MagicStringAST,
31+
setupOffset: number,
32+
): NodeTransform {
2433
return (node) => {
2534
if (!(node.type === (1 satisfies NodeTypes.ELEMENT))) return
2635
const i = node.props.findIndex(
@@ -45,15 +54,15 @@ function transformDirective(s: MagicStringAST): NodeTransform {
4554
s?.overwrite(
4655
directiveVStyleX.loc.start.offset,
4756
directiveVStyleX.loc.end.offset,
48-
`v-bind="${directiveVStyleX.exp.content}"`,
57+
`v-bind="${callStyleXAttrs(s, setupOffset)}(${directiveVStyleX.exp.content})"`,
4958
)
5059
return
5160
}
5261

5362
s?.overwrite(
5463
directiveVStyleX.loc.start.offset,
5564
directiveVStyleX.loc.end.offset,
56-
`v-bind="${STYLEX_PROPS}${prefix}${directiveVStyleX.exp.content}${postfix}"`,
65+
`v-bind="${callStyleXAttrs(s, setupOffset)}(${STYLEX_PROPS}${prefix}${directiveVStyleX.exp.content}${postfix})"`,
5766
)
5867
}
5968
}
@@ -103,7 +112,7 @@ export function transformDefineStyleX(
103112
if (scriptOffset !== undefined) normalScript.end()
104113

105114
const ctx = createTransformContext(template.ast!, {
106-
nodeTransforms: [transformDirective(s)],
115+
nodeTransforms: [transformDirective(s, setupOffset)],
107116
})
108117
traverseNode(template.ast!, ctx)
109118

packages/define-stylex/src/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
detectVueVersion,
44
FilterFileType,
55
getFilterPattern,
6+
normalizePath,
67
type BaseOptions,
78
type MarkRequired,
89
} from '@vue-macros/common'
@@ -13,6 +14,7 @@ import {
1314
type UnpluginInstance,
1415
} from 'unplugin'
1516
import { transformDefineStyleX } from './core'
17+
import { helperPrefix, styleXAttrsCode, styleXAttrsId } from './core/helper'
1618

1719
export type Options = BaseOptions
1820
export type OptionsResolved = MarkRequired<Options, 'include' | 'version'>
@@ -46,6 +48,14 @@ const plugin: UnpluginInstance<Options | undefined, false> = createUnplugin(
4648
enforce: 'pre',
4749
transformInclude: filter,
4850
transform: transformDefineStyleX,
51+
resolveId(id) {
52+
if (normalizePath(id).startsWith(helperPrefix)) return id
53+
},
54+
loadInclude: (id) => normalizePath(id).startsWith(helperPrefix),
55+
load(_id) {
56+
const id = normalizePath(_id)
57+
if (id === styleXAttrsId) return styleXAttrsCode
58+
},
4959
}
5060
},
5161
)

0 commit comments

Comments
 (0)