Skip to content

Commit

Permalink
feat: support jsxAttribute
Browse files Browse the repository at this point in the history
  • Loading branch information
zhiyuanzmj committed Dec 9, 2024
1 parent c4ff1d0 commit fca1501
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 30 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ defineExpose$({
defineExpose({
base64: $$(base64),
})
let compRef = $useRef()
defineRender(<Comp ref$={compRef} />)
// convert to:
let compRef = $(useRef())
defineRender(<Comp ref={$$(compRef)} />)
</script>
```

Expand Down
8 changes: 6 additions & 2 deletions playground/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { inject, provide, toRefs, watch } from 'vue'
<script setup lang="tsx">
import { type Ref, inject, provide, toRefs, watch } from 'vue'
import { useBase64 } from '@vueuse/core'
import { useUserStore } from '../store/user'
Expand All @@ -21,6 +21,10 @@ const stop = watch$(base64, () => {
defineExpose$({
base64,
})
const title = $ref('title')
const Comp = ({ title }: { title: Ref<string> }) => <div>{title.value}</div>
const Render = <Comp title$={title} />
</script>

<template>
Expand Down
42 changes: 26 additions & 16 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,24 +105,34 @@ function transformReactivityFunction(
if (node.type === 'TSNonNullExpression') {
node = node.expression
}
if (node.type !== 'CallExpression') return
if (node.type === 'CallExpression') {
if (
parent?.type === 'VariableDeclarator' &&
new RegExp(`^\\$(?!(\\$|${ignore.join('|')})?$)`).test(
s.sliceNode(node.callee, { offset }),
)
) {
s.appendRight(node.callee.start! + offset + 1, '(')
s.appendRight(node.end! + offset, ')')
}

if (
parent?.type === 'VariableDeclarator' &&
new RegExp(`^\\$(?!(\\$|${ignore.join('|')})?$)`).test(
s.sliceNode(node.callee, { offset }),
)
) {
s.appendRight(node.callee.start! + offset + 1, '(')
s.appendRight(node.end! + offset, ')')
}
if (/(?<!^(\$)?)\$$/.test(s.sliceNode(node.callee, { offset }))) {
s.remove(node.callee.end! + offset - 1, node.callee.end! + offset)

if (/(?<!^(\$)?)\$$/.test(s.sliceNode(node.callee, { offset }))) {
s.remove(node.callee.end! + offset - 1, node.callee.end! + offset)

node.arguments.forEach((argument) => {
transformArguments(argument, s, offset)
})
node.arguments.forEach((argument) => {
transformArguments(argument, s, offset)
})
}
} else if (
node.type === 'JSXAttribute' &&
node.value?.type === 'JSXExpressionContainer' &&
s.sliceNode(node.name).endsWith('$')
) {
s.remove(node.name.end! - 1, node.name.end!)
if (node.value.expression) {
s.appendLeft(node.value.expression.start! + offset, '$$(')
s.appendRight(node.value.expression.end! + offset, ')')
}
}
},
})
Expand Down
22 changes: 22 additions & 0 deletions src/volar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,28 @@ function transform({
transformArguments(argument)
})
}
} else if (
ts.isJsxAttribute(node) &&
node.initializer &&
ts.isJsxExpression(node.initializer) &&
node.initializer.expression &&
getText(node.name, ast, ts).endsWith('$')
) {
replaceSourceRange(codes, source, node.name.end - 1, node.name.end)
replaceSourceRange(
codes,
source,
node.initializer.expression.pos,
node.initializer.expression.pos,
'$$(',
)
replaceSourceRange(
codes,
source,
node.initializer.expression.end,
node.initializer.expression?.end,
')',
)
}

ts.forEachChild(node, (child) => {
Expand Down
13 changes: 5 additions & 8 deletions tests/__snapshots__/basic.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`fixtures > tests/fixtures/basic.vue 1`] = `
"import { defineComponent, ref, watch, openBlock, createElementBlock, toDisplayString, unref } from 'vue';
"import { defineComponent, ref, watch, openBlock, createBlock } from 'vue';
import _export_sfc from '[NULL]/plugin-vue/export-helper';
"use strict";
Expand All @@ -25,14 +25,11 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
defineExpose({
name: $$(name)
});
const title = $ref("title");
const Comp = ({ title: title2 }) => title2.value;
const Render = () => /* @__PURE__ */ React.createElement(Comp, { title: $$(title) });
return (_ctx, _cache) => {
return openBlock(), createElementBlock(
"div",
null,
toDisplayString(unref(name)),
1
/* TEXT */
);
return openBlock(), createBlock(Render);
};
}
});
Expand Down
10 changes: 6 additions & 4 deletions tests/fixtures/basic.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="tsx">
import { ref, watch } from 'vue'
import { Ref, ref, watch } from 'vue'
function useApi(defaultName = ref('')) {
const id = ref(1)
Expand All @@ -22,10 +22,12 @@ watch$(name, () => {})
defineExpose$({
name,
})
const title = $ref<string>('title')
const Comp = ({ title }: { title: Ref<string> }) => title.value
const Render = () => <Comp title$={title} />
</script>

<template>
<div>
{{ name }}
</div>
<Render />
</template>

0 comments on commit fca1501

Please sign in to comment.