diff --git a/js/app/components/aqlink.tsx b/js/app/components/aqlink.tsx
index 168affb48..f40f510cd 100644
--- a/js/app/components/aqlink.tsx
+++ b/js/app/components/aqlink.tsx
@@ -2,6 +2,7 @@ import {
Link,
NavigationProp,
ParamListBase,
+ useLinkBuilder,
useNavigation,
} from "@react-navigation/native";
import usePlatform from "hooks/usePlatform";
@@ -54,3 +55,21 @@ export function Redirect({ to }: { to: LinkParams }) {
}, []);
return ;
}
+
+// generates the proper href for a given LinkParams object, for better web support
+export function useAQLinkHref(to: LinkParams): { href?: string } {
+ const { isWeb } = usePlatform();
+ const buildLink = useLinkBuilder();
+
+ if (!isWeb) {
+ return { href: undefined };
+ }
+
+ try {
+ const href = buildLink(to.screen, to.params);
+ return { href };
+ } catch (e) {
+ console.warn("Failed to build link for", to, e);
+ return { href: undefined };
+ }
+}
diff --git a/js/app/components/sidebar/sidebar-item.tsx b/js/app/components/sidebar/sidebar-item.tsx
index 779fa77e9..9748bc132 100644
--- a/js/app/components/sidebar/sidebar-item.tsx
+++ b/js/app/components/sidebar/sidebar-item.tsx
@@ -1,12 +1,17 @@
-import { Text, useTheme } from "@streamplace/components";
+import { DrawerNavigationState, ParamListBase } from "@react-navigation/native";
+import { Text, useTheme, zero } from "@streamplace/components";
+import { useAQLinkHref } from "components/aqlink";
import React, { ReactNode, useState } from "react";
import {
+ GestureResponderEvent,
+ Pressable,
PressableStateCallbackType,
StyleProp,
View,
ViewStyle,
} from "react-native";
-import { Pressable } from "react-native-gesture-handler";
+
+import {} from "src/router";
export default function SidebarItem({
icon,
@@ -14,6 +19,7 @@ export default function SidebarItem({
collapsed,
active,
onPress,
+ route,
style = null,
tint = "rgba(189, 110, 134)",
}: {
@@ -24,7 +30,8 @@ export default function SidebarItem({
label: string | ReactNode;
collapsed: boolean;
active: boolean;
- onPress: () => void;
+ onPress: (event: GestureResponderEvent) => void;
+ route?: DrawerNavigationState["routes"][number];
style?:
| StyleProp
| ((state: PressableStateCallbackType) => StyleProp);
@@ -32,6 +39,10 @@ export default function SidebarItem({
}) {
const [hover, setHover] = useState(false);
const theme = useTheme();
+ const { href } = useAQLinkHref({
+ screen: route?.name || "Home",
+ params: route?.params as any,
+ });
// Handle different icon types - component, JSX element, or function returning JSX
const renderIcon = () => {
@@ -73,9 +84,18 @@ export default function SidebarItem({
style={style}
onHoverIn={() => setHover(true)}
onHoverOut={() => setHover(false)}
+ role="link"
+ accessibilityLabel={typeof label === "string" ? label : "Sidebar Item"}
+ // @ts-ignore This makes it render as on web!
+ href={href}
>
- {renderIcon()}
+ {renderIcon()}
{!collapsed && (
{
return {
minWidth: widthAnim.value,
@@ -61,26 +59,29 @@ export default function Sidebar({
return (
{!collapsed && Streamplace}
@@ -98,6 +99,7 @@ export default function Sidebar({
| React.ComponentType
| undefined;
+ console.log("router", route);
return (
{
+ route={route}
+ onPress={(ev) => {
+ ev.preventDefault();
if (route.name === "Home") {
- // copy logic for 'Home' to reset the stack
+ // reset the stack (b/c streamlist is in the same stack as home)
navigation.dispatch(
CommonActions.reset({
index: 0,
@@ -126,7 +130,7 @@ export default function Sidebar({
}
}}
style={options.drawerItemStyle}
- tint={options.drawerActiveTintColor as string} // Assuming tint is a string color or undefined
+ tint={options.drawerActiveTintColor as string}
/>
);
})}
--
2.51.2
From bf2fd1af1888ef09528ce421b4073b3941f2b81c Mon Sep 17 00:00:00 2001
From: Natalie Bridgers
Date: Wed, 1 Oct 2025 15:42:28 -0500
Subject: [PATCH 2/5] clear up console.logs
---
js/app/components/sidebar/sidebar-item.tsx | 8 +++++++-
js/app/components/sidebar/sidebar.tsx | 1 -
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/js/app/components/sidebar/sidebar-item.tsx b/js/app/components/sidebar/sidebar-item.tsx
index 9748bc132..743baac3c 100644
--- a/js/app/components/sidebar/sidebar-item.tsx
+++ b/js/app/components/sidebar/sidebar-item.tsx
@@ -73,7 +73,13 @@ export default function SidebarItem({
}
// Fallback
- console.log("tried to render item, but couldn't", (icon as any).$$typeof);
+ console.log(
+ "tried to render item for route",
+ label,
+ href,
+ ", but couldn't",
+ (icon as any).$$typeof,
+ );
return 📄;
};
diff --git a/js/app/components/sidebar/sidebar.tsx b/js/app/components/sidebar/sidebar.tsx
index 06b55a97d..feb044550 100644
--- a/js/app/components/sidebar/sidebar.tsx
+++ b/js/app/components/sidebar/sidebar.tsx
@@ -99,7 +99,6 @@ export default function Sidebar({
| React.ComponentType
| undefined;
- console.log("router", route);
return (
Date: Wed, 1 Oct 2025 15:48:11 -0500
Subject: [PATCH 3/5] skip rendering "display: none" components
---
js/app/components/sidebar/sidebar.tsx | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/js/app/components/sidebar/sidebar.tsx b/js/app/components/sidebar/sidebar.tsx
index feb044550..8139342ce 100644
--- a/js/app/components/sidebar/sidebar.tsx
+++ b/js/app/components/sidebar/sidebar.tsx
@@ -99,6 +99,21 @@ export default function Sidebar({
| React.ComponentType
| undefined;
+ // if we have style display: none on the drawer item, completely skip rendering it
+ const drawerItemStyle = options.drawerItemStyle;
+ let isHidden = false;
+ if (
+ drawerItemStyle &&
+ typeof drawerItemStyle === "object" &&
+ "display" in drawerItemStyle &&
+ (drawerItemStyle as any).display === "none"
+ ) {
+ isHidden = true;
+ }
+ if (isHidden) {
+ return null;
+ }
+
return (
Date: Wed, 1 Oct 2025 15:50:20 -0500
Subject: [PATCH 4/5] better accessibility label defaults?
---
js/app/components/sidebar/sidebar-item.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/app/components/sidebar/sidebar-item.tsx b/js/app/components/sidebar/sidebar-item.tsx
index 743baac3c..1dab7ce52 100644
--- a/js/app/components/sidebar/sidebar-item.tsx
+++ b/js/app/components/sidebar/sidebar-item.tsx
@@ -91,7 +91,7 @@ export default function SidebarItem({
onHoverIn={() => setHover(true)}
onHoverOut={() => setHover(false)}
role="link"
- accessibilityLabel={typeof label === "string" ? label : "Sidebar Item"}
+ accessibilityLabel={typeof label === "string" ? label : "Link to " + href}
// @ts-ignore This makes it render as on web!
href={href}
>
--
2.51.2
From a54f3bf10ac3a8c574bdd382951d70555567fd3a Mon Sep 17 00:00:00 2001
From: Natalie Bridgers
Date: Thu, 2 Oct 2025 19:41:05 -0500
Subject: [PATCH 5/5] remove weird import?
---
js/app/components/sidebar/sidebar-item.tsx | 2 --
1 file changed, 2 deletions(-)
diff --git a/js/app/components/sidebar/sidebar-item.tsx b/js/app/components/sidebar/sidebar-item.tsx
index 1dab7ce52..9dea23b47 100644
--- a/js/app/components/sidebar/sidebar-item.tsx
+++ b/js/app/components/sidebar/sidebar-item.tsx
@@ -11,8 +11,6 @@ import {
ViewStyle,
} from "react-native";
-import {} from "src/router";
-
export default function SidebarItem({
icon,
label,