From 49aa5829cef805a8594d7baed021b80bb741d6f4 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Sat, 13 Jun 2020 02:14:19 -0700 Subject: [PATCH 1/2] feat: sub menu and menu item select --- docs/component/menu.mdx | 39 +++++++++++++++++------ src/Dropdown/Dropdown.tsx | 2 +- src/Menu/Menu.tsx | 4 +++ src/Menu/MenuItem.tsx | 21 ++++++++----- src/Menu/SubMenu.tsx | 31 ++++++++++++++++++ src/Menu/__tests__/Menu.spec.tsx | 35 ++++++++++++++++----- src/Menu/styles.ts | 54 ++++++++++++++++++++++++++++++++ 7 files changed, 160 insertions(+), 26 deletions(-) create mode 100644 src/Menu/SubMenu.tsx create mode 100644 src/Menu/styles.ts diff --git a/docs/component/menu.mdx b/docs/component/menu.mdx index 48c75b36..0293ae8c 100644 --- a/docs/component/menu.mdx +++ b/docs/component/menu.mdx @@ -4,7 +4,7 @@ route: /component/menu menu: Component --- -import { Menu, Text } from 'fiber' +import { Menu, Text, Divider, Heading } from 'fiber' import { Playground } from 'docz' # Menu @@ -14,16 +14,35 @@ import { Playground } from 'docz' {() => { return ( -
- - - Item 1 - +
+ + Sub Menu 1 }> + Sub Menu 1.1 }> + + Item 1 + + + Item 2 + + + + Item 3 + + + Sub Menu 2 }> + + Item 4 + + + Item 5 + + + Item 6 + + + - Item 2 - - - Item 3 + Item 3
diff --git a/src/Dropdown/Dropdown.tsx b/src/Dropdown/Dropdown.tsx index d3dceb75..5868f119 100644 --- a/src/Dropdown/Dropdown.tsx +++ b/src/Dropdown/Dropdown.tsx @@ -38,7 +38,7 @@ const DropdownWrapper = styled.div` const useDropdownStatus = (trigger: TriggerType) => { const node = useRef< HTMLDivElement & { contains: (e: EventTarget) => Boolean } - // eslint-disable-next-line indent + // eslint-disable-next-line indent >(null) const [expand, setExpand] = useState(false) diff --git a/src/Menu/Menu.tsx b/src/Menu/Menu.tsx index 3bfafe7d..b90084bf 100644 --- a/src/Menu/Menu.tsx +++ b/src/Menu/Menu.tsx @@ -1,5 +1,6 @@ import { styleComposition } from '../utils/styles' +import { SubMenu } from './Submenu' import { MenuItem } from './MenuItem' import { MenuProps, MenuContext } from './useMenu' @@ -8,6 +9,7 @@ import styled from 'styled-components' type MenuFC

= FC

& { Item: FC + Sub: FC } const MenuWrapper = styled.ul` @@ -18,6 +20,7 @@ const MenuWrapper = styled.ul` padding: 0; overflow: auto; list-style-type: none; + border-right: solid 1px ${(props) => props.theme.colors.gray3}; ` const Menu: MenuFC = ({ children, inline }) => { @@ -29,5 +32,6 @@ const Menu: MenuFC = ({ children, inline }) => { } Menu.Item = MenuItem +Menu.Sub = SubMenu export { Menu } diff --git a/src/Menu/MenuItem.tsx b/src/Menu/MenuItem.tsx index 5e21032c..3ba58493 100644 --- a/src/Menu/MenuItem.tsx +++ b/src/Menu/MenuItem.tsx @@ -2,39 +2,46 @@ import { StyleProps, styleComposition } from '../utils/styles' import { useMenu } from './useMenu' -import styled from 'styled-components' -import React, { FC } from 'react' +import styled, { css } from 'styled-components' +import React, { FC, useState } from 'react' -export interface MenuItemProps extends StyleProps {} +export interface MenuItemProps extends StyleProps { } +const selectedItem = css` + color: white; + background: ${(props) => props.theme.colors.lightest}; + border-right: solid 3.5px ${(props) => props.theme.colors.light}; +` const BlockMenuItem = styled.li` ${styleComposition} display: block; padding: 8px 10px; float: none; - border-right: solid ${(props) => props.theme.colors.gray3} 0.5px; color: ${(props) => props.color}; text-align: left; text-decoration: none; &:hover { - background: ${(props) => props.theme.colors.gray3}; + color: ${(props) => props.theme.colors.light}; cursor: pointer; } + + ${(props) => props.selected ? selectedItem : null}; ` -const InlineMenuItem = styled(BlockMenuItem)` +const InlineMenuItem = styled(BlockMenuItem) ` display: inline-block; float: left; ` const MenuItem: FC = ({ children, ...props }) => { const { inline } = useMenu() + const [selected, setSelected] = useState(false) const Item = inline ? InlineMenuItem : BlockMenuItem - return {children} + return setSelected(!selected)}>{children} } export { MenuItem } diff --git a/src/Menu/SubMenu.tsx b/src/Menu/SubMenu.tsx new file mode 100644 index 00000000..73d0666d --- /dev/null +++ b/src/Menu/SubMenu.tsx @@ -0,0 +1,31 @@ +import { StyleProps } from '../utils/styles' + +import { Arrow, TitleWrapper, SubMenuWrapper, ItemWrapper } from './styles' + +import React, { FC, ReactElement, useState } from 'react' + +export type TitleFunc = () => React.ReactElement + +export interface SubMenuProps extends StyleProps { + title: ReactElement | TitleFunc; +} + +const SubMenu: FC = ({ children, title }) => { + const [expand, setExpand] = useState(false) + + const titleNode = typeof title === 'function' ? (title as TitleFunc)() : title + + return ( + + setExpand(!expand)}> + {titleNode} + + + + {expand ? children : null} + + + ) +} + +export { SubMenu } diff --git a/src/Menu/__tests__/Menu.spec.tsx b/src/Menu/__tests__/Menu.spec.tsx index d4b22db5..3c21c35c 100644 --- a/src/Menu/__tests__/Menu.spec.tsx +++ b/src/Menu/__tests__/Menu.spec.tsx @@ -1,4 +1,4 @@ -import { Menu, Text } from '../../' +import { Menu, Text, Divider } from '../../' import React from 'react' import { render } from 'test/utils' @@ -7,14 +7,33 @@ describe('Block Menu & Menu Items', () => { it('renders correctly', () => { const block = render(

+ Sub Menu 1 }> + Sub Menu 1.1 }> + + Item 1 + + + Item 2 + + + + Item 3 + + + Sub Menu 2 }> + + Item 4 + + + Item 5 + + + Item 6 + + + - Item 1 - - - Item 2 - - - Item 3 + Item 3 ) diff --git a/src/Menu/styles.ts b/src/Menu/styles.ts new file mode 100644 index 00000000..1a27684d --- /dev/null +++ b/src/Menu/styles.ts @@ -0,0 +1,54 @@ +import { styleComposition } from '../utils/styles' + +import styled, { css } from 'styled-components' + +export interface ExpandProps { + expand: boolean +} + +export const TitleWrapper = styled.div` + display: block; + padding: 8px 10px; + color: ${(props) => (props.expand ? props.theme.colors.light : null)}; + + &:hover { + color: ${(props) => props.theme.colors.light}; + cursor: pointer; + } +` + +export const SubMenuWrapper = styled.div` + display: block; +` + +export const ItemWrapper = styled.ul` + ${styleComposition} + + height: 100%; + margin: 0; + overflow: auto; +` + +const ArrowDown = css` + transform: rotate(45deg); +` + +const ArrowUp = css` + transform: rotate(-135deg); +` + +export const Arrow = styled.i` + display: inline-block; + margin: 10px; + padding: 3px; + float: right; + border: solid ${(props) => (props.expand ? props.theme.colors.light : null)}; + border-width: 0 3px 3px 0; + + ${(props) => (props.expand ? ArrowUp : ArrowDown)}; + + ${TitleWrapper}:hover & { + border: solid ${(props) => props.theme.colors.light}; + border-width: 0 3px 3px 0; + } +` From 8b065dc1930e83ed1b8b1bb1a890d1939a285dfe Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Sat, 13 Jun 2020 02:18:47 -0700 Subject: [PATCH 2/2] fix: update snapshot --- .../__snapshots__/Dropdown.spec.tsx.snap | 4 +- src/Menu/Menu.tsx | 2 +- .../__snapshots__/Menu.spec.tsx.snap | 79 +++++++++++++------ 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/src/Dropdown/__tests__/__snapshots__/Dropdown.spec.tsx.snap b/src/Dropdown/__tests__/__snapshots__/Dropdown.spec.tsx.snap index fda564f8..d8d9ebec 100644 --- a/src/Dropdown/__tests__/__snapshots__/Dropdown.spec.tsx.snap +++ b/src/Dropdown/__tests__/__snapshots__/Dropdown.spec.tsx.snap @@ -2,7 +2,7 @@ exports[`Menu & Menu Items renders correctly 1`] = `
@@ -13,7 +13,7 @@ exports[`Menu & Menu Items renders correctly 1`] = ` Hover Me
`; diff --git a/src/Menu/Menu.tsx b/src/Menu/Menu.tsx index b90084bf..e1c64602 100644 --- a/src/Menu/Menu.tsx +++ b/src/Menu/Menu.tsx @@ -1,6 +1,6 @@ import { styleComposition } from '../utils/styles' -import { SubMenu } from './Submenu' +import { SubMenu } from './SubMenu' import { MenuItem } from './MenuItem' import { MenuProps, MenuContext } from './useMenu' diff --git a/src/Menu/__tests__/__snapshots__/Menu.spec.tsx.snap b/src/Menu/__tests__/__snapshots__/Menu.spec.tsx.snap index 631954d8..912efe0a 100644 --- a/src/Menu/__tests__/__snapshots__/Menu.spec.tsx.snap +++ b/src/Menu/__tests__/__snapshots__/Menu.spec.tsx.snap @@ -2,47 +2,70 @@ exports[`Block Menu & Menu Items renders correctly 1`] = `
    -
  • - - Item 1 - -
  • -
  • + Sub Menu 1 + + +
+
    +
+
- - Item 2 - - -
  • + Sub Menu 2 + + +
  • +
      + +
      - Item 3 - + /> +
      +
    • + Item 3
    `; exports[`Inline Menu & Menu Items renders correctly 1`] = `