mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-02-24 12:12:54 +01:00
web: fix scrollbar styling in sidebar
This commit is contained in:
@@ -33,10 +33,11 @@ import {
|
||||
} from "./list-profiles";
|
||||
import Announcements from "../announcements";
|
||||
import { ListLoader } from "../loaders/list-loader";
|
||||
import ScrollContainer from "../scroll-container";
|
||||
import ScrollContainer, { ScrollContainerProps } from "../scroll-container";
|
||||
import { useKeyboardListNavigation } from "../../hooks/use-keyboard-list-navigation";
|
||||
import { VirtualizedGrouping, GroupingKey, Item } from "@notesnook/core";
|
||||
import {
|
||||
Components,
|
||||
FlatScrollIntoViewLocation,
|
||||
ItemProps,
|
||||
ScrollerProps,
|
||||
@@ -49,8 +50,9 @@ import { AppEventManager, AppEvents } from "../../common/app-events";
|
||||
|
||||
export const CustomScrollbarsVirtualList = forwardRef<
|
||||
HTMLDivElement,
|
||||
ScrollerProps
|
||||
ScrollerProps & ScrollContainerProps
|
||||
>(function CustomScrollbarsVirtualList(props, ref) {
|
||||
console.log({ props, ref });
|
||||
return (
|
||||
<ScrollContainer
|
||||
{...props}
|
||||
@@ -76,10 +78,21 @@ type ListContainerProps = {
|
||||
button?: {
|
||||
onClick: () => void;
|
||||
};
|
||||
Scroller?: Components["Scroller"];
|
||||
} & SxProp;
|
||||
function ListContainer(props: ListContainerProps) {
|
||||
const { type, group, items, context, refresh, header, button, compact, sx } =
|
||||
props;
|
||||
const {
|
||||
type,
|
||||
group,
|
||||
items,
|
||||
context,
|
||||
refresh,
|
||||
header,
|
||||
button,
|
||||
compact,
|
||||
sx,
|
||||
Scroller
|
||||
} = props;
|
||||
|
||||
const [focusedGroupIndex, setFocusedGroupIndex] = useState(-1);
|
||||
|
||||
@@ -213,7 +226,7 @@ function ListContainer(props: ListContainerProps) {
|
||||
onBlur={() => setFocusedGroupIndex(-1)}
|
||||
onKeyDown={(e) => onKeyDown(e.nativeEvent)}
|
||||
components={{
|
||||
Scroller: CustomScrollbarsVirtualList,
|
||||
Scroller: Scroller || CustomScrollbarsVirtualList,
|
||||
Item: VirtuosoItem,
|
||||
Header: ListHeader
|
||||
}}
|
||||
|
||||
@@ -21,28 +21,30 @@ import React, { PropsWithChildren, useLayoutEffect } from "react";
|
||||
import { MacScrollbar, MacScrollbarProps } from "mac-scrollbar";
|
||||
import "mac-scrollbar/dist/mac-scrollbar.css";
|
||||
|
||||
type ScrollContainerProps = {
|
||||
export type ScrollContainerProps = {
|
||||
style?: React.CSSProperties;
|
||||
forwardedRef?: (ref: HTMLDivElement | null) => void;
|
||||
};
|
||||
} & MacScrollbarProps;
|
||||
|
||||
const ScrollContainer = ({
|
||||
children,
|
||||
forwardedRef,
|
||||
style,
|
||||
...props
|
||||
}: PropsWithChildren<ScrollContainerProps>) => {
|
||||
return (
|
||||
<MacScrollbar
|
||||
suppressScrollX
|
||||
minThumbSize={40}
|
||||
{...props}
|
||||
ref={(div) => {
|
||||
forwardedRef && forwardedRef(div as HTMLDivElement);
|
||||
}}
|
||||
style={{
|
||||
position: "relative",
|
||||
height: "100%"
|
||||
height: "100%",
|
||||
...style
|
||||
}}
|
||||
suppressScrollX
|
||||
minThumbSize={40}
|
||||
>
|
||||
{children}
|
||||
</MacScrollbar>
|
||||
|
||||
41
apps/web/src/components/sidebar-scroller.tsx
Normal file
41
apps/web/src/components/sidebar-scroller.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { forwardRef } from "react";
|
||||
import { ScrollerProps } from "react-virtuoso";
|
||||
import ScrollContainer from "./scroll-container";
|
||||
|
||||
export const SidebarScroller = forwardRef<HTMLDivElement, ScrollerProps>(
|
||||
function CustomScroller(props, ref) {
|
||||
return (
|
||||
<ScrollContainer
|
||||
{...props}
|
||||
trackStyle={() => ({
|
||||
width: 3
|
||||
})}
|
||||
thumbStyle={() => ({ width: 3 })}
|
||||
suppressScrollX={true}
|
||||
forwardedRef={(sRef) => {
|
||||
if (typeof ref === "function") ref(sRef);
|
||||
else if (ref) ref.current = sRef;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -19,7 +19,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { useEffect, useImperativeHandle, useRef, useState } from "react";
|
||||
import { usePersistentState } from "../../hooks/use-persistent-state";
|
||||
import { ItemProps, Virtuoso, VirtuosoHandle } from "react-virtuoso";
|
||||
import {
|
||||
Components,
|
||||
ItemProps,
|
||||
Virtuoso,
|
||||
VirtuosoHandle
|
||||
} from "react-virtuoso";
|
||||
import { useKeyboardListNavigation } from "../../hooks/use-keyboard-list-navigation";
|
||||
import { CustomScrollbarsVirtualList, waitForElement } from "../list-container";
|
||||
|
||||
@@ -58,6 +63,8 @@ type TreeViewProps<T> = {
|
||||
deselectAll?: () => void;
|
||||
isSelected?: (id: string) => boolean;
|
||||
style?: React.CSSProperties;
|
||||
|
||||
Scroller?: Components["Scroller"];
|
||||
};
|
||||
export function VirtualizedTree<T>(props: TreeViewProps<T>) {
|
||||
const {
|
||||
@@ -75,7 +82,7 @@ export function VirtualizedTree<T>(props: TreeViewProps<T>) {
|
||||
deselectAll,
|
||||
bulkSelect,
|
||||
testId,
|
||||
style
|
||||
Scroller
|
||||
} = props;
|
||||
const [nodes, setNodes] = useState<TreeNode<T>[]>([]);
|
||||
const [expandedIds, setExpandedIds] = usePersistentState<ExpandedIds>(
|
||||
@@ -205,7 +212,7 @@ export function VirtualizedTree<T>(props: TreeViewProps<T>) {
|
||||
onMouseUp
|
||||
}}
|
||||
components={{
|
||||
Scroller: CustomScrollbarsVirtualList,
|
||||
Scroller: (Scroller as any) || CustomScrollbarsVirtualList,
|
||||
Item: VirtuosoItem,
|
||||
EmptyPlaceholder: Placeholder
|
||||
}}
|
||||
|
||||
@@ -19,7 +19,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { Notebook as NotebookType, VirtualizedGrouping } from "@notesnook/core";
|
||||
import { Box, Flex, Input, Text } from "@theme-ui/components";
|
||||
import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
||||
import {
|
||||
forwardRef,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState
|
||||
} from "react";
|
||||
import { db } from "../common/db";
|
||||
import { store, useStore } from "../stores/notebook-store";
|
||||
import { useStore as useSelectionStore } from "../stores/selection-store";
|
||||
@@ -33,6 +39,10 @@ import {
|
||||
import { ListLoader } from "../components/loaders/list-loader";
|
||||
import { debounce } from "@notesnook/common";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { CustomScrollbarsVirtualList } from "../components/list-container";
|
||||
import { ScrollerProps } from "react-virtuoso";
|
||||
import ScrollContainer from "../components/scroll-container";
|
||||
import { SidebarScroller } from "../components/sidebar-scroller";
|
||||
|
||||
export function Notebooks() {
|
||||
const roots = useStore((store) => store.notebooks);
|
||||
@@ -81,7 +91,16 @@ export function Notebooks() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box id="notebooks" sx={{ mx: 1, flex: 1 }}>
|
||||
<Box
|
||||
id="notebooks"
|
||||
sx={{
|
||||
flex: 1,
|
||||
'[data-viewport-type="element"]': {
|
||||
px: 1,
|
||||
width: `calc(100% - ${2 * 6}px) !important`
|
||||
}
|
||||
}}
|
||||
>
|
||||
<VirtualizedTree
|
||||
testId="notebooks-list"
|
||||
rootId={"root"}
|
||||
@@ -153,6 +172,7 @@ export function Notebooks() {
|
||||
expand={expand}
|
||||
/>
|
||||
)}
|
||||
Scroller={SidebarScroller}
|
||||
/>
|
||||
</Box>
|
||||
<Input
|
||||
|
||||
@@ -23,9 +23,12 @@ import Placeholder from "../components/placeholders";
|
||||
import { db } from "../common/db";
|
||||
import { ListLoader } from "../components/loaders/list-loader";
|
||||
import { Flex, Input } from "@theme-ui/components";
|
||||
import { useEffect, useState } from "react";
|
||||
import { forwardRef, useEffect, useState } from "react";
|
||||
import { debounce } from "@notesnook/common";
|
||||
import { Tag, VirtualizedGrouping } from "@notesnook/core";
|
||||
import ScrollContainer from "../components/scroll-container";
|
||||
import { ScrollerProps } from "react-virtuoso";
|
||||
import { SidebarScroller } from "../components/sidebar-scroller";
|
||||
|
||||
function Tags() {
|
||||
const tags = useStore((store) => store.tags);
|
||||
@@ -39,14 +42,24 @@ function Tags() {
|
||||
|
||||
if (!items) return <ListLoader />;
|
||||
return (
|
||||
<Flex variant="columnFill" id="tags">
|
||||
<Flex
|
||||
variant="columnFill"
|
||||
id="tags"
|
||||
sx={{
|
||||
flex: 1,
|
||||
'[data-viewport-type="element"]': {
|
||||
px: 1,
|
||||
width: `calc(100% - ${2 * 6}px) !important`
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ListContainer
|
||||
type="tags"
|
||||
sx={{ mx: 1 }}
|
||||
refresh={refresh}
|
||||
items={items}
|
||||
placeholder={<Placeholder context="tags" />}
|
||||
header={<></>}
|
||||
Scroller={SidebarScroller}
|
||||
/>
|
||||
<Input
|
||||
variant="clean"
|
||||
|
||||
Reference in New Issue
Block a user