MonsterUI Buttons and Links
Iterating through the ButtonT enum to show all MonsterUI button types visually.
from fastcore.utils import *
from fasthtml.common import *
from monsterui.all import *
tags = ["MonsterUI"]
Setup
Button()
<button type="submit" class="uk-button uk-button-default"></button>
show(Button("Click me"))
show(A("My link", href="example.com", cls=AT.muted))
show(NavBar(title="MySite", nav_links=(A("Link 1"), A("Link 2"))))
show(Button("Hey",cls=ButtonT.primary))
ButtonT
<enum 'ButtonT'>
[t.name for t in ButtonT]
['default', 'primary', 'secondary', 'danger', 'text', 'link', 'ghost']
AI Prompt
Is there a convenience function in enum to list all these?
AI Response
Yes! The Enum
class in Python has a built-in method called __members__
. You can use it like this:
ButtonT.__members__
Would you like me to explain more about what this returns and how it differs from the list comprehension approach you used?
ButtonT.__members__
mappingproxy({'default': <ButtonT.default: 'uk-button-default'>,
'primary': <ButtonT.primary: 'uk-button-primary'>,
'secondary': <ButtonT.secondary: 'uk-button-secondary'>,
'danger': <ButtonT.danger: 'uk-button-danger'>,
'text': <ButtonT.text: 'uk-button-text'>,
'link': <ButtonT.link: 'uk-button-link'>,
'ghost': <ButtonT.ghost: 'uk-button-ghost'>})
L(ButtonT.__members__)
(#7) ['default','primary','secondary','danger','text','link','ghost']
def _Button(t): return Button(f"{t} button",cls=t)
btns = L(ButtonT.__members__).map(_Button)
btns
(#7) [button(('default button',),{'type': 'submit', 'class': 'uk-button default'}),button(('primary button',),{'type': 'submit', 'class': 'uk-button primary'}),button(('secondary button',),{'type': 'submit', 'class': 'uk-button secondary'}),button(('danger button',),{'type': 'submit', 'class': 'uk-button danger'}),button(('text button',),{'type': 'submit', 'class': 'uk-button text'}),button(('link button',),{'type': 'submit', 'class': 'uk-button link'}),button(('ghost button',),{'type': 'submit', 'class': 'uk-button ghost'})]
to_xml(Div(*btns))
'<div>\n<button type="submit" class="uk-button default">default button</button><button type="submit" class="uk-button primary">primary button</button><button type="submit" class="uk-button secondary">secondary button</button><button type="submit" class="uk-button danger">danger button</button><button type="submit" class="uk-button text">text button</button><button type="submit" class="uk-button link">link button</button><button type="submit" class="uk-button ghost">ghost button</button></div>\n'
show(to_xml(Div(*btns)))
AI Prompt
Why don't the buttons look right?
AI Response
Looking at the button classes in the HTML output, I notice the classes are missing the uk-button-
prefix that we saw in the ButtonT
enum values. Instead, they just have uk-button default
, uk-button primary
, etc.
Let's check what's happening by looking at one button directly:
show(Button("test", cls=ButtonT.primary))
This should help us see if the issue is in how we're passing the enum values to the Button constructor.
AI Prompt
def _Button(t): return Button(f"{t} button",cls=ButtonT.t) btns = L(ButtonT.members).map(_Button) btns
AI Response
Ah, I see the issue in your code. ButtonT.t
isn't correct - you're trying to access a property t
on ButtonT
, but t
is actually the variable in your function containing the member name.
Instead, you should use ButtonT[t]
or getattr(ButtonT, t)
to look up the enum member by name. Would you like to try fixing this?
def _Button(t): return Button(f"{t} button",cls=ButtonT[t])
btns = L(ButtonT.__members__).map(_Button)
show(Div(*btns))
Improvements
This part is from SolveIt office hours with Isaac Flath.
AI Prompt
Is there any other way to get ButtonT.__members__
in enum or otherwise?
AI Response
Yes! There are a few other ways to get enum members:
- Using
list(ButtonT)
- this gives you the values - Using
ButtonT._member_names_
- this gives you just the names - Using
ButtonT._member_map_
- similar to__members__
but returns a regular dict
Would you like to try any of these to see how they differ?
list(ButtonT)[0].value
'uk-button-default'
Div(*[Button(v,cls=v) for v in list(ButtonT)])
<div>
<button type="submit" class="uk-button uk-button-default">uk-button-default</button><button type="submit" class="uk-button uk-button-primary">uk-button-primary</button><button type="submit" class="uk-button uk-button-secondary">uk-button-secondary</button><button type="submit" class="uk-button uk-button-danger">uk-button-danger</button><button type="submit" class="uk-button uk-button-text">uk-button-text</button><button type="submit" class="uk-button uk-button-link">uk-button-link</button><button type="submit" class="uk-button uk-button-ghost">uk-button-ghost</button></div>
show(Div(*[Button(v,cls=v) for v in list(ButtonT)]))
show(DivLAligned(*[Button(v,cls=v) for v in list(ButtonT)]))
show(Grid(*[Button(v,cls=v) for v in list(ButtonT)]))