re-implemented horizontal scroll for the bins list with a new package

This commit is contained in:
csawatzky 2025-03-11 15:52:20 -06:00
parent 8df5b5e602
commit d4bd6941d4
4 changed files with 119 additions and 17 deletions

46
package-lock.json generated
View file

@ -33,6 +33,7 @@
"react-color": "^2.19.3", "react-color": "^2.19.3",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-error-boundary": "^5.0.0", "react-error-boundary": "^5.0.0",
"react-horizontal-scrolling-menu": "^7.1.1",
"react-image": "^4.1.0", "react-image": "^4.1.0",
"react-infinite-scroller": "^1.2.6", "react-infinite-scroller": "^1.2.6",
"react-phone-input-2": "^2.15.1", "react-phone-input-2": "^2.15.1",
@ -4499,6 +4500,12 @@
"node": ">=4.0.0" "node": ">=4.0.0"
} }
}, },
"node_modules/compute-scroll-into-view": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz",
"integrity": "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==",
"license": "MIT"
},
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -7428,6 +7435,27 @@
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/react-horizontal-scrolling-menu": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/react-horizontal-scrolling-menu/-/react-horizontal-scrolling-menu-7.1.1.tgz",
"integrity": "sha512-g93/9RM4io8CHoyiZO+KBlBg5k/zlmzYe+d1Wln2XcTG7TKq60gwqR9toyBFnYW8x6Xk2tmvEXi5Y8dE40YkEw==",
"license": "MIT",
"dependencies": {
"smooth-scroll-into-view-if-needed": "^2.0.2"
},
"engines": {
"node": ">=18",
"npm": ">=9.5.0"
},
"funding": {
"type": "patreon",
"url": "https://patreon.com/asmyshlyaev177"
},
"peerDependencies": {
"react": ">=16.8",
"react-dom": ">=16.8"
}
},
"node_modules/react-image": { "node_modules/react-image": {
"version": "4.1.0", "version": "4.1.0",
"integrity": "sha512-qwPNlelQe9Zy14K2pGWSwoL+vHsAwmJKS6gkotekDgRpcnRuzXNap00GfibD3eEPYu3WCPlyIUUNzcyHOrLHjw==", "integrity": "sha512-qwPNlelQe9Zy14K2pGWSwoL+vHsAwmJKS6gkotekDgRpcnRuzXNap00GfibD3eEPYu3WCPlyIUUNzcyHOrLHjw==",
@ -7916,6 +7944,15 @@
"loose-envify": "^1.1.0" "loose-envify": "^1.1.0"
} }
}, },
"node_modules/scroll-into-view-if-needed": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz",
"integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==",
"license": "MIT",
"dependencies": {
"compute-scroll-into-view": "^3.0.2"
}
},
"node_modules/semver": { "node_modules/semver": {
"version": "6.3.1", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@ -8094,6 +8131,15 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/smooth-scroll-into-view-if-needed": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/smooth-scroll-into-view-if-needed/-/smooth-scroll-into-view-if-needed-2.0.2.tgz",
"integrity": "sha512-z54WzUSlM+xHHvJu3lMIsh+1d1kA4vaakcAtQvqzeGJ5Ffau7EKjpRrMHh1/OBo5zyU2h30ZYEt77vWmPHqg7Q==",
"license": "MIT",
"dependencies": {
"scroll-into-view-if-needed": "^3.1.0"
}
},
"node_modules/source-map": { "node_modules/source-map": {
"version": "0.5.7", "version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",

View file

@ -43,6 +43,7 @@
"react-color": "^2.19.3", "react-color": "^2.19.3",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-error-boundary": "^5.0.0", "react-error-boundary": "^5.0.0",
"react-horizontal-scrolling-menu": "^7.1.1",
"react-image": "^4.1.0", "react-image": "^4.1.0",
"react-infinite-scroller": "^1.2.6", "react-infinite-scroller": "^1.2.6",
"react-phone-input-2": "^2.15.1", "react-phone-input-2": "^2.15.1",

View file

@ -6,22 +6,24 @@ import {
Typography Typography
} from "@mui/material"; } from "@mui/material";
import { Bin } from "models"; import { Bin } from "models";
import React, { useRef, useState } from "react"; import React, { useContext, useRef, useState } from "react";
// import ScrollMenu from "react-horizontal-scroll-menu"; // import ScrollMenu from "react-horizontal-scroll-menu";
// import { useHistory } from "react-router"; // import { useHistory } from "react-router";
import { ArrowForward, ArrowBack } from "@mui/icons-material"; import { ArrowForward, ArrowBack, Replay } from "@mui/icons-material";
import { useMobile } from "hooks"; import { useMobile } from "hooks";
import BinCardV2 from "./BinCardV2"; import BinCardV2 from "./BinCardV2";
import { makeStyles } from "@mui/styles"; import { makeStyles } from "@mui/styles";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { publicApiType, ScrollMenu, VisibilityContext } from "react-horizontal-scrolling-menu";
import 'react-horizontal-scrolling-menu/dist/styles.css';
interface Props { interface Props {
bins: Bin[]; bins: Bin[];
duplicateBin: (bin: Bin) => void; duplicateBin: (bin: Bin) => void;
title?: string; title?: string;
gridView?: boolean; gridView?: boolean;
loadMore?: (newTranslation: number) => void; loadMore?: () => void;
startingTranslate: number; //startingTranslate: number;
valDisplay?: "high" | "low" | "average"; valDisplay?: "high" | "low" | "average";
} }
@ -29,9 +31,9 @@ const useStyles = makeStyles((theme: Theme) => {
return ({ return ({
gridListTile: { gridListTile: {
position: "relative", position: "relative",
minHeight: "184px", minHeight: "233px",
height: "auto !important", height: "auto !important",
//width: "184px", width: "184px",
padding: 2 padding: 2
}, },
hidden: { hidden: {
@ -41,13 +43,13 @@ const useStyles = makeStyles((theme: Theme) => {
}); });
export default function BinsList(props: Props) { export default function BinsList(props: Props) {
const { bins, duplicateBin, title, gridView, loadMore, startingTranslate, valDisplay } = props; const { bins, duplicateBin, title, gridView, loadMore, valDisplay } = props;
const classes = useStyles(); const classes = useStyles();
// const history = useHistory(); // const history = useHistory();
const navigate = useNavigate() const navigate = useNavigate()
const isMobile = useMobile(); const isMobile = useMobile();
const [duplicate, setDuplicate] = useState(false); const [duplicate, setDuplicate] = useState(false);
const scrollRef = useRef<any>(null); //const scrollRef = useRef<any>(null);
const goToBin = (i: number) => { const goToBin = (i: number) => {
let path = "/bins/" + bins[i].key(); let path = "/bins/" + bins[i].key();
@ -101,6 +103,59 @@ export default function BinsList(props: Props) {
// ); // );
// }; // };
const leftArrow = () => {
const visibility = useContext(VisibilityContext);
//const isFirstVisible = visibility.useIsVisible('first', false)
return (
<Button onClick={() => visibility.scrollPrev()} style={{ height: 233, display: isMobile ? "none" : "block" }}>
<ArrowBack />
</Button>
)
}
const rightArrow = () => {
const visibility = useContext(VisibilityContext);
const isLastVisible = visibility.useIsVisible('last', false)
return (
<Button
style={{ height: 233, display: isMobile ? "none" : "block" }}
onClick={() => {
if (isLastVisible) {
loadMore && loadMore()
}else {
visibility.scrollNext()
}
}}>
{isLastVisible ? <Replay /> : <ArrowForward />}
</Button>
)
}
const scroll = () => {
//const visibility = useContext(VisibilityContext);
return (
<ScrollMenu
LeftArrow={leftArrow}
RightArrow={rightArrow}>
{bins.map((b, i) => (
<Box
key={i}
className={classes.gridListTile}
onClick={() => {
//!duplicate && goToBin(i)
}}>
<BinCardV2
bin={b}
duplicateBin={duplicateBin}
dupHovered={setDuplicate}
valDisplay={valDisplay}
/>
</Box>
))}
</ScrollMenu>
)
}
const grid = () => { const grid = () => {
return ( return (
<Grid container direction="row"> <Grid container direction="row">
@ -146,7 +201,8 @@ export default function BinsList(props: Props) {
<React.Fragment> <React.Fragment>
{title && <Typography>{title}</Typography>} {title && <Typography>{title}</Typography>}
{/* {gridView ? grid() : scroll()} */} {/* {gridView ? grid() : scroll()} */}
{grid()} {/* {grid()} */}
{scroll()}
</React.Fragment> </React.Fragment>
); );
} }

View file

@ -192,11 +192,11 @@ export default function Bins(props: Props) {
// const history = useHistory(); // const history = useHistory();
const navigate = useNavigate() const navigate = useNavigate()
const [cardValDisplay, setCardValDisplay] = useState<"high" | "low" | "average">("average"); const [cardValDisplay, setCardValDisplay] = useState<"high" | "low" | "average">("average");
const [scrollTranslations, setScrollTranslations] = useState({ // const [scrollTranslations, setScrollTranslations] = useState({
bins: 0, // bins: 0,
empty: 0, // empty: 0,
fertilizer: 0 // fertilizer: 0
}); // });
// const StyledToggleButtonGroup = withStyles(theme => ({ // const StyledToggleButtonGroup = withStyles(theme => ({
// grouped: { // grouped: {
@ -621,11 +621,10 @@ export default function Bins(props: Props) {
bins={grainBins} bins={grainBins}
duplicateBin={duplicateBin} duplicateBin={duplicateBin}
title={"Grain Bins"} title={"Grain Bins"}
startingTranslate={scrollTranslations.bins} //startingTranslate={scrollTranslations.bins}
loadMore={newTranslation => { loadMore={() => {
if (paginatedBins.bins.length < paginatedBins.binsTotal) { if (paginatedBins.bins.length < paginatedBins.binsTotal) {
loadMoreBins(contentFilter, paginatedBins.binsOffset); loadMoreBins(contentFilter, paginatedBins.binsOffset);
setScrollTranslations({ ...scrollTranslations, bins: newTranslation });
} }
}} }}
/> />