Spaces:
Sleeping
Sleeping
Update testnavbar.py
Browse files- testnavbar.py +89 -3
testnavbar.py
CHANGED
|
@@ -1,9 +1,61 @@
|
|
| 1 |
from fasthtml.common import *
|
|
|
|
| 2 |
from monsterui.all import *
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
app, rt = fast_app(hdrs=hdrs, live=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
@rt
|
| 6 |
def index():
|
|
|
|
|
|
|
| 7 |
return Title('Hello World Title'), Container(
|
| 8 |
H3(A('H3 with Primary URL, a link does not work', href='', cls=AT.primary)),
|
| 9 |
P('I love monsterui!'),
|
|
@@ -11,8 +63,42 @@ def index():
|
|
| 11 |
A('Go to product gallery page', href='second.py', cls=AT.classic),
|
| 12 |
P('I love monsterui!'),
|
| 13 |
A('Go to Google, a link does not work', href='https://www.google.com', cls=AT.classic),
|
| 14 |
-
Card('A Fancy Card :)')
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
serve()
|
|
|
|
| 1 |
from fasthtml.common import *
|
| 2 |
+
# MonsterUI shadows fasthtml components with the same name
|
| 3 |
from monsterui.all import *
|
| 4 |
+
# If you don't want shadowing behavior, you use import monsterui.core as ... style instead
|
| 5 |
+
|
| 6 |
+
# Get frankenui and tailwind headers via CDN using Theme.blue.headers()
|
| 7 |
+
hdrs = Theme.blue.headers()
|
| 8 |
+
|
| 9 |
+
# fast_app is shadowed by MonsterUI to make it default to no Pico, and add body classes
|
| 10 |
+
# needed for frankenui theme styling
|
| 11 |
app, rt = fast_app(hdrs=hdrs, live=True)
|
| 12 |
+
|
| 13 |
+
# Examples Product Data to render in the gallery and detail pages
|
| 14 |
+
products = [
|
| 15 |
+
{"name": "Laptop", "price": "$999", "img": "https://picsum.photos/400/100?random=1"},
|
| 16 |
+
{"name": "Smartphone", "price": "$599", "img": "https://picsum.photos/400/100?random=2"},
|
| 17 |
+
{"name": "Headphones", "price": "$199", "img": "https://picsum.photos/400/100?random=3"},
|
| 18 |
+
{"name": "Smartwatch", "price": "$299", "img": "https://picsum.photos/400/100?random=4"},
|
| 19 |
+
{"name": "Tablet", "price": "$449", "img": "https://picsum.photos/400/100?random=5"},
|
| 20 |
+
{"name": "Camera", "price": "$799", "img": "https://picsum.photos/400/100?random=6"},]
|
| 21 |
+
|
| 22 |
+
def ProductCard(p):
|
| 23 |
+
# Card does lots of boilerplate classes so you can just pass in the content
|
| 24 |
+
return Card(
|
| 25 |
+
# width:100% makes the image take the full width so we are guarenteed that we won't
|
| 26 |
+
# have the image cut off or not large enough. Because all our images are a consistent
|
| 27 |
+
# size we do not need to worry about stretching or skewing the image, this is ideal.
|
| 28 |
+
# If you have images of different sizes, you will need to use object-fit:cover and/or
|
| 29 |
+
# height to either strech, shrink, or crop the image. It is much better to adjust your
|
| 30 |
+
# images to be a consistent size upfront so you don't have to handle edge cases of
|
| 31 |
+
# different images skeweing/stretching differently.
|
| 32 |
+
Img(src=p["img"], alt=p["name"], style="width:100%"),
|
| 33 |
+
# All components can take a cls argument to add additional styling - `mt-2` adds margin
|
| 34 |
+
# to the top (see spacing tutorial for details on spacing).
|
| 35 |
+
#
|
| 36 |
+
# Often adding space makes a site look more put together - usually the 2 - 5 range is a
|
| 37 |
+
# good choice
|
| 38 |
+
H4(p["name"], cls="mt-2"),
|
| 39 |
+
# There are helpful Enums, such as TextPresetsT, ButtonT, ContainerT, etc that allow for easy
|
| 40 |
+
# discoverability of class options.
|
| 41 |
+
# bold_sm is helpful for things that you want to look like regular text, but stand out
|
| 42 |
+
# visually for emphasis.
|
| 43 |
+
P(p["price"], cls=TextPresets.bold_sm),
|
| 44 |
+
# ButtonT.primary is useful for actions you really want the user to take (like adding
|
| 45 |
+
# something to the card) - these stand out visually. For dangerous actions (like
|
| 46 |
+
# deleting something) you generally would want to use ButtonT.destructive. For UX actions
|
| 47 |
+
# that aren't a goal of the page (like cancelling something that hasn't been submitted)
|
| 48 |
+
# you generally want the default styling.
|
| 49 |
+
Button("Click me!", cls=(ButtonT.primary, "mt-2"),
|
| 50 |
+
# HTMX can be used as normal on any component
|
| 51 |
+
hx_get=product_detail.to(product_name=p['name']),
|
| 52 |
+
hx_push_url='true',
|
| 53 |
+
hx_target='body'))
|
| 54 |
+
|
| 55 |
@rt
|
| 56 |
def index():
|
| 57 |
+
# Titled using a H1 title, sets the page title, and wraps contents in Main(Container(...)) using
|
| 58 |
+
# frankenui styles. Generally you will want to use Titled for all of your pages
|
| 59 |
return Title('Hello World Title'), Container(
|
| 60 |
H3(A('H3 with Primary URL, a link does not work', href='', cls=AT.primary)),
|
| 61 |
P('I love monsterui!'),
|
|
|
|
| 63 |
A('Go to product gallery page', href='second.py', cls=AT.classic),
|
| 64 |
P('I love monsterui!'),
|
| 65 |
A('Go to Google, a link does not work', href='https://www.google.com', cls=AT.classic),
|
| 66 |
+
Card('A Fancy Card :)'),
|
| 67 |
+
Titled("Example Store Front!",
|
| 68 |
+
Grid(*[ProductCard(p) for p in products], cols_lg=3))
|
| 69 |
+
|
| 70 |
+
example_product_description = """\n
|
| 71 |
+
This is a sample detailed description of the {product_name}. You can see when clicking on the card
|
| 72 |
+
from the gallery you can:
|
| 73 |
|
| 74 |
+
+ Have a detailed description of the product on the page
|
| 75 |
+
+ Have an order form to fill out and submit
|
| 76 |
+
+ Anything else you want!
|
| 77 |
+
"""
|
| 78 |
+
|
| 79 |
+
@rt
|
| 80 |
+
def product_detail(product_name:str):
|
| 81 |
+
return Titled("Product Detail",
|
| 82 |
+
# Grid lays out its children in a responsive grid
|
| 83 |
+
Grid(
|
| 84 |
+
Div(
|
| 85 |
+
H1(product_name),
|
| 86 |
+
# render_md is a helper that renders markdown into HTML using frankenui styles.
|
| 87 |
+
render_md(example_product_description.format(product_name=product_name))),
|
| 88 |
+
Div(
|
| 89 |
+
H3("Order Form"),
|
| 90 |
+
# Form automatically has a class of 'space-y-3' for a margin between each child.
|
| 91 |
+
Form(
|
| 92 |
+
# LabelInput is a convience wrapper for a label and input that links them.
|
| 93 |
+
LabelInput("Name", id='name'),
|
| 94 |
+
LabelInput("Email", id='email'),
|
| 95 |
+
LabelInput("Quantity", id='quantity'),
|
| 96 |
+
# ButtonT.primary because this is the primary action of the page!
|
| 97 |
+
Button("Submit", cls=ButtonT.primary))
|
| 98 |
+
|
| 99 |
+
),
|
| 100 |
+
# Grid has defaults and args for cols at different breakpoints, but you can pass in
|
| 101 |
+
# your own to customize responsiveness.
|
| 102 |
+
cols_lg=2))
|
| 103 |
|
| 104 |
serve()
|