Skip to content

Commit 93d5eef

Browse files
committed
refactor: replace Link and NavLink with button
Link (or NavLink) uses <a> tags under the hood. When mouse over, there will be a tiny (but noticable) tooltip in the left-bottom of your browser (maybe Chrome only) displaying the url of that <a> tag and it is not possible to hide it. It's quite anoying, as I am only doing client side routing, the url is of zero importance and will cover on the bottom buttons of my side bar.
1 parent c3ae1bb commit 93d5eef

File tree

3 files changed

+43
-27
lines changed

3 files changed

+43
-27
lines changed

web/src/routes/root/ChatTab/index.jsx

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import styles from "./index.module.css";
22

33
import { useContext, useEffect, useState, useRef } from "react";
4-
import { NavLink } from "react-router-dom";
4+
import { useNavigate, useParams } from "react-router-dom";
55
import PropTypes from "prop-types";
66
import Tooltip from "@mui/material/Tooltip";
77
import Icon from "@mui/material/Icon";
@@ -23,6 +23,9 @@ import { ConversationContext } from "@/contexts/conversation";
2323
* @returns
2424
*/
2525
const ChatTab = ({ chat, onShareClick, onDeleteClick }) => {
26+
const navigate = useNavigate();
27+
const params = useParams();
28+
2629
const { dispatch } = useContext(ConversationContext);
2730
const titleRef = useRef(null);
2831
const [titleEditable, setTitleEditable] = useState("false");
@@ -101,26 +104,29 @@ const ChatTab = ({ chat, onShareClick, onDeleteClick }) => {
101104
};
102105

103106
return (
104-
<NavLink
105-
to={`conversations/${chat.id}`}
106-
className={({ isActive, isPending }) =>
107-
`${styles.sidebarButton} ${isActive ? styles.active : isPending ? styles.pending : ""}`}
107+
<div
108+
className={`${styles.sidebarButton} ${params.convId === chat.id ? styles.active : ""}`}
108109
>
109110
<Tooltip title={titleRef.current?.innerText}>
110-
{/* contentEditable moves control out of react, so useState won't work correctly.
111-
* I use ref to get the value instead.
112-
*/}
113-
<span
114-
aria-label="chat title"
115-
ref={titleRef}
116-
className={styles.chatTitle}
117-
contentEditable={titleEditable}
118-
suppressContentEditableWarning={true} // TODO: I'm not sure whether I can ignore this warning
119-
onKeyDown={handleKeyDown}
120-
onBlur={() => setTitleEditable("false")}
111+
<div
112+
className={styles.titleContainer}
113+
onClick={() => navigate(`/conversations/${chat.id}`)}
121114
>
122-
{chat.title}
123-
</span>
115+
{/* contentEditable moves control out of react, so useState won't work correctly.
116+
* I use ref to get the value instead.
117+
*/}
118+
<span
119+
aria-label="chat title"
120+
ref={titleRef}
121+
className={styles.chatTitle}
122+
contentEditable={titleEditable}
123+
suppressContentEditableWarning={true} // TODO: I'm not sure whether I can ignore this warning
124+
onKeyDown={handleKeyDown}
125+
onBlur={() => setTitleEditable("false")}
126+
>
127+
{chat.title}
128+
</span>
129+
</div>
124130
</Tooltip>
125131
<Dropdown className={styles.chatOpMenu}>
126132
<DropdownButton ref={buttonRef} className={styles.chatOpMenuIcon}>
@@ -166,7 +172,7 @@ const ChatTab = ({ chat, onShareClick, onDeleteClick }) => {
166172
</li>
167173
</DropdownMenu>
168174
</Dropdown>
169-
</NavLink>
175+
</div>
170176
);
171177
};
172178

web/src/routes/root/ChatTab/index.module.css

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.sidebarButton {
22
height: 2rem;
3-
margin: 2px;
3+
margin: 2px 0;
44
padding: 3px;
55
background-color: var(--bg-primary);
66
color: var(--text-primary);
@@ -24,17 +24,27 @@
2424
background-color: var(--bg-secondary);
2525
}
2626

27+
.titleContainer {
28+
flex: 1;
29+
height: 100%;
30+
padding-left: 1rem;
31+
display: flex;
32+
justify-content: left;
33+
align-items: center;
34+
overflow: hidden;
35+
cursor: pointer;
36+
}
37+
2738
.chatTitle {
28-
margin-left: 5px;
39+
display: inline-block;
2940
/* line-height should be equal to height */
3041
height: 1.3rem;
3142
line-height: 1.3rem;
3243
color: var(--text-primary);
3344
border: none;
3445
text-align: left;
35-
/* the following 4 lines ellipsis text */
46+
/* the following 3 lines ellipsis text */
3647
/* See <https://stackoverflow.com/a/17783233/6564721> */
37-
width: 200px;
3848
white-space: nowrap;
3949
overflow: hidden;
4050
text-overflow: ellipsis;

web/src/routes/root/Sidebar/index.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import styles from "./index.module.css";
22

33
import { useContext } from "react";
4-
import { Link } from "react-router-dom";
4+
import { useNavigate } from "react-router-dom";
55
import PropTypes from "prop-types";
66

77
import AddOutlinedIcon from "@mui/icons-material/AddOutlined";
@@ -16,13 +16,14 @@ import ChatTab from "../ChatTab";
1616

1717
const Sidebar = ({ onShareClick, onDeleteClick }) => {
1818
const { groupedConvs } = useContext(ConversationContext);
19+
const navigate = useNavigate();
1920

2021
return (
2122
<aside className={styles.sidebar}>
22-
<Link className={styles.sidebarButton} to="/">
23+
<button className={styles.sidebarButton} onClick={() => navigate("/")}>
2324
<AddOutlinedIcon />
2425
New Chat
25-
</Link>
26+
</button>
2627
<nav className={styles.convList}>
2728
{groupedConvs && Object.entries(groupedConvs)
2829
.filter(([, convs]) => convs && convs.length > 0) // Filter out empty lists
@@ -60,5 +61,4 @@ Sidebar.propTypes = {
6061
onDeleteClick: PropTypes.func.isRequired,
6162
};
6263

63-
6464
export default Sidebar;

0 commit comments

Comments
 (0)