| /** |
| * 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 { useState } from "react"; |
| import ChevronDown from "react-feather/dist/icons/chevron-down"; |
| import styled from "styled-components"; |
| |
| import { MenuLink } from "./MenuLink"; |
| import { get } from "../../../utils/theme"; |
| |
| import { SubMenu } from "./SubMenu"; |
| import Utils from "../../../utils/utils"; |
| export const MenuItem = { |
| id: "", |
| name: "", |
| route: "", |
| href: "", |
| menu: [], |
| order: Number, |
| parent: "" |
| }; |
| |
| const Wrapper = styled.div` |
| display: flex; |
| flex-direction: column; |
| `; |
| |
| const OpenedProps = { |
| opened: false |
| }; |
| |
| const List = styled.dl` |
| flex: 1; |
| overflow-y: auto; |
| visibility: ${p => (p.opened ? "visible" : "hidden")}; |
| max-height: ${p => (p.opened ? "auto" : "0px")}; |
| `; |
| |
| List.defaultProps = OpenedProps; |
| |
| const iconRotate = p => (p.opened ? "-180deg" : "0deg"); |
| |
| const Icon = styled.div` |
| position: absolute; |
| top: 50%; |
| right: 20px; |
| transform: translateY(-50%) rotate(${iconRotate}); |
| transform-origin: 50% 50%; |
| transition: transform 0.3s; |
| & svg { |
| stroke: ${get("colors.sidebarText")}; |
| } |
| `; |
| Icon.defaultProps = OpenedProps; |
| const MenuProps = { |
| item: MenuItem, |
| sidebarToggle: null, |
| collapseAll: true |
| }; |
| |
| const MenuState = { |
| opened: false, |
| hasActive: false |
| }; |
| export const Menu = props => { |
| const { item, sidebarToggle, handleActiveMenu, activeMenu } = props; |
| const opened = Utils.checkMenuIsOPen(props); |
| const show = opened; |
| const hasChildren = !item.href && item.menu && item.menu.length > 0; |
| const hasToggle = !item.href && !item.route; |
| const handleToggle = ev => { |
| ev.preventDefault(); |
| handleActiveMenu(item); |
| }; |
| const options = { handleActiveMenu, activeMenu }; |
| let OutputHtml = ( |
| <Wrapper> |
| <MenuLink item={item} {...(hasToggle && { onClick: handleToggle })}> |
| {` ${item.name} `} |
| {hasChildren && ( |
| <Icon opened={show}> |
| <ChevronDown size={15} /> |
| </Icon> |
| )} |
| </MenuLink> |
| {hasChildren && ( |
| <List opened={show}> |
| {item.menu && |
| item.menu.map(dataItem => ( |
| <List opened={show} key={dataItem.name}> |
| <SubMenu item={dataItem} {...options} /> |
| </List> |
| ))} |
| </List> |
| )} |
| </Wrapper> |
| ); |
| |
| if (!hasChildren && !hasToggle) { |
| OutputHtml = ( |
| <Wrapper> |
| <MenuLink item={item} {...(opened && { handleToggle })}> |
| {`${item.name} `} |
| </MenuLink> |
| </Wrapper> |
| ); |
| } |
| return OutputHtml; |
| }; |
| Menu.defaultProps = MenuProps; |
| Menu.defaultProps = MenuState; |