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.