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


source

test_card_basic_examples

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

source

test_card_styles_examples

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

source

test_card_modifiers_examples

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

source

test_card_sizes_examples

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

source

test_card_basic_fasthtml_examples

 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()
<div>
  <div class="card bg-base-100 w-96 shadow-sm">
<figure><img src="https://img.daisyui.com/images/stock/photo-1606107557195-0e29a4b5b4aa.webp" alt="Shoes"></figure>    <div class="card-body">
      <h2 class="card-title">Card Title</h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
      <div class="card-actions justify-end">
<button class="btn btn-primary">Buy Now</button>      </div>
    </div>
  </div>
  <div class="card bg-base-100 w-96 shadow-sm">
    <div class="card-body">
      <h2 class="card-title">Card title!</h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
      <div class="card-actions justify-end">
<button class="btn btn-primary">Buy Now</button>      </div>
    </div>
  </div>
  <div class="card bg-base-100 w-96 shadow-sm">
    <div class="card-body">
      <h2 class="card-title">Card Title</h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
    </div>
<figure><img src="https://img.daisyui.com/images/stock/photo-1606107557195-0e29a4b5b4aa.webp" alt="Shoes"></figure>  </div>
</div>
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()

source

test_card_pricing_fasthtml_examples

 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()
<div>
  <div class="card w-96 bg-base-100 shadow-sm">
    <div class="card-body">
<span class="badge badge-xs badge-warning">Most Popular</span>      <div class="flex justify-between">
        <h2 class="text-3xl font-bold">Premium</h2>
<span class="text-xl">29/mo</span>      </div>
      <ul class="mt-6 flex flex-col gap-2 text-xs">
        <li>
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" stroke="currentColor" class="size-4 me-2 inline-block text-success"><path d="M5 13l4 4L19 7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg><span>High-resolution image generation</span>        </li>
        <li>
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" stroke="currentColor" class="size-4 me-2 inline-block text-success"><path d="M5 13l4 4L19 7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg><span>Customizable style templates</span>        </li>
        <li>
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" stroke="currentColor" class="size-4 me-2 inline-block text-success"><path d="M5 13l4 4L19 7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg><span>Batch processing capabilities</span>        </li>
        <li>
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" stroke="currentColor" class="size-4 me-2 inline-block text-success"><path d="M5 13l4 4L19 7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg><span>AI-driven image enhancements</span>        </li>
        <li class="opacity-50">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" stroke="currentColor" class="size-4 me-2 inline-block text-base-content/50"><path d="M5 13l4 4L19 7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="line-through">Seamless cloud integration</span>        </li>
        <li class="opacity-50">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" stroke="currentColor" class="size-4 me-2 inline-block text-base-content/50"><path d="M5 13l4 4L19 7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="line-through">Real-time collaboration tools</span>        </li>
      </ul>
      <div class="mt-6">
<button class="btn btn-primary btn-block">Subscribe</button>      </div>
    </div>
  </div>
</div>
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()

source

test_card_style_fasthtml_examples

 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()
<div>
  <div class="card w-96 bg-base-100 card-xs shadow-sm">
    <div class="card-body">
      <h2 class="card-title">Xsmall Card</h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
      <div class="justify-end card-actions">
<button class="btn btn-primary">Buy Now</button>      </div>
    </div>
  </div>
  <div class="card w-96 bg-base-100 card-sm shadow-sm">
    <div class="card-body">
      <h2 class="card-title">Small Card</h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
      <div class="justify-end card-actions">
<button class="btn btn-primary">Buy Now</button>      </div>
    </div>
  </div>
  <div class="card w-96 bg-base-100 card-md shadow-sm">
    <div class="card-body">
      <h2 class="card-title">Medium Card</h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
      <div class="justify-end card-actions">
<button class="btn btn-primary">Buy Now</button>      </div>
    </div>
  </div>
  <div class="card w-96 bg-base-100 card-lg shadow-sm">
    <div class="card-body">
      <h2 class="card-title">Large Card</h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
      <div class="justify-end card-actions">
<button class="btn btn-primary">Buy Now</button>      </div>
    </div>
  </div>
  <div class="card w-96 bg-base-100 card-xl shadow-sm">
    <div class="card-body">
      <h2 class="card-title">Xlarge Card</h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
      <div class="justify-end card-actions">
<button class="btn btn-primary">Buy Now</button>      </div>
    </div>
  </div>
  <div class="card card-border bg-base-100 w-96">
    <div class="card-body">
      <h2 class="card-title">Card Title</h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
      <div class="card-actions justify-end">
<button class="btn btn-primary">Buy Now</button>      </div>
    </div>
  </div>
  <div class="card card-dash bg-base-100 w-96">
    <div class="card-body">
      <h2 class="card-title">Card Title</h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
      <div class="card-actions justify-end">
<button class="btn btn-primary">Buy Now</button>      </div>
    </div>
  </div>
</div>
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()

source

test_card_layout_fasthtml_examples

 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()
<div>
  <div class="card bg-base-100 w-96 shadow-sm">
<figure><img src="https://img.daisyui.com/images/stock/photo-1606107557195-0e29a4b5b4aa.webp" alt="Shoes"></figure>    <div class="card-body">
      <h2 class="card-title">
Card Title        <div class="badge badge-secondary">NEW</div>
      </h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
      <div class="card-actions justify-end">
        <div class="badge badge-outline">Fashion</div>
        <div class="badge badge-outline">Products</div>
      </div>
    </div>
  </div>
  <div class="card bg-base-100 w-96 shadow-sm">
<figure class="px-10 pt-10"><img src="https://img.daisyui.com/images/stock/photo-1606107557195-0e29a4b5b4aa.webp" alt="Shoes" class="rounded-xl"></figure>    <div class="card-body items-center text-center">
      <h2 class="card-title">Card Title</h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
      <div class="card-actions">
<button class="btn btn-primary">Buy Now</button>      </div>
    </div>
  </div>
  <div class="card bg-base-100 image-full w-96 shadow-sm">
<figure><img src="https://img.daisyui.com/images/stock/photo-1606107557195-0e29a4b5b4aa.webp" alt="Shoes"></figure>    <div class="card-body">
      <h2 class="card-title">Card Title</h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
      <div class="card-actions justify-end">
<button class="btn btn-primary">Buy Now</button>      </div>
    </div>
  </div>
  <div class="card card-side bg-base-100 shadow-sm">
<figure><img src="https://img.daisyui.com/images/stock/photo-1635805737707-575885ab0820.webp" alt="Movie"></figure>    <div class="card-body">
      <h2 class="card-title">New movie is released!</h2>
      <p>Click the button to watch on Jetflix app.</p>
      <div class="card-actions justify-end">
<button class="btn btn-primary">Watch</button>      </div>
    </div>
  </div>
  <div class="card lg:card-side bg-base-100 shadow-sm">
<figure><img src="https://img.daisyui.com/images/stock/photo-1494232410401-ad00d5433cfa.webp" alt="Album"></figure>    <div class="card-body">
      <h2 class="card-title">New album is released!</h2>
      <p>Click the button to listen on Spotiwhy app.</p>
      <div class="card-actions justify-end">
<button class="btn btn-primary">Listen</button>      </div>
    </div>
  </div>
</div>
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()

source

test_card_special_fasthtml_examples

 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()
<div>
  <div class="card bg-primary text-primary-content w-96">
    <div class="card-body">
      <h2 class="card-title">Card title!</h2>
      <p>A card component has a figure, a body part, and inside body there are title and actions parts</p>
      <div class="card-actions justify-end">
<button class="btn">Buy Now</button>      </div>
    </div>
  </div>
  <div class="card bg-neutral text-neutral-content w-96">
    <div class="card-body items-center text-center">
      <h2 class="card-title">Cookies!</h2>
      <p>We are using cookies for no reason.</p>
      <div class="card-actions justify-end">
<button class="btn btn-primary">Accept</button><button class="btn btn-ghost">Deny</button>      </div>
    </div>
  </div>
  <div class="card bg-base-100 w-96 shadow-sm">
    <div class="card-body">
      <div class="card-actions justify-end">
<button class="btn btn-square btn-sm"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" fill="none" stroke="currentColor" class="h-6 w-6"><path d="M6 18L18 6M6 6l12 12" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg></button>      </div>
      <p>We are using cookies for no reason.</p>
    </div>
  </div>
</div>
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()