diff --git a/src/app/(main)/SideNav.tsx b/src/app/(main)/SideNav.tsx
index a16970875..360c0c1dd 100644
--- a/src/app/(main)/SideNav.tsx
+++ b/src/app/(main)/SideNav.tsx
@@ -13,6 +13,7 @@ import { SettingsNav } from '@/app/(main)/settings/SettingsNav';
import { WebsiteNav } from '@/app/(main)/websites/[websiteId]/WebsiteNav';
import { IconLabel } from '@/components/common/IconLabel';
import Link from '@/components/common/Link';
+import { OverlayScrollArea } from '@/components/common/OverlayScrollArea';
import { useGlobalState, useMessages, useNavigation } from '@/components/hooks';
import {
Globe,
@@ -103,7 +104,7 @@ export function SideNav(props: any) {
-
+
{websiteId ? (
) : pathname.includes('/settings') ? (
@@ -147,7 +148,7 @@ export function SideNav(props: any) {
})}
)}
-
+
-
+
+
+
diff --git a/src/app/global.css b/src/app/global.css
index ef8ce56bd..a9e21cd40 100644
--- a/src/app/global.css
+++ b/src/app/global.css
@@ -18,29 +18,6 @@ html[style*="padding-right"] {
padding-right: 0 !important;
}
-::-webkit-scrollbar {
- width: 15px;
- background: transparent;
-}
-
-::-webkit-scrollbar-track {
- border: 7px solid rgba(0, 0, 0, 0);
- background-color: var(--border-default);
- background-clip: padding-box;
-}
-
-::-webkit-scrollbar-thumb {
- border: 7px solid rgba(0, 0, 0, 0);
- background-color: var(--text-disabled);
- border-radius: var(--border-radius-full);
- background-clip: padding-box;
-}
-
-::-webkit-scrollbar-thumb:hover {
- border: 4px solid rgba(0, 0, 0, 0);
- background-clip: padding-box;
-}
-
/* Fix autofill background color to match theme */
input:is(:-webkit-autofill, :autofill),
input:is(:-webkit-autofill, :autofill):hover,
diff --git a/src/components/common/NavMenu.tsx b/src/components/common/NavMenu.tsx
index 75c9c35b8..3c7ea6361 100644
--- a/src/components/common/NavMenu.tsx
+++ b/src/components/common/NavMenu.tsx
@@ -52,17 +52,17 @@ export function NavMenu({
};
return (
-
+
{title && (
{title}
)}
-
+
{items?.map(({ label, items }, index) => {
if (label) {
return (
-
+
{label}
diff --git a/src/components/common/OverlayScrollArea.module.css b/src/components/common/OverlayScrollArea.module.css
new file mode 100644
index 000000000..ae1ead9bf
--- /dev/null
+++ b/src/components/common/OverlayScrollArea.module.css
@@ -0,0 +1,45 @@
+.root {
+ --overlay-scrollbar-track: var(--gray-50);
+ --overlay-scrollbar-thumb: var(--gray-300);
+ --overlay-scrollbar-thumb-hover: var(--gray-400);
+}
+
+.root > [data-orientation="vertical"] {
+ width: 4px;
+ margin: 16px 2px;
+ background-color: var(--overlay-scrollbar-track);
+}
+
+.root > [data-orientation="horizontal"] {
+ height: 4px;
+ margin: 2px 16px;
+ background-color: var(--overlay-scrollbar-track);
+}
+
+.root > [data-orientation] > div {
+ position: relative;
+ background-color: var(--overlay-scrollbar-thumb);
+}
+
+.root > [data-orientation] > div:hover,
+.root > [data-orientation] > div:active {
+ background-color: var(--overlay-scrollbar-thumb-hover);
+}
+
+.root > [data-orientation="vertical"] > div::before {
+ position: absolute;
+ inset: 0 -4px;
+ content: "";
+}
+
+.root > [data-orientation="horizontal"] > div::before {
+ position: absolute;
+ inset: -4px 0;
+ content: "";
+}
+
+:global([data-theme="dark"]) .root {
+ --overlay-scrollbar-track: var(--gray-800);
+ --overlay-scrollbar-thumb: var(--gray-600);
+ --overlay-scrollbar-thumb-hover: var(--gray-500);
+}
diff --git a/src/components/common/OverlayScrollArea.tsx b/src/components/common/OverlayScrollArea.tsx
new file mode 100644
index 000000000..4abd41ccf
--- /dev/null
+++ b/src/components/common/OverlayScrollArea.tsx
@@ -0,0 +1,6 @@
+import { cn, type ScrollAreaProps, ScrollArea as ZenScrollArea } from '@umami/react-zen';
+import styles from './OverlayScrollArea.module.css';
+
+export function OverlayScrollArea({ className, ...props }: ScrollAreaProps) {
+ return ;
+}
diff --git a/src/components/metrics/MetricsExpandedTable.tsx b/src/components/metrics/MetricsExpandedTable.tsx
index 96facd6d8..bba92420d 100644
--- a/src/components/metrics/MetricsExpandedTable.tsx
+++ b/src/components/metrics/MetricsExpandedTable.tsx
@@ -1,6 +1,7 @@
import { Button, Column, DataColumn, DataTable, Icon, Row, SearchField } from '@umami/react-zen';
import { type ReactNode, useState } from 'react';
import { LoadingPanel } from '@/components/common/LoadingPanel';
+import { OverlayScrollArea } from '@/components/common/OverlayScrollArea';
import { useMessages, useWebsiteExpandedMetricsQuery } from '@/components/hooks';
import { X } from '@/components/icons';
import { DownloadButton } from '@/components/input/DownloadButton';
@@ -76,55 +77,57 @@ export function MetricsExpandedTable({
height="100%"
loadingIcon="spinner"
>
-
- {items && (
-
-
- {row => (
-
-
-
- )}
-
-
- {row => row?.visitors?.toLocaleString()}
-
-
- {row => row?.visits?.toLocaleString()}
-
-
- {row => row?.pageviews?.toLocaleString()}
-
- {showBounceDuration && [
-
- {row => {
- const n = (Math.min(row?.visits, row?.bounces) / row?.visits) * 100;
- return `${Math.round(+n)}%`;
- }}
- ,
+
+
+ {items && (
+
+
+ {row => (
+
+
+
+ )}
+
+
+ {row => row?.visitors?.toLocaleString()}
+
+
+ {row => row?.visits?.toLocaleString()}
+
+
+ {row => row?.pageviews?.toLocaleString()}
+
+ {showBounceDuration && [
+
+ {row => {
+ const n = (Math.min(row?.visits, row?.bounces) / row?.visits) * 100;
+ return `${Math.round(+n)}%`;
+ }}
+ ,
-
- {row => {
- const n = row?.totaltime / row?.visits;
- return `${+n < 0 ? '-' : ''}${formatShortTime(Math.abs(~~n), ['m', 's'], ' ')}`;
- }}
- ,
- ]}
-
- )}
-
+
+ {row => {
+ const n = row?.totaltime / row?.visits;
+ return `${+n < 0 ? '-' : ''}${formatShortTime(Math.abs(~~n), ['m', 's'], ' ')}`;
+ }}
+ ,
+ ]}
+
+ )}
+
+
>
);