card

Cards are used to group and display content in a way that is easily readable.

Base Card

The base card components:

Exported source
card = SingleValueFactory("card", "Card container component") # Card container
card_title = SingleValueFactory("card-title", "Title part of card") # Card title
card_body = SingleValueFactory("card-body", "Body part (content) of card") # Card body
card_actions = SingleValueFactory("card-actions", "Actions part of card (buttons, etc.)") # Card actions

Card Styles

Different card style variants:

Exported source
card_styles = enums_to_simple_factory(card, [BorderStyle, DashStyle], "Card style variants (border, dash)") # Card style variants

Card Modifiers

Card modifier utilities:

Exported source
card_modifiers = SimpleFactory(
    {
        "side": "card-side",
        "image_full": "image-full"
    },
    "Card modifiers (side image, full background image)"
) # Card modifiers

Card Sizes

Card size variants:

Exported source
card_sizes = enums_to_simple_factory(card, [DaisyUINamedSize], "Card size variants from extra small to extra large") # Card size variants

Card Test Examples


test_card_basic_examples


def test_card_basic_examples(
    
):

Test basic card utilities.

Exported source
def test_card_basic_examples():
    """Test basic card utilities."""
    # Basic components
    assert str(card) == "card"
    assert str(card_title) == "card-title"
    assert str(card_body) == "card-body"
    assert str(card_actions) == "card-actions"
    
    # With modifiers
    assert str(card.hover) == "hover:card"
    assert str(card_title.md) == "md:card-title"
    assert str(card_body.dark) == "dark:card-body"

# Run the tests
test_card_basic_examples()

test_card_styles_examples


def test_card_styles_examples(
    
):

Test card style variants.

Exported source
def test_card_styles_examples():
    """Test card style variants."""
    assert str(card_styles.border) == "card-border"
    assert str(card_styles.dash) == "card-dash"

# Run the tests
test_card_styles_examples()

test_card_modifiers_examples


def test_card_modifiers_examples(
    
):

Test card modifier utilities.

Exported source
def test_card_modifiers_examples():
    """Test card modifier utilities."""
    assert str(card_modifiers.side) == "card-side"
    assert str(card_modifiers.image_full) == "image-full"

# Run the tests
test_card_modifiers_examples()

test_card_sizes_examples


def test_card_sizes_examples(
    
):

Test card size variants.

Exported source
def test_card_sizes_examples():
    """Test card size variants."""
    assert str(card_sizes.xs) == "card-xs"
    assert str(card_sizes.sm) == "card-sm"
    assert str(card_sizes.md) == "card-md"
    assert str(card_sizes.lg) == "card-lg"
    assert str(card_sizes.xl) == "card-xl"
    
    # With responsive modifiers
    assert str(card_sizes.xs.sm) == "sm:card-xs"
    assert str(card_sizes.lg.md) == "md:card-lg"

# Run the tests
test_card_sizes_examples()

test_card_basic_fasthtml_examples


def test_card_basic_fasthtml_examples(
    
):

Test basic card examples from daisyUI v5 documentation.

Exported source
def test_card_basic_fasthtml_examples():
    """Test basic card examples from daisyUI v5 documentation."""
    from fasthtml.common import Div, Figure, Img, H2, P, Button
    from cjm_fasthtml_tailwind.utilities.sizing import w
    from cjm_fasthtml_tailwind.utilities.effects import shadow
    from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import justify, flex_display
    from cjm_fasthtml_daisyui.utilities.semantic_colors import bg_dui
    from cjm_fasthtml_daisyui.components.actions.button import btn, btn_colors
    
    # Basic card with figure
    basic_card = Div(
        Figure(
            Img(
                src="https://img.daisyui.com/images/stock/photo-1606107557195-0e29a4b5b4aa.webp",
                alt="Shoes"
            )
        ),
        Div(
            H2("Card Title", cls=str(card_title)),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            Div(
                Button("Buy Now", cls=combine_classes(btn, btn_colors.primary)),
                cls=combine_classes(card_actions, justify.end)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, bg_dui.base_100, w._96, shadow.sm)
    )
    assert "card" in basic_card.attrs['class']
    assert "bg-base-100" in basic_card.attrs['class']
    assert "w-96" in basic_card.attrs['class']
    assert "shadow-sm" in basic_card.attrs['class']
    assert basic_card.children[0].tag == "figure"
    assert basic_card.children[0].children[0].tag == "img"
    assert basic_card.children[0].children[0].attrs['src'] == "https://img.daisyui.com/images/stock/photo-1606107557195-0e29a4b5b4aa.webp"
    assert basic_card.children[0].children[0].attrs['alt'] == "Shoes"
    assert basic_card.children[1].tag == "div"
    assert "card-body" in basic_card.children[1].attrs['class']
    assert basic_card.children[1].children[0].tag == "h2"
    assert "card-title" in basic_card.children[1].children[0].attrs['class']
    assert basic_card.children[1].children[0].children[0] == "Card Title"
    assert basic_card.children[1].children[1].tag == "p"
    assert basic_card.children[1].children[2].tag == "div"
    assert "card-actions" in basic_card.children[1].children[2].attrs['class']
    assert "justify-end" in basic_card.children[1].children[2].attrs['class']
    assert basic_card.children[1].children[2].children[0].tag == "button"
    assert "btn" in basic_card.children[1].children[2].children[0].attrs['class']
    assert "btn-primary" in basic_card.children[1].children[2].children[0].attrs['class']
    
    # Card with no image
    no_image_card = Div(
        Div(
            H2("Card title!", cls=str(card_title)),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            Div(
                Button("Buy Now", cls=combine_classes(btn, btn_colors.primary)),
                cls=combine_classes(card_actions, justify.end)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, bg_dui.base_100, w._96, shadow.sm)
    )
    assert "card" in no_image_card.attrs['class']
    assert len(no_image_card.children) == 1  # Only card-body, no figure
    assert no_image_card.children[0].tag == "div"
    assert "card-body" in no_image_card.children[0].attrs['class']
    assert no_image_card.children[0].children[0].children[0] == "Card title!"
    
    # Card with bottom image
    bottom_image_card = Div(
        Div(
            H2("Card Title", cls=str(card_title)),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            cls=str(card_body)
        ),
        Figure(
            Img(
                src="https://img.daisyui.com/images/stock/photo-1606107557195-0e29a4b5b4aa.webp",
                alt="Shoes"
            )
        ),
        cls=combine_classes(card, bg_dui.base_100, w._96, shadow.sm)
    )
    assert bottom_image_card.children[0].tag == "div"
    assert "card-body" in bottom_image_card.children[0].attrs['class']
    assert bottom_image_card.children[1].tag == "figure"
    assert bottom_image_card.children[1].children[0].tag == "img"
    
    # Return all examples in a Div
    return Div(
        basic_card,
        no_image_card,
        bottom_image_card
    )

# Run the tests
test_card_basic_fasthtml_examples()
Shoes

Card Title

A card component has a figure, a body part, and inside body there are title and actions parts

Card title!

A card component has a figure, a body part, and inside body there are title and actions parts

Card Title

A card component has a figure, a body part, and inside body there are title and actions parts

Shoes
test_func = test_card_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_card_pricing_fasthtml_examples


def test_card_pricing_fasthtml_examples(
    
):

Test pricing card example from daisyUI v5 documentation.

Exported source
def test_card_pricing_fasthtml_examples():
    """Test pricing card example from daisyUI v5 documentation."""
    from fasthtml.common import Div, H2, Span, Ul, Li, Button
    from fasthtml.svg import Svg, Path
    from cjm_fasthtml_tailwind.utilities.sizing import w, size_util
    from cjm_fasthtml_tailwind.utilities.effects import shadow, opacity
    from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import justify, flex, gap, flex_display
    from cjm_fasthtml_tailwind.utilities.spacing import m, me
    from cjm_fasthtml_tailwind.utilities.typography import font_size, font_weight, font_family, text_color, line_through
    from cjm_fasthtml_tailwind.utilities.layout import display_tw
    from cjm_fasthtml_tailwind.utilities.svg import stroke, stroke_width, fill
    from cjm_fasthtml_daisyui.utilities.semantic_colors import bg_dui, text_dui
    from cjm_fasthtml_daisyui.components.actions.button import btn, btn_colors, btn_modifiers
    from cjm_fasthtml_daisyui.components.data_display.badge import badge, badge_colors, badge_sizes, badge_styles
    
    # Create checkmark SVG icon
    checkmark_icon = Svg(
        Path(
            stroke_linecap="round",
            stroke_linejoin="round",
            stroke_width="2",
            d="M5 13l4 4L19 7"
        ),
        xmlns="http://www.w3.org/2000/svg",
        cls=combine_classes(size_util._4, me._2, display_tw.inline_block, text_dui.success),
        fill="none",
        viewBox="0 0 24 24",
        stroke="currentColor"
    )
    
    # Create disabled checkmark icon
    disabled_checkmark = Svg(
        Path(
            stroke_linecap="round",
            stroke_linejoin="round",
            stroke_width="2",
            d="M5 13l4 4L19 7"
        ),
        xmlns="http://www.w3.org/2000/svg",
        cls=combine_classes(size_util._4, me._2, display_tw.inline_block, text_dui.base_content.opacity(50)),
        fill="none",
        viewBox="0 0 24 24",
        stroke="currentColor"
    )
    
    # Pricing card
    pricing_card = Div(
        Div(
            Span("Most Popular", cls=combine_classes(badge, badge_sizes.xs, badge_colors.warning)),
            Div(
                H2("Premium", cls=combine_classes(font_size._3xl, font_weight.bold)),
                Span("29/mo", cls=str(font_size.xl)),
                cls=combine_classes(flex_display, justify.between)
            ),
            Ul(
                Li(
                    checkmark_icon,
                    Span("High-resolution image generation")
                ),
                Li(
                    checkmark_icon,
                    Span("Customizable style templates")
                ),
                Li(
                    checkmark_icon,
                    Span("Batch processing capabilities")
                ),
                Li(
                    checkmark_icon,
                    Span("AI-driven image enhancements")
                ),
                Li(
                    disabled_checkmark,
                    Span("Seamless cloud integration", cls=str(line_through)),
                    cls=str(opacity._50)
                ),
                Li(
                    disabled_checkmark,
                    Span("Real-time collaboration tools", cls=str(line_through)),
                    cls=str(opacity._50)
                ),
                cls=combine_classes(m.t._6, flex_display, flex.col, gap._2, font_size.xs)
            ),
            Div(
                Button("Subscribe", cls=combine_classes(btn, btn_colors.primary, btn_modifiers.block)),
                cls=str(m.t._6)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, w._96, bg_dui.base_100, shadow.sm)
    )
    
    # Verify card structure
    assert "card" in pricing_card.attrs['class']
    assert "w-96" in pricing_card.attrs['class']
    assert "bg-base-100" in pricing_card.attrs['class']
    assert "shadow-sm" in pricing_card.attrs['class']
    
    # Verify card body
    card_body_div = pricing_card.children[0]
    assert "card-body" in card_body_div.attrs['class']
    
    # Verify badge
    badge_span = card_body_div.children[0]
    assert "badge" in badge_span.attrs['class']
    assert "badge-xs" in badge_span.attrs['class']
    assert "badge-warning" in badge_span.attrs['class']
    assert badge_span.children[0] == "Most Popular"
    
    # Verify title section
    title_section = card_body_div.children[1]
    assert "flex" in title_section.attrs['class']
    assert "justify-between" in title_section.attrs['class']
    assert title_section.children[0].tag == "h2"
    assert "text-3xl" in title_section.children[0].attrs['class']
    assert "font-bold" in title_section.children[0].attrs['class']
    assert title_section.children[0].children[0] == "Premium"
    assert title_section.children[1].tag == "span"
    assert "text-xl" in title_section.children[1].attrs['class']
    assert title_section.children[1].children[0] == "29/mo"
    
    # Verify feature list
    feature_list = card_body_div.children[2]
    assert feature_list.tag == "ul"
    assert "mt-6" in feature_list.attrs['class']
    assert "flex" in feature_list.attrs['class']
    assert "flex-col" in feature_list.attrs['class']
    assert "gap-2" in feature_list.attrs['class']
    assert "text-xs" in feature_list.attrs['class']
    
    # Verify enabled features
    for i in range(4):
        li = feature_list.children[i]
        assert li.tag == "li"
        assert li.children[0].tag == "svg"
        assert "text-success" in li.children[0].attrs['class']
        assert li.children[1].tag == "span"
    
    # Verify disabled features
    for i in range(4, 6):
        li = feature_list.children[i]
        assert li.tag == "li"
        assert "opacity-50" in li.attrs['class']
        assert li.children[0].tag == "svg"
        assert "text-base-content/50" in li.children[0].attrs['class']
        assert li.children[1].tag == "span"
        assert "line-through" in li.children[1].attrs['class']
    
    # Verify subscribe button
    button_div = card_body_div.children[3]
    assert "mt-6" in button_div.attrs['class']
    assert button_div.children[0].tag == "button"
    assert "btn" in button_div.children[0].attrs['class']
    assert "btn-primary" in button_div.children[0].attrs['class']
    assert "btn-block" in button_div.children[0].attrs['class']
    assert button_div.children[0].children[0] == "Subscribe"
    
    # Return the pricing card in a Div
    return Div(pricing_card)

# Run the tests
test_card_pricing_fasthtml_examples()
Most Popular

Premium

29/mo
  • High-resolution image generation
  • Customizable style templates
  • Batch processing capabilities
  • AI-driven image enhancements
  • Seamless cloud integration
  • Real-time collaboration tools
test_func = test_card_pricing_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_card_style_fasthtml_examples


def test_card_style_fasthtml_examples(
    
):

Test card style variations from daisyUI v5 documentation.

Exported source
def test_card_style_fasthtml_examples():
    """Test card style variations from daisyUI v5 documentation."""
    from fasthtml.common import Div, H2, P, Button
    from cjm_fasthtml_tailwind.utilities.sizing import w
    from cjm_fasthtml_tailwind.utilities.effects import shadow
    from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import justify
    from cjm_fasthtml_daisyui.utilities.semantic_colors import bg_dui
    from cjm_fasthtml_daisyui.components.actions.button import btn, btn_colors
    
    # Card sizes - Extra Small
    xs_card = Div(
        Div(
            H2("Xsmall Card", cls=str(card_title)),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            Div(
                Button("Buy Now", cls=combine_classes(btn, btn_colors.primary)),
                cls=combine_classes(justify.end, card_actions)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, w._96, bg_dui.base_100, card_sizes.xs, shadow.sm)
    )
    assert "card" in xs_card.attrs['class']
    assert "card-xs" in xs_card.attrs['class']
    assert "w-96" in xs_card.attrs['class']
    assert xs_card.children[0].children[0].children[0] == "Xsmall Card"
    
    # Card sizes - Small
    sm_card = Div(
        Div(
            H2("Small Card", cls=str(card_title)),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            Div(
                Button("Buy Now", cls=combine_classes(btn, btn_colors.primary)),
                cls=combine_classes(justify.end, card_actions)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, w._96, bg_dui.base_100, card_sizes.sm, shadow.sm)
    )
    assert "card-sm" in sm_card.attrs['class']
    assert sm_card.children[0].children[0].children[0] == "Small Card"
    
    # Card sizes - Medium
    md_card = Div(
        Div(
            H2("Medium Card", cls=str(card_title)),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            Div(
                Button("Buy Now", cls=combine_classes(btn, btn_colors.primary)),
                cls=combine_classes(justify.end, card_actions)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, w._96, bg_dui.base_100, card_sizes.md, shadow.sm)
    )
    assert "card-md" in md_card.attrs['class']
    assert md_card.children[0].children[0].children[0] == "Medium Card"
    
    # Card sizes - Large
    lg_card = Div(
        Div(
            H2("Large Card", cls=str(card_title)),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            Div(
                Button("Buy Now", cls=combine_classes(btn, btn_colors.primary)),
                cls=combine_classes(justify.end, card_actions)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, w._96, bg_dui.base_100, card_sizes.lg, shadow.sm)
    )
    assert "card-lg" in lg_card.attrs['class']
    assert lg_card.children[0].children[0].children[0] == "Large Card"
    
    # Card sizes - Extra Large
    xl_card = Div(
        Div(
            H2("Xlarge Card", cls=str(card_title)),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            Div(
                Button("Buy Now", cls=combine_classes(btn, btn_colors.primary)),
                cls=combine_classes(justify.end, card_actions)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, w._96, bg_dui.base_100, card_sizes.xl, shadow.sm)
    )
    assert "card-xl" in xl_card.attrs['class']
    assert xl_card.children[0].children[0].children[0] == "Xlarge Card"
    
    # Card with border
    border_card = Div(
        Div(
            H2("Card Title", cls=str(card_title)),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            Div(
                Button("Buy Now", cls=combine_classes(btn, btn_colors.primary)),
                cls=combine_classes(card_actions, justify.end)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, card_styles.border, bg_dui.base_100, w._96)
    )
    assert "card" in border_card.attrs['class']
    assert "card-border" in border_card.attrs['class']
    assert "shadow" not in border_card.attrs['class']  # No shadow for border variant
    
    # Card with dash border
    dash_card = Div(
        Div(
            H2("Card Title", cls=str(card_title)),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            Div(
                Button("Buy Now", cls=combine_classes(btn, btn_colors.primary)),
                cls=combine_classes(card_actions, justify.end)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, card_styles.dash, bg_dui.base_100, w._96)
    )
    assert "card" in dash_card.attrs['class']
    assert "card-dash" in dash_card.attrs['class']
    assert "shadow" not in dash_card.attrs['class']  # No shadow for dash variant
    
    # Return all card style variations in a Div
    return Div(
        xs_card,
        sm_card,
        md_card,
        lg_card,
        xl_card,
        border_card,
        dash_card
    )

# Run the tests
test_card_style_fasthtml_examples()

Xsmall Card

A card component has a figure, a body part, and inside body there are title and actions parts

Small Card

A card component has a figure, a body part, and inside body there are title and actions parts

Medium Card

A card component has a figure, a body part, and inside body there are title and actions parts

Large Card

A card component has a figure, a body part, and inside body there are title and actions parts

Xlarge Card

A card component has a figure, a body part, and inside body there are title and actions parts

Card Title

A card component has a figure, a body part, and inside body there are title and actions parts

Card Title

A card component has a figure, a body part, and inside body there are title and actions parts

test_func = test_card_style_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_card_layout_fasthtml_examples


def test_card_layout_fasthtml_examples(
    
):

Test card layout variations from daisyUI v5 documentation.

Exported source
def test_card_layout_fasthtml_examples():
    """Test card layout variations from daisyUI v5 documentation."""
    from fasthtml.common import Div, Figure, Img, H2, P, Button
    from cjm_fasthtml_tailwind.utilities.sizing import w
    from cjm_fasthtml_tailwind.utilities.effects import shadow
    from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import justify, items
    from cjm_fasthtml_tailwind.utilities.typography import text_align
    from cjm_fasthtml_tailwind.utilities.spacing import p
    from cjm_fasthtml_tailwind.utilities.borders import rounded
    from cjm_fasthtml_daisyui.utilities.semantic_colors import bg_dui
    from cjm_fasthtml_daisyui.components.actions.button import btn, btn_colors
    from cjm_fasthtml_daisyui.components.data_display.badge import badge, badge_styles, badge_colors
    
    # Card with badge
    badge_card = Div(
        Figure(
            Img(
                src="https://img.daisyui.com/images/stock/photo-1606107557195-0e29a4b5b4aa.webp",
                alt="Shoes"
            )
        ),
        Div(
            H2(
                "Card Title",
                Div("NEW", cls=combine_classes(badge, badge_colors.secondary)),
                cls=str(card_title)
            ),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            Div(
                Div("Fashion", cls=combine_classes(badge, badge_styles.outline)),
                Div("Products", cls=combine_classes(badge, badge_styles.outline)),
                cls=combine_classes(card_actions, justify.end)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, bg_dui.base_100, w._96, shadow.sm)
    )
    assert "card" in badge_card.attrs['class']
    assert badge_card.children[1].children[0].tag == "h2"
    assert "card-title" in badge_card.children[1].children[0].attrs['class']
    assert badge_card.children[1].children[0].children[1].tag == "div"
    assert "badge" in badge_card.children[1].children[0].children[1].attrs['class']
    assert "badge-secondary" in badge_card.children[1].children[0].children[1].attrs['class']
    assert badge_card.children[1].children[0].children[1].children[0] == "NEW"
    assert "badge-outline" in badge_card.children[1].children[2].children[0].attrs['class']
    assert badge_card.children[1].children[2].children[0].children[0] == "Fashion"
    assert "badge-outline" in badge_card.children[1].children[2].children[1].attrs['class']
    assert badge_card.children[1].children[2].children[1].children[0] == "Products"
    
    # Card with centered content and paddings
    centered_card = Div(
        Figure(
            Img(
                src="https://img.daisyui.com/images/stock/photo-1606107557195-0e29a4b5b4aa.webp",
                alt="Shoes",
                cls=str(rounded.xl)
            ),
            cls=combine_classes(p.x._10, p.t._10)
        ),
        Div(
            H2("Card Title", cls=str(card_title)),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            Div(
                Button("Buy Now", cls=combine_classes(btn, btn_colors.primary)),
                cls=str(card_actions)
            ),
            cls=combine_classes(card_body, items.center, text_align.center)
        ),
        cls=combine_classes(card, bg_dui.base_100, w._96, shadow.sm)
    )
    assert "px-10" in centered_card.children[0].attrs['class']
    assert "pt-10" in centered_card.children[0].attrs['class']
    assert "rounded-xl" in centered_card.children[0].children[0].attrs['class']
    assert "card-body" in centered_card.children[1].attrs['class']
    assert "items-center" in centered_card.children[1].attrs['class']
    assert "text-center" in centered_card.children[1].attrs['class']
    
    # Card with image overlay
    overlay_card = Div(
        Figure(
            Img(
                src="https://img.daisyui.com/images/stock/photo-1606107557195-0e29a4b5b4aa.webp",
                alt="Shoes"
            )
        ),
        Div(
            H2("Card Title", cls=str(card_title)),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            Div(
                Button("Buy Now", cls=combine_classes(btn, btn_colors.primary)),
                cls=combine_classes(card_actions, justify.end)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, bg_dui.base_100, card_modifiers.image_full, w._96, shadow.sm)
    )
    assert "card" in overlay_card.attrs['class']
    assert "image-full" in overlay_card.attrs['class']
    assert overlay_card.children[0].tag == "figure"
    assert overlay_card.children[1].tag == "div"
    assert "card-body" in overlay_card.children[1].attrs['class']
    
    # Card with image on side
    side_card = Div(
        Figure(
            Img(
                src="https://img.daisyui.com/images/stock/photo-1635805737707-575885ab0820.webp",
                alt="Movie"
            )
        ),
        Div(
            H2("New movie is released!", cls=str(card_title)),
            P("Click the button to watch on Jetflix app."),
            Div(
                Button("Watch", cls=combine_classes(btn, btn_colors.primary)),
                cls=combine_classes(card_actions, justify.end)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, card_modifiers.side, bg_dui.base_100, shadow.sm)
    )
    assert "card" in side_card.attrs['class']
    assert "card-side" in side_card.attrs['class']
    assert side_card.children[0].tag == "figure"
    assert side_card.children[1].children[0].children[0] == "New movie is released!"
    assert side_card.children[1].children[1].children[0] == "Click the button to watch on Jetflix app."
    
    # Responsive card (vertical on small screen, horizontal on large screen)
    responsive_card = Div(
        Figure(
            Img(
                src="https://img.daisyui.com/images/stock/photo-1494232410401-ad00d5433cfa.webp",
                alt="Album"
            )
        ),
        Div(
            H2("New album is released!", cls=str(card_title)),
            P("Click the button to listen on Spotiwhy app."),
            Div(
                Button("Listen", cls=combine_classes(btn, btn_colors.primary)),
                cls=combine_classes(card_actions, justify.end)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, card_modifiers.side.lg, bg_dui.base_100, shadow.sm)
    )
    assert "card" in responsive_card.attrs['class']
    assert "lg:card-side" in responsive_card.attrs['class']
    assert responsive_card.children[1].children[0].children[0] == "New album is released!"
    assert responsive_card.children[1].children[1].children[0] == "Click the button to listen on Spotiwhy app."
    
    # Return all card layout variations in a Div
    return Div(
        badge_card,
        centered_card,
        overlay_card,
        side_card,
        responsive_card
    )

# Run the tests
test_card_layout_fasthtml_examples()
Shoes

Card Title
NEW

A card component has a figure, a body part, and inside body there are title and actions parts

Fashion
Products
Shoes

Card Title

A card component has a figure, a body part, and inside body there are title and actions parts

Shoes

Card Title

A card component has a figure, a body part, and inside body there are title and actions parts

Movie

New movie is released!

Click the button to watch on Jetflix app.

Album

New album is released!

Click the button to listen on Spotiwhy app.

test_func = test_card_layout_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_card_special_fasthtml_examples


def test_card_special_fasthtml_examples(
    
):

Test special card examples from daisyUI v5 documentation.

Exported source
def test_card_special_fasthtml_examples():
    """Test special card examples from daisyUI v5 documentation."""
    from fasthtml.common import Div, H2, P, Button
    from fasthtml.svg import Svg, Path
    from cjm_fasthtml_tailwind.utilities.sizing import w, h
    from cjm_fasthtml_tailwind.utilities.effects import shadow
    from cjm_fasthtml_tailwind.utilities.flexbox_and_grid import justify, items
    from cjm_fasthtml_tailwind.utilities.typography import text_align
    from cjm_fasthtml_tailwind.utilities.svg import stroke, stroke_width, fill
    from cjm_fasthtml_daisyui.utilities.semantic_colors import bg_dui, text_dui
    from cjm_fasthtml_daisyui.components.actions.button import btn, btn_colors, btn_modifiers, btn_sizes, btn_styles
    
    # Card with custom color
    custom_color_card = Div(
        Div(
            H2("Card title!", cls=str(card_title)),
            P("A card component has a figure, a body part, and inside body there are title and actions parts"),
            Div(
                Button("Buy Now", cls=str(btn)),
                cls=combine_classes(card_actions, justify.end)
            ),
            cls=str(card_body)
        ),
        cls=combine_classes(card, bg_dui.primary, text_dui.primary_content, w._96)
    )
    assert "card" in custom_color_card.attrs['class']
    assert "bg-primary" in custom_color_card.attrs['class']
    assert "text-primary-content" in custom_color_card.attrs['class']
    assert "w-96" in custom_color_card.attrs['class']
    assert custom_color_card.children[0].children[0].children[0] == "Card title!"
    # Button uses default style since card has custom background
    assert custom_color_card.children[0].children[2].children[0].attrs['class'] == "btn"
    
    # Centered card with neutral color
    centered_neutral_card = Div(
        Div(
            H2("Cookies!", cls=str(card_title)),
            P("We are using cookies for no reason."),
            Div(
                Button("Accept", cls=combine_classes(btn, btn_colors.primary)),
                Button("Deny", cls=combine_classes(btn, btn_styles.ghost)),
                cls=combine_classes(card_actions, justify.end)
            ),
            cls=combine_classes(card_body, items.center, text_align.center)
        ),
        cls=combine_classes(card, bg_dui.neutral, text_dui.neutral_content, w._96)
    )
    assert "card" in centered_neutral_card.attrs['class']
    assert "bg-neutral" in centered_neutral_card.attrs['class']
    assert "text-neutral-content" in centered_neutral_card.attrs['class']
    assert "card-body" in centered_neutral_card.children[0].attrs['class']
    assert "items-center" in centered_neutral_card.children[0].attrs['class']
    assert "text-center" in centered_neutral_card.children[0].attrs['class']
    assert centered_neutral_card.children[0].children[0].children[0] == "Cookies!"
    assert centered_neutral_card.children[0].children[1].children[0] == "We are using cookies for no reason."
    # Check two action buttons
    assert "btn-primary" in centered_neutral_card.children[0].children[2].children[0].attrs['class']
    assert centered_neutral_card.children[0].children[2].children[0].children[0] == "Accept"
    assert "btn-ghost" in centered_neutral_card.children[0].children[2].children[1].attrs['class']
    assert centered_neutral_card.children[0].children[2].children[1].children[0] == "Deny"
    
    # Card with action on top
    action_top_card = Div(
        Div(
            Div(
                Button(
                    Svg(
                        Path(
                            stroke_linecap="round",
                            stroke_linejoin="round",
                            stroke_width="2",
                            d="M6 18L18 6M6 6l12 12"
                        ),
                        xmlns="http://www.w3.org/2000/svg",
                        cls=combine_classes(h._6, w._6),
                        fill="none",
                        viewBox="0 0 24 24",
                        stroke="currentColor"
                    ),
                    cls=combine_classes(btn, btn_modifiers.square, btn_sizes.sm)
                ),
                cls=combine_classes(card_actions, justify.end)
            ),
            P("We are using cookies for no reason."),
            cls=str(card_body)
        ),
        cls=combine_classes(card, bg_dui.base_100, w._96, shadow.sm)
    )
    assert "card" in action_top_card.attrs['class']
    assert "bg-base-100" in action_top_card.attrs['class']
    assert "w-96" in action_top_card.attrs['class']
    assert "shadow-sm" in action_top_card.attrs['class']
    # Verify actions are first child of card body
    card_body_div = action_top_card.children[0]
    assert "card-body" in card_body_div.attrs['class']
    assert card_body_div.children[0].tag == "div"
    assert "card-actions" in card_body_div.children[0].attrs['class']
    assert "justify-end" in card_body_div.children[0].attrs['class']
    # Verify close button
    close_button = card_body_div.children[0].children[0]
    assert close_button.tag == "button"
    assert "btn" in close_button.attrs['class']
    assert "btn-square" in close_button.attrs['class']
    assert "btn-sm" in close_button.attrs['class']
    assert close_button.children[0].tag == "svg"
    assert "h-6" in close_button.children[0].attrs['class']
    assert "w-6" in close_button.children[0].attrs['class']
    # Verify text comes after actions
    assert card_body_div.children[1].tag == "p"
    assert card_body_div.children[1].children[0] == "We are using cookies for no reason."
    
    # Return all special card examples in a Div
    return Div(
        custom_color_card,
        centered_neutral_card,
        action_top_card
    )

# Run the tests
test_card_special_fasthtml_examples()

Card title!

A card component has a figure, a body part, and inside body there are title and actions parts

Cookies!

We are using cookies for no reason.

We are using cookies for no reason.

test_func = test_card_special_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()