diff --git a/frontend/package.json b/frontend/package.json index fa490dd..a2d1b78 100755 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,6 +17,7 @@ "@headlessui/react": "^2.2.0", "@nightingale-elements/nightingale-interpro-track": "^5.4.1", "@nightingale-elements/nightingale-manager": "^5.4.1", + "@nightingale-elements/nightingale-msa": "^5.4.1", "@nightingale-elements/nightingale-navigation": "^5.4.1", "@nightingale-elements/nightingale-sequence": "^5.4.1", "@radix-ui/react-popover": "^1.1.5", diff --git a/frontend/src/components/nightingale-wrapper/NightingaleMSAWrapper.css b/frontend/src/components/nightingale-wrapper/NightingaleMSAWrapper.css new file mode 100644 index 0000000..5a3748d --- /dev/null +++ b/frontend/src/components/nightingale-wrapper/NightingaleMSAWrapper.css @@ -0,0 +1,9 @@ +nightingale-msa { + box-sizing: border-box; + display: block; + flex: 1; + width: 100%; + height: 100%; + overflow: auto; + border: 1px solid #ccc; +} diff --git a/frontend/src/components/nightingale-wrapper/NightingaleMSAWrapper.tsx b/frontend/src/components/nightingale-wrapper/NightingaleMSAWrapper.tsx new file mode 100644 index 0000000..e244af1 --- /dev/null +++ b/frontend/src/components/nightingale-wrapper/NightingaleMSAWrapper.tsx @@ -0,0 +1,45 @@ +import { useEffect, useRef } from "react"; +import "@nightingale-elements/nightingale-msa"; +import type { + Region, + SequencesMSA, +} from "@nightingale-elements/nightingale-msa"; +import "./NightingaleMSAWrapper.css"; + +type Props = { + sequences: SequencesMSA; + features?: Region[]; +}; + +type NightingaleMSAElement = { + data: SequencesMSA; + features?: Region[]; +} & HTMLElement; + +const NightingaleMSAWrapper = ({ sequences, features }: Props) => { + const msaRef = useRef(null); + + useEffect(() => { + if (msaRef.current) { + msaRef.current.data = sequences; + if (features) { + msaRef.current.features = features.map((feature) => ({ + ...feature, + })); + } + } + }, [sequences, features]); + + return ( + + ); +}; + +export default NightingaleMSAWrapper; diff --git a/frontend/src/pages/Testbed.tsx b/frontend/src/pages/Testbed.tsx index 81a6bd0..236cce4 100755 --- a/frontend/src/pages/Testbed.tsx +++ b/frontend/src/pages/Testbed.tsx @@ -29,6 +29,10 @@ import { FaTableCells, } from "react-icons/fa6"; import { random, sample, uniq, uniqueId } from "lodash"; +import type { + Region, + SequencesMSA, +} from "@nightingale-elements/nightingale-msa"; import CustomIcon from "@/assets/custom-icon.svg?react"; import Ago from "@/components/Ago"; import Alert from "@/components/Alert"; @@ -42,6 +46,7 @@ import IPR from "@/components/IPR"; import Link from "@/components/Link"; import Meta from "@/components/Meta"; import Network from "@/components/Network"; +import NightingaleMSAWrapper from "@/components/nightingale-wrapper/NightingaleMSAWrapper"; import NumberBox from "@/components/NumberBox"; import Popover from "@/components/Popover"; import Radios from "@/components/Radios"; @@ -187,6 +192,41 @@ const tracks = Array(10) }), })); +type ExtendedRegion = Region & { + type: string; + start: number; + end: number; +}; + +const mockSequences: SequencesMSA = [ + { name: "Seq1", sequence: "ATGCATGCATGC" }, + { name: "Seq2", sequence: "ATGC-TGCATGC" }, + { name: "Seq3", sequence: "ATGCATGC-TGC" }, +]; + +const mockFeatures: ExtendedRegion[] = [ + { + type: "domain", + start: 1, + end: 6, + residues: { from: 1, to: 6 }, + sequences: { from: 0, to: 2 }, + mouseOverFillColor: "rgba(255, 0, 0, 0.5)", + fillColor: "rgba(255, 0, 0, 0.3)", + borderColor: "rgb(255, 0, 0)", + }, + { + type: "motif", + start: 8, + end: 12, + residues: { from: 8, to: 12 }, + sequences: { from: 0, to: 2 }, + mouseOverFillColor: "rgba(255, 0, 0, 0.5)", + fillColor: "rgba(255, 0, 0, 0.3)", + borderColor: "rgb(255, 0, 0)", + }, +]; + /** test and example usage of formatting, elements, components, etc. */ const TestbedPage = () => { /** palettes for color maps */ @@ -225,6 +265,16 @@ const TestbedPage = () => { +
+ }> + MSA Visualization + + +
+ {/* regular html elements and css classes for basic formatting */}
}> diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts index 49f0507..b88be56 100755 --- a/frontend/src/vite-env.d.ts +++ b/frontend/src/vite-env.d.ts @@ -9,6 +9,7 @@ namespace React.JSX { // eslint-disable-next-line interface IntrinsicElements { "nightingale-manager": JSX.HTMLAttributes; + "nightingale-msa": JSX.HTMLAttributes; "nightingale-navigation": JSX.HTMLAttributes; "nightingale-sequence": JSX.HTMLAttributes; "nightingale-interpro-track": JSX.HTMLAttributes;