diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap
index 3188a866070..fe18b80a4fe 100644
--- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap
+++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap
@@ -1,5 +1,16 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+exports[`compiler: element transform > checkbox with static indeterminate 1`] = `
+"import { setProp as _setProp, template as _template } from 'vue';
+const t0 = _template("", true)
+
+export function render(_ctx) {
+ const n0 = t0()
+ _setProp(n0, "indeterminate", "")
+ return n0
+}"
+`;
+
exports[`compiler: element transform > component > cache v-on expression with unique handler name 1`] = `
"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback } from 'vue';
diff --git a/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts b/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts
index a693db4ad39..259db412fb6 100644
--- a/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts
+++ b/packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts
@@ -583,6 +583,15 @@ describe('compiler: element transform', () => {
expect(ir.block.effect).lengthOf(0)
})
+ test('checkbox with static indeterminate', () => {
+ const { code } = compileWithElementTransform(
+ ``,
+ )
+
+ expect(code).toContain('_setProp(n0, "indeterminate", "")')
+ expect(code).toMatchSnapshot()
+ })
+
test('props + children', () => {
const { code, ir } = compileWithElementTransform(
`
`,
diff --git a/packages/compiler-vapor/src/transforms/transformElement.ts b/packages/compiler-vapor/src/transforms/transformElement.ts
index 05153e729af..67f203e87f5 100644
--- a/packages/compiler-vapor/src/transforms/transformElement.ts
+++ b/packages/compiler-vapor/src/transforms/transformElement.ts
@@ -192,6 +192,9 @@ function resolveSetupReference(name: string, context: TransformContext) {
: undefined
}
+// keys cannot be a part of the template and need to be set dynamically
+const dynamicKeys = ['indeterminate']
+
function transformNativeElement(
node: PlainElementNode,
propsResult: PropsResult,
@@ -223,7 +226,12 @@ function transformNativeElement(
} else {
for (const prop of propsResult[1]) {
const { key, values } = prop
- if (key.isStatic && values.length === 1 && values[0].isStatic) {
+ if (
+ key.isStatic &&
+ values.length === 1 &&
+ values[0].isStatic &&
+ !dynamicKeys.includes(key.content)
+ ) {
template += ` ${key.content}`
if (values[0].content) template += `="${values[0].content}"`
} else {
diff --git a/packages/runtime-vapor/__tests__/dom/prop.spec.ts b/packages/runtime-vapor/__tests__/dom/prop.spec.ts
index 9d07b413541..26877f03f13 100644
--- a/packages/runtime-vapor/__tests__/dom/prop.spec.ts
+++ b/packages/runtime-vapor/__tests__/dom/prop.spec.ts
@@ -299,6 +299,17 @@ describe('patchProp', () => {
`Failed setting prop "someProp" on : value foo is invalid.`,
).toHaveBeenWarnedLast()
})
+
+ test('checkbox with indeterminate', () => {
+ const el = document.createElement('input')
+ el.type = 'checkbox'
+ setProp(el, 'indeterminate', true)
+ expect(el.indeterminate).toBe(true)
+ setProp(el, 'indeterminate', false)
+ expect(el.indeterminate).toBe(false)
+ setProp(el, 'indeterminate', '')
+ expect(el.indeterminate).toBe(true)
+ })
})
describe('setDynamicProp', () => {
diff --git a/packages/runtime-vapor/src/dom/prop.ts b/packages/runtime-vapor/src/dom/prop.ts
index 346bea53eb1..c66b44259af 100644
--- a/packages/runtime-vapor/src/dom/prop.ts
+++ b/packages/runtime-vapor/src/dom/prop.ts
@@ -1,6 +1,7 @@
import {
type NormalizedStyle,
canSetValueDirectly,
+ includeBooleanAttr,
isOn,
isString,
normalizeClass,
@@ -81,7 +82,9 @@ export function setDOMProp(el: any, key: string, value: any): void {
let needRemove = false
if (value === '' || value == null) {
const type = typeof prev
- if (value == null && type === 'string') {
+ if (type === 'boolean') {
+ value = includeBooleanAttr(value)
+ } else if (value == null && type === 'string') {
// e.g.
value = ''
needRemove = true