diff --git a/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/attributes/AttrsScope.kt b/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/attributes/AttrsScope.kt
index 43bb3992f25..5aa369f4a85 100644
--- a/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/attributes/AttrsScope.kt
+++ b/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/attributes/AttrsScope.kt
@@ -97,10 +97,17 @@ interface AttrsScope : EventsListenerScope {
* @param attr - the name of the attribute
* @param value - the value of the attribute
*
- * For boolean attributes cast boolean value to String and pass it as value.
+ * For boolean attributes, use the other overload with a boolean [value] parameter, or cast boolean value to String and pass it as value.
*/
fun attr(attr: String, value: String): AttrsScope
+ /**
+ * Adds a boolean attribute.
+ * @see AttrsScope.attr
+ */
+ fun attr(attr: String, value: Boolean = true) =
+ attr(attr, value.toString())
+
/**
* [prop] allows setting values of element's properties which can't be set using [attr].
* [update] is a lambda with two parameters: `element` and `value`. `element` is a reference to a native element.
@@ -198,7 +205,7 @@ open class AttrsScopeBuilder(
* @param attr - the name of the attribute
* @param value - the value of the attribute
*
- * For boolean attributes cast boolean value to String and pass it as value.
+ * For boolean attributes, use the other overload with a boolean [value] parameter, or cast boolean value to String and pass it as value.
*/
override fun attr(attr: String, value: String): AttrsScope {
attributesMap[attr] = value
diff --git a/html/core/src/jsTest/kotlin/elements/AttributesTests.kt b/html/core/src/jsTest/kotlin/elements/AttributesTests.kt
index 790e895383c..f866706bcc7 100644
--- a/html/core/src/jsTest/kotlin/elements/AttributesTests.kt
+++ b/html/core/src/jsTest/kotlin/elements/AttributesTests.kt
@@ -1,8 +1,8 @@
package org.jetbrains.compose.web.core.tests
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import kotlinx.browser.document
import kotlinx.dom.clear
@@ -10,11 +10,10 @@ import org.jetbrains.compose.web.attributes.*
import org.jetbrains.compose.web.css.*
import org.jetbrains.compose.web.dom.*
import org.jetbrains.compose.web.dom.Text
+import org.jetbrains.compose.web.testutils.runTest
+import org.w3c.dom.*
import kotlin.test.Test
import kotlin.test.assertEquals
-import org.jetbrains.compose.web.testutils.*
-import org.w3c.dom.*
-import kotlin.test.assertContains
import kotlin.test.assertTrue
class AttributesTests {
@@ -459,7 +458,7 @@ class AttributesTests {
id("id$readKey")
}
) {
- @Suppress("DEPRECATION")
+ @Suppress("DEPRECATION")
DisposableRefEffect(readKey) {
val p = document.createElement("p").also { it.innerHTML = "Key=$readKey" }
it.appendChild(p)
@@ -508,7 +507,7 @@ class AttributesTests {
with(child) {
val attrs = getAttributeNames().toList()
assertEquals(2, attrs.size)
- assertTrue(attrs.containsAll(listOf("style", "class",)))
+ assertTrue(attrs.containsAll(listOf("style", "class")))
assertEquals("button", tagName.lowercase())
assertEquals("a", getAttribute("class"))
@@ -579,4 +578,16 @@ class AttributesTests {
assertEquals("400", attrsMap["height"])
}
}
+
+ @Test
+ fun booleanAttributeTest() = runTest {
+ composition {
+ TextInput {
+ attr("required", true)
+ }
+ }
+ with(nextChild()) {
+ assertEquals("true", getAttribute("required"))
+ }
+ }
}