Repository: jwstegemann/fritz2
Issue: Headless: `ModalPanel` overwrites manually specified ID

Any manually specified id via the `modalPanel` factory function is overridden upon rendering (1.0-SNAPSHOT).

This is due to the `render()` function setting the id of it's containing tag to a random value if no explicit id has been set. The factory function, however, passes the explicitly specified id to the tag factory but not to the `ModalPanel` itself. This results in the id being overridden once `render()` is called as the component is not aware of the explicit id and creates a new random one.

See _Additional Context_ below for more information.

**To Reproduce**
Inside a `modal` context, create a new `modalPanel` and explicitly specify an id like this:
```kotlin
modal {
    // some initialization code ...
    
    modalPanel(id = "TEST") { /* ... */ }
}
```
This is the resulting HTML:
```html
<div id="some-random-id" class="...">
    <!--parent is modalPanel-->
    ...
</div>
```

**Expected behavior**
The resulting HTML should have the specified id:
```html
<div id="TEST" class="...">
    <!--parent is modalPanel-->
    ...
</div>
```

**Additional context**
This is how the factory function creates the `ModalPanel`:
```kotlin
tag(this, classes, id, internalScope) {
    //             ^^
    //             The explicit id is passed to the tag factory
    addComponentStructureInfo("parent is modalPanel", this@modalPanel.scope, this)
    ModalPanel(this).run {
        //        ^^
        //        The id is not passed to the panel itself even though it accepts an explicit id
        initialize()
        render()
    }
}
```
When `render()` is called, it overrides the explicit id previously set by the factory:
```kotlin
val componentId: String by lazy { explicitId ?: Id.next() } 
//                                ^^^^^^^^^^
//                                `explicitId` was not passed in via the constructor and is `null`.
//                                As a result, a new id is generated...

// ...

fun render() {
    attr("id", componentId) // <-- ... and applied to the containing `Tag`.
    attr("role", Aria.Role.dialog)
    attr(Aria.modal, "true")
    title?.let { attr(Aria.labelledby, it.id) }
    attr(Aria.describedby, descriptions.map { d -> d.id }.joinToString(" "))
}
```



Changed files:
headless/src/jsMain/kotlin/dev/fritz2/headless/components/modal.kt

diff --git a/headless/src/jsMain/kotlin/dev/fritz2/headless/components/modal.kt b/headless/src/jsMain/kotlin/dev/fritz2/headless/components/modal.kt
index c8e186fb..8e35c506 100644
--- a/headless/src/jsMain/kotlin/dev/fritz2/headless/components/modal.kt
+++ b/headless/src/jsMain/kotlin/dev/fritz2/headless/components/modal.kt
@@ -157,9 +157,9 @@ class Modal(val renderContext: RenderContext) : RenderContext by renderContext,
         initialize: ModalPanel<C>.() -> Unit
     ) {
         panel = {
-            tag(this, classes, id, internalScope) {
+            tag(this, classes, null, internalScope) {
                 addComponentStructureInfo("parent is modalPanel", this@modalPanel.scope, this)
-                ModalPanel(this).run {
+                ModalPanel(this, id).run {
                     initialize()
                     render()
                 }