Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,337 changes: 1,337 additions & 0 deletions assets/css/presets/lyra.css

Large diffs are not rendered by default.

1,360 changes: 1,360 additions & 0 deletions assets/css/presets/maia.css

Large diffs are not rendered by default.

1,364 changes: 1,364 additions & 0 deletions assets/css/presets/mira.css

Large diffs are not rendered by default.

758 changes: 758 additions & 0 deletions assets/css/themes.css

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions assets/css/wrapper.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
@tailwind components;
@tailwind utilities;

@import "./presets/lyra.css";
@import "./presets/atlas.css";
@import "./presets/minimal.css";

:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
Expand Down Expand Up @@ -35,6 +39,20 @@
--chart-3: oklch(0.7 0 0);
--chart-4: oklch(0.82 0 0);
--chart-5: oklch(0.92 0 0);

--font-geist: "Geist Variable", sans-serif;
--font-inter: "Inter Variable", sans-serif;
--font-noto-sans: "Noto Sans Variable", sans-serif;
--font-nunito-sans: "Nunito Sans Variable", sans-serif;
--font-figtree: "Figtree Variable", sans-serif;
--font-roboto: "Roboto", sans-serif;
--font-raleway: "Raleway", sans-serif;
--font-dm-sans: "DM Sans", sans-serif;
--font-public-sans: "Public Sans", sans-serif;
--font-outfit: "Outfit", sans-serif;

--font-jetbrains-mono: "JetBrains Mono Variable", monospace;
--font-geist-mono: "Geist Mono Variable", monospace;
}

.dark {
Expand Down
9 changes: 9 additions & 0 deletions assets/svg/base-ui/dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions assets/svg/base-ui/light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/svg/radix-ui/dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/svg/radix-ui/light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
85 changes: 85 additions & 0 deletions scripts/generate_themes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import re
from pathlib import Path

# Provide the themes from shadcn/ui #
# by downloading the raw file and cleaning the TypeScript exports and variables #
THEMES_FILE = Path("scripts/themes.json")
OUTPUT_CSS = Path("assets/css/themes.css")

text = THEMES_FILE.read_text()
lines = [
"/* Generated from https://github.com/shadcn-ui/ui/blob/main/apps/v4/registry/themes.ts */\n"
]

# Split by theme objects manually
theme_splits = re.split(r"\},\s*\{", text)


def extract_vars_from_lines(lines_list):
var_lines = []
for line in lines_list:
line = line.strip().rstrip(",")
if not line:
continue
# Match key: value (quoted or unquoted)
m = re.match(r'["]?([\w-]+)["]?\s*:\s*["]?(.+?)["]?$', line)
if m:
key, val = m.groups()
var_lines.append(f" --{key}: {val};")
return var_lines


for theme_text in theme_splits:
# Extract theme name
name_match = re.search(r'name\s*:\s*"([^"]+)"', theme_text)
if not name_match:
continue
name = name_match.group(1)

# Extract light block lines
light_lines = []
dark_lines = []

in_light = False
in_dark = False
brace_count = 0

for line in theme_text.splitlines():
stripped = line.strip()
if stripped.startswith("light: {"):
in_light = True
brace_count = 1
continue
elif stripped.startswith("dark: {"):
in_dark = True
brace_count = 1
continue

# Track braces to know when block ends
if in_light or in_dark:
brace_count += line.count("{")
brace_count -= line.count("}")
if brace_count == 0:
in_light = False
in_dark = False
continue
if in_light:
light_lines.append(line)
if in_dark:
dark_lines.append(line)

# Write light CSS
if light_lines:
lines.append(f".{name} {{")
lines.extend(extract_vars_from_lines(light_lines))
lines.append("}\n")

# Write dark CSS
if dark_lines:
lines.append(f".{name}-dark {{")
lines.extend(extract_vars_from_lines(dark_lines))
lines.append("}\n")

OUTPUT_CSS.parent.mkdir(parents=True, exist_ok=True)
OUTPUT_CSS.write_text("\n".join(lines))
print(f"Wrote {OUTPUT_CSS}")
13 changes: 13 additions & 0 deletions src/create/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from reflex.experimental import ClientStateVar

# Var holding component library value
component_library = ClientStateVar.create("component_library", "Base UI")

# Var holding the current theme
theme = ClientStateVar.create("theme", "neutral")

# Var holding the current font family
font_family = ClientStateVar.create("font_family", "Inter")

# Var holding the current radius
radius = ClientStateVar.create("radius", "none")
Empty file added src/create/layout/preview.py
Empty file.
41 changes: 41 additions & 0 deletions src/create/layout/sidebars.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import reflex as rx

from src.create.ui.menu.fonts import font_menu
from src.create.ui.menu.library import component_library_menu
from src.create.ui.menu.radius import radius_menu
from src.create.ui.menu.theme import theme_menu

SidebarStyle = "max-w-[12rem] w-full sticky top-18 max-h-[100vh] z-[10]"
ContentStyle = "flex flex-col items-center gap-y-4 [&_.rt-ScrollAreaScrollbar]:mt-[2rem] [&_.rt-ScrollAreaScrollbar]:mb-[2rem]"


def component_sidebar():
content = rx.el.div(
component_library_menu(),
theme_menu(),
font_menu(),
radius_menu(),
class_name="flex flex-col max-w-[18rem] w-full h-full",
)

return rx.el.div(
rx.scroll_area(
content,
class_name=ContentStyle,
),
class_name=SidebarStyle,
)


def menu_option_sidebar():
content = rx.el.div(
class_name="flex flex-col max-w-[18rem] w-full h-full",
)

return rx.el.div(
rx.scroll_area(
content,
class_name=ContentStyle,
),
class_name=SidebarStyle,
)
39 changes: 39 additions & 0 deletions src/create/page.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import reflex as rx

from src.create.layout.sidebars import component_sidebar, menu_option_sidebar
from src.docs.library.examples.accordion.accordion import accordion_example
from src.templates.navbar import navbar


def create_page():
"""The main page layout for buridan-ui/create feature"""
return rx.el.body(
rx.el.div(
rx.el.header(navbar(), class_name="sticky top-0 z-50"),
rx.el.main(
rx.el.div(
menu_option_sidebar(),
rx.el.div(
rx.el.div(
# main_content,
# font-(family-name:--font-jetbrains-mono)
rx.el.div(
accordion_example(),
class_name="style-mira border border-input w-full p-4",
),
rx.el.div(
accordion_example(),
class_name="style-maia w-full border border-input p-4",
),
class_name="flex-1 min-w-0 pt-6",
),
component_sidebar(),
class_name="flex items-start w-full flex-1 min-w-0",
),
class_name="flex w-full gap-x-0 xl:max-w-[80rem] 2xl:max-w-[85rem] mx-auto",
),
class_name="w-full",
),
class_name="bg-background relative flex h-screen flex-col",
),
)
86 changes: 86 additions & 0 deletions src/create/ui/menu/fonts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import reflex as rx

import src.create.hooks as hooks
from src.docs.library.base_ui.components.base.button import button
from src.docs.library.base_ui.components.base.select import select
from src.docs.library.base_ui.icons.hugeicon import hi

FONTS = [
"Inter",
"JetBrains Mono",
"Geist",
"Geist Mono",
"Noto Sans",
"Nunito Sans",
"Figtree",
"Roboto",
"Raleway",
"DM Sans",
"Public Sans",
"Outfit",
]


def font_options(font: str):
font_var = f"--font-{font.lower().replace(' ', '-')}"

return select.item(
rx.el.div(
rx.el.p(font, class_name="!text-xs text-muted-foreground capitalize"),
select.item_text(
"Every test phrase hides a parade of playful symbols.",
class_name=f"line-clamp-2 !text-sm font-(family-name:{font_var})",
),
class_name="flex flex-col gap-y-1 w-full justify-start items-start",
),
select.item_indicator(
hi("Tick02Icon", class_name="size-4"),
),
value=font,
class_name="w-full flex items-center justify-between rounded-lg",
on_click=rx.call_script(hooks.font_family.set_value(font)),
)


def font_menu():
return select.root(
select.trigger(
render_=button(
rx.el.div(
rx.el.div(
rx.el.p(
"Font",
class_name="text-xs text-muted-foreground",
),
rx.el.p(
select.value(),
class_name="text-md font-medium capitalize",
),
class_name="flex flex-col items-start",
),
hi(
"TextFontIcon",
class_name="size-4",
),
class_name="!w-full flex items-center justify-between p-2",
),
variant="ghost",
class_name="w-full !p-0 h-12 rounded-xl",
),
),
select.portal(
select.positioner(
select.popup(
select.group(
*[font_options(font) for font in FONTS],
class_name="!w-[18rem]",
),
class_name="!rounded-xl h-[50vh] overflow-scroll scrollbar-none",
),
side_offset=4,
side="left",
),
),
name="font_selector",
default_value="Inter",
)
Loading