Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spec for Spright chat components #2513

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 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,7 @@
{
"type": "none",
"comment": "Spec for Spright chat components",
"packageName": "@ni/spright-components",
"email": "jattasNI@users.noreply.github.com",
"dependentChangeType": "none"
}
252 changes: 252 additions & 0 deletions packages/spright-components/src/chat/specs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
# Chat components

## Overview

This spec describes a set of components that can be used to compose a chat interface. This includes:

- chat message: a single entry in a chat conversation, including some content and metadata about the message
- chat conversation: a collection of messages that are laid out to convey the order the messages were sent

### Background

Some Intelligent Test application teams are beginning development on chat interfaces in early 2025. Developers from one of those teams will build these components as their first Nimble contribution.

Initial designer-vetted visual designs exist in [Nimble_Components Figma](https://www.figma.com/design/PO9mFOu5BCl8aJvFchEeuN/Nimble_Components?node-id=12342-81782&node-type=canvas&t=L5GvLaC3injrqWrR-0).

There is not yet an interaction design specification for these components.

This work started with an innovation project ([branch](/~https://github.com/ni/nimble/compare/main...spright-chat-components)) and is not yet tracked with an issue.

### Containing Library

These components will initially be added to Spright. Per [Spright contributing guidelines](/packages/spright-components/CONTRIBUTING.md):

1. there is not yet an approved interaction design
2. we are unsure if the components are sufficiently atomic or general purpose to belong in Nimble
3. there is a short development timeline so it may be necessary to defer fulfilling other Nimble requirements like accessibility and support for all frameworks

### Non-goals

The components will only provide the presentation layer, not logic for interacting with each other or any service to add messages to a conversation.

The message component will allow slotting arbitrary content, but any efforts to add content types to Nimble are out of scope of this document. For example, adding capabilities to the rich text viewer or adding styling for specific content types.

### Features

#### Chat message

1. Display arbitrary slotted content. For example: text, rich text, buttons, or a spinner.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had a meeting with LV about their AI assistant and they require showing an image of the VI connector. The same image LV shows in a VI's context help. So, we require supporting images.

Another feature they want is the ability to add buttons at the top-right of a message respond. The scenario UX showed was generating multiple VI descriptions and having '<' and '>' buttons to see them one at time. There will also be a button or a dropdown to allow the user to ask the AI to try again with some options from the dropdown. Alice is working on the UX design. I will ask her to send me a link so you can see it.

Copy link
Contributor Author

@jattasNI jattasNI Jan 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add images to the list of example content. With this design the message content is entirely up to the client application so supporting images wouldn't take any additional work. However at some point (outside the scope of this spec) we'll want to discuss how we plan to do that: if we want to use Nimble's rich text viewer we would need to enhance its capabilities.

I'll be interested to see those new designs. If they're within the body of the message then we can support it with the proposed approach. If they're separate content that are positioned by the message then we may want to add some new slots or attributes. We could tackle that in a follow up update to this document.

1. Layout content to the right, center, or left of parent container depending on metadata about who sent the message.
1. Size based on content size with maximum width (but not height) based on parent's width.
1. Change the styling of the message depending on metadata about who sent the message. For example: render user messages in a bubble with the tail pointing to the right but render system messages with no styling.

#### Chat conversation

1. Lays out messages vertically based on their order.
1. Displays a vertical scrollbar if there are more messages than fit in the height allocated to the conversation.
1. Only appearance of its own is to set a background color.

### Risks and Challenges

These components are competing against possible implementations within applications. Depending on who implements these components, the overhead of learning the Nimble repo's tech stack could introduce a small risk.

### Prior Art/Examples

**Screenshot of Figma design of chat and conversation component (light mode)**
![ ](spec-images/chat-conversation.png)

**Screenshot of Figma design of chat components embeded within larger pane (dark mode)**
![ ](spec-images/chat-pane.png)

---

## Design

### Examples

#### Text conversation example

```html
<spright-chat-conversation>
<spright-chat-message status="incoming">
Hi, how can I help?
</spright-chat-message>
<spright-chat-message status="outgoing">
I need to analyze my data to find anomalies.
</spright-chat-message>
<spright-chat-message status="system">
<nimble-spinner></nimble-spinner>
</spright-chat-message>
</spright-chat-conversation>
```

#### Rich text message example

```html
<spright-chat-conversation>
<spright-chat-message status="incoming">
<nimble-rich-text-viewer id="welcome"></nimble-rich-text-viewer>
</spright-chat-message>
</spright-chat-conversation>
```

```js
const richText = document.querySelector('#welcome');
richText.markdown = 'Welcome **Homer**, how can I help?';
```

#### Prompt buttons message example

```html
<spright-chat-message status="system">
<nimble-button appearance="block">Help with my taxes</nimble-button>
<nimble-button appearance="block">Provide me some life advice</nimble-button>
</spright-chat-message
```

### API

#### Message

- _Component Name_ `spright-chat-message`
- _Props/Attrs_
- `status = "incoming" | "outgoing" | "system"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason we went for status over appearance was the concern we might want block / ghost / outline versions or something? Or I guess we could have appearance bubble (sms-style) vs threaded (slack/discord-style), etc. in the future. Edit: actually I don't think that appearance would be per message but instead per conversation.

The name status doesn't feel quite right, feel like status is a transitory thing like "in progress", "delayed", etc. Like the status of a message could be loading or is-typing or failed-to-send or something.

Did we already think about type or mode? Other options didn't come to mind yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any preference of incoming/outgoing vs inbound/outbound? Seems like the latter is used more for tech / messaging (email inbox, sms, etc). Looks like the terms used in lightning as well (didn't search more broadly): https://www.lightningdesignsystem.com/components/chat/

- _Methods_
- _Events_
- _CSS Classes and CSS Custom Properties that affect the component_
- _How native CSS Properties (height, width, etc.) affect the component_
- A message will grow its width to fit its content, up to a maximum width.
- A message will grow its height to fit its content, with no maximum height.
- Clients could override this behavior but we don't anticipate use cases for doing so when the message is used within a conversation
- _Slots_

- arbitrary content can be added to the default slot to be displayed within the message

#### Conversation

- _Component Name_ `spright-chat-conversation`
- _Props/Attrs_
- _Methods_
- _Events_
- _CSS Classes and CSS Custom Properties that affect the component_
- _How native CSS Properties (height, width, etc.) affect the component_
- Clients can size the conversation using normal CSS rules.
- The conversation will show a scrollbar if content overflows vertically.
- The conversation will have a minimum width that clients are discouraged from overriding.
- _Slots_
- chat messages are added to the default slot. The DOM order of the messages controls their screen order within the conversation (earlier DOM order => earlier message => top of the conversation)

### Anatomy

#### Message

A message is simply a `div` which will styled with background / border / rounded corners and the default slot for the message contents.

```html
<template>
<div>
<slot></slot>
</div>
</template>
```

#### Conversation

Other than setting a background, a conversation has no appearance of its own and simply contains the default slot for messages.

```html
<template>
<slot></slot>
</template>
```

### Native form integration

Native form integration is not needed for these components.

### Angular integration
jattasNI marked this conversation as resolved.
Show resolved Hide resolved

Angular integration has not yet been evaluated. It is not anticipated to be needed for initial clients.

_Describe the plan for Angular support, including directives for attribute binding and ControlValueAccessor for form integration. Depending on the contributor's needs, implementing Angular integration may be deferred but the initial spec should still document what work will be needed._

### Blazor integration

Blazor integration has not yet been evaluated. It is anticipated to be needed for initial clients so this section will be completed before Blazor development begins.

_Describe the plan for Blazor support, including form integration. See the [nimble-blazor CONTRIBUTING.md](/packages/blazor-workspace/NimbleBlazor/CONTRIBUTING.md) for details. Depending on the contributor's needs, implementing Blazor integration may be deferred but the initial spec should still document what work will be needed._

### Visual Appearance

Initial designer-vetted visual designs exist in [Nimble_Components Figma](https://www.figma.com/design/PO9mFOu5BCl8aJvFchEeuN/Nimble_Components?node-id=12342-81782&node-type=canvas&t=L5GvLaC3injrqWrR-0).

---

## Implementation

### States

None.

### Accessibility

Accessibility has not yet been evaluated.

_Consider the accessibility of the component, including:_

- _Keyboard Navigation and Focus_
- _Form Input and Autofill_
- _Use with Assistive Technology. For example:_
- _All components should define a role and support labels / being labelled so that assistive technology can identify them_
- _The implications shadow dom might have on how roles and attributes are presented in the accessibility tree_
- _Components which delegate focus require all global ARIA attributes to be enumerated_
- _Components should either follow an existing [ARIA Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/) or provide thorough research indicating why a new pattern is appropriate. Research should include sources like [Open UI Community Group](/~https://github.com/openui/open-ui) and other popular design systems._
- _Behavior with browser configurations like "Prefers reduced motion"_
- _Support for standard link behaviors if the component is an anchor or contains an anchor. These behaviors are enumerated in the [anchor-patterns story](/packages/nimble-components/src/patterns/anchor/tests/anchor-patterns.mdx). The story should be updated to include the new component._

### Mobile

Component layout will be tested at small screen sizes. The plans for content sizing and showing scrollbars should allow for adequate mobile layout. But initially there will be no specific testing of mobile behaviors as initial clients are desktop applications.

### Globalization

The content is provided by applications so they are responsible for localization.

Defining the behavior for RTL languages is initially out of scope. But the API can easily be extended to support changing the layout for an RTL language when that is desired.

### Security

Applications are responsible for the security of the content added to messages. These components will not provide any validation or sanitization.

### Performance

Applications should consider the performance of conversations with large, complex, or numerous messages. Applications can add virtualization features like a "load more messages" button with no change to the chat components. Other virtualization features like loading more messages when scrolling near the end of a conversation should be trivial to add but are out of scope of this document.

### Dependencies

No new dependencies.

### Test Plan

Typical unit tests and Chromatic visual tests. Spright maintains the same testing standards as Nimble.

### Tooling

This is likely the first Spright components most applications will adopt so they will need to add a new dependency. Blazor applications should follow [the Spright Blazor README](/~https://github.com/ni/nimble/blob/spright-chat-components/packages/blazor-workspace/SprightBlazor/README.md#getting-started) to set up this dependency.

### Documentation

Standard Storybook documentation. Since these are a Spright components we should ensure the documentation conveys the component status and gaps.

There are parallel efforts to standardize and document other aspects of chat applications (for example the tone and language used by automated conversation participants) that are out of scope of this document.

---

## Open Issues

1. Should we introduce an input toolbar component where a user can type messages and interact with related buttons? Or should applications construct this using the existing Nimble toolbar?
- Pros of dedicated component:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to have a dedicated component based on the pros. I do agree it is better to have the toolbar in a single place so it can be updated in a single place.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we may have different answers in the short term and medium/long term. My current leaning for the first pass is to just focus on the message and conversation and not create a toolbar in Spright. That gives the dev team time to get up to speed and the UX team time to solidify the toolbar UX more.

Then once we know more in a few weeks/months if we find we still want a toolbar it's easy to add it.

1. consistent layout and reduced implementation effort across applications
1. single implementation to change if requirements change
- Pros of applications leveraging Nimble toolbar:
jattasNI marked this conversation as resolved.
Show resolved Hide resolved
1. dedicated component would require a large API surface area for configuring the visibility and enabled state of numerous buttons and firing events when the user interacts with the toolbar inputs.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading