Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.OneColumn
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.Phone
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.RadioButtons
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.Region
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.RichText
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.RootContainer
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.SimpleTable
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.SimpleTableManual
Expand Down Expand Up @@ -61,6 +62,7 @@ import com.pega.constellation.sdk.kmp.core.components.fields.EmailComponent
import com.pega.constellation.sdk.kmp.core.components.fields.IntegerComponent
import com.pega.constellation.sdk.kmp.core.components.fields.PhoneComponent
import com.pega.constellation.sdk.kmp.core.components.fields.RadioButtonsComponent
import com.pega.constellation.sdk.kmp.core.components.fields.RichTextComponent
import com.pega.constellation.sdk.kmp.core.components.fields.TextAreaComponent
import com.pega.constellation.sdk.kmp.core.components.fields.TextInputComponent
import com.pega.constellation.sdk.kmp.core.components.fields.TimeComponent
Expand Down Expand Up @@ -106,6 +108,7 @@ object ComponentRegistry {
Def(SimpleTableManual) { SimpleTableManualComponent(it) },
Def(SimpleTableSelect) { SimpleTableSelectComponent(it) },
Def(TextArea) { TextAreaComponent(it) },
Def(RichText) { RichTextComponent(it) },
Def(TextInput) { TextInputComponent(it) },
Def(Time) { TimeComponent(it) },
Def(URL) { UrlComponent(it) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ object ComponentTypes {
val Integer = ComponentType("Integer")
val Phone = ComponentType("Phone")
val RadioButtons = ComponentType("RadioButtons")
val RichText = ComponentType("RichText")
val TextArea = ComponentType("TextArea")
val TextInput = ComponentType("TextInput")
val Time = ComponentType("Time")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.pega.constellation.sdk.kmp.core.components.fields

import com.pega.constellation.sdk.kmp.core.api.ComponentContext

class RichTextComponent(context: ComponentContext) : FieldComponent(context)
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ androidx-test-junit = "1.3.0"
compose-hot-reload = "1.0.0"
compose-multiplatform = "1.9.0" # warning: update bumps kotlinx-datetime, which breaks iOS
compose-navigation = "2.9.1"
htmlconverter = "1.1.0"
kotlin = "2.2.21"
kotlinx-coroutines = "1.10.2"
kotlinx-datetime = "0.6.2" # warning: update breaks iOS compilation
Expand Down Expand Up @@ -43,6 +44,7 @@ androidx-ui-test-junit4-android = { group = "androidx.compose.ui", name = "ui-te
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version.ref = "uiautomator" }
androidx-webkit = { module = "androidx.webkit:webkit", version.ref = "webkit" }
htmlconverter = { module = "be.digitalia.compose.htmlconverter:htmlconverter", version.ref = "htmlconverter" }
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { FieldBaseComponent } from "./field-base.component.js";

export class RichTextComponent extends FieldBaseComponent {}
4 changes: 2 additions & 2 deletions scripts/dxcomponents/mappings/sdk-pega-component-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import { TimeComponent } from "../components/fields/time.component.js";
import { UrlComponent } from "../components/fields/url.component.js";
// import { UserReferenceComponent } from './_components/field/user-reference/user-reference.component';
// import { ScalarListComponent } from './_components/field/scalar-list/scalar-list.component';
// import { RichTextComponent } from './_components/field/rich-text/rich-text.component';
import { RichTextComponent } from "../components/fields/rich-text.component.js";
import { UnsupportedComponent } from "../components/widgets/unsupported.component.js";

// Template components
Expand Down Expand Up @@ -207,7 +207,7 @@ const pegaSdkComponentMap = {
reference: ReferenceComponent,
RadioButtons: RadioButtonsComponent,
Region: RegionComponent,
// RichText: RichTextComponent,
RichText: RichTextComponent,
// RichTextEditor: RichTextEditorComponent,
RootContainer: RootContainerComponent,
// ScalarList: ScalarListComponent,
Expand Down
1 change: 1 addition & 0 deletions ui-components-cmp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ kotlin {
implementation(libs.kotlinx.serialization.json)
implementation(libs.table.m3)
implementation(libs.compose.dnd)
implementation(libs.htmlconverter)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,21 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.unit.sp

@Composable
fun FieldValue(label: String, value: String) {
FieldValue(label, AnnotatedString(value))
}

@Composable
fun FieldValue(label: String, value: AnnotatedString) {
Column(modifier = Modifier.fillMaxWidth()) {
if (label.trim().isNotEmpty()) {
Text(label, fontSize = 14.sp, color = Color.Gray)
}
Text(value.ifEmpty { "---" }, fontSize = 14.sp)
val annotated = if (value.trim().isNotEmpty()) value else AnnotatedString("---")
Text(annotated, fontSize = 14.sp)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.pega.constellation.sdk.kmp.ui.components.cmp.controls.form

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.TextFieldValue
import be.digitalia.compose.htmlconverter.htmlToAnnotatedString
import com.pega.constellation.sdk.kmp.ui.components.cmp.controls.form.internal.Input

@Composable
fun RichText(
value: String,
label: String,
modifier: Modifier = Modifier,
helperText: String = "",
validateMessage: String = "",
required: Boolean = false,
disabled: Boolean = false,
readOnly: Boolean = false
) {
if (readOnly) {
// Read-only RichText renders on web as display-only
RichTextFieldValue(label, value)
} else {
Input(
value = TextFieldValue(rememberAnnotated(value)),
label = label,
modifier = modifier,
helperText = helperText,
validateMessage = validateMessage,
required = required,
disabled = disabled,
readOnly = true, // not allowing editing in RichText for now
lines = 3
)
}
}

@Composable
fun RichTextFieldValue(label: String, value: String) {
FieldValue(label, rememberAnnotated(value))
}

@Composable
private fun rememberAnnotated(value: String) =
remember(value) { htmlToAnnotatedString(value, compactMode = true) }
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.text.input.TextFieldValue
import com.pega.constellation.sdk.kmp.ui.components.cmp.controls.form.Label

@Composable
Expand All @@ -31,11 +32,52 @@ internal fun Input(
leadingIcon: @Composable (() -> Unit)? = null,
trailingIcon: @Composable (() -> Unit)? = null,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
) {
Input(
value = TextFieldValue(value),
label = label,
modifier = modifier,
helperText = helperText,
validateMessage = validateMessage,
hideLabel = hideLabel,
placeholder = placeholder,
required = required,
disabled = disabled,
readOnly = readOnly,
onValueChange = onValueChange,
onFocusChange = onFocusChange,
lines = lines,
keyboardOptions = keyboardOptions,
leadingIcon = leadingIcon,
trailingIcon = trailingIcon,
interactionSource = interactionSource
)
}

@Composable
internal fun Input(
value: TextFieldValue,
label: String,
modifier: Modifier = Modifier,
helperText: String = "",
validateMessage: String = "",
hideLabel: Boolean = false,
placeholder: String = "",
required: Boolean = false,
disabled: Boolean = false,
readOnly: Boolean = false,
onValueChange: (String) -> Unit = {},
onFocusChange: (Boolean) -> Unit = {},
lines: Int = 1,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
leadingIcon: @Composable (() -> Unit)? = null,
trailingIcon: @Composable (() -> Unit)? = null,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
) {
Column(modifier = modifier) {
OutlinedTextField(
value = value,
onValueChange = onValueChange,
onValueChange = { onValueChange(it.text) },
modifier = Modifier
.fillMaxWidth()
.onFocusChanged { onFocusChange(it.isFocused) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.OneColumn
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.Phone
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.RadioButtons
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.Region
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.RichText
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.RootContainer
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.SimpleTable
import com.pega.constellation.sdk.kmp.core.components.ComponentTypes.SimpleTableManual
Expand Down Expand Up @@ -63,6 +64,7 @@ import com.pega.constellation.sdk.kmp.ui.renderer.cmp.fields.EmailRenderer
import com.pega.constellation.sdk.kmp.ui.renderer.cmp.fields.IntegerRenderer
import com.pega.constellation.sdk.kmp.ui.renderer.cmp.fields.PhoneRenderer
import com.pega.constellation.sdk.kmp.ui.renderer.cmp.fields.RadioButtonsRenderer
import com.pega.constellation.sdk.kmp.ui.renderer.cmp.fields.RichTextRenderer
import com.pega.constellation.sdk.kmp.ui.renderer.cmp.fields.TextAreaRenderer
import com.pega.constellation.sdk.kmp.ui.renderer.cmp.fields.TextInputRenderer
import com.pega.constellation.sdk.kmp.ui.renderer.cmp.fields.TimeRenderer
Expand Down Expand Up @@ -104,6 +106,7 @@ object ComponentRenderers {
RadioButtons to RadioButtonsRenderer(),
Region to RegionRenderer(),
RootContainer to RootContainerRenderer(),
RichText to RichTextRenderer(),
SimpleTable to SimpleTableRenderer(),
SimpleTableManual to SimpleTableManualRenderer(),
SimpleTableSelect to SimpleTableSelectRenderer(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.pega.constellation.sdk.kmp.ui.renderer.cmp.fields

import androidx.compose.runtime.Composable
import com.pega.constellation.sdk.kmp.core.components.fields.RichTextComponent
import com.pega.constellation.sdk.kmp.ui.components.cmp.controls.form.RichText
import com.pega.constellation.sdk.kmp.ui.components.cmp.controls.form.RichTextFieldValue
import com.pega.constellation.sdk.kmp.ui.renderer.cmp.ComponentRenderer
import com.pega.constellation.sdk.kmp.ui.renderer.cmp.helpers.WithFieldHelpers

class RichTextRenderer : ComponentRenderer<RichTextComponent> {
@Composable
override fun RichTextComponent.Render() {
WithFieldHelpers(
displayOnly = {
RichTextFieldValue(label, value)
},
editable = {
RichText(
value = value,
label = label,
helperText = helperText,
validateMessage = validateMessage,
required = required,
disabled = disabled,
readOnly = readOnly
)
}
)
}
}