Repository: jwstegemann/fritz2
Issue: Fix internal (selection) store handling of components with custom events context

Currently the following components offer a custom ``events`` context with events tailored to the specific component:
- DataTable
- SelectField
- CheckboxGroup
- RadioGroup

You have the option to pass a dedicated store into the factory function, in order to set the (selected) values automatically.
But the API offers also the possibility, to manually configure the selection events:
```kotlin
val languages = listOf("javascript", "java", "kotlin", "scala")
val selectedLanguage = storeOf("")
selectField(items = languages, value = selectedLanguage /* (A) pass in a store for handling the selection */) {
    placeholder("Select your favorite programming language")
    events {
        selected.map handledBy someOtherHandler // (B) manually react to a selection
    }
}
```
The *explicitly* declared (additional) event handling in case (B) gets overriden currently! This is clearly buggy.

It should be possible to use both event-processing in parallel. 

(A typical use case might to advance within a sequential user input within a wizard alike form. By choosing a value, the next step should get activated as well as the selected value should be stored somewhere)

## Solution

Don't replace the user's ``event`` context declarations with the one that ties the *internal* store to the externally injected one.
Instead pass the internal store's flow to the ``update``-handler of the external store *directly*:
```kotlin
// until now
EventsContext(this, multiSelectionStore.toggle).apply {
    this@CheckboxGroupComponent.events.value(this)
    // Don't do this anymore!
    this@CheckboxGroupComponent.values?.let { selected handledBy it.update }
}

// much better (could be placed near to the preselection handling)
this@CheckboxGroupComponent.values?.let { multiSelectionStore.data handledBy it.update }
```

Changed files:
components/src/jsMain/kotlin/dev/fritz2/components/datatable/component.kt

diff --git a/components/src/jsMain/kotlin/dev/fritz2/components/datatable/component.kt b/components/src/jsMain/kotlin/dev/fritz2/components/datatable/component.kt
index 2fac7162..e43767de 100644
--- a/components/src/jsMain/kotlin/dev/fritz2/components/datatable/component.kt
+++ b/components/src/jsMain/kotlin/dev/fritz2/components/datatable/component.kt
@@ -158,15 +158,24 @@ open class DataTableComponent<T, I>(val dataStore: RootStore<List<T>>, protected
         context.apply {
             this@DataTableComponent.dataStore.data handledBy this@DataTableComponent.selectionStore.syncHandler
 
-            // preset selection via external store or flow
+            // preset selection via external store or flow and forward selection to external store
             when (this@DataTableComponent.selection.value.selectionMode) {
-                SelectionMode.Single ->
+                SelectionMode.Single -> {
                     (this@DataTableComponent.selection.value.single?.store?.value?.data
                         ?: this@DataTableComponent.selection.value.single?.row!!.values) handledBy
                             this@DataTableComponent.selectionStore.updateRow
-                SelectionMode.Multi -> (this@DataTableComponent.selection.value.multi?.store?.value?.data
-                    ?: this@DataTableComponent.selection.value.multi?.rows!!.values) handledBy
-                        this@DataTableComponent.selectionStore.update
+                    this@DataTableComponent.selection.value.single!!.store.value?.let {
+                        this@DataTableComponent.selectionStore.selectedData.map { it.firstOrNull() } handledBy it.update
+                    }
+                }
+                SelectionMode.Multi -> {
+                    (this@DataTableComponent.selection.value.multi?.store?.value?.data
+                        ?: this@DataTableComponent.selection.value.multi?.rows!!.values) handledBy
+                            this@DataTableComponent.selectionStore.update
+                    this@DataTableComponent.selection.value.multi!!.store.value?.let {
+                        this@DataTableComponent.selectionStore.selectedData handledBy it.update
+                    }
+                }
                 else -> Unit
             }
 
@@ -185,18 +194,6 @@ open class DataTableComponent<T, I>(val dataStore: RootStore<List<T>>, protected
                 position { relative { } }
             }) {
                 this@DataTableComponent.renderTable(baseClass, id, prefix, this@DataTableComponent.rowIdProvider, this)
-
-                // tie selection to external store if needed
-                when (this@DataTableComponent.selection.value.selectionMode) {
-                    SelectionMode.Single -> this@DataTableComponent.selection.value.single!!.store.value?.let {
-                        this@DataTableComponent.events { selectedRow handledBy it.update }
-                    }
-                    SelectionMode.Multi -> this@DataTableComponent.selection.value.multi!!.store.value?.let {
-                        this@DataTableComponent.events { selectedRows handledBy it.update }
-                    }
-                    else -> Unit
-                }
-
                 EventsContext(this, this@DataTableComponent.selectionStore).apply {
                     this@DataTableComponent.events.value(this)
                 }
@@ -340,7 +337,7 @@ open class DataTableComponent<T, I>(val dataStore: RootStore<List<T>>, protected
                 tr {
                     component.stateStore.renderingHeaderData(component)
                         .renderEach(component.columnStateIdProvider) { (column, sorting) ->
-                           th({
+                            th({
                                 Sorting.sorted(sorting.strategy)
                                 Theme().dataTableStyles.headerStyle(
                                     this,
@@ -348,7 +345,7 @@ open class DataTableComponent<T, I>(val dataStore: RootStore<List<T>>, protected
                                 )
                                 component.header.value.styling.value()
                                 column.headerStyling(this, sorting.strategy)
-                            })  {
+                            }) {
                                 flexBox({
                                     height { "100%" }
                                     position { relative { } }