diff --git a/docs/app/assets/tailwind-theme.css b/docs/app/assets/tailwind-theme.css
index 848002ec1fc..0df15d1f618 100644
--- a/docs/app/assets/tailwind-theme.css
+++ b/docs/app/assets/tailwind-theme.css
@@ -3,6 +3,22 @@
@custom-variant dark (&:where(.dark, .dark *));
+.dark .static-shiki .shiki {
+ color: var(--shiki-dark) !important;
+ background-color: var(--shiki-dark-bg) !important;
+ font-style: var(--shiki-dark-font-style) !important;
+ font-weight: var(--shiki-dark-font-weight) !important;
+ text-decoration: var(--shiki-dark-text-decoration) !important;
+}
+
+.dark .static-shiki .shiki span {
+ color: var(--shiki-dark) !important;
+ background-color: transparent !important;
+ font-style: var(--shiki-dark-font-style) !important;
+ font-weight: var(--shiki-dark-font-weight) !important;
+ text-decoration: var(--shiki-dark-text-decoration) !important;
+}
+
:root {
/* Primary */
--primary-1: var(--violet-1);
@@ -2184,4 +2200,4 @@
#ph-conversations-widget-container button[aria-label^="Open chat"]+div {
display: none !important;
-}
\ No newline at end of file
+}
diff --git a/docs/app/reflex_docs/pages/docs_landing/views/ai_builder.py b/docs/app/reflex_docs/pages/docs_landing/views/ai_builder.py
index caed0932ec5..c1f44ec534c 100644
--- a/docs/app/reflex_docs/pages/docs_landing/views/ai_builder.py
+++ b/docs/app/reflex_docs/pages/docs_landing/views/ai_builder.py
@@ -88,7 +88,7 @@ def card(
class_name="flex flex-col gap-2 p-8",
),
content,
- rx.el.a(href=href, class_name="absolute inset-0"),
+ rx.el.a(href=href, aria_label=title, class_name="absolute inset-0"),
class_name="flex flex-col bg-secondary-1/96 backdrop-blur-[16px] rounded-xl relative cursor-pointer transition-colors overflow-hidden shadow-[0_0_0_1px_rgba(0,0,0,0.04),0_12px_24px_0_rgba(0,0,0,0.08),0_1px_1px_0_rgba(0,0,0,0.01),0_4px_8px_0_rgba(0,0,0,0.03)] dark:shadow-none dark:border dark:border-secondary-4",
)
diff --git a/docs/app/reflex_docs/pages/docs_landing/views/framework.py b/docs/app/reflex_docs/pages/docs_landing/views/framework.py
index c857b5edefe..216ae938fab 100644
--- a/docs/app/reflex_docs/pages/docs_landing/views/framework.py
+++ b/docs/app/reflex_docs/pages/docs_landing/views/framework.py
@@ -38,7 +38,7 @@ def docs_item(
description,
class_name="text-secondary-11 text-sm font-[475]",
),
- rx.el.a(to=href, class_name="absolute inset-0"),
+ rx.el.a(to=href, aria_label=title, class_name="absolute inset-0"),
class_name="flex flex-col gap-2 py-8 pr-8 relative group lg:max-w-[21rem] w-full max-lg:text-start hover:bg-[linear-gradient(243deg,var(--secondary-2)_0%,var(--secondary-1)_100%)]",
)
diff --git a/docs/app/reflex_docs/pages/docs_landing/views/link_item.py b/docs/app/reflex_docs/pages/docs_landing/views/link_item.py
index 6097a3dddd2..c86d93ec734 100644
--- a/docs/app/reflex_docs/pages/docs_landing/views/link_item.py
+++ b/docs/app/reflex_docs/pages/docs_landing/views/link_item.py
@@ -43,7 +43,7 @@ def link_item(
description,
class_name="text-secondary-11 text-sm font-[475] text-start",
),
- rx.el.a(to=href, class_name="absolute inset-0"),
+ rx.el.a(to=href, aria_label=title, class_name="absolute inset-0"),
class_name=ui.cn(
"flex flex-col gap-2 pr-8 py-8 group border-r border-b border-secondary-4 relative max-lg:p-6 hover:bg-[linear-gradient(243deg,var(--secondary-2)_0%,var(--secondary-1)_100%)]",
"lg:pl-8 pl-6" if has_padding_left else "",
diff --git a/docs/app/reflex_docs/templates/docpage/docpage.py b/docs/app/reflex_docs/templates/docpage/docpage.py
index 997b4195904..bccb0fae12a 100644
--- a/docs/app/reflex_docs/templates/docpage/docpage.py
+++ b/docs/app/reflex_docs/templates/docpage/docpage.py
@@ -234,22 +234,26 @@ def feedback_content() -> rx.Component:
def feedback_button() -> rx.Component:
thumb_cn = "w-full gap-2 px-3 py-0.5 flex flex-row items-center justify-center whitespace-nowrap border cursor-pointer transition-colors font-small"
return ui.popover.root(
- ui.popover.trigger(
- render_=rx.el.div(
- feedback_choice_button(
+ rx.el.div(
+ ui.popover.trigger(
+ render_=feedback_choice_button(
"Yes",
"ThumbsUpIcon",
1,
ui.cn("rounded-[20px_0_0_20px] border-r-0", thumb_cn),
),
- feedback_choice_button(
+ ),
+ ui.popover.trigger(
+ render_=feedback_choice_button(
"No",
"ThumbsDownIcon",
0,
ui.cn("rounded-[0_20px_20px_0]", thumb_cn),
),
- class_name="w-full lg:w-auto items-center flex flex-row",
),
+ role="group",
+ aria_label="Was this page helpful?",
+ class_name="w-full lg:w-auto items-center flex flex-row",
),
ui.popover.portal(
ui.popover.positioner(
@@ -746,8 +750,10 @@ def breadcrumb(path: str, nav_sidebar: rx.Component, doc_content: str | None = N
return rx.box(
docs_sidebar_drawer(
nav_sidebar,
- trigger=rx.box(
- class_name="absolute inset-0 bg-transparent z-[1] lg:hidden flex",
+ trigger=rx.el.button(
+ type="button",
+ aria_label="Open docs navigation",
+ class_name="absolute inset-0 bg-transparent z-[1] lg:hidden flex border-none p-0 cursor-pointer",
),
),
rx.box(
diff --git a/docs/app/reflex_docs/views/inkeep.py b/docs/app/reflex_docs/views/inkeep.py
index 72a826518e5..f3cb89793bd 100644
--- a/docs/app/reflex_docs/views/inkeep.py
+++ b/docs/app/reflex_docs/views/inkeep.py
@@ -1,8 +1,12 @@
"""UI and logic inkeep chat component."""
import reflex as rx
+from reflex.constants import MemoizationMode
+from reflex.event import EventSpec
+from reflex.experimental.client_state import ClientStateVar
from reflex.utils.imports import ImportVar
from reflex.vars import Var
+from reflex.vars.base import VarData
class InkeepSearchBar(rx.NoSSRComponent):
@@ -10,11 +14,126 @@ class InkeepSearchBar(rx.NoSSRComponent):
library = "@inkeep/cxkit-react@0.5.115"
+_INKEEP_LOADED_STATE = "inkeep_loaded"
+_INKEEP_OPEN_STATE = "inkeep_open"
+_SEARCH_WRAPPER_ID = "inkeep-search-wrapper"
+_SEARCH_TRIGGER_ID = "inkeep-search-trigger"
+_SEARCH_TRIGGER_FALLBACK_STYLE = (
+ f"#{_SEARCH_WRAPPER_ID}:has(> [id^='inkeep-shadow']) "
+ f"> #{_SEARCH_TRIGGER_ID} {{ display: none; }}"
+)
+
+# Inline copy of assets/icons/search.svg so the placeholder needs no extra request.
+_SEARCH_ICON_SVG = (
+ ''
+)
+
+# Runs on mount (as a real effect, not an inert rendered