Skip to content

Commit 3dcee7d

Browse files
committed
Merge branch 'main' into disable-auto-setters
2 parents a0c33c0 + ef93161 commit 3dcee7d

File tree

8 files changed

+721
-14
lines changed

8 files changed

+721
-14
lines changed

reflex/app.py

+12
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
Default404Page,
7171
wait_for_client_redirect,
7272
)
73+
from reflex.components.core.sticky import sticky
7374
from reflex.components.core.upload import Upload, get_upload_dir
7475
from reflex.components.radix import themes
7576
from reflex.config import environment, get_config
@@ -875,6 +876,15 @@ def _setup_error_boundary(self):
875876
continue
876877
self._pages[k] = self._add_error_boundary_to_component(component)
877878

879+
def _setup_sticky_badge(self):
880+
"""Add the sticky badge to the app."""
881+
for k, component in self._pages.items():
882+
# Would be nice to share single sticky_badge across all pages, but
883+
# it bungles the StatefulComponent compile step.
884+
sticky_badge = sticky()
885+
sticky_badge._add_style_recursive({})
886+
self._pages[k] = Fragment.create(sticky_badge, component)
887+
878888
def _apply_decorated_pages(self):
879889
"""Add @rx.page decorated pages to the app.
880890
@@ -1005,6 +1015,8 @@ def get_compilation_time() -> str:
10051015
self._validate_var_dependencies()
10061016
self._setup_overlay_component()
10071017
self._setup_error_boundary()
1018+
if config.show_built_with_reflex:
1019+
self._setup_sticky_badge()
10081020

10091021
progress.advance(task)
10101022

reflex/components/core/sticky.py

+160
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
"""Components for displaying the Reflex sticky logo."""
2+
3+
from reflex.components.component import ComponentNamespace
4+
from reflex.components.core.colors import color
5+
from reflex.components.core.cond import color_mode_cond, cond
6+
from reflex.components.core.responsive import tablet_and_desktop
7+
from reflex.components.el.elements.inline import A
8+
from reflex.components.el.elements.media import Path, Rect, Svg
9+
from reflex.components.radix.themes.typography.text import Text
10+
from reflex.experimental.client_state import ClientStateVar
11+
from reflex.style import Style
12+
from reflex.vars.base import Var, VarData
13+
14+
15+
class StickyLogo(Svg):
16+
"""A simple Reflex logo SVG with only the letter R."""
17+
18+
@classmethod
19+
def create(cls):
20+
"""Create the simple Reflex logo SVG.
21+
22+
Returns:
23+
The simple Reflex logo SVG.
24+
"""
25+
return super().create(
26+
Rect.create(width="16", height="16", rx="2", fill="#6E56CF"),
27+
Path.create(d="M10 9V13H12V9H10Z", fill="white"),
28+
Path.create(d="M4 3V13H6V9H10V7H6V5H10V7H12V3H4Z", fill="white"),
29+
width="16",
30+
height="16",
31+
viewBox="0 0 16 16",
32+
xmlns="http://www.w3.org/2000/svg",
33+
)
34+
35+
def add_style(self):
36+
"""Add the style to the component.
37+
38+
Returns:
39+
The style of the component.
40+
"""
41+
return Style(
42+
{
43+
"fill": "white",
44+
}
45+
)
46+
47+
48+
class StickyLabel(Text):
49+
"""A label that displays the Reflex sticky."""
50+
51+
@classmethod
52+
def create(cls):
53+
"""Create the sticky label.
54+
55+
Returns:
56+
The sticky label.
57+
"""
58+
return super().create("Built with Reflex")
59+
60+
def add_style(self):
61+
"""Add the style to the component.
62+
63+
Returns:
64+
The style of the component.
65+
"""
66+
return Style(
67+
{
68+
"color": color("slate", 1),
69+
"font_weight": "600",
70+
"font_family": "'Instrument Sans', sans-serif",
71+
"font_size": "0.875rem",
72+
"line_height": "1rem",
73+
"letter_spacing": "-0.00656rem",
74+
}
75+
)
76+
77+
78+
class StickyBadge(A):
79+
"""A badge that displays the Reflex sticky logo."""
80+
81+
@classmethod
82+
def create(cls):
83+
"""Create the sticky badge.
84+
85+
Returns:
86+
The sticky badge.
87+
"""
88+
return super().create(
89+
StickyLogo.create(),
90+
tablet_and_desktop(StickyLabel.create()),
91+
href="https://reflex.dev",
92+
target="_blank",
93+
width="auto",
94+
padding="0.375rem",
95+
align="center",
96+
text_align="center",
97+
)
98+
99+
def add_style(self):
100+
"""Add the style to the component.
101+
102+
Returns:
103+
The style of the component.
104+
"""
105+
is_localhost_cs = ClientStateVar.create(
106+
"is_localhost",
107+
default=True,
108+
global_ref=False,
109+
)
110+
localhost_hostnames = Var.create(
111+
["localhost", "127.0.0.1", "[::1]"]
112+
).guess_type()
113+
is_localhost_expr = localhost_hostnames.contains(
114+
Var("window.location.hostname", _var_type=str).guess_type(),
115+
)
116+
check_is_localhost = Var(
117+
f"useEffect(({is_localhost_cs}) => {is_localhost_cs.set}({is_localhost_expr}), [])",
118+
_var_data=VarData(
119+
imports={"react": "useEffect"},
120+
),
121+
)
122+
is_localhost = is_localhost_cs.value._replace(
123+
merge_var_data=VarData.merge(
124+
check_is_localhost._get_all_var_data(),
125+
VarData(hooks={str(check_is_localhost): None}),
126+
),
127+
)
128+
return Style(
129+
{
130+
"position": "fixed",
131+
"bottom": "1rem",
132+
"right": "1rem",
133+
# Do not show the badge on localhost.
134+
"display": cond(is_localhost, "none", "flex"),
135+
"flex-direction": "row",
136+
"gap": "0.375rem",
137+
"align-items": "center",
138+
"width": "auto",
139+
"border-radius": "0.5rem",
140+
"color": color_mode_cond("#E5E7EB", "#27282B"),
141+
"border": color_mode_cond("1px solid #27282B", "1px solid #E5E7EB"),
142+
"background-color": color_mode_cond("#151618", "#FCFCFD"),
143+
"padding": "0.375rem",
144+
"transition": "background-color 0.2s ease-in-out",
145+
"box-shadow": "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
146+
"z-index": "9998",
147+
"cursor": "pointer",
148+
},
149+
)
150+
151+
152+
class StickyNamespace(ComponentNamespace):
153+
"""Sticky components namespace."""
154+
155+
__call__ = staticmethod(StickyBadge.create)
156+
label = staticmethod(StickyLabel.create)
157+
logo = staticmethod(StickyLogo.create)
158+
159+
160+
sticky = StickyNamespace()

0 commit comments

Comments
 (0)