fhdaisy

A FastHTML wrapper for Daisy-UI

fhdaisy provides Python components for using DaisyUI in FastHTML applications. For example, Btn('Click me', cls='-primary') creates <button class="btn btn-primary">Click me</button>. Component names follow DaisyUI’s CSS classes: card becomes Card, and alert becomes Alert. Modifiers can omit the component prefix, as in -primary for btn-primary.

fhdaisy.xtras provides helpers for repeated structures such as accordions and forms. You can also write your own helpers.

Usage

Installation

Install latest from pypi

$ pip install fhdaisy

Documentation

DaisyUI

DaisyUI adds component classes to Tailwind CSS. Tailwind utilities such as bg-blue-500 and p-4 each control a styling property. DaisyUI classes such as btn, card, and modal define styles for whole components. For example, class="btn btn-primary" styles a button without listing its individual Tailwind utilities.

DaisyUI provides CSS-based components with themes, responsive design, and accessibility features. It does not require a JavaScript framework. FastHTML can use these components in server-rendered HTML.

Daisy basics

from fasthtml.common import *
from fasthtml.jupyter import *
from fhdaisy import *

DaisyUI buttons use the btn class. Additional classes prefixed with btn- modify their appearance:

c = Button('Hey there', cls='btn btn-primary')
print(c)
<button class="btn btn-primary">Hey there</button>

Use mk_previewer() to preview components in Jupyter, Solveit, and similar environments:

p = mk_previewer()

Pass the button to the previewer:

p(c)

fhdaisy basics

fhdaisy components create HTML elements with the corresponding DaisyUI base class. Btn creates a <button> with class btn. The HTML tag follows DaisyUI’s documentation. For example, Alert creates a <div> and Input creates an <input>.

In the cls parameter, a leading - expands to the component’s class prefix. For Btn, -primary, -outline, and -sm expand to btn-primary, btn-outline, and btn-sm.

The previous button can therefore be written as:

c = Btn('Hey there', cls='-primary')
print(c)
<button class="btn btn-primary ">Hey there</button>

This renders identically to the previous manual version.

p(c)

DaisyUI input classes follow the same pattern:

  • input supplies the base input styling.
  • input-bordered adds a border.
  • input-primary uses the primary colour theme.

Using the full class names:

p( Input(placeholder='Enter name', cls='input input-bordered') )

Input supplies the base input class. Use -bordered as shorthand for input-bordered:

p( Input(placeholder='Enter name', cls='-bordered') )
print( Alert('Success! Your changes have been saved', cls='-success -soft') )
<div class="alert alert-success alert-soft ">Success! Your changes have been saved</div>

DaisyUI creates alerts using the alert class on a <div> element. Here’s the traditional DaisyUI approach:

p( Div('This is an important message!', cls='alert alert-info') )

Alert also creates a <div>. Its name comes from the CSS class, rather than an HTML tag. HTML has no <alert> element:

p( Alert('This is an important message!', cls='-info') )

Multi-part components

A DaisyUI card contains nested elements:

  • A <div> with class card as the container
  • An optional <figure> for images
  • A <div> with class card-body for the main content
  • Within the card body:
    • An optional <h2> with class card-title
    • Content paragraphs
    • A <div> with class card-actions for buttons

fhdaisy provides Card for the container. The part names card-body, card-title, and card-actions correspond to CardBody, CardTitle, and CardActions:

p ( Card(
        Figure(Img(src='https://picsum.photos/seed/fd/400/225')),
        CardBody(
            CardTitle('Card title'),
            P('This is a sample card with some content'),
            CardActions(cls='justify-end')( Btn('Buy Now', cls='-primary') )
        ) , cls='w-96 bg-base-100 shadow-sm'
) )

Xtras

from fhdaisy.xtras import *
import fasthtml.components as fh

An accordion item contains a radio input, a title, and content inside a Collapse component:

p ( Collapse(
        fh.Input(type='radio', name='acc1', checked="checked"),
        CollapseTitle('Click to expand', cls='font-semibold'),
        CollapseContent('This is the hidden content', cls='text-sm'),
        cls='-arrow border border-base-300'
) )

fhdaisy.xtras provides mk_accordion_item to construct those parts:

p (mk_accordion_item('Click to expand', 'This is the hidden content',
    name='acc1', checked=True, cls='-arrow border border-base-300', titlecls='font-semibold'))

mk_accordion builds an accordion from a sequence of items. All xtras helpers use the mk_ prefix to distinguish them from components that map directly to DaisyUI classes:

accitems = [
    ('How do I create an account?', 'Click the "Sign Up" button in the top right corner.'),
    ('I forgot my password', 'Click on "Forgot Password" on the login page.'),
    ('How do I update my profile?', 'Go to "My Account" settings and select "Edit Profile".')
]
p( mk_accordion(*accitems,
        titlecls='font-semibold', contentcls='text-sm',
        itemcls='-arrow border border-base-300',
        cls='-vertical min-w-md') )

Custom functions

Write custom helpers for repeated structures that fhdaisy.xtras does not yet cover. Use the mk_ prefix for these helpers too.

A DaisyUI rating consists of masked input elements, one for each star or other shape. Written individually, the inputs look like this:

p( Rating(
    Mask(cls='-star-2 bg-orange-400', checked=True, name='rating-demo'),
    Mask(cls='-star-2 bg-orange-400', checked=True, name='rating-demo'),
    Mask(cls='-star-2 bg-orange-400', checked=True, name='rating-demo'),
    Mask(cls='-star-2 bg-orange-400', checked=False, name='rating-demo'),
    Mask(cls='-star-2 bg-orange-400', checked=False, name='rating-demo'),
    cls='-sm'
) )

A mk_rating helper can generate the inputs from the number of stars and the selected count:

def mk_rating(n, checked, nm=None, cls='', itemcls=''):
    return Rating(*[Mask(cls=itemcls, checked=(i<checked), name=nm) for i in range(n)], cls=cls)

This creates the same five-star rating with three stars selected:

p( mk_rating(5, 3, nm='rating-demo', cls='-sm', itemcls='-star-2 bg-orange-400') )

For other repeated structures, put the component construction in a mk_ function. Make the parts that vary between uses its parameters.

Full example

This example combines several components. Sonnet-3.5 generated it in Solveit:

c = Div(
    Card(
        Figure(Img(src="https://picsum.photos/seed/42/400/250")),
        CardBody(
            H2("Mountain Adventure", cls="card-title"),
            Flex(
                Badge("New", cls="-primary"),
                Badge("Featured", cls="-secondary -outline"),
                Badge("Travel", cls="-accent -soft"),
                cls="gap-2 mb-3"),
            P("Discover breathtaking mountain trails and scenic vistas on this unforgettable journey."),
            Flex(
                Avatar(
                    Div(Img(src="https://picsum.photos/80/80", cls="rounded-full"), cls="w-10"),
                    cls="-online"),
                Div(
                    Div("Alex Chen", cls="font-semibold"),
                    Div("2 hours ago", cls="text-sm opacity-50")),
                cls="items-center gap-3 my-4"),
            mk_rating(5, 3, nm='rating-demo', cls='-sm', itemcls='-star-2 bg-orange-400'),
            Progress(value="75", max="100", cls="-primary -sm mt-3"),
            CardActions(
                Btn("Learn More", cls="-primary"),
                Btn("Bookmark"),
                cls="justify-end mt-4")
        ),
        cls="w-96 bg-base-100 shadow-xl"),
    cls="min-h-screen bg-base-200 flex items-center justify-center p-8"
)
p(c)

Next steps

Try components interactively in Jupyter or Solveit. Create a previewer with mk_previewer() and compare different combinations and modifiers. Start with Btn or Alert and modifiers such as -primary, -outline, and -lg. Then try multi-part components such as cards and modals.

The markdown version of this documentation makes useful context for an LLM. Click “commonmark” on the documentation page to obtain it. Provide it when asking an assistant to prototype an interface or convert existing HTML designs to fhdaisy.

See the DaisyUI component documentation for all components and modifiers. See the FastHTML documentation for building complete applications.

Contributions of useful mk_ helpers are welcome in the fhdaisy repository. Use that prefix for helpers that construct repeated component structures.