Skip to content
Open
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
@@ -0,0 +1,60 @@
---
title: AiUserMessage
---

Компонент AiUserMessage используется для отображения запроса пользователя в ИИ-сценариях.

В `isInEdit` отображает редактируемое поле в виде компонента [Editable](EditableUsage.md),
при переходе в этот режим, Editable захватывает фокус и активизируется ввод текста.
В обычном режиме текст отображается посредстов мкомпонента [Text](TextUsage.md). С помощью `actions`
и `editableActions` передайте контент для взаимодействия [ButtonGroup](ButtonGroupUsage.md) кнопки в
группах стилизуются автоматически. Для отображения загружаемого пользователем контента используйте
`uploadingContent` компоненты File и Image так же будут стилизованы автоматически.


## Простой пример использования

```kotlin
// @sample: com/sdds/compose/uikit/fixtures/samples/aiusermessage/AiUserMessage_Simple.kt
```

## Пример использования с контентом для взаимодействия

```kotlin
// @sample: com/sdds/compose/uikit/fixtures/samples/aiusermessage/AiUserMessage_WithActions.kt
```

## Пример использования с контентом для взаимодействия отображающимся в редактируемом режиме

```kotlin
// @sample: com/sdds/compose/uikit/fixtures/samples/aiusermessage/AiUserMessage_WithEditableActions.kt
```

## Полный пример использования

```kotlin
// @sample: com/sdds/compose/uikit/fixtures/samples/aiusermessage/AiUserMessage_FullUsage.kt
```


## Стиль AiUserMessage

В большинстве случаев можно использовать готовые сгенерированные стили, а при необходимости создать
собственный стиль через метод `builder()`. Подробнее о том, как работают `Style`, `StyleBuilder`
и параметры стиля с состояниями, см. в разделе [Стилизация компонентов](../theme/Styles.md).

<!-- @style-api -->

### Создание стиля с помощью builder()

```kotlin
// @sample: com/sdds/compose/uikit/fixtures/samples/aiusermessage/AiUserMessage_Style.kt
```

## Слоты

- `value` - начальное значение отображаемого текста.
- `onValueChange` - поведение при изменении текстового значания.
- `isInEdit` - переводит компонент в режим редактирования.
- `actions` и `editableActions` - слоты с областью видимости `ButtonGroupScope`, каждый отрисовывается в отдельном ButtonGroup.
- `uploadingContent` - слот с областью видимости `ColumnScope`, отрисовывается внутри Column.
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ data class ComponentKey(
val DropZone = ComponentKey(CoreComponentName.DROP_ZONE)
val AiHeader = ComponentKey(CoreComponentName.AI_HEADER)
val Splitter = ComponentKey(CoreComponentName.SPLITTER)
val AiUserMessage = ComponentKey(CoreComponentName.AI_USER_MESSAGE)
}
}

Expand Down Expand Up @@ -261,6 +262,7 @@ private enum class CoreComponentName(displayName: String? = null) {
EDITABLE,
AI_HEADER,
DROP_ZONE,
AI_USER_MESSAGE,
SPLITTER,
;

Expand Down Expand Up @@ -369,6 +371,7 @@ private fun CoreComponentName.group(): ComponentGroup {
CoreComponentName.FLOW -> CoreComponentGroup.LAYOUT
CoreComponentName.AI_HEADER,
CoreComponentName.AI_ANSWER,
CoreComponentName.AI_USER_MESSAGE,
-> CoreComponentGroup.AI_KIT
}.let { ComponentGroup(it.displayName, it.ordinal) }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
package com.sdds.compose.uikit.fixtures.samples.aiusermessage

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import com.sdds.compose.docs.composableCodeSnippet
import com.sdds.compose.uikit.Button
import com.sdds.compose.uikit.ButtonGroupStyle
import com.sdds.compose.uikit.EditableStyle
import com.sdds.compose.uikit.File
import com.sdds.compose.uikit.FileActionPlacement
import com.sdds.compose.uikit.FileStyle
import com.sdds.compose.uikit.Icon
import com.sdds.compose.uikit.IconButton
import com.sdds.compose.uikit.ImageStyle
import com.sdds.compose.uikit.ai.AiUserMessage
import com.sdds.compose.uikit.ai.AiUserMessageStyle
import com.sdds.docs.DocSample
import com.sdds.icons.R

@Composable
@DocSample(needScreenshot = true)
fun AiUserMessage_Simple() {
composableCodeSnippet {
var text by remember { mutableStateOf("text") }
AiUserMessage(
modifier = Modifier.fillMaxWidth(),
value = text,
onValueChange = { text = it },
)
}
}

@Composable
@DocSample(needScreenshot = true)
fun AiUserMessage_WithActions() {
composableCodeSnippet {
var text by remember { mutableStateOf("text") }
AiUserMessage(
modifier = Modifier.fillMaxWidth(),
value = text,
onValueChange = { text = it },
actions = {
button { IconButton(iconRes = R.drawable.ic_backward_outline_24, onClick = {}) }
button { IconButton(iconRes = R.drawable.ic_copy_outline_24, onClick = {}) }
},
)
}
}

@Composable
@DocSample(needScreenshot = true)
fun AiUserMessage_WithEditableActions() {
composableCodeSnippet {
var text by remember { mutableStateOf("text") }
AiUserMessage(
modifier = Modifier.fillMaxWidth(),
value = text,
isInEdit = true,
onValueChange = { text = it },
editableActions = {
button {
Button(label = "Сохранить", onClick = {})
}
button {
Button(label = "Отменить", onClick = {})
}
},
actions = {
button { IconButton(iconRes = R.drawable.ic_backward_outline_24, onClick = {}) }
button { IconButton(iconRes = R.drawable.ic_copy_outline_24, onClick = {}) }
},
)
}
}

@Composable
@DocSample(needScreenshot = true)
fun AiUserMessage_FullUsage() {
composableCodeSnippet {
var editMode by remember { mutableStateOf(false) }
var message by remember { mutableStateOf("Text") }
var draftMessage by remember { mutableStateOf("") }

AiUserMessage(
modifier = Modifier.fillMaxWidth(),
value = if (editMode) draftMessage else message,
onValueChange = { draftMessage = it },
isInEdit = editMode,
uploadingContent =
{
repeat(5) {
File(
modifier = Modifier.width(200.dp),
label = "some_file$it.pdf",
isLoading = false,
image = {
Icon(
painterResource(R.drawable.ic_file_check_fill_24),
contentDescription = "",
)
},
action = {
IconButton(
iconRes = R.drawable.ic_close_16,
onClick = {},
)
},
actionPlacement = FileActionPlacement.End,
)
}
},
editableActions =
{
button {
Button(label = "Сохранить", onClick = {
message = draftMessage
editMode = false
})
}
button {
Button(label = "Отменить", onClick = {
draftMessage = message
editMode = false
})
}
},
actions =
{
button { IconButton(iconRes = R.drawable.ic_backward_outline_24, onClick = {}) }
button { IconButton(iconRes = R.drawable.ic_copy_outline_24, onClick = {}) }
button { IconButton(iconRes = R.drawable.ic_plasma_24, onClick = {}) }
button {
IconButton(iconRes = R.drawable.ic_edit_outline_24, onClick = {
draftMessage = message
editMode = true
})
}
},
)
}
}

@Composable
@DocSample(needScreenshot = false)
fun AiUserMessage_Style() {
composableCodeSnippet {
AiUserMessageStyle.builder()
.uploadingShape(placeholder(RoundedCornerShape(0.dp), "/** Токен формы (скругления) */"))
.messageShape(placeholder(RoundedCornerShape(0.dp), "/** Токен формы (скругления) */"))
.textStyle(placeholder(TextStyle.Default, "/** Токен типографики */"))
.editableStyle(
placeholder(
EditableStyle.builder().style(),
"/** Стиль редактируемого поля */",
),
)
.actionsButtonGroupStyle(
placeholder(
ButtonGroupStyle.builder().style(),
"/** Стиль группы кнопок, расположенных внизу */",
),
)
.editableActionsButtonGroupStyle(
placeholder(
ButtonGroupStyle.builder().style(),
"/** Стиль группы кнопок, отображающихся в режиме редактирования */",
),
)
.uploadingImageStyle(
placeholder(
ImageStyle.builder().style(),
"/** Стиль загружаемых изображений */",
),
)
.uploadingFileStyle(
placeholder(
FileStyle.builder().style(),
"/** Стиль загружаемых файлов */",
),
)
.colors {
textColor(placeholder(Color.White, "/** Токен цвета */"))
uploadingBackground(placeholder(Color.White, "/** Токен цвета */"))
messageBackground(placeholder(Color.White, "/** Токен цвета */"))
}
.dimensions {
uploadingPaddingStart(0.0.dp)
uploadingPaddingEnd(0.0.dp)
uploadingPaddingTop(0.0.dp)
uploadingPaddingBottom(0.0.dp)
messagePaddingStart(18.0.dp)
messagePaddingEnd(18.0.dp)
messagePaddingTop(21.0.dp)
messagePaddingBottom(21.0.dp)
uploadingGroupGap(10.0.dp)
uploadingFilesGap(0.0.dp)
actionsGap(12.0.dp)
editableActionsGap(16.0.dp)
}
.style()
}
}
Loading
Loading