sticky.py 4.8 KB

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