Conversation

Description

Conversation lays out an issue-tracker style discussion: ConversationComment cards joined by a vertical rail, with ConversationEvent rows between them for changes such as a label added or the thread closed. A comment has an avatar, an action and timestamp, role badges, an optional "…" menu, a Markdown body rendered by a MarkdownBlock, attachments and emoji reactions. A ConversationComposer with Write / Preview tabs can be placed at the foot of the thread with .Composer(...). .Compact() switches every item, including ones added later, to a denser layout.

Usage

Create the thread with Conversation() and add comments and events with .Children(...) or .Add(...). The composer's OnSubmit callback receives the Markdown text; the sample adds it to the thread as a new comment.

The same items in compact form, with a Highlighted() comment and events whose rail icon is filled with Tone(...):

API reference

class

Conversation

public sealed class Conversation : IComponent, IHasMarginPadding

A discussion thread in the shape of an issue tracker's conversation: a column of ConversationComment cards joined by a vertical rail, with ConversationEvent rows for what happened in between (labels added, someone assigned, the thread closed) and an optional ConversationComposer at the foot. Any other IComponent can be added as an item too, and sits on the rail like the rest.

Remarks

Pair it with a MetadataPanel beside it for the assignees / labels / milestone column.

Namespace
Tesserae
Implements
IComponent, IHasMarginPadding

Constructors

NameDescription
ConversationInitializes a new, empty conversation.
Constructor
Conversation
public Conversation()

Initializes a new, empty conversation.

Properties

NameDescription
Margin
Padding
ItemsThe items in the conversation, in the order they were added.
IsCompactWhether the thread is drawn in its dense form (see Compact).
Property
Conversation.Margin
public string Margin { get ; set ; }
Property
Conversation.Padding
public string Padding { get ; set ; }
Property
Conversation.Items
public IReadOnlyList<IComponent> Items

The items in the conversation, in the order they were added.

Property
Conversation.IsCompact
public bool IsCompact { get ; set ; }

Whether the thread is drawn in its dense form (see Compact).

Methods

NameDescription
AddAppends an item - a comment, an event or any other component - to the end of the thread.
ChildrenAppends several items to the end of the thread.
RemoveRemoves an item from the thread.
ClearRemoves every item from the thread. The composer stays.
CompactDraws the thread densely: tighter comment headers and bodies, smaller avatars, reaction chips and rail icons, less space between items and a shorter composer - for a thread in a side panel, or a long one that should fit more on screen. It applies to everything in the thread, including items added later.
ComposerSets what sits under the last item, off the rail: usually a ConversationComposer. Pass null to remove it.
RenderRenders the component.
Method
Conversation.Add
public Conversation Add(IComponent item)

Appends an item - a comment, an event or any other component - to the end of the thread.

Method
Conversation.Children
public Conversation Children(params IComponent[] items)

Appends several items to the end of the thread.

Method
Conversation.Remove
public Conversation Remove(IComponent item)

Removes an item from the thread.

Method
Conversation.Clear
public Conversation Clear()

Removes every item from the thread. The composer stays.

Method
Conversation.Compact
public Conversation Compact(bool value = true)

Draws the thread densely: tighter comment headers and bodies, smaller avatars, reaction chips and rail icons, less space between items and a shorter composer - for a thread in a side panel, or a long one that should fit more on screen. It applies to everything in the thread, including items added later.

Method
Conversation.Composer
public Conversation Composer(IComponent composer)

Sets what sits under the last item, off the rail: usually a ConversationComposer. Pass null to remove it.

Method
Conversation.Render
public HTMLElement Render()

Renders the component.

class

ConversationComment

public sealed class ConversationComment : ComponentBase<ConversationComment, HTMLElement>

One comment in a Conversation: a card whose header names the author (with their Avatar), what they did and when, carries their role badges and an overflow menu, and whose body is Markdown (rendered by a MarkdownBlock) or any component. Images or other attachments go under the body, and emoji reactions in a row at the foot.

Namespace
Tesserae
Inheritance
ComponentBase<ConversationComment, HTMLElement> → ConversationComment

Constructors

NameDescription
ConversationCommentInitializes a new comment.
Constructor
ConversationComment
public ConversationComment(string author, string markdown = null, string timestamp = null, Avatar avatar = null)

Initializes a new comment.

Parameters

author
The name shown in bold at the start of the header.
markdown
The body, as Markdown. Pass null to set a component body later with Body.
timestamp
When it was posted, as display text (e.g. "on Jul 22", "3 days ago").
avatar
The author's avatar. Defaults to one made from the author's initials.

Properties

NameDescription
AuthorThe author's name.
MarkdownThe Markdown body, or null when the body is a component.
Property
ConversationComment.Author
public string Author

The author's name.

Property
ConversationComment.Markdown
public string Markdown

The Markdown body, or null when the body is a component.

Methods

NameDescription
SetAuthorSets the author's name.
SetAvatarSets the avatar shown at the start of the header. It is drawn at XSmall.
ActionSets the verb between the author and the time - "commented" by default, "opened" for the first post of an issue, "replied", ...
TimestampSets when the comment was posted, as display text, with an optional tooltip (typically the full date and time).
EditedShows (or hides) the "edited" marker after the time, with an optional tooltip such as who edited it and when.
RoleAdds an outlined role badge to the right of the header - "Author", "Member", "Contributor", "Bot", ...
ClearRolesRemoves every role badge.
MenuGives the header an overflow ("…") button that opens a menu with these items - copy link, quote reply, edit, delete, ...
BodySets the body to Markdown, rendered and sanitized by a MarkdownBlock.
AttachmentAdds an attachment under the body - an Image (a screenshot), a file card, anything. Several attachments wrap in a row.
ReactionAdds (or updates) a reaction chip at the foot of the comment. reacted marks the chip as one the current user has added. A chip whose count reaches zero is removed.
OnReactRegisters a callback for when the current user adds or removes a reaction, by clicking a chip or picking one from the add-reaction button (which this also shows). The arguments are the comment, the emoji and whether it is now added. The chip has already been updated when it is called.
ReactionChoicesSets the emoji the add-reaction button offers. Defaults to DefaultReactions.
GetReactionThe count of a reaction, and whether the current user is one of those who added it.
HighlightedMarks the comment as highlighted - a primary border, as for the comment a link points to, or the one a reader is replying to.
RenderRenders the component.
Method
ConversationComment.SetAuthor
public ConversationComment SetAuthor(string author)

Sets the author's name.

Method
ConversationComment.SetAvatar
public ConversationComment SetAvatar(Avatar avatar)

Sets the avatar shown at the start of the header. It is drawn at XSmall.

Method
ConversationComment.Action
public ConversationComment Action(string action)

Sets the verb between the author and the time - "commented" by default, "opened" for the first post of an issue, "replied", ...

Method
ConversationComment.Timestamp
public ConversationComment Timestamp(string text, string tooltip = null)

Sets when the comment was posted, as display text, with an optional tooltip (typically the full date and time).

Method
ConversationComment.Edited
public ConversationComment Edited(bool edited = true, string tooltip = null)

Shows (or hides) the "edited" marker after the time, with an optional tooltip such as who edited it and when.

Method
ConversationComment.Role
public ConversationComment Role(string role)

Adds an outlined role badge to the right of the header - "Author", "Member", "Contributor", "Bot", ...

Method
ConversationComment.ClearRoles
public ConversationComment ClearRoles()

Removes every role badge.

Method
ConversationComment.Menu
public ConversationComment Menu(params ContextMenu.Item[] items)

Gives the header an overflow ("…") button that opens a menu with these items - copy link, quote reply, edit, delete, ...

Method
ConversationComment.Body
Overload
Body(string, MarkdownSanitization)Sets the body to Markdown, rendered and sanitized by a MarkdownBlock.
Body(IComponent)Sets the body to any component.
Body(string, MarkdownSanitization)
public ConversationComment Body(string markdown, MarkdownSanitization sanitization = MarkdownSanitization.Default)

Sets the body to Markdown, rendered and sanitized by a MarkdownBlock.

Parameters

markdown string
sanitization MarkdownSanitization
Body(IComponent)
public ConversationComment Body(IComponent content)

Sets the body to any component.

Parameters

content IComponent
Method
ConversationComment.Attachment
public ConversationComment Attachment(IComponent attachment)

Adds an attachment under the body - an Image (a screenshot), a file card, anything. Several attachments wrap in a row.

Method
ConversationComment.Reaction
public ConversationComment Reaction(string emoji, int count, bool reacted = false)

Adds (or updates) a reaction chip at the foot of the comment. reacted marks the chip as one the current user has added. A chip whose count reaches zero is removed.

Method
ConversationComment.OnReact
public ConversationComment OnReact(Action<ConversationComment, string, bool> onReact)

Registers a callback for when the current user adds or removes a reaction, by clicking a chip or picking one from the add-reaction button (which this also shows). The arguments are the comment, the emoji and whether it is now added. The chip has already been updated when it is called.

Method
ConversationComment.ReactionChoices
public ConversationComment ReactionChoices(params string[] emojis)

Sets the emoji the add-reaction button offers. Defaults to DefaultReactions.

Method
ConversationComment.GetReaction
public (int count, bool reacted) GetReaction(string emoji)

The count of a reaction, and whether the current user is one of those who added it.

Method
ConversationComment.Highlighted
public ConversationComment Highlighted(bool value = true)

Marks the comment as highlighted - a primary border, as for the comment a link points to, or the one a reader is replying to.

Method
ConversationComment.Render
public override HTMLElement Render()

Renders the component.

Fields

NameDescription
DefaultReactionsThe reactions offered by the add-reaction picker, unless ReactionChoices changes them.
Field
ConversationComment.DefaultReactions
public static readonly string[] DefaultReactions = { "👍", "👎", "😄", "🎉", "😕", "❤️", "🚀", "👀" }

The reactions offered by the add-reaction picker, unless ReactionChoices changes them.

class

ConversationEvent

public sealed class ConversationEvent : ComponentBase<ConversationEvent, HTMLElement>

A one-line event on a Conversation's rail, between comments: an icon on the rail, then who did what and when - "Ana added the bug label 2 days ago". Components such as Tags can be placed inline in the sentence, and a detail line (a commit, a linked pull request) under it.

Namespace
Tesserae
Inheritance
ComponentBase<ConversationEvent, HTMLElement> → ConversationEvent

Constructors

NameDescription
ConversationEventInitializes a new event.
Constructor
ConversationEvent
public ConversationEvent(UIcons icon, string actor, string text, string timestamp = null)

Initializes a new event.

Parameters

icon
The icon drawn on the rail (a tag for a label change, a check for a close, ...).
actor
Who did it, shown in bold. Pass null for an event nobody did.
text
What they did, e.g. "added" or "closed this as completed".
timestamp
When, as display text.

Methods

NameDescription
SetAvatarSets the actor's avatar, drawn small before their name. Pass null to show none.
InlinePlaces components inline in the sentence, after the text - the label Tags that were added, a milestone link, the name of a branch.
TimestampSets when it happened, as display text, with an optional tooltip.
DetailSets a line under the sentence - the commit that referenced the issue, a pull request, a quote.
ToneFills the icon on the rail with a tone, for the events that change the state of the thread: success when it is reopened, danger when it is closed as not planned, AI or primary when it is completed. Neutral (the default) is the plain outlined icon.
RenderRenders the component.
Method
ConversationEvent.SetAvatar
public ConversationEvent SetAvatar(Avatar avatar)

Sets the actor's avatar, drawn small before their name. Pass null to show none.

Method
ConversationEvent.Inline
Overload
Inline(IComponent[])Places components inline in the sentence, after the text - the label Tags that were added, a milestone link, the name of a branch.
Inline(string)Places text inline in the sentence, after anything already there.
Inline(IComponent[])
public ConversationEvent Inline(params IComponent[] components)

Places components inline in the sentence, after the text - the label Tags that were added, a milestone link, the name of a branch.

Parameters

components IComponent[]
Inline(string)
public ConversationEvent Inline(string text)

Places text inline in the sentence, after anything already there.

Parameters

text string
Method
ConversationEvent.Timestamp
public ConversationEvent Timestamp(string text, string tooltip = null)

Sets when it happened, as display text, with an optional tooltip.

Method
ConversationEvent.Detail
public ConversationEvent Detail(IComponent detail)

Sets a line under the sentence - the commit that referenced the issue, a pull request, a quote.

Method
ConversationEvent.Tone
public ConversationEvent Tone(BadgeTone tone)

Fills the icon on the rail with a tone, for the events that change the state of the thread: success when it is reopened, danger when it is closed as not planned, AI or primary when it is completed. Neutral (the default) is the plain outlined icon.

Method
ConversationEvent.Render
public override HTMLElement Render()

Renders the component.

class

ConversationComposer

public sealed class ConversationComposer : ComponentBase<ConversationComposer, HTMLElement>

The reply box at the foot of a Conversation: the current user's Avatar beside a card with Write / Preview tabs, a Markdown TextArea, a live MarkdownBlock preview and a submit button (plus any extra actions, such as "Close issue").

Namespace
Tesserae
Inheritance
ComponentBase<ConversationComposer, HTMLElement> → ConversationComposer

Constructors

NameDescription
ConversationComposerInitializes a new composer.
Constructor
ConversationComposer
public ConversationComposer(Avatar avatar = null, string placeholder = "Add your comment here...", string submitText = "Comment")

Initializes a new composer.

Parameters

avatar
The current user's avatar, drawn to the left of the box. Pass null for none.
placeholder
The placeholder of the text area.
submitText
The text of the submit button.

Properties

NameDescription
TextThe text currently in the box.
TextAreaThe underlying text area, for anything this component does not expose.
Property
ConversationComposer.Text
public string Text

The text currently in the box.

Property
ConversationComposer.TextArea
public TextArea TextArea

The underlying text area, for anything this component does not expose.

Methods

NameDescription
SetAvatarSets the current user's avatar. Pass null to show none.
SetTextSets the text in the box.
OnSubmitRegisters the callback for the submit button (and Ctrl/⌘+Enter). It gets the composer and the Markdown text; the box is cleared and back on the Write tab when it is called.
ActionsAdds buttons to the left of the submit button - "Close issue", "Cancel", ...
FocusMoves focus into the text area.
RenderRenders the component.
Method
ConversationComposer.SetAvatar
public ConversationComposer SetAvatar(Avatar avatar)

Sets the current user's avatar. Pass null to show none.

Method
ConversationComposer.SetText
public ConversationComposer SetText(string text)

Sets the text in the box.

Method
ConversationComposer.OnSubmit
public ConversationComposer OnSubmit(Action<ConversationComposer, string> onSubmit)

Registers the callback for the submit button (and Ctrl/⌘+Enter). It gets the composer and the Markdown text; the box is cleared and back on the Write tab when it is called.

Method
ConversationComposer.Actions
public ConversationComposer Actions(params Button[] buttons)

Adds buttons to the left of the submit button - "Close issue", "Cancel", ...

Method
ConversationComposer.Focus
public ConversationComposer Focus()

Moves focus into the text area.

Method
ConversationComposer.Render
public override HTMLElement Render()

Renders the component.

See also