/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import * as React from "react"; import { SFC } from "react"; import styled from "styled-components"; import { get } from "../../../utils/theme"; import { mq } from "../../../styles/responsive"; const OpenProps = { opened: true }; const IconFirst = p => (!p.opened ? "0px" : "10px"); const IconMiddle = p => (!p.opened ? "1" : "0"); const IconLast = p => (!p.opened ? "0px" : "-6px"); const IconRotate = p => (!p.opened ? "0deg" : "45deg"); const Icon = styled.div` position: relative; width: 23px; height: 32px; transform: translateX(${p => (p.opened ? "-2px" : "-1px")}) translateY(${p => (p.opened ? "0" : "2px")}) scale(${p => (p.opened ? 0.8 : 1)}); `; Icon.defaultProps = OpenProps; const sidebarBg = get("colors.sidebarBg"); const sidebarPrimary = get("colors.sidebarPrimary"); const sidebarText = get("colors.sidebarText"); const primaryColor = get("colors.primary"); const backgroundColor = get("colors.background"); const textColor = get("colors.text"); const IconLine = styled.span` content: ""; display: block; position: absolute; width: 100%; height: 2px; left: 0; right: 0; background: ${p => (p.opened ? sidebarText(p) : textColor(p))}; transition: transform 0.3s, opacity 0.3s; &:nth-of-type(1) { top: -2px; transform: translateY(${IconFirst}) rotate(${IconRotate}); } &:nth-of-type(2) { top: 6px; opacity: ${IconMiddle}; } &:nth-of-type(3) { top: 14px; transform: translateY(${IconLast}) rotate(-${IconRotate}); } `; IconLine.defaultProps = OpenProps; const translateX = p => (!p.opened ? "10px" : "-6px"); const translateY = p => (!p.opened ? "4px" : "0px"); const radii = get("radii"); const ToggleButton = styled.button` cursor: pointer; z-index: 99; position: absolute; display: flex; align-items: center; justify-content: center; padding: 5px 6px; width: 33px; height: 30px; top: ${p => (p.opened ? "3px" : "2px")}; right: ${p => (p.opened ? "-39px" : "-27px")}; transform: translateX(${translateX}) translateY(${translateY}); transition: transform 0.3s; outline: none; border: none; background: ${p => (p.opened ? sidebarBg(p) : backgroundColor(p))}; border-radius: ${p => (p.opened ? `0 0 ${radii(p)} 0` : `${radii(p)}`)}; &:before { position: absolute; content: ""; top: -3px; left: 0; width: calc(100% + 1px); height: ${p => (p.opened ? "3px" : 0)}; background: ${p => sidebarPrimary(p) || primaryColor(p)}; } ${mq({ display: ["block", "block", "block", "none"] })}; `; ToggleButton.defaultProps = OpenProps; // interface HamburgerProps extends OpenProps { // onClick: (ev: React.SyntheticEvent<any>) => void // } const HamburgerProps = Object.assign({}, OpenProps, { onClick: ev => null }); export const Hamburger = ({ opened, onClick }) => ( <ToggleButton opened={opened} onClick={onClick}> <Icon opened={opened}> <IconLine opened={opened} /> <IconLine opened={opened} /> <IconLine opened={opened} /> </Icon> </ToggleButton> );