diff --git a/ai.zip b/ai.zip new file mode 100644 index 0000000..64a22ab Binary files /dev/null and b/ai.zip differ diff --git a/assets/avatars/reflex.webp b/assets/avatars/reflex.webp new file mode 100644 index 0000000..f23d421 Binary files /dev/null and b/assets/avatars/reflex.webp differ diff --git a/assets/avatars/shadcn.webp b/assets/avatars/shadcn.webp new file mode 100644 index 0000000..62160d8 Binary files /dev/null and b/assets/avatars/shadcn.webp differ diff --git a/assets/site-bindings.js b/assets/site-bindings.js new file mode 100644 index 0000000..925bf8c --- /dev/null +++ b/assets/site-bindings.js @@ -0,0 +1,43 @@ +window.toggleTheme = function () { + const html = document.documentElement; + let targetTheme = "dark"; + + if (html.classList.contains("dark")) { + html.classList.remove("dark"); + html.classList.add("light"); + html.style.colorScheme = "light"; + targetTheme = "light"; + } else { + html.classList.remove("light"); + html.classList.add("dark"); + html.style.colorScheme = "dark"; + targetTheme = "dark"; + } + + localStorage.setItem("site-theme", targetTheme); + localStorage.setItem("theme", targetTheme); + localStorage.setItem("last_compiled_theme", targetTheme); + + if (window.preview) { + window.preview.applyAll(); + } +}; + +document.addEventListener("keydown", (e) => { + if ( + e.target instanceof HTMLInputElement || + e.target instanceof HTMLTextAreaElement || + e.target.isContentEditable + ) { + return; + } + + if (e.ctrlKey || e.metaKey || e.altKey) { + return; + } + + if (e.key.toLowerCase() === "d") { + e.preventDefault(); + window.toggleTheme(); + } +}); diff --git a/native/hooks/head_components.py b/native/hooks/head_components.py index 2f44ad1..558c8c0 100644 --- a/native/hooks/head_components.py +++ b/native/hooks/head_components.py @@ -46,6 +46,7 @@ APP_HEAD_COMPONENTS: list[Component] = [ link(rel="preconnect", href="https://fonts.googleapis.com"), link(rel="preconnect", href="https://fonts.gstatic.com", crossorigin="true"), + script(src="/site-bindings.js"), script(src="/prism.js"), script(src="/theme-preview.js"), script(src="/typeset-preview.js"), diff --git a/native/pages/create.py b/native/pages/create.py index 9d8bf99..67be651 100644 --- a/native/pages/create.py +++ b/native/pages/create.py @@ -342,7 +342,7 @@ def source_space(): def create_page(): return rx.el.div( rx.el.div( - navbar(class_name="max-w-full !pl-4 !pr-6"), + navbar(), rx.el.main( sidebar(), preview_space(), diff --git a/native/pages/landing.py b/native/pages/landing.py index 87e75cf..2d3af98 100644 --- a/native/pages/landing.py +++ b/native/pages/landing.py @@ -1,6 +1,7 @@ from reflex_components_core.el import Section, a, div, img, section from components.core.hugeicon import hi +from components.ui.avatar import avatar from components.ui.button import button from native.lib.examples.card_01 import card_01 from native.lib.examples.card_02 import card_02 @@ -22,11 +23,33 @@ title="Native HTML UI components you can copy, paste, and ship in minutes.", description="Production-ready shadcn/ui blocks and components designed for Reflex. Extend, override, and ship without fighting the framework. Open source, no lock-in.", ctas=[ + a( + button("Documentation", variant="secondary"), + href="/docs", + ), a( button("Build Your Own", hi("ArrowRight02Icon", class_name="size-4")), href="/create", ), ], + logos=[ + avatar.group( + avatar.root( + avatar.image( + src="/avatars/shadcn.webp", + custom_attrs={"alt": "@shadcn"}, + ), + avatar.fallback("SH"), + ), + avatar.root( + avatar.image( + src="/avatars/reflex.webp", + custom_attrs={"alt": "@reflex"}, + ), + avatar.fallback("RD"), + ), + ) + ], ) def landing_page() -> Section: @@ -62,11 +85,11 @@ def landing_page() -> Section: landing_mobile = div( img( src="site/landing_ss_dark.webp", - class_name="w-[1450px] max-w-none hidden dark:flex", + class_name="w-[1800px] max-w-none hidden dark:flex", ), img( src="/site/landing_ss_light.webp", - class_name="w-[1450px] max-w-none flex dark:hidden", + class_name="w-[1800px] max-w-none flex dark:hidden", ), class_name="overflow-x-hidden w-full flex justify-center", ) diff --git a/native/pages/typeset.py b/native/pages/typeset.py index d67eb79..a06aeb2 100644 --- a/native/pages/typeset.py +++ b/native/pages/typeset.py @@ -218,8 +218,8 @@ def source_space(): def typeset_page(): return rx.el.div( + navbar(), rx.el.div( - navbar(class_name="max-w-full !pl-4 !pr-6"), rx.el.main( sidebar(), preview_space(), diff --git a/native/templates/layout.py b/native/templates/layout.py index 455fef9..9dd7c43 100644 --- a/native/templates/layout.py +++ b/native/templates/layout.py @@ -20,6 +20,10 @@ def wrapper(*args, **kwargs): navbar(), div( div( + div( + *(logos if logos else []), + class_name="mx-auto flex justify-center", + ), h1( title, class_name="mx-auto max-w-4xl py-4 text-center text-4xl font-bold tracking-tighter text-balance sm:text-5xl md:py-6", @@ -32,11 +36,7 @@ def wrapper(*args, **kwargs): *(ctas if ctas else []), class_name="flex w-full items-center justify-center gap-2 pt-8 **:data-[slot=button]:shadow-none", ), - div( - *(logos if logos else []), - class_name="mx-auto mt-10 flex justify-center", - ), - class_name="mx-auto flex flex-1 flex-col", + class_name="mx-auto flex flex-1 flex-col mt-10 mb-16", ), class_name="w-full px-4", ), diff --git a/native/templates/theme.py b/native/templates/theme.py index a500da5..0caff01 100644 --- a/native/templates/theme.py +++ b/native/templates/theme.py @@ -36,33 +36,7 @@ def theme_toggle_button(): stroke_linejoin="round", class_name="size-4 !transition-none", ), - on_click=lambda _: call_script( - """ - const html = document.documentElement; - let targetTheme = 'dark'; - if (html.classList.contains('dark')) { - html.classList.remove('dark'); - html.classList.add('light'); - html.style.colorScheme = 'light'; - targetTheme = 'light'; - } else { - html.classList.remove('light'); - html.classList.add('dark'); - html.style.colorScheme = 'dark'; - targetTheme = 'dark'; - } - localStorage.setItem('site-theme', targetTheme); - localStorage.setItem('theme', targetTheme); - localStorage.setItem('last_compiled_theme', targetTheme); - - if (window.preview) { - window.preview.applyAll(); - console.log('toggle fired, dark =', document.documentElement.classList.contains('dark')); - } else { - console.log('window.preview is undefined at toggle time'); - } - """ - ), + on_click=lambda _: call_script("window.toggleTheme()"), variant="ghost", size="sm", )