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