Repository: jwstegemann/fritz2
Issue: Fix ``for`` Attribute of radioGroupOptionLabel and checkboxGroupOptionLabel

Currently the ``for`` attribute links to a false Id! It references the Id of the ``radioGroupOption`` and not those of the ``radioGroupOptionToggle``, which would be the correct one.

The  following snippet shows the issue:
```kotlin
radioGroupOption {
    radioGroupOptionToggle(tag = RenderContext::input) {
        type("radio")
        // --> id == this@radioGroupOption.id + "-toggle"
    }
    radioGroupOptionLabel {
        ...
        // --> for == this@radioGroupOption.id
    }
}
```

The same issue exists for ``checkboxGroupOptionLabel`` too.

Changed files:
headless/src/jsMain/kotlin/dev/fritz2/headless/components/switch.kt, headless/src/jsMain/kotlin/dev/fritz2/headless/components/radioGroup.kt, headless/src/jsMain/kotlin/dev/fritz2/headless/components/checkboxGroup.kt

diff --git a/headless/src/jsMain/kotlin/dev/fritz2/headless/components/checkboxGroup.kt b/headless/src/jsMain/kotlin/dev/fritz2/headless/components/checkboxGroup.kt
index bd4439fb..598eac55 100644
--- a/headless/src/jsMain/kotlin/dev/fritz2/headless/components/checkboxGroup.kt
+++ b/headless/src/jsMain/kotlin/dev/fritz2/headless/components/checkboxGroup.kt
@@ -112,6 +112,8 @@ class CheckboxGroup<C : HTMLElement, T>(tag: Tag<C>, private val explicitId: Str
         private var label: Tag<HTMLElement>? = null
         private var descriptions: MutableList<Tag<HTMLElement>> = mutableListOf()
 
+        private val toggleId = "${optionId}-toggle"
+
         fun render() {
             toggle?.apply {
                 label?.let { attr(Aria.labelledby, it.id) }
@@ -138,7 +140,7 @@ class CheckboxGroup<C : HTMLElement, T>(tag: Tag<C>, private val explicitId: Str
             content: Tag<CT>.() -> Unit
         ): Tag<CT> {
             addComponentStructureInfo("checkboxGroupOptionToggle", this@checkboxGroupOptionToggle.scope, this)
-            return tag(this, classes, "${optionId}-toggle", scope) {
+            return tag(this, classes, toggleId, scope) {
                 content()
                 attr("role", Aria.Role.checkbox)
                 attr(Aria.checked, selected.asString())
@@ -193,7 +195,7 @@ class CheckboxGroup<C : HTMLElement, T>(tag: Tag<C>, private val explicitId: Str
             content: Tag<CL>.() -> Unit
         ): Tag<CL> {
             addComponentStructureInfo("checkboxGroupOptionLabel", this@checkboxGroupOptionLabel.scope, this)
-            return tag(this, classes, "$optionId-label", scope, content).also { label = it }
+            return tag(this, classes, "${optionId}-toggle", scope, content).also { label = it }
         }
 
         /**
diff --git a/headless/src/jsMain/kotlin/dev/fritz2/headless/components/radioGroup.kt b/headless/src/jsMain/kotlin/dev/fritz2/headless/components/radioGroup.kt
index a10f783c..f1101de1 100644
--- a/headless/src/jsMain/kotlin/dev/fritz2/headless/components/radioGroup.kt
+++ b/headless/src/jsMain/kotlin/dev/fritz2/headless/components/radioGroup.kt
@@ -130,6 +130,8 @@ class RadioGroup<C : HTMLElement, T>(tag: Tag<C>, private val explicitId: String
         private var label: Tag<HTMLElement>? = null
         private var descriptions: MutableList<Tag<HTMLElement>> = mutableListOf()
 
+        private val toggleId = "$optionId-toggle"
+
         fun render() {
             toggle?.apply {
                 label?.let { attr(Aria.labelledby, it.id) }
@@ -156,7 +158,7 @@ class RadioGroup<C : HTMLElement, T>(tag: Tag<C>, private val explicitId: String
             content: Tag<CT>.() -> Unit
         ): Tag<CT> {
             addComponentStructureInfo("radioGroupOptionToggle", this@radioGroupOptionToggle.scope, this)
-            return tag(this, classes, "$optionId-toggle", scope) {
+            return tag(this, classes, toggleId, scope) {
                 content()
                 attr("role", Aria.Role.radio)
                 attr(Aria.checked, selected.asString())
@@ -220,7 +222,7 @@ class RadioGroup<C : HTMLElement, T>(tag: Tag<C>, private val explicitId: String
             content: Tag<HTMLLabelElement>.() -> Unit
         ) = radioGroupOptionLabel(classes, scope, RenderContext::label) {
             content()
-            `for`(optionId)
+            `for`(toggleId)
         }
 
         /**
diff --git a/headless/src/jsMain/kotlin/dev/fritz2/headless/components/switch.kt b/headless/src/jsMain/kotlin/dev/fritz2/headless/components/switch.kt
index 727f7317..782c7386 100644
--- a/headless/src/jsMain/kotlin/dev/fritz2/headless/components/switch.kt
+++ b/headless/src/jsMain/kotlin/dev/fritz2/headless/components/switch.kt
@@ -93,6 +93,8 @@ class SwitchWithLabel<C : HTMLElement>(tag: Tag<C>, id: String?) :
     private var label: Tag<HTMLElement>? = null
     private var descriptions: MutableList<Tag<HTMLElement>> = mutableListOf()
 
+    private val toggleId by lazy { "$componentId-toggle" }
+
     override fun render() {
         attr("id", componentId)
         toggle?.apply {
@@ -120,7 +122,7 @@ class SwitchWithLabel<C : HTMLElement>(tag: Tag<C>, id: String?) :
         content: Tag<CT>.() -> Unit
     ) : Tag<CT> {
         addComponentStructureInfo("switchToggle", this@switchToggle.scope, this)
-        return tag(this, classes, "$componentId-toggle", scope) {
+        return tag(this, classes, toggleId, scope) {
             content()
             renderSwitchCore(this)
         }.also { toggle = it }
@@ -170,7 +172,7 @@ class SwitchWithLabel<C : HTMLElement>(tag: Tag<C>, id: String?) :
         content: Tag<HTMLLabelElement>.() -> Unit
     ) = switchLabel(classes, scope, RenderContext::label) {
         content()
-        `for`(componentId)
+        `for`(toggleId)
     }
 
     /**