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


test_chat_basic_examples


def 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()

test_chat_placement_examples


def 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()

test_chat_bubble_colors_examples


def 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()

test_chat_basic_fasthtml_examples


def 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()
It's over Anakin,
I have the high ground.
You underestimate my power!
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()

test_chat_with_image_fasthtml_examples


def 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()
Tailwind CSS chat bubble component
It was said that you would, destroy the Sith, not join them.
Tailwind CSS chat bubble component
It was said that you would, destroy the Sith, not join them.
Tailwind CSS chat bubble component
It was you who would bring balance to the Force
Tailwind CSS chat bubble component
Not leave it in Darkness
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()

test_chat_colors_fasthtml_examples


def 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()
What kind of nonsense is this
Put me on the Council and not make me a Master!??
That's never been done in the history of the Jedi.
It's insulting!
Calm down, Anakin.
You have been given a great honor.
To be on the Council at your age.
It's never happened before.
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()