From 23bdc016376b8b921802e3b9f88711f1f472b3aa Mon Sep 17 00:00:00 2001 From: ndendic Date: Sat, 15 Feb 2025 08:17:55 +0100 Subject: [PATCH 1/2] Cusom Themes support in ThemePicker --- monsterui/franken.py | 4 ++-- nbs/02_franken.ipynb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/monsterui/franken.py b/monsterui/franken.py index 8bb5ae1..768300d 100644 --- a/monsterui/franken.py +++ b/monsterui/franken.py @@ -1494,7 +1494,7 @@ def render_md(md_content:str, # Markdown content return NotStr(apply_classes(html_content, class_map, class_map_mods)) # %% ../nbs/02_franken.ipynb -def ThemePicker(color=True, radii=True, shadows=True, font=True, mode=True, cls='p-4'): +def ThemePicker(color=True, radii=True, shadows=True, font=True, mode=True, cls='p-4', custom_themes=[]): "Theme picker component with configurable sections" def _opt(val, txt, **kwargs): return Option(txt, value=val, **kwargs) def _optgrp(key, lbl, opts): return fh.Optgroup(data_key=key, label=lbl)(*opts) @@ -1506,7 +1506,7 @@ def _optgrp(key, lbl, opts): return fh.Optgroup(data_key=key, label=lbl)(*opts) [('Slate','#64748b'),('Stone','#78716c'),('Gray','#6b7280'), ('Neutral','#737373'),('Red','#dc2626'),('Rose','#e11d48'), ('Orange','#f97316'),('Green','#16a34a'),('Blue','#2563eb'), - ('Yellow','#facc15'),('Violet','#7c3aed')]]])) + ('Yellow','#facc15'),('Violet','#7c3aed'),*custom_themes]]])) if radii: groups.append(_optgrp('radii', 'Radii', [ _opt('uk-radii-none','None'), _opt('uk-radii-sm','Small'), _opt('uk-radii-md','Medium',selected=True), _opt('uk-radii-lg','Large')])) diff --git a/nbs/02_franken.ipynb b/nbs/02_franken.ipynb index 7987c43..d99a878 100644 --- a/nbs/02_franken.ipynb +++ b/nbs/02_franken.ipynb @@ -3098,7 +3098,7 @@ "outputs": [], "source": [ "#| export\n", - "def ThemePicker(color=True, radii=True, shadows=True, font=True, mode=True, cls='p-4'):\n", + "def ThemePicker(color=True, radii=True, shadows=True, font=True, mode=True, cls='p-4', custom_themes=[]):\n", " \"Theme picker component with configurable sections\"\n", " def _opt(val, txt, **kwargs): return Option(txt, value=val, **kwargs)\n", " def _optgrp(key, lbl, opts): return fh.Optgroup(data_key=key, label=lbl)(*opts)\n", @@ -3110,7 +3110,7 @@ " [('Slate','#64748b'),('Stone','#78716c'),('Gray','#6b7280'),\n", " ('Neutral','#737373'),('Red','#dc2626'),('Rose','#e11d48'),\n", " ('Orange','#f97316'),('Green','#16a34a'),('Blue','#2563eb'),\n", - " ('Yellow','#facc15'),('Violet','#7c3aed')]]]))\n", + " ('Yellow','#facc15'),('Violet','#7c3aed'),*custom_themes]]]))\n", " if radii: groups.append(_optgrp('radii', 'Radii', [\n", " _opt('uk-radii-none','None'), _opt('uk-radii-sm','Small'),\n", " _opt('uk-radii-md','Medium',selected=True), _opt('uk-radii-lg','Large')]))\n", From b93c0e7a2ed7e3357090f27f75a5d932f04c89dd Mon Sep 17 00:00:00 2001 From: Isaac Flath Date: Wed, 19 Feb 2025 09:49:21 -0500 Subject: [PATCH 2/2] docs --- docs/api_reference/api_reference.py | 9 +++++ docs/custom_theme.css | 56 +++++++++++++++++++++++++++++ docs/main.py | 8 +++-- 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 docs/custom_theme.css diff --git a/docs/api_reference/api_reference.py b/docs/api_reference/api_reference.py index 98cff91..b74e635 100644 --- a/docs/api_reference/api_reference.py +++ b/docs/api_reference/api_reference.py @@ -184,9 +184,18 @@ def ex_theme_switcher(): H3("Theme Picker", id='theme'), fn2code_string(ex_theme_switcher), ThemePicker, + H3("Custom Themes"), + render_md(""" +1. You can use [this theme](https://github.com/AnswerDotAI/MonsterUI/blob/main/docs/custom_theme.css) as a starting point. +2. Add the theme to your headers as a link like this `Link(rel="stylesheet", href="/custom_theme.css", type="text/css")` +3. Then add the theme to the `ThemePicker` component. For example `ThemePicker(custom_themes=[('Grass', '#10b981')])` +"""), "Themes are controlled with `bg-background text-foreground` classes on the `Body` tag. `fast_app` and `FastHTML` will do this for you automatically so you typically do not have to do anything", fast_app, FastHTML, + + Blockquote(P("Users have said", A("this site", href="https://ui.jln.dev/"), " is helpful in creating your own themes.")), + title="Headers") # Typography diff --git a/docs/custom_theme.css b/docs/custom_theme.css new file mode 100644 index 0000000..92251a1 --- /dev/null +++ b/docs/custom_theme.css @@ -0,0 +1,56 @@ +/* custom_theme.css */ + +.uk-theme-grass { + --background: 78 47% 99%; + --foreground: 78 51% 0%; + --muted: 78 12% 85%; + --muted-foreground: 78 8% 38%; + --popover: 78 47% 99%; + --popover-foreground: 78 51% 0%; + --card: 78 47% 99%; + --card-foreground: 78 51% 0%; + --border: 78 2% 93%; + --input: 78 2% 93%; + --primary: 78 28% 60%; + --primary-foreground: 0 0% 0%; + --secondary: 78 8% 81%; + --secondary-foreground: 78 8% 21%; + --accent: 78 8% 81%; + --accent-foreground: 78 8% 21%; + --destructive: 17 86% 32%; + --destructive-foreground: 17 86% 92%; + --ring: 78 28% 60%; + --chart-1: 78 28% 60%; + --chart-2: 78 8% 81%; + --chart-3: 78 8% 81%; + --chart-4: 78 8% 84%; + --chart-5: 78 31% 60%; + --radius: 0.5rem; + } + + .dark.uk-theme-grass { + --background: 78 48% 2%; + --foreground: 78 24% 99%; + --muted: 78 12% 15%; + --muted-foreground: 78 8% 62%; + --popover: 78 48% 2%; + --popover-foreground: 78 24% 99%; + --card: 78 48% 2%; + --card-foreground: 78 24% 99%; + --border: 78 2% 14%; + --input: 78 2% 14%; + --primary: 78 28% 60%; + --primary-foreground: 0 0% 0%; + --secondary: 78 8% 14%; + --secondary-foreground: 78 8% 74%; + --accent: 78 8% 14%; + --accent-foreground: 78 8% 74%; + --destructive: 17 86% 60%; + --destructive-foreground: 17 86% 0%; + --ring: 78 28% 60%; + --chart-1: 78 28% 60%; + --chart-2: 78 8% 14%; + --chart-3: 78 8% 14%; + --chart-4: 78 8% 17%; + --chart-5: 78 31% 60%; + } \ No newline at end of file diff --git a/docs/main.py b/docs/main.py index 343fa8e..694e526 100644 --- a/docs/main.py +++ b/docs/main.py @@ -23,7 +23,11 @@ def _not_found(req, exc): req, None) -app,rt = fast_app(exception_handlers={404:_not_found}, pico=False, hdrs=(*Theme.blue.headers(highlightjs=True), Link(rel="icon", type="image/x-icon", href="/favicon.ico")), live=True) + +app,rt = fast_app(exception_handlers={404:_not_found}, pico=False, + hdrs=(*Theme.blue.headers(highlightjs=True), Link(rel="icon", type="image/x-icon", href="/favicon.ico"), + Link(rel="stylesheet", href="/custom_theme.css", type="text/css")), + live=True) def is_htmx(request=None): "Check if the request is an HTMX request" @@ -157,7 +161,7 @@ def tutorial_layout(o:str='', request=None): @rt def theme_switcher(request): - return _create_page(Div(ThemePicker(),cls="p-12"), request, None) + return _create_page(Div(ThemePicker(custom_themes=[("Grass", "#10b981")]),cls="p-12"), request, None) ### # Build the Getting Started Pages