Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a sticky Built with Reflex badge #4584

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
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
19 changes: 16 additions & 3 deletions reflex/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
Default404Page,
wait_for_client_redirect,
)
from reflex.components.core.sticky import sticky
from reflex.components.core.upload import Upload, get_upload_dir
from reflex.components.radix import themes
from reflex.config import environment, get_config
Expand Down Expand Up @@ -858,6 +859,15 @@ def _setup_error_boundary(self):
continue
self._pages[k] = self._add_error_boundary_to_component(component)

def _setup_sticky_badge(self):
"""Add the sticky badge to the app."""
for k, component in self._pages.items():
# Would be nice to share single sticky_badge across all pages, but
# it bungles the StatefulComponent compile step.
sticky_badge = sticky()
sticky_badge._add_style_recursive({})
self._pages[k] = Fragment.create(sticky_badge, component)

def _apply_decorated_pages(self):
"""Add @rx.page decorated pages to the app.

Expand Down Expand Up @@ -946,10 +956,16 @@ def get_compilation_time() -> str:
if not should_compile:
return

# Get the env mode.
config = get_config()

self._validate_var_dependencies()
self._setup_overlay_component()
self._setup_error_boundary()

if config.show_built_with_reflex:
self._setup_sticky_badge()

# Create a progress bar.
progress = Progress(
*Progress.get_default_columns()[:-1],
Expand All @@ -968,9 +984,6 @@ def get_compilation_time() -> str:
+ adhoc_steps_without_executor,
)

# Get the env mode.
config = get_config()

# Store the compile results.
compile_results = []

Expand Down
160 changes: 160 additions & 0 deletions reflex/components/core/sticky.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
"""Components for displaying the Reflex sticky logo."""

from reflex.components.component import ComponentNamespace
from reflex.components.core.colors import color
from reflex.components.core.cond import color_mode_cond, cond
from reflex.components.core.responsive import tablet_and_desktop
from reflex.components.el.elements.inline import A
from reflex.components.el.elements.media import Path, Rect, Svg
from reflex.components.radix.themes.typography.text import Text
from reflex.experimental.client_state import ClientStateVar
from reflex.style import Style
from reflex.vars.base import Var, VarData


class StickyLogo(Svg):
"""A simple Reflex logo SVG with only the letter R."""

@classmethod
def create(cls):
"""Create the simple Reflex logo SVG.

Returns:
The simple Reflex logo SVG.
"""
return super().create(
Rect.create(width="16", height="16", rx="2", fill="#6E56CF"),
Path.create(d="M10 9V13H12V9H10Z", fill="white"),
Path.create(d="M4 3V13H6V9H10V7H6V5H10V7H12V3H4Z", fill="white"),
width="16",
height="16",
viewBox="0 0 16 16",
xmlns="http://www.w3.org/2000/svg",
)

def add_style(self):
"""Add the style to the component.

Returns:
The style of the component.
"""
return Style(
{
"fill": "white",
}
)


class StickyLabel(Text):
"""A label that displays the Reflex sticky."""

@classmethod
def create(cls):
"""Create the sticky label.

Returns:
The sticky label.
"""
return super().create("Built with Reflex")

def add_style(self):
"""Add the style to the component.

Returns:
The style of the component.
"""
return Style(
{
"color": color("slate", 1),
"font_weight": "600",
"font_family": "'Instrument Sans', sans-serif",
"font_size": "0.875rem",
"line_height": "1rem",
"letter_spacing": "-0.00656rem",
}
)


class StickyBadge(A):
"""A badge that displays the Reflex sticky logo."""

@classmethod
def create(cls):
"""Create the sticky badge.

Returns:
The sticky badge.
"""
return super().create(
StickyLogo.create(),
tablet_and_desktop(StickyLabel.create()),
href="https://reflex.dev",
target="_blank",
width="auto",
padding="0.375rem",
align="center",
text_align="center",
)

def add_style(self):
"""Add the style to the component.

Returns:
The style of the component.
"""
is_localhost_cs = ClientStateVar.create(
"is_localhost",
default=True,
global_ref=False,
)
localhost_hostnames = Var.create(
["localhost", "127.0.0.1", "[::1]"]
).guess_type()
is_localhost_expr = localhost_hostnames.contains(
Var("window.location.hostname", _var_type=str).guess_type(),
)
check_is_localhost = Var(
f"useEffect(({is_localhost_cs}) => {is_localhost_cs.set}({is_localhost_expr}), [])",
_var_data=VarData(
imports={"react": "useEffect"},
),
)
is_localhost = is_localhost_cs.value._replace(
Lendemor marked this conversation as resolved.
Show resolved Hide resolved
merge_var_data=VarData.merge(
check_is_localhost._get_all_var_data(),
VarData(hooks={str(check_is_localhost): None}),
),
)
return Style(
{
"position": "fixed",
"bottom": "1rem",
"right": "1rem",
# Do not show the badge on localhost.
"display": cond(is_localhost, "none", "flex"),
"flex-direction": "row",
"gap": "0.375rem",
"align-items": "center",
"width": "auto",
"border-radius": "0.5rem",
"color": color_mode_cond("#E5E7EB", "#27282B"),
"border": color_mode_cond("1px solid #27282B", "1px solid #E5E7EB"),
"background-color": color_mode_cond("#151618", "#FCFCFD"),
"padding": "0.375rem",
"transition": "background-color 0.2s ease-in-out",
"box-shadow": "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
"z-index": "9998",
"cursor": "pointer",
},
)


class StickyNamespace(ComponentNamespace):
"""Sticky components namespace."""

__call__ = staticmethod(StickyBadge.create)
label = staticmethod(StickyLabel.create)
logo = staticmethod(StickyLogo.create)


sticky = StickyNamespace()
Loading
Loading