diff --git a/src/components/Card/Card.tsx b/src/components/Card/Card.tsx index 8709b97..1d8984a 100644 --- a/src/components/Card/Card.tsx +++ b/src/components/Card/Card.tsx @@ -1,95 +1,103 @@ -import Typography from '@mui/material/Typography'; -import MaterialCard from '@mui/material/Card'; -import { CardMediaProps } from '@mui/material/CardMedia'; -import CardMedia from '@mui/material/CardMedia'; +import { + Box as MuiBox, + Card as MuiCard, + CardProps as MuiCardProps, + CardMedia as MuiCardMedia, + CardMediaProps as MuiCardMediaProps +} from '@mui/material'; +import { Link } from 'react-router-dom'; +import { Typography } from 'components/Typography'; +import { PrimaryButton } from 'components/PrimaryButton'; import testImage from '../../nasaTest.jpeg'; -import Box from '@mui/material/Box'; -import { useState } from 'react'; export type CardProps = { - /** Title to display in the card */ - title: string, /** Content to display in the card */ - content: string, + description?: string; + /** Height of the card */ + height: number; /** Image to display in the card */ - image: CardMediaProps['image'] -} - -export const Card = ({ - title = '', - content = '', - image = testImage -}: CardProps) => { - const [isCardHovered, setIsCardHovered] = useState(false); + image: MuiCardMediaProps['image']; + /** Description of the image displayed in the card */ + imageDescription: string; + /** Width of the card **/ + maxWidth: number; + /** Title to display in the card */ + title: string; + /** Link to go to when card or button is clicked */ + url: string; + /** Width of the card **/ + width: number; +} & MuiCardProps; - const onCardMouseOver = () => { - setIsCardHovered(true); - } +export const Card = (props: CardProps) => { - const onCardMouseOut = () => { - setIsCardHovered(false); - } + const { + description = '', + height = 480, + image = testImage, + imageDescription, + maxWidth = 345, + title, + url, + width = 312, + ...other + } = props; return ( - - - - - - {title} {/**/} - {content} - - - - - + + + + + + + + {description} + + + + + + ); } diff --git a/src/components/Cards/ButtonCard/ButtonCard.tsx b/src/components/Cards/ButtonCard/ButtonCard.tsx new file mode 100644 index 0000000..da27a81 --- /dev/null +++ b/src/components/Cards/ButtonCard/ButtonCard.tsx @@ -0,0 +1,69 @@ +import { Box as MuiBox, Card as MuiCard, Stack as MuiStack } from "@mui/material"; +import { Typography } from "components/Typography"; +import { IconArrowRight, IconArrowDiagonal } from "components/Icons"; + +export type ButtonCardProps = { + title: string; + linkType?:"internal" | "external"; + width?:string; +} + +export const ButtonCard = ({ + title, + linkType = "internal", + width = "100%" +}:ButtonCardProps) => { + + let icon = + + if( linkType === "external" ) { + icon = + } + + return <> + + + + + + {title} +
+ {icon} +
+
+
+
+
+
+ +} + +export default ButtonCard; \ No newline at end of file diff --git a/src/components/Cards/ButtonCard/index.ts b/src/components/Cards/ButtonCard/index.ts new file mode 100644 index 0000000..0cbd4ee --- /dev/null +++ b/src/components/Cards/ButtonCard/index.ts @@ -0,0 +1 @@ +export * from "./ButtonCard"; \ No newline at end of file diff --git a/src/components/Cards/MediaCard/MediaCard.tsx b/src/components/Cards/MediaCard/MediaCard.tsx new file mode 100644 index 0000000..f1decd1 --- /dev/null +++ b/src/components/Cards/MediaCard/MediaCard.tsx @@ -0,0 +1,95 @@ +import { + Box as MuiBox, + Card as MuiCard, + CardMedia as MuiCardMedia, + CardMediaProps as MuiCardMediaProps, + Stack as MuiStack +} from "@mui/material"; +import { Typography } from "components/Typography"; +import { IconArrowRight } from "components/Icons"; +import testImage from '../../../nasaTest.jpeg'; + +export type MediaCardProps = { + description?:string; + image:MuiCardMediaProps['image']; + imageDescription:string; + title:string; +} + +export const MediaCard = ({ + description, + image = testImage, + imageDescription, + title, +}:MediaCardProps) => { + + return <> + + + + + + + {title} +
+ +
+
+ { description && {description} } +
+
+
+ +} + +export default MediaCard; \ No newline at end of file diff --git a/src/components/Cards/MediaCard/index.ts b/src/components/Cards/MediaCard/index.ts new file mode 100644 index 0000000..21f4689 --- /dev/null +++ b/src/components/Cards/MediaCard/index.ts @@ -0,0 +1 @@ +export * from "./MediaCard"; \ No newline at end of file diff --git a/src/components/Cards/index.ts b/src/components/Cards/index.ts new file mode 100644 index 0000000..1a64ab4 --- /dev/null +++ b/src/components/Cards/index.ts @@ -0,0 +1,2 @@ +export * from "./ButtonCard"; +export * from "./MediaCard"; \ No newline at end of file diff --git a/src/components/Footer/Footer.scss b/src/components/Footer/Footer.scss new file mode 100644 index 0000000..51b7537 --- /dev/null +++ b/src/components/Footer/Footer.scss @@ -0,0 +1,45 @@ +.pds-wds-footer-root { + + background-color: #000000; + text-align: left; + + a { + color: #FFFFFF; + + &:hover { + text-decoration: underline; + text-decoration-style: dashed; + text-underline-offset: .3em; + } + + &:focus { + outline: .25rem solid var(--pds-secondary-blue-t1); + outline-offset: 0; + } + + } + + & .pds-wds-footer-container { + padding: 39px 40px 56px 40px; + } + + a.pds-wds-footer-primary-link { + color: var(--pds-secondary-white-s2); + margin-bottom: 19px; + } + + a.pds-wds-footer-secondary-link { + color: var(--pds-secondary-white-s2); + margin-bottom: 8px; + padding: 8px 12px 8px 12px; + } + + .pds-wds-footer-metadata { + color: #959599; + + .MuiTypography-root { + margin-bottom: 8px; + } + } + +} \ No newline at end of file diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx new file mode 100644 index 0000000..c188e52 --- /dev/null +++ b/src/components/Footer/Footer.tsx @@ -0,0 +1,110 @@ +import { + Box as MuiBox, + //Grid as MuiGrid, + Container as MuiContainer, + Stack as MuiStack, + } from "@mui/material"; +import Grid from '@mui/material/Unstable_Grid2'; // Grid version 2 +import { Link } from "react-router-dom"; +import { Typography } from "components/Typography"; +import nasaLogo from "../../assets/nasa.svg"; + +import "./Footer.scss"; + +export type FooterLink = { + id: string; + label: string; + href: string; +}; + +export type FooterProps = { + primaryLinks:FooterLink[], + secondaryLinks:FooterLink[], + pageLastUpdated:string +} + +export const Footer = ({ + primaryLinks, + secondaryLinks, + pageLastUpdated +}:FooterProps) => { + return <> +
+ + + + + The National Aeronautics and Space Administration (NASA) Logo + + + + + + The National Aeronautics
and Space Administration
+ NASA explores the unknown in air and space, innovates for the benefit of humanity, and inspires the world through discovery. +

+ + About NASA's Mission + +

+
+
+ + { + + + { + primaryLinks.map( (link:FooterLink, primaryLinkIndex) => { + return <> + + {link.label} + + + }) + } + + + + } + +
+ + {/* */} + + { + secondaryLinks.map( (link, index) => { + return <> + + {link.label} + + + }) + } + + + + + + Page Last Updated: + {pageLastUpdated} + + + NASA Official: + Jordan Padams + + + +
+
+
+
+ +}; + +export default Footer; \ No newline at end of file diff --git a/src/components/Footer/index.ts b/src/components/Footer/index.ts new file mode 100644 index 0000000..ba51bfb --- /dev/null +++ b/src/components/Footer/index.ts @@ -0,0 +1 @@ +export * from "./Footer" \ No newline at end of file diff --git a/src/components/PrimaryButton/PrimaryButton.scss b/src/components/PrimaryButton/PrimaryButton.scss new file mode 100644 index 0000000..a28c23b --- /dev/null +++ b/src/components/PrimaryButton/PrimaryButton.scss @@ -0,0 +1,80 @@ +.pds-wds-primary-button { + + &.MuiIconButton-root { + + background-color: #F64137; + color: #FFFFFF; + + &:hover { + background-color: #B60109; + } + + &.pds-wds-primary-button-size-14 { + height: 16px; + width: 16px; + padding: 4px; + + & > svg { + width: 8px; + height: 8px; + } + } + + &.pds-wds-primary-button-size-16 { + height: 20px; + width: 20px; + padding: 5px; + + & > svg { + width: 10px; + height: 10px; + } + } + + &.pds-wds-primary-button-size-18 { + height: 24px; + width: 24px; + padding: 6px; + + & > svg { + width: 12px; + height: 12px; + } + } + + &.pds-wds-primary-button-size-22 { + height: 28px; + width: 28px; + padding: 7px; + + & > svg { + width: 14px; + height: 14px; + } + } + + &.pds-wds-primary-button-size-29 { + height: 32px; + width: 32px; + padding: 8px; + + & > svg { + width: 16px; + height: 16px; + } + } + + &.pds-wds-primary-button-size-36 { + height: 36px; + width: 36px; + padding: 9px; + + & > svg { + width: 18px; + height: 18px; + } + } + + } + +} \ No newline at end of file diff --git a/src/components/PrimaryButton/PrimaryButton.tsx b/src/components/PrimaryButton/PrimaryButton.tsx new file mode 100644 index 0000000..5484225 --- /dev/null +++ b/src/components/PrimaryButton/PrimaryButton.tsx @@ -0,0 +1,108 @@ +import { Box as MuiBox, IconButton as MuiIconButton, Stack as MuiStack } from '@mui/material'; +import { Typography } from 'components/Typography'; +import { IconArrowDiagonal, IconArrowRight } from 'components/Icons'; + +import "./PrimaryButton.scss" + + +export type PrimaryButtonProps = { + iconType?: "internal" | "external" + label: string; + size?: "14" | "16" | "18" | "22" | "29" | "36"; +} + +export const PrimaryButton = ({ + iconType = "internal", + label, + size = "16" +}:PrimaryButtonProps) => { + + const alignItems = "flex-end"; + const justifyContent = "left"; + + switch(size) { + + case "14": + + return <> + + + {label} + + { iconType === "internal" ? : } + + + + + + default: + case "16": + + return <> + + + {label} + + { iconType === "internal" ? : } + + + + + + case "18": + + return <> + + + {label} + + { iconType === "internal" ? : } + + + + + + case "22": + + return <> + + + {label} + + { iconType === "internal" ? : } + + + + + + case "29": + + return <> + + + {label} + + { iconType === "internal" ? : } + + + + + + case "36": + + return <> + + + {label} + + { iconType === "internal" ? : } + + + + + + } + +} + +export default PrimaryButton \ No newline at end of file diff --git a/src/components/PrimaryButton/index.ts b/src/components/PrimaryButton/index.ts new file mode 100644 index 0000000..bb77cc1 --- /dev/null +++ b/src/components/PrimaryButton/index.ts @@ -0,0 +1 @@ +export * from "./PrimaryButton"; \ No newline at end of file diff --git a/src/components/QuickLInksBar/QuickLinksBar.scss b/src/components/QuickLInksBar/QuickLinksBar.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/components/QuickLInksBar/QuickLinksBar.tsx b/src/components/QuickLInksBar/QuickLinksBar.tsx new file mode 100644 index 0000000..ead13b3 --- /dev/null +++ b/src/components/QuickLInksBar/QuickLinksBar.tsx @@ -0,0 +1,44 @@ +import { Stack as MuiStack } from "@mui/material"; +import { Button } from "components/Button"; +import { PrimaryButton } from "components/PrimaryButton"; +import { Typography } from "components/Typography"; + +import "./QuickLinksBar.scss" +import { Link } from "react-router-dom"; + +export type QuickLinksBarProps = { + + primaryLinks:Array<{label:string, url:string }>; + secondaryLinks:Array<{label:string, url:string, urlType?:"internal" | "external" }>; + title:string; +} + +export const QuickLinksBar = ({ + primaryLinks, + secondaryLinks, + title +}:QuickLinksBarProps) => { + return <> + + {title} + + + { + primaryLinks.map( (link, index) => { + return + }) + } + + + { + secondaryLinks.map( (link, index) => { + return + }) + } + + + + +} + +export default QuickLinksBar; \ No newline at end of file diff --git a/src/components/QuickLInksBar/index.ts b/src/components/QuickLInksBar/index.ts new file mode 100644 index 0000000..4a6e194 --- /dev/null +++ b/src/components/QuickLInksBar/index.ts @@ -0,0 +1 @@ +export * from "./QuickLinksBar"; \ No newline at end of file diff --git a/src/components/Tabs/Tabs.scss b/src/components/Tabs/Tabs.scss new file mode 100644 index 0000000..95cf29d --- /dev/null +++ b/src/components/Tabs/Tabs.scss @@ -0,0 +1,44 @@ + +/* Tabs */ +.pds-wds-tabs { + + & > .MuiTabs-root { + + border-bottom: 1px solid #D1D1D1; + + .MuiTab-root { + + color: #000000; + + &.Mui-selected { + color: #000000; + } + + /* &:focus { + border: 1px #58585B dotted; + top: 1px; + } */ + + } + + .MuiTabs-scrollButtons.Mui-disabled { + opacity: 0.3; + } + + .MuiTabs-indicator { + background-color: #000000; + height: 4px; + } + + } + +} + +.pds-wds-tab { + + & > .MuiBox-root { + padding-left: 0; + padding-right: 0; + } + +} \ No newline at end of file diff --git a/src/components/Tabs/Tabs.tsx b/src/components/Tabs/Tabs.tsx new file mode 100644 index 0000000..d94d0a4 --- /dev/null +++ b/src/components/Tabs/Tabs.tsx @@ -0,0 +1,68 @@ +import { useState } from 'react'; +import { Box as MuiBox, Tabs as MuiTabs, Tab as MuiTab } from '@mui/material'; + +import "./Tabs.scss"; + +interface TabPanelProps { + children?: React.ReactNode; + index: number; + value: number; +} + +export type TabProps = { + description:string + tabs:Array<{label:string, content:React.ReactElement}> +} + +function CustomTabPanel(props: TabPanelProps) { + const { children, value, index, ...other } = props; + + return ( + + ); +} + +function a11yProps(index: number) { + return { + id: `simple-tab-${index}`, + 'aria-controls': `simple-tabpanel-${index}`, + }; +} + +export const Tabs = ({ + description, + tabs +}:TabProps) => { + + const [value, setValue] = useState(0); + + const handleChange = (_event: React.SyntheticEvent, newValue: number) => { + setValue(newValue); + }; + + return <> + + + { + tabs.map((tab, tabIndex) => { + return + }) + } + + { + tabs.map( (tab, tabIndex) => { + return {tab.content} + }) + } + + +} \ No newline at end of file diff --git a/src/components/Tabs/index.ts b/src/components/Tabs/index.ts new file mode 100644 index 0000000..69ae2cc --- /dev/null +++ b/src/components/Tabs/index.ts @@ -0,0 +1 @@ +export * from "./Tabs"; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 9a5a068..46e2e95 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,14 +2,19 @@ import "./styles/styles.scss"; export * from "./components/Breadcrumbs"; export * from "./components/Button"; export * from "./components/Card"; +export * from "./components/Cards"; export * from "./components/Chip"; export * from "./components/FeaturedLink"; export * from "./components/FeaturedLinkDetails"; +export * from "./components/Footer"; export * from "./components/Header"; export * from "./components/HelloWorld"; export * from "./components/Icons"; export * from "./components/Loader"; export * from "./components/Pagination"; +export * from "./components/PrimaryButton"; +export * from "./components/QuickLInksBar"; +export * from "./components/Tabs"; export * from "./components/Tag"; export * from "./components/TextField"; export * from "./components/Typography";