reflex-site-shared 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. reflex_site_shared/__init__.py +1 -0
  2. reflex_site_shared/backend/__init__.py +1 -0
  3. reflex_site_shared/backend/get_blogs.py +44 -0
  4. reflex_site_shared/backend/signup.py +112 -0
  5. reflex_site_shared/components/__init__.py +1 -0
  6. reflex_site_shared/components/blocks/__init__.py +6 -0
  7. reflex_site_shared/components/blocks/code.py +111 -0
  8. reflex_site_shared/components/blocks/collapsible.py +63 -0
  9. reflex_site_shared/components/blocks/demo.py +173 -0
  10. reflex_site_shared/components/blocks/flexdown.py +170 -0
  11. reflex_site_shared/components/blocks/headings.py +274 -0
  12. reflex_site_shared/components/blocks/typography.py +135 -0
  13. reflex_site_shared/components/code_card.py +206 -0
  14. reflex_site_shared/components/docs.py +122 -0
  15. reflex_site_shared/components/hosting_banner.py +5 -0
  16. reflex_site_shared/components/icons.py +698 -0
  17. reflex_site_shared/components/image_zoom.py +23 -0
  18. reflex_site_shared/components/marketing_button.py +41 -0
  19. reflex_site_shared/components/marquee.py +33 -0
  20. reflex_site_shared/components/patterns.py +125 -0
  21. reflex_site_shared/constants.py +38 -0
  22. reflex_site_shared/gallery/__init__.py +3 -0
  23. reflex_site_shared/gallery/apps.py +306 -0
  24. reflex_site_shared/gallery/common.py +278 -0
  25. reflex_site_shared/gallery/gallery.py +301 -0
  26. reflex_site_shared/gallery/r_svg_loader.py +140 -0
  27. reflex_site_shared/gallery/sidebar.py +238 -0
  28. reflex_site_shared/gallery/templates/api-admin-panel.md +34 -0
  29. reflex_site_shared/gallery/templates/chat-app.md +42 -0
  30. reflex_site_shared/gallery/templates/ci-job.md +30 -0
  31. reflex_site_shared/gallery/templates/customer-app.md +50 -0
  32. reflex_site_shared/gallery/templates/dalle.md +37 -0
  33. reflex_site_shared/gallery/templates/dashboard.md +48 -0
  34. reflex_site_shared/gallery/templates/image-gen.md +41 -0
  35. reflex_site_shared/gallery/templates/llamaindex-app.md +68 -0
  36. reflex_site_shared/gallery/templates/nba-app.md +29 -0
  37. reflex_site_shared/gallery/templates/sales-app.md +40 -0
  38. reflex_site_shared/lib/__init__.py +1 -0
  39. reflex_site_shared/lib/meta/__init__.py +1 -0
  40. reflex_site_shared/lib/meta/meta.py +362 -0
  41. reflex_site_shared/lib/route.py +61 -0
  42. reflex_site_shared/meta/__init__.py +1 -0
  43. reflex_site_shared/meta/meta.py +362 -0
  44. reflex_site_shared/pages/__init__.py +1 -0
  45. reflex_site_shared/pages/page404.py +24 -0
  46. reflex_site_shared/route.py +5 -0
  47. reflex_site_shared/styles/__init__.py +3 -0
  48. reflex_site_shared/styles/colors.py +17 -0
  49. reflex_site_shared/styles/custom-colors.css +182 -0
  50. reflex_site_shared/styles/fonts.py +95 -0
  51. reflex_site_shared/styles/globals.css +2051 -0
  52. reflex_site_shared/styles/shadows.py +8 -0
  53. reflex_site_shared/styles/styles.py +81 -0
  54. reflex_site_shared/telemetry/__init__.py +3 -0
  55. reflex_site_shared/telemetry/pixels.py +30 -0
  56. reflex_site_shared/templates/__init__.py +1 -0
  57. reflex_site_shared/templates/gallery_app_page.py +89 -0
  58. reflex_site_shared/templates/marketing_page.py +101 -0
  59. reflex_site_shared/templates/webpage.py +92 -0
  60. reflex_site_shared/utils/__init__.py +1 -0
  61. reflex_site_shared/utils/docpage.py +120 -0
  62. reflex_site_shared/utils/md.py +52 -0
  63. reflex_site_shared/views/__init__.py +1 -0
  64. reflex_site_shared/views/cta_card.py +55 -0
  65. reflex_site_shared/views/footer.py +317 -0
  66. reflex_site_shared/views/hosting_banner.py +154 -0
  67. reflex_site_shared/views/marketing_navbar.py +650 -0
  68. reflex_site_shared/views/sidebar/__init__.py +203 -0
  69. reflex_site_shared-0.0.1.dist-info/METADATA +14 -0
  70. reflex_site_shared-0.0.1.dist-info/RECORD +71 -0
  71. reflex_site_shared-0.0.1.dist-info/WHEEL +4 -0
@@ -0,0 +1 @@
1
+ """Reflex Site Shared module."""
@@ -0,0 +1 @@
1
+ """Backend module."""
@@ -0,0 +1,44 @@
1
+ """Get Blogs module."""
2
+
3
+ from typing import TypedDict
4
+
5
+ import httpx
6
+
7
+ import reflex as rx
8
+ from reflex_site_shared.constants import RECENT_BLOGS_API_URL
9
+
10
+
11
+ class BlogPostDict(TypedDict):
12
+ """BlogPostDict."""
13
+
14
+ title: str
15
+ description: str
16
+ author: str
17
+ date: str
18
+ image: str
19
+ tag: str
20
+ url: str
21
+
22
+
23
+ class RecentBlogsState(rx.State):
24
+ """RecentBlogsState."""
25
+
26
+ posts: rx.Field[list[BlogPostDict]] = rx.field(default_factory=list)
27
+ _fetched: bool = False
28
+
29
+ @rx.event(background=True, temporal=True)
30
+ async def fetch_recent_blogs(self):
31
+ """Fetch recent blogs."""
32
+ if self._fetched:
33
+ return
34
+ try:
35
+ async with httpx.AsyncClient() as client:
36
+ resp = await client.get(RECENT_BLOGS_API_URL, timeout=10)
37
+ resp.raise_for_status()
38
+ data = resp.json()
39
+ async with self:
40
+ self.posts = data.get("posts", [])
41
+ self._fetched = True
42
+ except Exception:
43
+ async with self:
44
+ self.posts = []
@@ -0,0 +1,112 @@
1
+ """Signup module."""
2
+
3
+ import contextlib
4
+ import os
5
+ from typing import Any
6
+
7
+ import httpx
8
+ from email_validator import EmailNotValidError, ValidatedEmail, validate_email
9
+
10
+ import reflex as rx
11
+ from reflex_site_shared.constants import (
12
+ API_BASE_URL_LOOPS,
13
+ REFLEX_DEV_WEB_NEWSLETTER_FORM_WEBHOOK_URL,
14
+ )
15
+
16
+
17
+ class IndexState(rx.State):
18
+ """Hold the state for the home page."""
19
+
20
+ # Whether the user signed up for the newsletter.
21
+ signed_up: bool = False
22
+
23
+ # Whether to show the confetti.
24
+ show_confetti: bool = False
25
+
26
+ @rx.event(background=True)
27
+ async def send_contact_to_webhook(
28
+ self,
29
+ email: str | None,
30
+ ) -> None:
31
+ """Send contact to webhook."""
32
+ with contextlib.suppress(httpx.HTTPError):
33
+ async with httpx.AsyncClient() as client:
34
+ response = await client.post(
35
+ REFLEX_DEV_WEB_NEWSLETTER_FORM_WEBHOOK_URL,
36
+ json={
37
+ "email": email,
38
+ },
39
+ )
40
+ response.raise_for_status()
41
+
42
+ @rx.event(background=True)
43
+ async def add_contact_to_loops(
44
+ self,
45
+ email: str | None,
46
+ ):
47
+ """Add contact to loops."""
48
+ url: str = f"{API_BASE_URL_LOOPS}/contacts/create"
49
+ loops_api_key: str | None = os.getenv("LOOPS_API_KEY")
50
+ if loops_api_key is None:
51
+ return
52
+
53
+ headers = {
54
+ "Accept": "application/json",
55
+ "Authorization": f"Bearer {loops_api_key}",
56
+ }
57
+ try:
58
+ async with httpx.AsyncClient() as client:
59
+ response = await client.post(
60
+ url,
61
+ headers=headers,
62
+ json={
63
+ "email": email,
64
+ },
65
+ )
66
+ response.raise_for_status() # Raise an exception for HTTP errors (4xx and 5xx)
67
+
68
+ except httpx.HTTPError:
69
+ pass
70
+
71
+ @rx.event
72
+ def signup_for_another_user(self):
73
+ """Signup for another user."""
74
+ self.signed_up = False
75
+
76
+ @rx.event(background=True)
77
+ async def signup(
78
+ self,
79
+ form_data: dict[str, Any],
80
+ ):
81
+ """Sign the user up for the newsletter.
82
+
83
+ Yields:
84
+ The event actions.
85
+ """
86
+ email: str | None = None
87
+ if email_to_validate := form_data.get("input_email"):
88
+ try:
89
+ validated_email: ValidatedEmail = validate_email(
90
+ email_to_validate,
91
+ check_deliverability=True,
92
+ )
93
+ email = validated_email.normalized
94
+
95
+ except EmailNotValidError as e:
96
+ # Alert the error message.
97
+ yield rx.toast.warning(
98
+ str(e),
99
+ style={
100
+ "border": "1px solid #3C3646",
101
+ "background": "linear-gradient(218deg, #1D1B23 -35.66%, #131217 100.84%)",
102
+ },
103
+ )
104
+ return
105
+ yield IndexState.send_contact_to_webhook(email)
106
+ yield IndexState.add_contact_to_loops(email)
107
+ async with self:
108
+ self.signed_up = True
109
+ yield
110
+ yield [
111
+ rx.toast.success("Thanks for signing up to the Newsletter!"),
112
+ ]
@@ -0,0 +1 @@
1
+ """Components module."""
@@ -0,0 +1,6 @@
1
+ """Blocks module."""
2
+
3
+ from .code import *
4
+ from .demo import *
5
+ from .headings import *
6
+ from .typography import *
@@ -0,0 +1,111 @@
1
+ """Code block components for documentation pages."""
2
+
3
+ import reflex as rx
4
+ import reflex_site_shared.styles.fonts as fonts
5
+ from reflex_site_shared import styles
6
+
7
+
8
+ @rx.memo
9
+ def code_block(code: str, language: str):
10
+ """Code block.
11
+
12
+ Returns:
13
+ The component.
14
+ """
15
+ return rx.box(
16
+ rx._x.code_block(
17
+ code,
18
+ language=language,
19
+ class_name="code-block",
20
+ can_copy=True,
21
+ ),
22
+ class_name="relative mb-4",
23
+ )
24
+
25
+
26
+ @rx.memo
27
+ def code_block_dark(code: str, language: str):
28
+ """Code block dark.
29
+
30
+ Returns:
31
+ The component.
32
+ """
33
+ return rx.box(
34
+ rx._x.code_block(
35
+ code,
36
+ language=language,
37
+ class_name="code-block",
38
+ can_copy=True,
39
+ ),
40
+ class_name="relative mb-4",
41
+ )
42
+
43
+
44
+ def code_block_markdown(*children, **props):
45
+ """Code block markdown.
46
+
47
+ Returns:
48
+ The component.
49
+ """
50
+ language = props.get("language", "plain")
51
+ return code_block(code=children[0], language=language)
52
+
53
+
54
+ def code_block_markdown_dark(*children, **props):
55
+ """Code block markdown dark.
56
+
57
+ Returns:
58
+ The component.
59
+ """
60
+ language = props.get("language", "plain")
61
+ return code_block_dark(code=children[0], language=language)
62
+
63
+
64
+ def doccmdoutput(
65
+ command: str,
66
+ output: str,
67
+ ) -> rx.Component:
68
+ """Create a documentation code snippet.
69
+
70
+ Args:
71
+ command: The command to display.
72
+ output: The output of the command.
73
+
74
+ Returns:
75
+ The styled command and its example output.
76
+ """
77
+ return rx.vstack(
78
+ rx._x.code_block(
79
+ command,
80
+ can_copy=True,
81
+ border_radius=styles.DOC_BORDER_RADIUS,
82
+ background="transparent",
83
+ theme="ayu-dark",
84
+ language="bash",
85
+ code_tag_props={
86
+ "style": {
87
+ "fontFamily": "inherit",
88
+ }
89
+ },
90
+ style=fonts.code,
91
+ font_family="JetBrains Mono",
92
+ width="100%",
93
+ ),
94
+ rx._x.code_block(
95
+ output,
96
+ can_copy=False,
97
+ border_radius="12px",
98
+ background="transparent",
99
+ theme="ayu-dark",
100
+ language="log",
101
+ code_tag_props={
102
+ "style": {
103
+ "fontFamily": "inherit",
104
+ }
105
+ },
106
+ style=fonts.code,
107
+ font_family="JetBrains Mono",
108
+ width="100%",
109
+ ),
110
+ padding_y="1em",
111
+ )
@@ -0,0 +1,63 @@
1
+ """Collapsible accordion box used by alert and video blocks."""
2
+
3
+ from collections.abc import Sequence
4
+
5
+ from reflex_base.constants.colors import ColorType
6
+
7
+ import reflex as rx
8
+
9
+
10
+ def collapsible_box(
11
+ trigger_children: Sequence[rx.Component],
12
+ body: rx.Component,
13
+ color: ColorType,
14
+ *,
15
+ item_border_radius: str = "12px",
16
+ ) -> rx.Component:
17
+ """Collapsible accordion wrapper shared by alert and video directives.
18
+
19
+ Returns:
20
+ The component.
21
+ """
22
+ return rx.box(
23
+ rx.accordion.root(
24
+ rx.accordion.item(
25
+ rx.accordion.header(
26
+ rx.accordion.trigger(
27
+ rx.hstack(
28
+ *trigger_children,
29
+ rx.spacer(),
30
+ rx.accordion.icon(color=f"{rx.color(color, 11)}"),
31
+ align_items="center",
32
+ justify_content="left",
33
+ text_align="left",
34
+ spacing="2",
35
+ width="100%",
36
+ ),
37
+ padding="0px",
38
+ color=f"{rx.color(color, 11)} !important",
39
+ background_color="transparent !important",
40
+ border_radius="12px",
41
+ _hover={},
42
+ ),
43
+ ),
44
+ body,
45
+ border_radius=item_border_radius,
46
+ padding=["16px", "24px"],
47
+ background_color=f"{rx.color(color, 3)}",
48
+ border="none",
49
+ ),
50
+ background="transparent !important",
51
+ border_radius="12px",
52
+ box_shadow="none !important",
53
+ collapsible=True,
54
+ width="100%",
55
+ ),
56
+ border=f"1px solid {rx.color(color, 4)}",
57
+ border_radius="12px",
58
+ background_color=f"{rx.color(color, 3)} !important",
59
+ width="100%",
60
+ margin_bottom="16px",
61
+ margin_top="16px",
62
+ overflow="hidden",
63
+ )
@@ -0,0 +1,173 @@
1
+ """Components for rendering code demos in the documentation."""
2
+
3
+ import textwrap
4
+ from typing import Any
5
+
6
+ import ruff_format
7
+
8
+ import reflex as rx
9
+
10
+ from .code import code_block, code_block_dark
11
+
12
+
13
+ def docdemobox(*children, **props) -> rx.Component:
14
+ """Create a documentation demo box with the output of the code.
15
+
16
+ Args:
17
+ children: The children to display.
18
+ props: Additional props to apply to the box.
19
+
20
+ Returns:
21
+ The styled demo box.
22
+ """
23
+ return rx.box(
24
+ *children,
25
+ **props,
26
+ class_name="flex flex-col p-6 rounded-xl overflow-x-auto border border-slate-4 bg-slate-2 items-center justify-center w-full",
27
+ )
28
+
29
+
30
+ def doccode(
31
+ code: str,
32
+ language: str = "python",
33
+ lines: tuple[int, int] | None = None,
34
+ theme: str = "light",
35
+ ) -> rx.Component:
36
+ """Create a documentation code snippet.
37
+
38
+ Args:
39
+ code: The code to display.
40
+ language: The language of the code.
41
+ lines: The start/end lines to display.
42
+ theme: The theme for the code snippet.
43
+
44
+ Returns:
45
+ The styled code snippet.
46
+ """
47
+ # For Python snippets, lint the code with black.
48
+ if language == "python":
49
+ code = ruff_format.format_string(textwrap.dedent(code)).strip()
50
+
51
+ # If needed, only display a subset of the lines.
52
+ if lines is not None:
53
+ code = textwrap.dedent(
54
+ "\n".join(code.strip().splitlines()[lines[0] : lines[1]])
55
+ ).strip()
56
+
57
+ # Create the code snippet.
58
+ cb = code_block_dark if theme == "dark" else code_block
59
+ return cb(
60
+ code=code,
61
+ language=language,
62
+ )
63
+
64
+
65
+ def docdemo(
66
+ code: str,
67
+ state: str | None = None,
68
+ comp: rx.Component | None = None,
69
+ context: bool = False,
70
+ demobox_props: dict[str, Any] | None = None,
71
+ theme: str | None = None,
72
+ **props,
73
+ ) -> rx.Component:
74
+ """Create a documentation demo with code and output.
75
+
76
+ Args:
77
+ code: The code to render the component.
78
+ state: Code for any state needed for the component.
79
+ comp: The pre-rendered component.
80
+ context: Whether to wrap the render code in a function.
81
+ demobox_props: Props to apply to the demo box.
82
+ theme: The theme for the code snippet.
83
+ props: Additional props to apply to the component.
84
+
85
+ Returns:
86
+ The styled demo.
87
+ """
88
+ demobox_props = demobox_props or {}
89
+ # Render the component if necessary.
90
+ if comp is None:
91
+ comp = eval(code)
92
+
93
+ # Wrap the render code in a function if needed.
94
+ if context:
95
+ code = f"""def index():
96
+ return {code}
97
+ """
98
+
99
+ # Add the state code
100
+ if state is not None:
101
+ code = state + code
102
+
103
+ if demobox_props.pop("toggle", False):
104
+ return rx.tabs.root(
105
+ rx.tabs.list(
106
+ rx.tabs.trigger(
107
+ rx.box(
108
+ "UI",
109
+ ),
110
+ value="tab1",
111
+ class_name="tab-style",
112
+ ),
113
+ rx.tabs.trigger(
114
+ rx.box(
115
+ "Code",
116
+ ),
117
+ value="tab2",
118
+ class_name="tab-style",
119
+ ),
120
+ class_name="justify-end",
121
+ ),
122
+ rx.tabs.content(
123
+ rx.box(docdemobox(comp, **(demobox_props or {})), class_name="my-4"),
124
+ value="tab1",
125
+ ),
126
+ rx.tabs.content(
127
+ rx.box(doccode(code, theme=theme or "light"), class_name="my-4"),
128
+ value="tab2",
129
+ ),
130
+ default_value="tab1",
131
+ )
132
+ # Create the demo.
133
+ return rx.box(
134
+ docdemobox(comp, **(demobox_props or {})),
135
+ doccode(code, theme=theme or "light"),
136
+ class_name="py-4 gap-4 flex flex-col w-full",
137
+ **props,
138
+ )
139
+
140
+
141
+ def docgraphing(
142
+ code: str,
143
+ comp: rx.Component | None = None,
144
+ data: str | None = None,
145
+ ):
146
+ """Docgraphing.
147
+
148
+ Returns:
149
+ The component.
150
+ """
151
+ return rx.box(
152
+ rx.flex(
153
+ comp,
154
+ class_name="w-full flex flex-col p-6 rounded-xl overflow-x-auto border border-slate-4 bg-slate-2 items-center justify-center",
155
+ ),
156
+ rx.tabs.root(
157
+ rx.tabs.list(
158
+ rx.tabs.trigger("Code", value="code", class_name="tab-style"),
159
+ rx.tabs.trigger("Data", value="data", class_name="tab-style"),
160
+ justify_content="end",
161
+ ),
162
+ rx.box(
163
+ rx.tabs.content(doccode(code), value="code", class_name="w-full px-0"),
164
+ rx.tabs.content(
165
+ doccode(data or ""), value="data", class_name="w-full px-0"
166
+ ),
167
+ class_name="w-full my-4",
168
+ ),
169
+ default_value="code",
170
+ class_name="w-full mt-6 justify-end",
171
+ ),
172
+ class_name="w-full py-4 flex flex-col",
173
+ )
@@ -0,0 +1,170 @@
1
+ """Flexdown module — component maps and markdown helpers."""
2
+
3
+ # pyright: reportAttributeAccessIssue=false
4
+ from reflex_base.constants.colors import ColorType
5
+
6
+ import reflex as rx
7
+ from reflex_site_shared.components.blocks.code import (
8
+ code_block_markdown,
9
+ code_block_markdown_dark,
10
+ )
11
+ from reflex_site_shared.components.blocks.headings import (
12
+ h1_comp_xd,
13
+ h2_comp_xd,
14
+ h3_comp_xd,
15
+ h4_comp_xd,
16
+ img_comp_xd,
17
+ )
18
+ from reflex_site_shared.components.blocks.typography import (
19
+ code_comp,
20
+ doclink2,
21
+ list_comp,
22
+ ordered_list_comp,
23
+ text_comp,
24
+ unordered_list_comp,
25
+ )
26
+ from reflex_site_shared.styles.fonts import base, code
27
+
28
+
29
+ def get_code_style(color: ColorType):
30
+ """Get code style.
31
+
32
+ Returns:
33
+ The component.
34
+ """
35
+ return {
36
+ "p": {"margin_y": "0px"},
37
+ "code": {
38
+ "color": rx.color(color, 11),
39
+ "border_radius": "4px",
40
+ "border": f"1px solid {rx.color(color, 5)}",
41
+ "background": rx.color(color, 4),
42
+ **code,
43
+ },
44
+ **base,
45
+ }
46
+
47
+
48
+ def _markdown_table(*children, **props) -> rx.Component:
49
+ return rx.box(
50
+ rx.el.table(
51
+ *children,
52
+ class_name="w-full border-collapse text-sm border border-secondary-4 rounded-lg overflow-hidden bg-white-1 ",
53
+ **props,
54
+ ),
55
+ class_name="w-full rounded-xl border border-secondary-a4 my-6 max-w-full overflow-hidden",
56
+ )
57
+
58
+
59
+ def _markdown_thead(*children, **props) -> rx.Component:
60
+ return rx.el.thead(
61
+ *children,
62
+ class_name="bg-secondary-1 border-b border-secondary-4",
63
+ **props,
64
+ )
65
+
66
+
67
+ def _markdown_tbody(*children, **props) -> rx.Component:
68
+ return rx.el.tbody(
69
+ *children,
70
+ class_name="[&_tr:nth-child(even)]:bg-secondary-1",
71
+ **props,
72
+ )
73
+
74
+
75
+ def _markdown_tr(*children, **props) -> rx.Component:
76
+ return rx.el.tr(
77
+ *children,
78
+ class_name="border-b border-secondary-4 last:border-b-0",
79
+ **props,
80
+ )
81
+
82
+
83
+ def _markdown_th(*children, **props) -> rx.Component:
84
+ return rx.el.th(
85
+ *children,
86
+ class_name="px-3 py-2.5 text-left text-xs font-[575] text-secondary-12 align-top",
87
+ **props,
88
+ )
89
+
90
+
91
+ def _markdown_td(*children, **props) -> rx.Component:
92
+ return rx.el.td(
93
+ *children,
94
+ class_name="px-3 py-2.5 text-xs font-medium first:font-[575] text-secondary-11 align-top",
95
+ **props,
96
+ )
97
+
98
+
99
+ _markdown_table_component_map: dict[str, object] = {
100
+ "table": _markdown_table,
101
+ "thead": _markdown_thead,
102
+ "tbody": _markdown_tbody,
103
+ "tr": _markdown_tr,
104
+ "th": _markdown_th,
105
+ "td": _markdown_td,
106
+ }
107
+
108
+ component_map = {
109
+ "h1": lambda text: h1_comp_xd(text=text),
110
+ "h2": lambda text: h2_comp_xd(text=text),
111
+ "h3": lambda text: h3_comp_xd(text=text),
112
+ "h4": lambda text: h4_comp_xd(text=text),
113
+ "p": lambda text: text_comp(text=text),
114
+ "li": lambda text: list_comp(text=text),
115
+ "a": doclink2,
116
+ "code": lambda text: code_comp(text=text),
117
+ "pre": code_block_markdown,
118
+ "img": lambda src: img_comp_xd(src=src),
119
+ **_markdown_table_component_map,
120
+ }
121
+ comp2 = component_map.copy()
122
+ comp2["pre"] = code_block_markdown_dark
123
+ comp2["ul"] = lambda items: unordered_list_comp(items=items)
124
+ comp2["ol"] = lambda items: ordered_list_comp(items=items)
125
+
126
+
127
+ def markdown(text: str):
128
+ """Markdown.
129
+
130
+ Returns:
131
+ The component.
132
+ """
133
+ return rx.markdown(text, component_map=component_map)
134
+
135
+
136
+ def markdown_codeblock(value: str, **props: object) -> rx.Component:
137
+ """Render a code block using the Shiki-based code block component.
138
+
139
+ Returns:
140
+ The component.
141
+ """
142
+ return rx._x.code_block(value, **props)
143
+
144
+
145
+ def markdown_with_shiki(*args, **kwargs):
146
+ """Wrapper for the markdown component with a customized component map.
147
+ Uses the experimental Shiki-based code block (rx._x.code_block)
148
+ instead of the default CodeBlock component for code blocks.
149
+
150
+ Note: This wrapper should be removed once the default codeblock
151
+ in rx.markdown component map is updated to the Shiki-based code block.
152
+
153
+ Returns:
154
+ The component.
155
+ """
156
+ return rx.markdown(
157
+ *args,
158
+ component_map={
159
+ "h1": lambda text: h1_comp_xd(text=text),
160
+ "h2": lambda text: h2_comp_xd(text=text),
161
+ "h3": lambda text: h3_comp_xd(text=text),
162
+ "h4": lambda text: h4_comp_xd(text=text),
163
+ "p": lambda text: text_comp(text=text),
164
+ "li": lambda text: list_comp(text=text),
165
+ "a": doclink2,
166
+ "pre": markdown_codeblock,
167
+ "img": lambda src: img_comp_xd(src=src),
168
+ },
169
+ **kwargs,
170
+ )