update: show scroll arrows on narrow displays
This commit is contained in:
committed by
Nicolás Hatcher Andrés
parent
7bcd978998
commit
6c27ae1355
@@ -14,6 +14,8 @@ import {
|
||||
ArrowUpToLine,
|
||||
Bold,
|
||||
ChevronDown,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
DecimalsArrowLeft,
|
||||
DecimalsArrowRight,
|
||||
Euro,
|
||||
@@ -36,7 +38,7 @@ import {
|
||||
Undo2,
|
||||
WrapText,
|
||||
} from "lucide-react";
|
||||
import { useRef, useState } from "react";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ArrowMiddleFromLine } from "../../icons";
|
||||
import { theme } from "../../theme";
|
||||
@@ -94,17 +96,51 @@ function Toolbar(properties: ToolbarProperties) {
|
||||
const [fillColorPickerOpen, setFillColorPickerOpen] = useState(false);
|
||||
const [borderPickerOpen, setBorderPickerOpen] = useState(false);
|
||||
const [nameManagerDialogOpen, setNameManagerDialogOpen] = useState(false);
|
||||
const [showLeftArrow, setShowLeftArrow] = useState(false);
|
||||
const [showRightArrow, setShowRightArrow] = useState(false);
|
||||
|
||||
const fontColorButton = useRef(null);
|
||||
const fillColorButton = useRef(null);
|
||||
const borderButton = useRef(null);
|
||||
const toolbarRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { canEdit } = properties;
|
||||
|
||||
const scrollLeft = () =>
|
||||
toolbarRef.current?.scrollBy({ left: -200, behavior: "smooth" });
|
||||
const scrollRight = () =>
|
||||
toolbarRef.current?.scrollBy({ left: 200, behavior: "smooth" });
|
||||
|
||||
const updateArrows = useCallback(() => {
|
||||
if (!toolbarRef.current) return;
|
||||
const { scrollLeft, scrollWidth, clientWidth } = toolbarRef.current;
|
||||
setShowLeftArrow(scrollLeft > 0);
|
||||
setShowRightArrow(scrollLeft < scrollWidth - clientWidth);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const toolbar = toolbarRef.current;
|
||||
if (!toolbar) return;
|
||||
|
||||
updateArrows();
|
||||
toolbar.addEventListener("scroll", updateArrows);
|
||||
return () => toolbar.removeEventListener("scroll", updateArrows);
|
||||
}, [updateArrows]);
|
||||
|
||||
return (
|
||||
<ToolbarContainer>
|
||||
<ToolbarWrapper>
|
||||
{showLeftArrow && (
|
||||
<ScrollArrow
|
||||
$direction="left"
|
||||
onClick={scrollLeft}
|
||||
title={t("toolbar.scroll_left")}
|
||||
>
|
||||
<ChevronLeft />
|
||||
</ScrollArrow>
|
||||
)}
|
||||
<ToolbarContainer ref={toolbarRef}>
|
||||
{/* History/Edit Group */}
|
||||
<ButtonGroup>
|
||||
<StyledButton
|
||||
@@ -514,23 +550,40 @@ function Toolbar(properties: ToolbarProperties) {
|
||||
model={properties.nameManagerProperties}
|
||||
/>
|
||||
</ToolbarContainer>
|
||||
{showRightArrow && (
|
||||
<ScrollArrow
|
||||
$direction="right"
|
||||
onClick={scrollRight}
|
||||
title={t("toolbar.scroll_right")}
|
||||
>
|
||||
<ChevronRight />
|
||||
</ScrollArrow>
|
||||
)}
|
||||
</ToolbarWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const ToolbarContainer = styled("div")`
|
||||
const ToolbarWrapper = styled("div")`
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
background: ${({ theme }) => theme.palette.background.paper};
|
||||
height: ${TOOLBAR_HEIGHT}px;
|
||||
line-height: ${TOOLBAR_HEIGHT}px;
|
||||
border-bottom: 1px solid ${({ theme }) => theme.palette.grey["300"]};
|
||||
font-family: Inter;
|
||||
border-radius: 4px 4px 0px 0px;
|
||||
`;
|
||||
|
||||
const ToolbarContainer = styled("div")`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
overflow-x: auto;
|
||||
padding: 0px 12px;
|
||||
gap: 4px;
|
||||
scrollbar-width: none;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
type TypeButtonProperties = { $pressed: boolean };
|
||||
@@ -617,4 +670,33 @@ const ButtonGroup = styled("div")({
|
||||
gap: "4px",
|
||||
});
|
||||
|
||||
type ScrollArrowProps = { $direction: "left" | "right" };
|
||||
const ScrollArrow = styled("button", {
|
||||
shouldForwardProp: (prop) => prop !== "$direction",
|
||||
})<ScrollArrowProps>(({ $direction }) => ({
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
transform: "translateY(-50%)",
|
||||
[$direction]: "0px",
|
||||
zIndex: 10,
|
||||
width: "24px",
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
backgroundColor: "white",
|
||||
border:
|
||||
$direction === "left"
|
||||
? `none; border-right: 1px solid ${theme.palette.grey["300"]};`
|
||||
: `none; border-left: 1px solid ${theme.palette.grey["300"]};`,
|
||||
cursor: "pointer",
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.grey["100"],
|
||||
},
|
||||
svg: {
|
||||
width: "16px",
|
||||
height: "16px",
|
||||
},
|
||||
}));
|
||||
|
||||
export default Toolbar;
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
"vertical_align_top": "Align top",
|
||||
"selected_png": "Export Selected area as PNG",
|
||||
"wrap_text": "Wrap text",
|
||||
"scroll_left": "Scroll left",
|
||||
"scroll_right": "Scroll right",
|
||||
"format_menu": {
|
||||
"auto": "Auto",
|
||||
"number": "Number",
|
||||
|
||||
Reference in New Issue
Block a user