]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-vapor): set static indeterminate as prop
authordaiwei <daiwei521@126.com>
Tue, 30 Sep 2025 08:32:22 +0000 (16:32 +0800)
committerdaiwei <daiwei521@126.com>
Thu, 9 Oct 2025 02:58:19 +0000 (10:58 +0800)
packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts
packages/compiler-vapor/src/transforms/transformElement.ts
packages/runtime-vapor/__tests__/dom/prop.spec.ts
packages/runtime-vapor/src/dom/prop.ts

index 3188a866070b762926636a68204f4fd9f157758e..fe18b80a4fe353c40f679806c3a2115cebb8802d 100644 (file)
@@ -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("<input type=\\"checkbox\\">", 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';
 
index a693db4ad3961f85cd9367650b565217880c4479..259db412fb69403fa7554963211bf8f90f09fe24 100644 (file)
@@ -583,6 +583,15 @@ describe('compiler: element transform', () => {
     expect(ir.block.effect).lengthOf(0)
   })
 
+  test('checkbox with static indeterminate', () => {
+    const { code } = compileWithElementTransform(
+      `<input type="checkbox" indeterminate/>`,
+    )
+
+    expect(code).toContain('_setProp(n0, "indeterminate", "")')
+    expect(code).toMatchSnapshot()
+  })
+
   test('props + children', () => {
     const { code, ir } = compileWithElementTransform(
       `<div id="foo"><span/></div>`,
index 4bad22264f6c1d296e4a003a5c98a527975f04c5..34f295433d71b57ac7f507bc41814570ef45508f 100644 (file)
@@ -199,6 +199,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,
@@ -230,7 +233,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 {
index 9d07b413541932f0f6c58ddc1a630138b15e866e..26877f03f1393e9184f77793d6c914fd9ca50f94 100644 (file)
@@ -299,6 +299,17 @@ describe('patchProp', () => {
         `Failed setting prop "someProp" on <div>: 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', () => {
index 411cf762c29e7780b6f082ec957c9d17ceccfdb8..eb48cdef96e8b36793724684961cdefd314c4617 100644 (file)
@@ -1,6 +1,7 @@
 import {
   type NormalizedStyle,
   canSetValueDirectly,
+  includeBooleanAttr,
   isOn,
   isString,
   normalizeClass,
@@ -110,7 +111,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. <div :id="null">
       value = ''
       needRemove = true