Clean up components

This commit is contained in:
Aarni Halinen
2020-10-10 18:13:28 +03:00
parent 3b2ca4f26c
commit 6531fd1daa
19 changed files with 157 additions and 342 deletions
+99
View File
@@ -0,0 +1,99 @@
import React from "react";
import styled from "styled-components";
import AccordionIcon from "./AccordionIcon";
import { colors } from "@theme/colors";
const Container = styled.div`
margin: 0.2em;
padding: 0.2em;
display: flex;
flex-flow: column nowrap;
border-style: solid;
border-color: ${colors.lightTurquoise};
border-width: 1px;
button {
display: flex;
flex-flow: row nowrap;
background-color: ${colors.white};
width: 100%;
margin: 0;
padding: 0;
border: 0;
outline: none;
}
h5 {
display: flex;
flex: 1;
text-align: center;
padding-left: 1em;
color: ${colors.blue1};
font-size: 1.125rem;
margin: auto;
}
& > div {
overflow: hidden;
}
`;
const Panel = styled.div<{visible?: boolean}>`
margin-top: ${(p) => p.visible ? "0" : "-100%"};
display: flex;
max-height: 15rem;
transition: margin-top 400ms ease-in-out;
div {
min-width: 40px;
max-width: 40px;
margin: 0.6em;
}
p {
padding-left: 1em;
margin: auto;
}
`;
export interface AccordionProps {
title: string;
}
export interface AccordionState {
isOpen: boolean;
}
class Accordion extends React.Component<AccordionProps, AccordionState> {
constructor(props: AccordionProps) {
super(props);
this.state = {
isOpen: false,
};
}
handleClick() {
this.setState((prevState) => ({
isOpen: !prevState.isOpen,
}));
}
render() {
const { isOpen } = this.state;
return (
<Container>
<button type="button" onClick={() => this.handleClick()}>
<AccordionIcon open={isOpen} />
<h5>{this.props.title}</h5>
</button>
<div>
<Panel visible={isOpen}>
{this.props.children}
</Panel>
</div>
</Container>
);
}
}
export default Accordion;
-59
View File
@@ -1,59 +0,0 @@
@import "../../assets/scss/globals";
.accordion {
margin: 0.2em;
padding: 0.2em;
display: flex;
flex-flow: column nowrap;
border-style: solid;
border-color: color(light-turquoise);
border-width: 1px;
&__desc {
display: flex;
margin-top: -100%;
max-height: 15rem;
-webkit-transition: margin-top 400ms ease-in-out;
-webkit-transform: margin-top 400ms ease-in-out;
-moz-transform: margin-top 400ms ease-in-out;
-o-transform: margin-top 400ms ease-in-out;
transition: margin-top 400ms ease-in-out;
&.open {
margin-top: 0;
}
div {
min-width: 40px;
max-width: 40px;
margin: 0.6em;
}
p {
padding-left: 1em;
margin: auto;
}
}
button {
display: flex;
flex-flow: row nowrap;
background-color: color(white1);
width: 100%;
margin: 0;
padding: 0;
border: 0;
outline: none;
}
h5 {
display: flex;
flex: 1;
text-align: center;
padding-left: 1em;
color: color(blue1);
font-size: 1.125rem;
margin: auto;
}
}
-50
View File
@@ -1,50 +0,0 @@
import React from "react";
import "./Accordion.scss";
import AccordionIcon from "../AccordionIcon";
export interface AccordionProps {
title: string;
}
export interface AccordionState {
isOpen: boolean;
}
interface DescriptionProps {
visible: boolean;
}
const Description: React.SFC<DescriptionProps> = (props) => (
<div className={`accordion__desc ${props.visible ? "open" : ""}`}>{props.children}</div>
);
class Accordion extends React.Component<AccordionProps, AccordionState> {
constructor(props: AccordionProps) {
super(props);
this.state = {
isOpen: false,
};
}
handleClick() {
this.setState((prevState) => ({
isOpen: !prevState.isOpen,
}));
}
render() {
const { isOpen } = this.state;
return (
<div className="accordion">
<button type="button" onClick={() => this.handleClick()}>
<AccordionIcon open={isOpen} />
<h5>{this.props.title}</h5>
</button>
<div style={{ overflow: "hidden", }}>
<Description visible={isOpen}>{this.props.children}</Description>
</div>
</div>
);
}
}
export default Accordion;
+1 -1
View File
@@ -1,2 +1,2 @@
import Accordion from "./Accordion";
import Accordion from "../Accordion";
export default Accordion;
-93
View File
@@ -1,93 +0,0 @@
@import "../../assets/scss/globals";
.card {
background-color: color(white1);
color: color(dark-blue);
white-space: wrap;
margin: 1rem 1rem;
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
width: calc(25% - 2rem);
@media screen and (min-width: 1000px) and (max-width: 1200px - 1px) {
width: calc(50% - 2rem);
margin-bottom: 2rem;
}
@media screen and (max-width: 1000px - 1px) {
width: 100%;
margin-bottom: 3rem;
margin-left: 0;
margin-right: 0;
}
&__title {
padding: 0.5rem;
margin-bottom: 0.5rem;
display: flex;
justify-content: center;
font-size: 1.5rem;
text-align: center;
font-weight: 300;
color: color(black1);
}
&__image {
width: 100%;
height: 300px;
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
margin-bottom: 1rem;
@media screen and (min-width: 1200px) {
height: 15vw;
}
@media screen and (max-width: 1200px - 1px) {
height: 35vh;
}
}
&__button {
display: flex;
justify-content: center;
button {
height: 100%;
}
}
&__text {
display: flex;
justify-content: center;
text-align: center;
text-overflow: ellipsis;
font-size: 16px;
margin: 0 0 0.5rem;
font-weight: 200;
line-height: 22px;
color: color(black1);
@media screen and (max-width: 1200px - 1px) {
margin: 0.5rem 0;
font-size: 16px;
}
}
&__datetime {
color: color(orange1);
display: flex;
justify-content: center;
text-align: center;
font-size: 0.9rem;
font-weight: 600;
@media screen and (max-width: 1200px - 1px) {
margin: 0.5rem 0;
font-size: 16px;
}
}
}
-57
View File
@@ -1,57 +0,0 @@
import React from "react";
import "./Card.scss";
import Anchor from "../Anchor";
import { Button } from "@components/index";
interface CardProps {
title: string;
start_time: string;
text: string;
link?: string;
image?: string;
buttonText?: string;
buttonOnClick?: () => void;
}
const Card: React.FC<CardProps> = ({ title, text, link, image, buttonText, start_time, buttonOnClick }) => {
const options = {
day: "numeric",
month: "numeric",
year: "numeric",
hour: "numeric",
minute: "2-digit"
};
const datetime = new Date(start_time).toLocaleString("fi-FI", options);
const imageElem = image ? (
<div style={{ backgroundImage: `url(${image})`, }} className="card__image" />
) : null;
if (link) {
return (
<Anchor to={link} className="card">
{imageElem}
<div className="card__datetime">{datetime}</div>
<div className="card__title">{title}</div>
<div className="card__text">{text}</div>
<div className="card__button">
<Button type="filled" onClick={buttonOnClick}>
<h6>{buttonText}</h6>
</Button>
</div>
</Anchor>
);
}
return (
<div className="card">
{imageElem}
<div className="card__datetime">{datetime}</div>
<div className="card__title">{title}</div>
<div className="card__text">{text}</div>
<Button type="filled" onClick={buttonOnClick}>
<h6>{buttonText}</h6>
</Button>
</div>
);
}
export default Card;
+36
View File
@@ -0,0 +1,36 @@
import React from "react";
import styled from "styled-components";
import { colors } from "@theme/colors";
interface DropDownBoxProps {
onMouseEnter: () => void;
onMouseLeave: () => void;
visible: boolean;
}
const Box = styled.div`
background-color: ${colors.white};
margin-top: 0.8rem;
position: absolute;
left: 0;
top: 30px;
z-index: 20;
a {
text-decoration: underline;
color: ${colors.darkBlue} !important;
text-transform: uppercase;
}
`;
const DropDownBox: React.FC<DropDownBoxProps> = ({ children, onMouseEnter, onMouseLeave, visible }) => (
<Box
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
hidden={!visible}
>
{children}
</Box>
);
export default DropDownBox;
@@ -1,17 +0,0 @@
@import "../../assets/scss/globals";
.drop-down-box {
background-color: color(white1);
margin-top: 0.8rem;
position: absolute;
left: 0;
top: 30px;
z-index: 20;
&,
& a {
color: color(dark-blue) !important;
text-transform: uppercase;
}
}
@@ -1,27 +0,0 @@
import React from "react";
import "./DropDownBox.scss";
export interface DropDownBoxProps {
onMouseEnter: () => void;
onMouseLeave: () => void;
visible: boolean;
}
export interface DropDownBoxState {}
class DropDownBox extends React.Component<DropDownBoxProps, DropDownBoxState> {
render() {
const { children, onMouseEnter, onMouseLeave, visible } = this.props;
return (
<div
className="drop-down-box"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
hidden={!visible}
>
{children}
</div>
);
}
}
export default DropDownBox;
-2
View File
@@ -1,2 +0,0 @@
import DropDownBox from "./DropDownBox";
export default DropDownBox;
+15
View File
@@ -0,0 +1,15 @@
import React from "react";
import styled from "styled-components";
const Box = styled.div`
justify-content: flex-end;
text-align: center;
`;
const InfoBox: React.FC = ({ children }) => (
<Box>
{children}
</Box>
)
export default InfoBox;
-6
View File
@@ -1,6 +0,0 @@
@import "../../assets/scss/globals";
.info-box {
justify-content: flex-end;
text-align: center;
}
-22
View File
@@ -1,22 +0,0 @@
import React from "react";
import "./InfoBox.scss";
export interface InfoBoxProps {}
export interface InfoBoxState {}
class InfoBox extends React.Component<InfoBoxProps, InfoBoxState> {
constructor(props: InfoBoxProps) {
super(props);
}
render() {
const { children } = this.props;
return (
<div className="info-box">
{children}
</div>
);
}
}
export default InfoBox;
-2
View File
@@ -1,2 +0,0 @@
import InfoBox from "./InfoBox";
export default InfoBox;
@@ -1,6 +1,6 @@
import React from "react";
import "./NavbarDropdownLink.scss";
import DropDownBox from "../DropDownBox/DropDownBox";
import DropDownBox from "../DropDownBox";
import Anchor from "../Anchor";
export interface NavbarDropdownLinkProps {
@@ -7,6 +7,7 @@ $border-width: 2px;
.navigation-mobile-menu {
a,
a:-webkit-any-link {
text-decoration: none;
fill: color(light-blue);
color: color(light-blue);
}
+2
View File
@@ -7,3 +7,5 @@ export { default as Divider } from "./Divider";
export { default as CardSection } from "./Sections/CardSection";
export { default as SossoSection } from "./Sections/SossoSection";
export { default as TextSection } from "./Sections/TextSection";
export { default as InfoBox } from "./InfoBox";
export { default as Accordion } from "./Accordion";
+1 -2
View File
@@ -2,9 +2,8 @@ import React from "react";
import styled from "styled-components";
import FreshmenPageHero from "./FreshmenPageHero";
import PageLink from "@components/PageLink";
import InfoBox from "@components/InfoBox";
import Anchor from "@components/Anchor";
import { SossoSection, TextSection } from "@components/index";
import { SossoSection, TextSection, InfoBox } from "@components/index";
const KippariImage = styled.img`
max-width:100%;
+1 -3
View File
@@ -1,11 +1,9 @@
import React from "react";
import styled from "styled-components";
import PageLink from "@components/PageLink";
import InfoBox from "@components/InfoBox";
import Accordion from "@components/Accordion";
import TextAnchor from "@components/TextAnchor";
import Anchor from "@components/Anchor";
import { SossoSection, TextSection } from "@components/index";
import { SossoSection, TextSection, InfoBox, Accordion } from "@components/index";
import GuildPageHero from "./GuildPageHero";
import FullWidthSection from "@components/Sections/FullWidthSection";