diff --git a/frontend/src/layout/navigation-3000/Navigation.scss b/frontend/src/layout/navigation-3000/Navigation.scss
index 6a9f62270700a..5983884d0eb7e 100644
--- a/frontend/src/layout/navigation-3000/Navigation.scss
+++ b/frontend/src/layout/navigation-3000/Navigation.scss
@@ -619,11 +619,6 @@
.SidebarListItem__icon {
flex-shrink: 0;
}
-
- .SidebarListItem__name {
- overflow: hidden;
- text-overflow: ellipsis;
- }
}
.SidebarListItem__rename {
diff --git a/frontend/src/layout/navigation-3000/components/SearchHighlight.tsx b/frontend/src/layout/navigation-3000/components/SearchHighlight.tsx
new file mode 100644
index 0000000000000..3c8c785433695
--- /dev/null
+++ b/frontend/src/layout/navigation-3000/components/SearchHighlight.tsx
@@ -0,0 +1,29 @@
+interface Props {
+ string: string
+ substring: string
+ className?: string
+}
+
+/**
+ * Highlight a substring within a string (case-insensitive)
+ * @param string - the aggregate string to search within (e.g. "Hello, world!")
+ * @param substring - the substring to search for (e.g. "world")
+ * @param className - additional classes to apply to the component
+ */
+export default function SearchHighlight({ string, substring, className }: Props): JSX.Element {
+ const parts = string.split(new RegExp(`(${substring})`, 'gi'))
+ return (
+
+ {parts.map((part, index) => (
+
+ {part}
+
+ ))}
+
+ )
+}
diff --git a/frontend/src/layout/navigation-3000/components/SidebarList.tsx b/frontend/src/layout/navigation-3000/components/SidebarList.tsx
index b002c2d2f504b..72decf9b4642d 100644
--- a/frontend/src/layout/navigation-3000/components/SidebarList.tsx
+++ b/frontend/src/layout/navigation-3000/components/SidebarList.tsx
@@ -15,6 +15,8 @@ import { AutoSizer } from 'react-virtualized/dist/es/AutoSizer'
import { InfiniteLoader } from 'react-virtualized/dist/es/InfiniteLoader'
import { List, ListProps } from 'react-virtualized/dist/es/List'
+import SearchHighlight from '~/layout/navigation-3000/components/SearchHighlight'
+
import { ITEM_KEY_PART_SEPARATOR, navigation3000Logic } from '../navigationLogic'
import {
BasicListItem,
@@ -305,7 +307,7 @@ function SidebarListItem({ item, validateName, active, style }: SidebarListItemP
style={{ '--depth': item.depth } as React.CSSProperties}
>
{item.icon && {item.icon}
}
- {item.name}
+
)
} else if (!save || (!isItemTentative(item) && newName === null)) {
@@ -313,7 +315,7 @@ function SidebarListItem({ item, validateName, active, style }: SidebarListItemP
throw new Error('Tentative items should not be rendered in read mode')
}
let formattedName = item.searchMatch?.nameHighlightRanges?.length ? (
- {item.name}
+
) : (
item.name
)
@@ -495,40 +497,6 @@ function SidebarListItem({ item, validateName, active, style }: SidebarListItemP
)
}
-/** Text with specified ranges highlighted by increased font weight. Great for higlighting search term matches. */
-function TextWithHighlights({
- children,
- ranges,
-}: {
- children: string
- ranges: readonly [number, number][]
-}): JSX.Element {
- const segments: JSX.Element[] = []
- let previousBoldEnd = 0
- let segmentIndex = 0
- // Divide the item name into bold and regular segments
- for (let i = 0; i < ranges.length; i++) {
- const [currentBoldStart, currentBoldEnd] = ranges[i]
- if (currentBoldStart > previousBoldEnd) {
- segments.push(
- {children.slice(previousBoldEnd, currentBoldStart)}
- )
- segmentIndex++
- }
- segments.push({children.slice(currentBoldStart, currentBoldEnd)})
- segmentIndex++
- previousBoldEnd = currentBoldEnd
- }
- // If there is a non-highlighted segment left at the end, add it now
- if (previousBoldEnd < children.length) {
- segments.push(
- {children.slice(previousBoldEnd, children.length)}
- )
- }
-
- return <>{segments}>
-}
-
/** Smart rendering of list item extra context. */
function ExtraContext({ data }: { data: ExtraListItemContext }): JSX.Element {
return isDayjs(data) ? : <>{data}>