diff --git a/src/components/GensploreView.js b/src/components/GensploreView.js index 994c4a6..64ea228 100644 --- a/src/components/GensploreView.js +++ b/src/components/GensploreView.js @@ -7,6 +7,9 @@ import React, { useCallback, } from "react"; + +import Offcanvas from './Offcanvas'; // Import the new offcanvas component + import Tooltip from "./Tooltip"; import { getReverseComplement, filterFeatures } from "../utils"; import SingleRow from "./SingleRow"; @@ -18,7 +21,7 @@ import { useWindowVirtualizer } from "@tanstack/react-virtual"; import { ToastContainer, toast } from "react-toastify"; import SearchPanel from "../SearchPanel"; import { GiDna1 } from "react-icons/gi"; -import { MdSettings } from "react-icons/md"; + function GensploreView({ genbankString, searchInput, setSearchInput }) { const [searchPanelOpen, setSearchPanelOpen] = useState(false); @@ -292,6 +295,37 @@ function GensploreView({ genbankString, searchInput, setSearchInput }) { setLastSearch(sequenceSearchInput); }, [sequenceSearchInput, curSeqHitIndex,includeRC]); + const [featureOffcanvasOpen, setFeatureOffcanvasOpen] = useState(false); + const [featureVisibility, setFeatureVisibility] = useState({}); + const visibleFeatures = useMemo(() => { + if (!genbankData) return []; + const visibleFeatures = []; + genbankData.parsedSequence.features.forEach((feature, i) => { + if (featureVisibility[i]) { + visibleFeatures.push(feature); + } + }); + return visibleFeatures; + }, [featureVisibility, genbankData]); + + + + useEffect(() => { + if (!genbankData) return; + const newFeatureVisibility = {}; + /* + feature.type !== "source" && + feature.type !== "gene" && + feature.type !== "mRNA" && + */ + genbankData.parsedSequence.features.forEach((feature, i) => { + newFeatureVisibility[i] = feature.type !== "source" && feature.type !== "gene" && feature.type !== "mRNA" + } + ); + setFeatureVisibility(newFeatureVisibility); + }, [genbankData]); + + //console.log("virtualItems", virtualItems); @@ -374,7 +408,8 @@ function GensploreView({ genbankString, searchInput, setSearchInput }) { )}
- +
@@ -436,6 +471,7 @@ function GensploreView({ genbankString, searchInput, setSearchInput }) {
+ + + + setFeatureOffcanvasOpen(false)}> + + + + + + + + + + + + + {genbankData?.parsedSequence.features.map((feature, index) => ( + + + + + + + + ))} + +
+ Feature + + Type +
+ { + const newFeatureVisibility = { ...featureVisibility }; + newFeatureVisibility[index] = !newFeatureVisibility[index]; + setFeatureVisibility(newFeatureVisibility); + } + } + /> + {feature.name}{feature.type}
+
); } diff --git a/src/components/Offcanvas.js b/src/components/Offcanvas.js new file mode 100644 index 0000000..657fb15 --- /dev/null +++ b/src/components/Offcanvas.js @@ -0,0 +1,35 @@ +import React from 'react'; + +const Offcanvas = ({ isOpen, onClose, children }) => { + return ( +
+
+ {/* Background overlay */} +
+ + {/* Offcanvas Panel from Bottom */} +
+ {/* Offcanvas Panel */} +
+
+ +
+ {/* Place your content here */} + {children} +
+
+
+
+
+
+ ); +}; + +export default Offcanvas; diff --git a/src/components/SettingsPanel.js b/src/components/SettingsPanel.js index d0789b9..ca826a6 100644 --- a/src/components/SettingsPanel.js +++ b/src/components/SettingsPanel.js @@ -3,11 +3,15 @@ import Slider from 'rc-slider'; import "rc-slider/assets/index.css"; import { AiOutlineZoomIn, AiOutlineZoomOut } from 'react-icons/ai'; import { MdSettings } from 'react-icons/md'; +import { PiTagChevronFill } from "react-icons/pi"; -const SettingsPanel = ({ zoomLevel, setZoomLevel, configModalOpen, setConfigModalOpen }) => { +const SettingsPanel = ({ zoomLevel, setZoomLevel, configModalOpen, setConfigModalOpen, setFeatureOffcanvasOpen }) => { return ( <> - +