Docs Components Data Display

Bubble

React example follows below.
ts
const bubbleFixture = {
id: "bubble",
incoming: {
opening: {
text: "Can we publish the release notes today?",
variant: "secondary",
groupPosition: "first",
},
reply: {
text: "Yes — the final checks are green.",
variant: "secondary",
groupPosition: "last",
reactions: [
{ label: "👍", count: 2 },
{ label: "✨", count: 1 },
],
reactionsLabel: "Two thumbs-up reactions and one celebration reaction",
},
},
outgoing: {
text: "Perfect. I’ll publish them now.",
align: "end",
},
} as const;
import { Bubble } from "@grassroot/ui-react";
export default function BubbleDemo() {
const { incoming, outgoing } = bubbleFixture;
return (
<div>
<div
role="log"
aria-label="Conversation preview"
className="flex w-full max-w-[460px] flex-col gap-5"
>
<div className="flex flex-col gap-1.5">
<Bubble variant={incoming.opening.variant} groupPosition={incoming.opening.groupPosition}>
{incoming.opening.text}
</Bubble>
<Bubble
variant={incoming.reply.variant}
groupPosition={incoming.reply.groupPosition}
reactions={incoming.reply.reactions}
reactionsLabel={incoming.reply.reactionsLabel}
>
{incoming.reply.text}
</Bubble>
</div>
<Bubble align={outgoing.align}>{outgoing.text}</Bubble>
</div>
</div>
);
}
ts
<script setup lang="ts">
const bubbleFixture = {
id: "bubble",
incoming: {
opening: {
text: "Can we publish the release notes today?",
variant: "secondary",
groupPosition: "first",
},
reply: {
text: "Yes — the final checks are green.",
variant: "secondary",
groupPosition: "last",
reactions: [
{ label: "👍", count: 2 },
{ label: "✨", count: 1 },
],
reactionsLabel: "Two thumbs-up reactions and one celebration reaction",
},
},
outgoing: {
text: "Perfect. I’ll publish them now.",
align: "end",
},
} as const;
import { Bubble } from "@grassroot/ui-vue";
</script>
<template>
<div>
<div
role="log"
aria-label="Conversation preview"
class="flex w-full max-w-[460px] flex-col gap-5"
>
<div class="flex flex-col gap-1.5">
<Bubble
:variant="bubbleFixture.incoming.opening.variant"
:group-position="bubbleFixture.incoming.opening.groupPosition"
>
{{ bubbleFixture.incoming.opening.text }}
</Bubble>
<Bubble
:variant="bubbleFixture.incoming.reply.variant"
:group-position="bubbleFixture.incoming.reply.groupPosition"
:reactions="bubbleFixture.incoming.reply.reactions"
:reactions-label="bubbleFixture.incoming.reply.reactionsLabel"
>
{{ bubbleFixture.incoming.reply.text }}
</Bubble>
</div>
<Bubble :align="bubbleFixture.outgoing.align">{{ bubbleFixture.outgoing.text }}</Bubble>
</div>
</div>
</template>
ts
import { Component } from "@angular/core";
const bubbleFixture = {
id: "bubble",
incoming: {
opening: {
text: "Can we publish the release notes today?",
variant: "secondary",
groupPosition: "first",
},
reply: {
text: "Yes — the final checks are green.",
variant: "secondary",
groupPosition: "last",
reactions: [
{ label: "👍", count: 2 },
{ label: "✨", count: 1 },
],
reactionsLabel: "Two thumbs-up reactions and one celebration reaction",
},
},
outgoing: {
text: "Perfect. I’ll publish them now.",
align: "end",
},
} as const;
import { GrassrootBubble } from "@grassroot/ui-angular";
@Component({
selector: "app-bubble-demo",
standalone: true,
imports: [GrassrootBubble],
host: { style: "display: contents" },
template: `
<div>
<div
role="log"
aria-label="Conversation preview"
class="flex w-full max-w-[460px] flex-col gap-5"
>
<div class="flex flex-col gap-1.5">
<grassroot-bubble
[variant]="fixture.incoming.opening.variant"
[groupPosition]="fixture.incoming.opening.groupPosition"
>
{{ fixture.incoming.opening.text }}
</grassroot-bubble>
<grassroot-bubble
[variant]="fixture.incoming.reply.variant"
[groupPosition]="fixture.incoming.reply.groupPosition"
[reactions]="fixture.incoming.reply.reactions"
[reactionsLabel]="fixture.incoming.reply.reactionsLabel"
>
{{ fixture.incoming.reply.text }}
</grassroot-bubble>
</div>
<grassroot-bubble [align]="fixture.outgoing.align">{{
fixture.outgoing.text
}}</grassroot-bubble>
</div>
</div>
`,
})
export class BubbleDemoComponent {
protected readonly fixture = bubbleFixture;
}
export default BubbleDemoComponent;
ts
<script lang="ts">
const bubbleFixture = {
id: "bubble",
incoming: {
opening: {
text: "Can we publish the release notes today?",
variant: "secondary",
groupPosition: "first",
},
reply: {
text: "Yes — the final checks are green.",
variant: "secondary",
groupPosition: "last",
reactions: [
{ label: "👍", count: 2 },
{ label: "✨", count: 1 },
],
reactionsLabel: "Two thumbs-up reactions and one celebration reaction",
},
},
outgoing: {
text: "Perfect. I’ll publish them now.",
align: "end",
},
} as const;
import { Bubble } from "@grassroot/ui-svelte";
</script>
<div>
<div
role="log"
aria-label="Conversation preview"
class="flex w-full max-w-[460px] flex-col gap-5"
>
<div class="flex flex-col gap-1.5">
<Bubble
variant={bubbleFixture.incoming.opening.variant}
groupPosition={bubbleFixture.incoming.opening.groupPosition}
>
{bubbleFixture.incoming.opening.text}
</Bubble>
<Bubble
variant={bubbleFixture.incoming.reply.variant}
groupPosition={bubbleFixture.incoming.reply.groupPosition}
reactions={bubbleFixture.incoming.reply.reactions}
reactionsLabel={bubbleFixture.incoming.reply.reactionsLabel}
>
{bubbleFixture.incoming.reply.text}
</Bubble>
</div>
<Bubble align={bubbleFixture.outgoing.align}>{bubbleFixture.outgoing.text}</Bubble>
</div>
</div>
ts
/** @jsxImportSource solid-js */
const bubbleFixture = {
id: "bubble",
incoming: {
opening: {
text: "Can we publish the release notes today?",
variant: "secondary",
groupPosition: "first",
},
reply: {
text: "Yes — the final checks are green.",
variant: "secondary",
groupPosition: "last",
reactions: [
{ label: "👍", count: 2 },
{ label: "✨", count: 1 },
],
reactionsLabel: "Two thumbs-up reactions and one celebration reaction",
},
},
outgoing: {
text: "Perfect. I’ll publish them now.",
align: "end",
},
} as const;
import { Bubble } from "@grassroot/ui-solid";
import type { JSX } from "solid-js";
export default function BubbleDemo(): JSX.Element {
return (
<div>
<div
role="log"
aria-label="Conversation preview"
class="flex w-full max-w-[460px] flex-col gap-5"
>
<div class="flex flex-col gap-1.5">
<Bubble
variant={bubbleFixture.incoming.opening.variant}
groupPosition={bubbleFixture.incoming.opening.groupPosition}
>
{bubbleFixture.incoming.opening.text}
</Bubble>
<Bubble
variant={bubbleFixture.incoming.reply.variant}
groupPosition={bubbleFixture.incoming.reply.groupPosition}
reactions={bubbleFixture.incoming.reply.reactions}
reactionsLabel={bubbleFixture.incoming.reply.reactionsLabel}
>
{bubbleFixture.incoming.reply.text}
</Bubble>
</div>
<Bubble align={bubbleFixture.outgoing.align}>{bubbleFixture.outgoing.text}</Bubble>
</div>
</div>
);
}

Installation

API Reference

Import

import { Bubble } from "@grassroot/ui-react";

Props

Prop
Type
Default
Requirement
Description
variant
BubbleVariant | undefined
"default"
optional
—
align
BubbleAlign | undefined
"start"
optional
—
reactions
readonly BubbleReaction[] | undefined
—
optional
Static reactions displayed against the bubble edge.
reactionSide
BubbleReactionSide | undefined
"bottom"
optional
—
reactionAlign
BubbleReactionAlign | undefined
"end"
optional
—
reactionsLabel
string | undefined
—
optional
Accessible summary for the static reaction row.
groupPosition
BubbleGroupPosition | undefined
"single"
optional
Controls corner treatment when several bubbles are visually grouped.
Prop
variant
Type
BubbleVariant | undefined
Default
"default"
Requirement
optional
Description
—
Prop
align
Type
BubbleAlign | undefined
Default
"start"
Requirement
optional
Description
—
Prop
reactions
Type
readonly BubbleReaction[] | undefined
Default
—
Requirement
optional
Description
Static reactions displayed against the bubble edge.
Prop
reactionSide
Type
BubbleReactionSide | undefined
Default
"bottom"
Requirement
optional
Description
—
Prop
reactionAlign
Type
BubbleReactionAlign | undefined
Default
"end"
Requirement
optional
Description
—
Prop
reactionsLabel
Type
string | undefined
Default
—
Requirement
optional
Description
Accessible summary for the static reaction row.
Prop
groupPosition
Type
BubbleGroupPosition | undefined
Default
"single"
Requirement
optional
Description
Controls corner treatment when several bubbles are visually grouped.

Content regions

  • children

Native attributes

Standard DOM and ARIA attributes not listed above spread onto the root element.

Import

import { Bubble } from "@grassroot/ui-vue";

Props

Prop
Type
Default
Requirement
variant
BubbleVariant | undefined
"default"
optional
align
BubbleAlign | undefined
"start"
optional
reactions
readonly BubbleReaction[] | undefined
() => []
optional
reactionSide
BubbleReactionSide | undefined
"bottom"
optional
reactionAlign
BubbleReactionAlign | undefined
"end"
optional
reactionsLabel
string | undefined
—
optional
groupPosition
BubbleGroupPosition | undefined
"single"
optional
Prop
variant
Type
BubbleVariant | undefined
Default
"default"
Requirement
optional
Prop
align
Type
BubbleAlign | undefined
Default
"start"
Requirement
optional
Prop
reactions
Type
readonly BubbleReaction[] | undefined
Default
() => []
Requirement
optional
Prop
reactionSide
Type
BubbleReactionSide | undefined
Default
"bottom"
Requirement
optional
Prop
reactionAlign
Type
BubbleReactionAlign | undefined
Default
"end"
Requirement
optional
Prop
reactionsLabel
Type
string | undefined
Default
—
Requirement
optional
Prop
groupPosition
Type
BubbleGroupPosition | undefined
Default
"single"
Requirement
optional

Content regions

  • default

Import

import { Component } from "@angular/core";
import { GrassrootBubble } from "@grassroot/ui-angular";

Props

Prop
Type
Default
Requirement
variant
BubbleVariant
"default"
optional
align
BubbleAlign
"start"
optional
reactions
readonly BubbleReaction[]
[]
optional
reactionSide
BubbleReactionSide
"bottom"
optional
reactionAlign
BubbleReactionAlign
"end"
optional
reactionsLabel
string
—
optional
groupPosition
BubbleGroupPosition
"single"
optional
Prop
variant
Type
BubbleVariant
Default
"default"
Requirement
optional
Prop
align
Type
BubbleAlign
Default
"start"
Requirement
optional
Prop
reactions
Type
readonly BubbleReaction[]
Default
[]
Requirement
optional
Prop
reactionSide
Type
BubbleReactionSide
Default
"bottom"
Requirement
optional
Prop
reactionAlign
Type
BubbleReactionAlign
Default
"end"
Requirement
optional
Prop
reactionsLabel
Type
string
Default
—
Requirement
optional
Prop
groupPosition
Type
BubbleGroupPosition
Default
"single"
Requirement
optional

Content regions

  • default

Import

import { Bubble } from "@grassroot/ui-svelte";

Props

Prop
Type
Default
Requirement
variant
BubbleVariant
"default"
optional
align
BubbleAlign
"start"
optional
reactions
readonly BubbleReaction[]
—
optional
reactionSide
BubbleReactionSide
"bottom"
optional
reactionAlign
BubbleReactionAlign
"end"
optional
reactionsLabel
string
—
optional
groupPosition
BubbleGroupPosition
"single"
optional
class
string
—
optional
Prop
variant
Type
BubbleVariant
Default
"default"
Requirement
optional
Prop
align
Type
BubbleAlign
Default
"start"
Requirement
optional
Prop
reactions
Type
readonly BubbleReaction[]
Default
—
Requirement
optional
Prop
reactionSide
Type
BubbleReactionSide
Default
"bottom"
Requirement
optional
Prop
reactionAlign
Type
BubbleReactionAlign
Default
"end"
Requirement
optional
Prop
reactionsLabel
Type
string
Default
—
Requirement
optional
Prop
groupPosition
Type
BubbleGroupPosition
Default
"single"
Requirement
optional
Prop
class
Type
string
Default
—
Requirement
optional

Content regions

  • children

Import

import { Bubble } from "@grassroot/ui-solid";
import type { JSX } from "solid-js";

Props

Prop
Type
Default
Requirement
variant
BubbleVariant
—
optional
align
BubbleAlign
—
optional
reactions
readonly BubbleReaction[]
—
optional
reactionSide
BubbleReactionSide
—
optional
reactionAlign
BubbleReactionAlign
—
optional
reactionsLabel
string
—
optional
groupPosition
BubbleGroupPosition
—
optional
className
string
—
optional
Prop
variant
Type
BubbleVariant
Default
—
Requirement
optional
Prop
align
Type
BubbleAlign
Default
—
Requirement
optional
Prop
reactions
Type
readonly BubbleReaction[]
Default
—
Requirement
optional
Prop
reactionSide
Type
BubbleReactionSide
Default
—
Requirement
optional
Prop
reactionAlign
Type
BubbleReactionAlign
Default
—
Requirement
optional
Prop
reactionsLabel
Type
string
Default
—
Requirement
optional
Prop
groupPosition
Type
BubbleGroupPosition
Default
—
Requirement
optional
Prop
className
Type
string
Default
—
Requirement
optional

Content regions

  • children

Native attributes

Standard DOM and ARIA attributes not listed above spread onto the root element.