File size: 7,562 Bytes
d467ea7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
"""FrankenUI Forms Example built with MonsterUI (original design by ShadCN)"""


from fasthtml.common import *
from monsterui.all import *
from fasthtml.svg import *

app, rt = fast_app(hdrs=Theme.blue.headers())

def HelpText(c): return P(c,cls=TextPresets.muted_sm)

def heading():
    return Div(cls="space-y-5")(
            H2("Settings"),
            Subtitle("Manage your account settings and set e-mail preferences."),
            DividerSplit())


sidebar = NavContainer(
    *map(lambda x: Li(A(x)), ("Profile", "Account", "Appearance", "Notifications", "Display")),
    uk_switcher="connect: #component-nav; animation: uk-animation-fade",
    cls=(NavT.secondary,"space-y-4 p-4 w-1/5"))


def FormSectionDiv(*c, cls='space-y-2', **kwargs): return Div(*c, cls=cls, **kwargs)

def FormLayout(title, subtitle, *content, cls='space-y-3 mt-4'): return Container(Div(H3(title), Subtitle(subtitle), DividerLine(), Form(*content, cls=cls)))

def profile_form():
    content = (FormSectionDiv(
            LabelInput("Username", placeholder='sveltecult', id='username'),
            HelpText("This is your public display name. It can be your real name or a pseudonym. You can only change this once every 30 days.")),
        FormSectionDiv(
            LabelSelect(
                      Option("Select a verified email to display", value="", selected=True, disabled=True),
                     *[Option(o, value=o) for o in ('m@example.com', 'm@yahoo.com', 'm@cloud.com')],  
                     label="Email", id="email"),
            HelpText("You can manage verified email addresses in your email settings.")),
        FormSectionDiv(
            LabelTextArea("Bio", id="bio", placeholder="Tell us a little bit about yourself"),
            HelpText("You can @mention other users and organizations to link to them."),
            P("String must contain at least 4 character(s)", cls="text-destructive")),
        FormSectionDiv(
            FormLabel("URLs"),
            HelpText("Add links to your website, blog, or social media profiles."),
            Input(value="https://www.franken-ui.dev"),
            Input(value="https://github.com/sveltecult/franken-ui"),
            Button("Add URL")),
            Button('Update profile', cls=ButtonT.primary))
    
    return FormLayout('Profile', 'This is how others will see you on the site.', *content)

def account_form():
    content = (
        FormSectionDiv(
            LabelInput("Name", placeholder="Your name", id="name"),
            HelpText("This is the name that will be displayed on your profile and in emails.")),
        FormSectionDiv(
            LabelInput("Date of Birth", type="date", placeholder="Pick a date", id="date_of_birth"),
            HelpText("Your date of birth is used to calculate your age.")),
        FormSectionDiv(
            LabelSelect(*Options("Select a language", "English", "French", "German", "Spanish", "Portuguese", selected_idx=1, disabled_idxs={0}),
                          label='Language', id="language"),
            HelpText("This is the language that will be used in the dashboard.")),
        Button('Update profile', cls=ButtonT.primary))
    
    return FormLayout('Account', 'Update your account settings. Set your preferred language and timezone.', *content)

def appearance_form():
    def theme_item(bg_color, content_bg, text_bg):
        common_content = f"space-y-2 rounded-md {content_bg} p-2 shadow-sm"
        item_row = lambda: Div(cls=f"flex items-center space-x-2 {common_content}")(
            Div(cls=f"h-4 w-4 rounded-full {text_bg}"),
            Div(cls=f"h-2 w-[100px] rounded-lg {text_bg}"))
        
        return Div(cls=f"space-y-2 rounded-sm {bg_color} p-2")(
            Div(cls=common_content)(
                Div(cls=f"h-2 w-[80px] rounded-lg {text_bg}"),
                Div(cls=f"h-2 w-[100px] rounded-lg {text_bg}")),
            item_row(),
            item_row())
    
    common_toggle_cls = "block cursor-pointer items-center rounded-md border-2 border-muted p-1 ring-ring"

    content = (
        FormSectionDiv(
            LabelSelect(*Options('Select a font family', 'Inter', 'Geist', 'Open Sans', selected_idx=2, disabled_idxs={0}),
            label='Font Family', id='font_family'), 
            HelpText("Set the font you want to use in the dashboard.")),
        FormSectionDiv(
            FormLabel("Theme"),
            HelpText("Select the theme for the dashboard."),
            Grid(
                A(id="theme-toggle-light", cls=common_toggle_cls)(theme_item("bg-[#ecedef]", "bg-white", "bg-[#ecedef]")),
                A(id="theme-toggle-dark", cls=f"{common_toggle_cls} bg-popover")(theme_item("bg-slate-950", "bg-slate-800", "bg-slate-400")),
                cols_max=2,cls=('max-w-md','gap-8'))),
            Button('Update preferences', cls=ButtonT.primary))
    
    return FormLayout('Appearance', 'Customize the appearance of the app. Automatically switch between day and night themes.', *content)


notification_items = [
    {"title": "Communication emails", "description": "Receive emails about your account activity.", "checked": False, "disabled": False},
    {"title": "Marketing emails", "description": "Receive emails about new products, features, and more.", "checked": False, "disabled": False},
    {"title": "Social emails", "description": "Receive emails for friend requests, follows, and more.", "checked": True, "disabled": False},
    {"title": "Security emails", "description": "Receive emails about your account activity and security.", "checked": True, "disabled": True}]

def notifications_form():
    def RadioLabel(label): return DivLAligned(Radio(name="notification", checked=(label=="Nothing")), FormLabel(label))

    def NotificationCard(item):
        return Card(
            Div(cls="space-y-0.5")(
                FormLabel(Strong(item['title'], cls=TextT.sm),
                HelpText(item['description']))))
    content = Div(
        FormSectionDiv(
            FormLabel("Notify me about"),
            *map(RadioLabel, ["All new messages", "Direct messages and mentions", "Nothing"])),
        Div(
            H4("Email Notifications", cls="mb-4"),
            Grid(*map(NotificationCard, notification_items), cols=1)),
            LabelCheckboxX("Use different settings for my mobile devices", id="notification_mobile"),
            HelpText("You can manage your mobile notifications in the mobile settings page."),
            Button('Update notifications', cls=ButtonT.primary))
    
    return FormLayout('Notifications', 'Configure how you receive notifications.', *content)

def display_form():
    content = (
        Div(cls="space-y-2")(
            Div(cls="mb-4")(
                H5("Sidebar"),
                Subtitle("Select the items you want to display in the sidebar.")),
            *[Div(CheckboxX(id=f"display_{i}", checked=i in [0, 1, 2]),FormLabel(label))
              for i, label in enumerate(["Recents", "Home", "Applications", "Desktop", "Downloads", "Documents"])]),
            Button('Update display', cls=ButtonT.primary))
    return FormLayout('Display', 'Turn items on or off to control what\'s displayed in the app.', *content)

@rt
def index():
    return Title("Forms Example"),Container(
        heading(),
        Div(cls="flex gap-x-12")(
            sidebar,
                Ul(id="component-nav", cls="uk-switcher max-w-2xl")(
                    Li(cls="uk-active")(profile_form(),
                    *map(Li, [account_form(), appearance_form(), notifications_form(), display_form()])))))

serve()