chat bubble

Chat bubbles are used to show one line of conversation and all its data, including the author image, author name, time, etc.

Base Chat

The base chat components:

Exported source
chat = SingleValueFactory("chat", "Container for one line of conversation and its data") # Chat container
chat_image = SingleValueFactory("chat-image", "Author image part of chat") # Chat image
chat_header = SingleValueFactory("chat-header", "Text above the chat bubble") # Chat header
chat_footer = SingleValueFactory("chat-footer", "Text below the chat bubble") # Chat footer
chat_bubble = SingleValueFactory("chat-bubble", "Chat bubble element") # Chat bubble

Chat Placement

Chat placement alignment (required):

Exported source
chat_placement = SimpleFactory(
    {
        "start": "chat-start",
        "end": "chat-end"
    },
    "Chat placement alignment (start or end - required)"
) # Chat placement

Chat Bubble Colors

Chat bubble color variants using daisyUI semantic colors:

Exported source
chat_bubble_colors = enums_to_simple_factory(chat_bubble, [SemanticColorBrand, SemanticColorStatus], "Chat bubble color variants using daisyUI semantic colors") # Chat bubble color variants

Chat Test Examples


source

test_chat_basic_examples

 test_chat_basic_examples ()

Test basic chat utilities.

Exported source
def test_chat_basic_examples():
    """Test basic chat utilities."""
    # Basic components
    assert str(chat) == "chat"
    assert str(chat_image) == "chat-image"
    assert str(chat_header) == "chat-header"
    assert str(chat_footer) == "chat-footer"
    assert str(chat_bubble) == "chat-bubble"
    
    # With modifiers
    assert str(chat.hover) == "hover:chat"
    assert str(chat_bubble.md) == "md:chat-bubble"
    assert str(chat_header.dark) == "dark:chat-header"

# Run the tests
test_chat_basic_examples()

source

test_chat_placement_examples

 test_chat_placement_examples ()

Test chat placement utilities.

Exported source
def test_chat_placement_examples():
    """Test chat placement utilities."""
    assert str(chat_placement.start) == "chat-start"
    assert str(chat_placement.end) == "chat-end"
    
    # With responsive modifiers
    assert str(chat_placement.start.hover) == "hover:chat-start"
    assert str(chat_placement.end.md) == "md:chat-end"

# Run the tests
test_chat_placement_examples()

source

test_chat_bubble_colors_examples

 test_chat_bubble_colors_examples ()

Test chat bubble color variants.

Exported source
def test_chat_bubble_colors_examples():
    """Test chat bubble color variants."""
    # All color variants
    assert str(chat_bubble_colors.neutral) == "chat-bubble-neutral"
    assert str(chat_bubble_colors.primary) == "chat-bubble-primary"
    assert str(chat_bubble_colors.secondary) == "chat-bubble-secondary"
    assert str(chat_bubble_colors.accent) == "chat-bubble-accent"
    assert str(chat_bubble_colors.info) == "chat-bubble-info"
    assert str(chat_bubble_colors.success) == "chat-bubble-success"
    assert str(chat_bubble_colors.warning) == "chat-bubble-warning"
    assert str(chat_bubble_colors.error) == "chat-bubble-error"
    
    # With modifiers
    assert str(chat_bubble_colors.primary.hover) == "hover:chat-bubble-primary"
    assert str(chat_bubble_colors.success.focus) == "focus:chat-bubble-success"

# Run the tests
test_chat_bubble_colors_examples()

source

test_chat_basic_fasthtml_examples

 test_chat_basic_fasthtml_examples ()

Test basic chat-start and chat-end from daisyUI v5 documentation.

Exported source
def test_chat_basic_fasthtml_examples():
    """Test basic chat-start and chat-end from daisyUI v5 documentation."""
    from fasthtml.common import Div, Br
    
    # Basic chat-start and chat-end
    chat_start = Div(
        Div(
            "It's over Anakin,",
            Br(),
            "I have the high ground.",
            cls=str(chat_bubble)
        ),
        cls=combine_classes(chat, chat_placement.start)
    )
    assert chat_start.tag == "div"
    assert "chat" in chat_start.attrs['class']
    assert "chat-start" in chat_start.attrs['class']
    assert chat_start.children[0].tag == "div"
    assert "chat-bubble" in chat_start.children[0].attrs['class']
    assert chat_start.children[0].children[0] == "It's over Anakin,"
    assert chat_start.children[0].children[1].tag == "br"
    assert chat_start.children[0].children[2] == "I have the high ground."
    
    chat_end = Div(
        Div("You underestimate my power!", cls=str(chat_bubble)),
        cls=combine_classes(chat, chat_placement.end)
    )
    assert chat_end.tag == "div"
    assert "chat" in chat_end.attrs['class']
    assert "chat-end" in chat_end.attrs['class']
    assert "chat-bubble" in chat_end.children[0].attrs['class']
    assert chat_end.children[0].children[0] == "You underestimate my power!"
    
    # Return all examples in a Div
    return Div(chat_start, chat_end)

# Run the tests
test_chat_basic_fasthtml_examples()
<div>
  <div class="chat chat-start">
    <div class="chat-bubble">
It's over Anakin,<br>I have the high ground.    </div>
  </div>
  <div class="chat chat-end">
    <div class="chat-bubble">You underestimate my power!</div>
  </div>
</div>
test_func = test_chat_basic_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

source

test_chat_with_image_fasthtml_examples

 test_chat_with_image_fasthtml_examples ()

Test chat with image from daisyUI v5 documentation.

Exported source
def test_chat_with_image_fasthtml_examples():
    """Test chat with image from daisyUI v5 documentation."""
    from fasthtml.common import Div, Img
    from cjm_fasthtml_tailwind.utilities.sizing import w
    from cjm_fasthtml_tailwind.utilities.borders import rounded
    from cjm_fasthtml_daisyui.components.data_display.avatar import avatar
    
    # Define the image URL once
    kenobee_img = "https://img.daisyui.com/images/profile/demo/kenobee@192.webp"
    
    # Single chat with image
    single_chat = Div(
        Div(
            Div(
                Img(
                    alt="Tailwind CSS chat bubble component",
                    src=kenobee_img
                ),
                cls=combine_classes(w._10, rounded.full)
            ),
            cls=combine_classes(chat_image, avatar)
        ),
        Div(
            "It was said that you would, destroy the Sith, not join them.",
            cls=str(chat_bubble)
        ),
        cls=combine_classes(chat, chat_placement.start)
    )
    assert "chat" in single_chat.attrs['class']
    assert "chat-start" in single_chat.attrs['class']
    assert "chat-image" in single_chat.children[0].attrs['class']
    assert "avatar" in single_chat.children[0].attrs['class']
    assert "w-10" in single_chat.children[0].children[0].attrs['class']
    assert "rounded-full" in single_chat.children[0].children[0].attrs['class']
    assert single_chat.children[0].children[0].children[0].tag == "img"
    assert single_chat.children[0].children[0].children[0].attrs['src'] == kenobee_img
    assert "chat-bubble" in single_chat.children[1].attrs['class']
    assert single_chat.children[1].children[0] == "It was said that you would, destroy the Sith, not join them."
    
    # Multiple messages with same image
    chat_message_1 = Div(
        Div(
            Div(
                Img(
                    alt="Tailwind CSS chat bubble component",
                    src=kenobee_img
                ),
                cls=combine_classes(w._10, rounded.full)
            ),
            cls=combine_classes(chat_image, avatar)
        ),
        Div(
            "It was said that you would, destroy the Sith, not join them.",
            cls=str(chat_bubble)
        ),
        cls=combine_classes(chat, chat_placement.start)
    )
    
    chat_message_2 = Div(
        Div(
            Div(
                Img(
                    alt="Tailwind CSS chat bubble component",
                    src=kenobee_img
                ),
                cls=combine_classes(w._10, rounded.full)
            ),
            cls=combine_classes(chat_image, avatar)
        ),
        Div(
            "It was you who would bring balance to the Force",
            cls=str(chat_bubble)
        ),
        cls=combine_classes(chat, chat_placement.start)
    )
    
    chat_message_3 = Div(
        Div(
            Div(
                Img(
                    alt="Tailwind CSS chat bubble component",
                    src=kenobee_img
                ),
                cls=combine_classes(w._10, rounded.full)
            ),
            cls=combine_classes(chat_image, avatar)
        ),
        Div(
            "Not leave it in Darkness",
            cls=str(chat_bubble)
        ),
        cls=combine_classes(chat, chat_placement.start)
    )
    
    # Verify all messages have consistent structure
    for msg in [chat_message_1, chat_message_2, chat_message_3]:
        assert "chat" in msg.attrs['class']
        assert "chat-start" in msg.attrs['class']
        assert "chat-image" in msg.children[0].attrs['class']
        assert "avatar" in msg.children[0].attrs['class']
        assert msg.children[0].children[0].children[0].attrs['src'] == kenobee_img
        assert "chat-bubble" in msg.children[1].attrs['class']
    
    # Verify different message content
    assert chat_message_1.children[1].children[0] == "It was said that you would, destroy the Sith, not join them."
    assert chat_message_2.children[1].children[0] == "It was you who would bring balance to the Force"
    assert chat_message_3.children[1].children[0] == "Not leave it in Darkness"
    
    # Return all examples in a Div
    return Div(single_chat, chat_message_1, chat_message_2, chat_message_3)

# Run the tests
test_chat_with_image_fasthtml_examples()
<div>
  <div class="chat chat-start">
    <div class="chat-image avatar">
      <div class="w-10 rounded-full">
<img alt="Tailwind CSS chat bubble component" src="https://img.daisyui.com/images/profile/demo/kenobee@192.webp">      </div>
    </div>
    <div class="chat-bubble">It was said that you would, destroy the Sith, not join them.</div>
  </div>
  <div class="chat chat-start">
    <div class="chat-image avatar">
      <div class="w-10 rounded-full">
<img alt="Tailwind CSS chat bubble component" src="https://img.daisyui.com/images/profile/demo/kenobee@192.webp">      </div>
    </div>
    <div class="chat-bubble">It was said that you would, destroy the Sith, not join them.</div>
  </div>
  <div class="chat chat-start">
    <div class="chat-image avatar">
      <div class="w-10 rounded-full">
<img alt="Tailwind CSS chat bubble component" src="https://img.daisyui.com/images/profile/demo/kenobee@192.webp">      </div>
    </div>
    <div class="chat-bubble">It was you who would bring balance to the Force</div>
  </div>
  <div class="chat chat-start">
    <div class="chat-image avatar">
      <div class="w-10 rounded-full">
<img alt="Tailwind CSS chat bubble component" src="https://img.daisyui.com/images/profile/demo/kenobee@192.webp">      </div>
    </div>
    <div class="chat-bubble">Not leave it in Darkness</div>
  </div>
</div>
test_func = test_chat_with_image_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()

source

test_chat_colors_fasthtml_examples

 test_chat_colors_fasthtml_examples ()

Test chat bubble with colors from daisyUI v5 documentation.

Exported source
def test_chat_colors_fasthtml_examples():
    """Test chat bubble with colors from daisyUI v5 documentation."""
    from fasthtml.common import Div
    
    # Chat bubbles with different colors - all start aligned
    primary_chat = Div(
        Div(
            "What kind of nonsense is this",
            cls=combine_classes(chat_bubble, chat_bubble_colors.primary)
        ),
        cls=combine_classes(chat, chat_placement.start)
    )
    assert "chat" in primary_chat.attrs['class']
    assert "chat-start" in primary_chat.attrs['class']
    assert "chat-bubble" in primary_chat.children[0].attrs['class']
    assert "chat-bubble-primary" in primary_chat.children[0].attrs['class']
    assert primary_chat.children[0].children[0] == "What kind of nonsense is this"
    
    secondary_chat = Div(
        Div(
            "Put me on the Council and not make me a Master!??",
            cls=combine_classes(chat_bubble, chat_bubble_colors.secondary)
        ),
        cls=combine_classes(chat, chat_placement.start)
    )
    assert "chat-bubble-secondary" in secondary_chat.children[0].attrs['class']
    assert secondary_chat.children[0].children[0] == "Put me on the Council and not make me a Master!??"
    
    accent_chat = Div(
        Div(
            "That's never been done in the history of the Jedi.",
            cls=combine_classes(chat_bubble, chat_bubble_colors.accent)
        ),
        cls=combine_classes(chat, chat_placement.start)
    )
    assert "chat-bubble-accent" in accent_chat.children[0].attrs['class']
    assert accent_chat.children[0].children[0] == "That's never been done in the history of the Jedi."
    
    neutral_chat = Div(
        Div(
            "It's insulting!",
            cls=combine_classes(chat_bubble, chat_bubble_colors.neutral)
        ),
        cls=combine_classes(chat, chat_placement.start)
    )
    assert "chat-bubble-neutral" in neutral_chat.children[0].attrs['class']
    assert neutral_chat.children[0].children[0] == "It's insulting!"
    
    # Chat bubbles with different colors - all end aligned
    info_chat = Div(
        Div(
            "Calm down, Anakin.",
            cls=combine_classes(chat_bubble, chat_bubble_colors.info)
        ),
        cls=combine_classes(chat, chat_placement.end)
    )
    assert "chat" in info_chat.attrs['class']
    assert "chat-end" in info_chat.attrs['class']
    assert "chat-bubble-info" in info_chat.children[0].attrs['class']
    assert info_chat.children[0].children[0] == "Calm down, Anakin."
    
    success_chat = Div(
        Div(
            "You have been given a great honor.",
            cls=combine_classes(chat_bubble, chat_bubble_colors.success)
        ),
        cls=combine_classes(chat, chat_placement.end)
    )
    assert "chat-bubble-success" in success_chat.children[0].attrs['class']
    assert success_chat.children[0].children[0] == "You have been given a great honor."
    
    warning_chat = Div(
        Div(
            "To be on the Council at your age.",
            cls=combine_classes(chat_bubble, chat_bubble_colors.warning)
        ),
        cls=combine_classes(chat, chat_placement.end)
    )
    assert "chat-bubble-warning" in warning_chat.children[0].attrs['class']
    assert warning_chat.children[0].children[0] == "To be on the Council at your age."
    
    error_chat = Div(
        Div(
            "It's never happened before.",
            cls=combine_classes(chat_bubble, chat_bubble_colors.error)
        ),
        cls=combine_classes(chat, chat_placement.end)
    )
    assert "chat-bubble-error" in error_chat.children[0].attrs['class']
    assert error_chat.children[0].children[0] == "It's never happened before."
    
    # Return all examples in a Div
    return Div(
        primary_chat, secondary_chat, accent_chat, neutral_chat,
        info_chat, success_chat, warning_chat, error_chat
    )

# Run the tests
test_chat_colors_fasthtml_examples()
<div>
  <div class="chat chat-start">
    <div class="chat-bubble chat-bubble-primary">What kind of nonsense is this</div>
  </div>
  <div class="chat chat-start">
    <div class="chat-bubble chat-bubble-secondary">Put me on the Council and not make me a Master!??</div>
  </div>
  <div class="chat chat-start">
    <div class="chat-bubble chat-bubble-accent">That's never been done in the history of the Jedi.</div>
  </div>
  <div class="chat chat-start">
    <div class="chat-bubble chat-bubble-neutral">It's insulting!</div>
  </div>
  <div class="chat chat-end">
    <div class="chat-bubble chat-bubble-info">Calm down, Anakin.</div>
  </div>
  <div class="chat chat-end">
    <div class="chat-bubble chat-bubble-success">You have been given a great honor.</div>
  </div>
  <div class="chat chat-end">
    <div class="chat-bubble chat-bubble-warning">To be on the Council at your age.</div>
  </div>
  <div class="chat chat-end">
    <div class="chat-bubble chat-bubble-error">It's never happened before.</div>
  </div>
</div>
test_func = test_chat_colors_fasthtml_examples
app, rt = create_test_app(theme=DaisyUITheme.LIGHT)

@rt
def index():
    return create_test_page(test_func.__doc__.title().replace('.', ''), test_func())
server = start_test_server(app)
display(HTMX())
server.stop()