π― Overview
This module provides a comprehensive set of Material Design components for building FastHTML applications.
π Buttons
ButtonT, NavToggleButton
Button variants and navigation toggles
π Links
AT (AnchorChain)
Styled anchor/link variants
π Layout
Grid , GridCell , DivHStacked , DivVStacked , DivCentered
Grid system and flex layouts
π¨ Icons
Icon
Material Design icons
π§ Navigation
NavBar , NavContainer , NavSideBarContainer , BottomNav
Navigation components
π¬ Modals
Modal , ModalButton , ModalTitle , ModalBody , ModalFooter
Dialog windows
π Forms
Field , LabelInput , CheckboxX , Radio , Switch , TextArea , Range , Select , FormGrid
Form inputs and layout
β³ Feedback
Progress , LoadingIndicator , Toast , Snackbar
Loading and notifications
π Tables
Table , Td , Th , TableFromLists , TableFromDicts , Pagination
Data tables
π Cards
Card , Toolbar
Content containers
π€ Typography
TextT , TextPresets , CodeSpan , CodeBlock , Blockquote
Text styling
πͺ Misc
FAQItem , CookiesBanner , Divider, Avatar
Utility components
π Table of Contents
π Buttons - Button variants and chains
π Anchor - Link styling
π Grid - Grid system and layout
π¨ Icon - Material icons
π§ NavBar - Top navigation
π¬ Modal Dialog - Dialogs and popups
π Label Input - Input fields with labels
π·οΈ Form Label - Standalone form labels
βοΈ Checkbox - Checkbox inputs
π Radio - Radio buttons
π Switch - Toggle switches
π Text Area - Multi-line text
π Range - Slider inputs
π Select - Dropdown menus
π FormGrid - Form layouts
π Progress - Progress bars
β³ Loading Indicator - Spinners
π Tables - Data tables
π Pagination - Page navigation
π Card - Content cards
π§ Toolbar - Action bars
π Toast / Snackbar - Notifications
π¦ Nav Container - Navigation drawers
π Sidebar - Side navigation
π€ Typography - Text styling
π Anchor
Chainable anchor/link styles.
AT
Chainable anchor styles (AT.primary, AT.chip, AT.button, etc.)
π‘ Use case : A("Learn More", href="/docs", cls=AT.button.primary) creates a button-styled link.
Code
def ex_links():
return Article(
A('Default Link' ),
Hr(),
A('Muted Link' , cls= AT.muted),
Hr(),
A('Text Link' , cls= AT.text),
Hr(),
A('Reset Link' , cls= AT.reset),
Hr(),
A('Primary Link' , cls= AT.primary),
Hr(),
A('Classic Link' , cls= AT.classic),
Hr(),
cls= "padding" )
preview(ex_links())
π Grid
Responsive grid system and flex layout helpers.
Grid Parameters
cells
-
Grid children, auto-wrapped with span classes based on cols
space
SpaceT.medium_space
Spacing between grid cells
cols_min
1
Minimum columns at smallest breakpoint
cols_max
4
Maximum columns at largest breakpoint
cols
None
Fixed column count for all breakpoints
cols_sm
None
Column count for small screens
cols_md
None
Column count for medium screens
cols_lg
None
Column count for large screens
responsive
True
Center grid with responsive max-width
padding
True
Add padding around the grid
GridCell Parameters
span
String like 's12 m6 l4' or tuple of GridSpanT values
cls
Additional CSS classes
π‘ Use case : Grid(GridCell("A", span=6), GridCell("B", span=6)) creates a 2-column layout.
source
Grid
def Grid(
cells:VAR_POSITIONAL, space:SpaceT=< SpaceT.medium_space: 'medium-space' > , cols_min:int = 1 , cols_max:int = 4 ,
cols:int = None , cols_sm:int = None , cols_md:int = None , cols_lg:int = None , responsive:bool = True , padding:bool = True ,
cls:str = '' , kwargs:VAR_KEYWORD
):
BeerCSS responsive grid with smart column defaults and mobile-first design.
MonsterUI-compatible API: cols parameter auto-derives responsive breakpoints: cols=4 -> cols_sm=1, cols_md=2, cols_lg=4 (mobile stacks, tablet halves, desktop full)
For explicit control, use cols_sm, cols_md, cols_lg directly.
source
GridCell
def GridCell(
c:VAR_POSITIONAL, span:tuple = (), cls:str = '' , kwargs:VAR_KEYWORD
):
Wrap content as a BeerCSS grid cell with responsive span control.
source
GridSpanT
def GridSpanT(
args:VAR_POSITIONAL, kwds:VAR_KEYWORD
):
Grid span classes for responsive layouts (BeerCSS)
source
SpaceT
def SpaceT(
args:VAR_POSITIONAL, kwds:VAR_KEYWORD
):
Space types using BeerCSS spacing classes
Code
def ex_grid():
return Grid(
Div(
P("Column 1 Item 1" ),
P("Column 1 Item 2" ),
P("Column 1 Item 3" )),
Div(
P("Column 2 Item 1" ),
P("Column 2 Item 2" ),
P("Column 2 Item 2" )),
Div(
P("Column 3 Item 1" ),
P("Column 3 Item 2" ),
P("Column 3 Item 3" )))
preview(ex_grid())
Code
def ex_product_grid():
products = [
{"name" : "Laptop" , "price" : "$999" , "img" : "https://picsum.photos/200/100?random=1" },
{"name" : "Smartphone" , "price" : "$599" , "img" : "https://picsum.photos/200/100?random=2" },
{"name" : "Headphones" , "price" : "$199" , "img" : "https://picsum.photos/200/100?random=3" },
{"name" : "Smartwatch" , "price" : "$299" , "img" : "https://picsum.photos/200/100?random=4" },
{"name" : "Tablet" , "price" : "$449" , "img" : "https://picsum.photos/200/100?random=5" },
{"name" : "Camera" , "price" : "$799" , "img" : "https://picsum.photos/200/100?random=6" },
]
product_cards = [
Card(
Img(src= p["img" ], alt= p["name" ], style= "width:100%; height:100px; object-fit:cover;" ),
H4(p["name" ], cls= "mt-2" ),
P(p["price" ]),
Button("Add to Cart" , cls= (ButtonT.primary, "mt-2" ))
) for p in products
]
return Grid(* product_cards, cols_lg= 3 )
preview(ex_product_grid())
source
DivHStacked
def DivHStacked(
c:VAR_POSITIONAL, responsive:bool = True , padding:bool = True , cls:str = '' , kwargs:VAR_KEYWORD
):
Responsive horizontal stack with padding and mobile compatibility.
source
DivLAligned
def DivLAligned(
c:VAR_POSITIONAL, cls:str = '' , kwargs:VAR_KEYWORD
):
MonsterUI-compatible left-aligned row using BeerCSS tokens.
Code
def ex_l_aligned_div():
return Article(
DivLAligned(
Img(src= "https://picsum.photos/100/100?random=1" , style= "max-width: 100px;" ),
H4("Left Aligned Title" ),
P("Some text that's left-aligned with the title and image." )
),
cls= "padding" )
preview(ex_l_aligned_div())
source
DivVStacked
def DivVStacked(
c:VAR_POSITIONAL, responsive:bool = True , padding:bool = True , cls:str = '' , kwargs:VAR_KEYWORD
):
Responsive vertical stack with padding and mobile compatibility.
Code
def ex_v_stacked_div():
return Article(
DivVStacked(
H2("Vertical Stack" ),
P("First paragraph in the stack" ),
P("Second paragraph in the stack" ),
Button("Action Button" , cls= ButtonT.secondary)
),
cls= "padding" )
preview(ex_v_stacked_div())
Code
def ex_h_stacked_div():
return Article(
DivHStacked(
Div(H4("Column 1" ), P("Content for column 1" )),
Div(H4("Column 2" ), P("Content for column 2" )),
Div(H4("Column 3" ), P("Content for column 3" ))
),
cls= "padding" )
preview(ex_h_stacked_div())
source
DivRAligned
def DivRAligned(
c:VAR_POSITIONAL, cls:str = '' , kwargs:VAR_KEYWORD
):
MonsterUI-compatible right-aligned row using BeerCSS tokens.
Code
def ex_r_aligned_div():
return Article(
DivRAligned(
Button("Action" , cls= ButtonT.primary),
P("Right-aligned text" ),
Img(src= "https://picsum.photos/100/100?random=3" , style= "max-width: 100px;" )
),
cls= "padding" )
preview(ex_r_aligned_div())
source
DivCentered
def DivCentered(
c:VAR_POSITIONAL, cls:str = '' , kwargs:VAR_KEYWORD
):
Center-aligned container using BeerCSS tokens.
Code
def ex_centered_div():
return Article(
DivCentered(
H3("Centered Title" ),
P("This content is centered both horizontally and vertically." )
),
cls= "padding" )
preview(ex_centered_div())
source
DivFullySpaced
def DivFullySpaced(
c:VAR_POSITIONAL, cls:str = '' , kwargs:VAR_KEYWORD
):
Row with children stretched to far ends using BeerCSS max spacers.
Code
def ex_fully_spaced_div():
return Article(
DivFullySpaced(
Button("Left" , cls= ButtonT.primary),
Button("Center" , cls= ButtonT.secondary),
Button("Right" , cls= ButtonT.destructive),
Button("Right2" , cls= ButtonT.destructive)
),
cls= "padding"
)
preview(ex_fully_spaced_div())
π¨ Icon
Material Design icon component.
Icon
Material icon with optional click handler
π‘ Use case : Icon("settings", cls="large primary") creates a large primary settings icon.
source
Icon
def Icon(
icon:str , size:str = None , fill:bool = False , cls:tuple = (), kwargs:VAR_KEYWORD
):
Material Design icon with optional size and fill
Code
def ex_icon():
return Article(
Grid(
Icon('menu' , size= 'large' ),
Icon('settings' , cls= 'primary-text' ),
Icon('favorite' , fill= True )
),
cls= "padding" )
preview(ex_icon())
π§ NavBar
Horizontal navigation bar component with HTMX SPA navigation defaults.
brand
None
Brand element (logo/title) positioned on the left
sticky
False
Stick navbar to top on scroll
blur
None
Glass effect: 'small-blur', 'medium-blur', 'large-blur'
size
'small'
Navbar height: 'small', 'medium', 'large'
center
False
Center navigation links (vs right-aligned)
hx_boost
True
Auto-enhance <a> links for HTMX navigation
hx_target
'#main-content'
Target element for boosted links
hx_swap
None
HTMX swap method (e.g., 'outerHTML')
π‘ Basic usage : NavBar(A("Home"), A("About"), brand=H3("MyApp"), sticky=True)
π‘ With glass effect : NavBar(..., sticky=True, blur='small-blur', hx_swap='outerHTML')
source
NavBar
def NavBar(
children:VAR_POSITIONAL, brand:NoneType= None , sticky:bool = False , blur:NoneType= None , cls:str = '' ,
size:str = 'small' , center:bool = False , end:NoneType= None , hx_boost:bool = True , hx_target:str = '#main-content' ,
hx_swap:NoneType= None , kwargs:VAR_KEYWORD
):
Horizontal navigation bar with HTMX SPA navigation defaults.
Args: brand: Brand element (logo/title) positioned on the left sticky: Whether navbar sticks to top on scroll blur: Blur effect class (βsmall-blurβ, βmedium-blurβ, βlarge-blurβ) for glass effect size: Navbar size - βsmallβ (default), βmediumβ, βlargeβ, or None center: Center the navigation links (default False = links on right) end: Optional end slot content (shown at right when center=True) hx_boost: Auto-enhance all links for HTMX navigation (default True) hx_target: Target element for boosted links (default β#main-contentβ) hx_swap: HTMX swap method (e.g., βouterHTMLβ for full main swap)
Layout modes: center=False: [brand] [spacer] [linksβ¦] center=True: [brand] [spacer] [links centered] [spacer] [end?]
Code
def ex_navbar1():
return NavBar(A("Page1" ,href= '/rt1' ),
A("Page2" ,href= '/rt2' ),
A("Page3" ,href= '/rt3' ),
brand= H3('My Blog' ))
preview(ex_navbar1())
π¬ Modal Dialog
Modal/dialog components for popups and confirmations.
Modal Parameters
*c
-
Modal content (title, body, etc.)
id
None
Modal ID for data-ui targeting
footer
None
Footer content (auto-wrapped in Nav)
active
False
Whether modal starts active/visible
overlay
'default'
Overlay style: 'default' (plain), 'blur', 'small-blur', 'medium-blur', 'large-blur', or False/None (no overlay)
position
None
Position: None (center), 'left', 'right', 'top', 'bottom'
cls
()
Additional CSS classes
Helper Components
ModalButton(text, id)
Button that opens modal via data-ui
ModalCancel(text, modal_id)
Cancel button that closes modal
ModalConfirm(text, modal_id)
Confirm button that closes modal
ModalTitle(*c)
H5-based title component
ModalBody(*c)
Div wrapper for body content
ModalFooter(*c)
Nav wrapper with right-aligned buttons
π‘ Use case : Use data-ui="#modal-id" to link triggers to modals. Position dialogs as side drawers ('left', 'right') or sheets ('top', 'bottom').
source
ModalBody
def ModalBody(
c:VAR_POSITIONAL, cls:tuple = (), kwargs:VAR_KEYWORD
):
Modal body wrapper for content layout.
source
ModalTitle
def ModalTitle(
c:VAR_POSITIONAL, cls:tuple = (), kwargs:VAR_KEYWORD
):
Modal title using H5 element.
source
ModalConfirm
def ModalConfirm(
text:str = 'Confirm' , modal_id:NoneType= None , cls:tuple = (), kwargs:VAR_KEYWORD
):
Confirm button that closes modal via data-ui.
source
ModalCancel
def ModalCancel(
text:str = 'Cancel' , modal_id:NoneType= None , cls:tuple = (), kwargs:VAR_KEYWORD
):
Cancel button that closes modal via data-ui.
source
Modal
def Modal(
c:VAR_POSITIONAL, id :NoneType= None , footer:NoneType= None , active:bool = False , overlay:str = 'default' ,
position:NoneType= None , cls:tuple = (), kwargs:VAR_KEYWORD
):
BeerCSS modal dialog with position and overlay options.
Always returns a list for consistent unpacking with *Modal(β¦). When overlay is enabled, clicking the overlay closes the modal.
Args: *c: Modal content (title, body, etc.) id: Modal ID for data-ui targeting footer: Footer content (auto-wrapped in Nav if not already) active: Whether modal starts active/visible overlay: Overlay style - βdefaultβ (plain), βblurβ, βsmall-blurβ, βmedium-blurβ, βlarge-blurβ, or False/None (no overlay) position: Position - None (center), βleftβ, βrightβ, βtopβ, βbottomβ cls: Additional CSS classes
Returns: List of elements (overlay + dialog, or just [dialog] if no overlay)
Code
def test_modal():
"""Test modal with position and overlay options."""
return Article(
# Centered modal with default (plain) overlay
Button("Centered (Default Overlay)" , data_ui= "#modal-center" , cls= "primary" ),
* Modal(
ModalTitle("Centered Dialog" ),
ModalBody("This modal uses the default plain overlay (no blur)" ),
footer= ModalFooter(
ModalCancel(modal_id= "modal-center" ),
ModalConfirm(modal_id= "modal-center" )
),
id = "modal-center"
),
# Left drawer with blur overlay
Button("Left Drawer (Blur)" , data_ui= "#modal-left" , cls= "secondary" ),
* Modal(
ModalTitle("Left Navigation" ),
ModalBody("This is a left-side drawer with blur overlay. Click overlay to close." ),
footer= ModalFooter(
ModalCancel(modal_id= "modal-left" ),
ModalConfirm(modal_id= "modal-left" )
),
id = "modal-left" ,
position= 'left' ,
overlay= 'blur'
),
# Right panel with default overlay
Button("Right Panel" , data_ui= "#modal-right" ),
* Modal(
ModalTitle("Right Panel" ),
ModalBody("This is a right-side panel. Click overlay to close." ),
footer= ModalFooter(
ModalCancel(modal_id= "modal-right" ),
ModalConfirm(modal_id= "modal-right" )
),
id = "modal-right" ,
position= 'right'
),
# Bottom sheet
Button("Bottom Sheet" , data_ui= "#modal-bottom" , cls= "tertiary" ),
* Modal(
ModalTitle("Bottom Sheet" ),
ModalBody("This is a bottom sheet with medium blur" ),
footer= ModalFooter(
ModalCancel(modal_id= "modal-bottom" ),
ModalConfirm(modal_id= "modal-bottom" )
),
id = "modal-bottom" ,
position= 'bottom' ,
overlay= 'medium-blur'
),
cls= "padding"
)
preview(test_modal())
βοΈ Checkbox
CheckboxX
BeerCSS checkbox with label support
π‘ Use case : Boolean form inputs with Material Design styling.
source
CheckboxX
def CheckboxX(
c:VAR_POSITIONAL, cls:tuple = (), kwargs:VAR_KEYWORD
):
BeerCSS checkbox with label support.
Code
def ex_checkbox():
return Article(
CheckboxX(),
CheckboxX("Accept terms" ),
CheckboxX("Enabled" , checked= True ),
CheckboxX("Option 1" , name= "options" , value= "opt1" ),
cls= "padding" )
preview(ex_checkbox())
π Radio
Radio
BeerCSS radio button with label
π‘ Use case : Single-selection from mutually exclusive options.
source
Radio
def Radio(
c:VAR_POSITIONAL, cls:tuple = (), kwargs:VAR_KEYWORD
):
BeerCSS radio button with label.
Code
def ex_Radio():
return Article(
Radio("Option 1" , name= "group1" , value= "opt1" ),
Radio("Option 2" , name= "group1" , value= "opt2" , checked= True ),
cls= "padding" )
preview(ex_Radio())
π Switch
Switch
Toggle switch for on/off states
π‘ Use case : Binary settings like dark mode, notifications, feature toggles.
source
Switch
def Switch(
c:VAR_POSITIONAL, cls:tuple = (), kwargs:VAR_KEYWORD
):
BeerCSS toggle switch for on/off states.
If label text is provided, wraps in a nav with the label on the left and the switch on the right (standard BeerCSS pattern).
Code
def ex_switch():
return Article(
Switch("Enable notifications" , name= "notifications" , checked= False ),
Switch("Dark mode" , name= "dark_mode" , checked= True ),
Switch(name= "no_label" ), # Switch without label
cls= "padding" )
preview(ex_switch())
π Text Area
TextArea
Multi-line text input with field wrapper
π‘ Use case : Comments, descriptions, long-form text input.
source
TextArea
def TextArea(
c:VAR_POSITIONAL, cls:tuple = (), kwargs:VAR_KEYWORD
):
BeerCSS textarea with field wrapper for consistent styling.
Code
def ex_TextArea():
return Article(
TextArea(placeholder= "Enter description..." ),
TextArea("Initial text" , rows= 5 ),
TextArea(placeholder= " " ),
cls= "padding" )
preview(ex_TextArea())
π Range
Range
Slider input for numeric ranges
π‘ Use case : Volume controls, price filters, numeric value selection within bounds.
source
Range
def Range(
c:VAR_POSITIONAL, min :NoneType= None , max :NoneType= None , step:NoneType= None , cls:tuple = (), kwargs:VAR_KEYWORD
):
BeerCSS range slider with two-tone fill effect.
Code
def ex_range():
return Article(
Range(value= 25 ),
Range(min = 0 , max = 100 , value= 50 ),
cls= "padding" )
preview(ex_range())