Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit 097bd8d

Browse files
authored
feat(faq): add toggle menu, re-org codebase (#1311)
1 parent d1c682f commit 097bd8d

File tree

15 files changed

+323
-145
lines changed

15 files changed

+323
-145
lines changed

src/spec/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export type {
8080
TASType,
8181
TASState,
8282
TTagMode,
83+
TMenuOption,
8384
} from './utils'
8485

8586
export type { TGQLError } from './graphql'

src/spec/utils.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,11 @@ export type TASType = 'BUG' | 'FEATURE' | 'DEFAULT' | 'QUESTION' | 'LOCK'
191191
export type TASState = 'TODO' | 'WIP' | 'DONE' | 'DEFAULT' | 'RESOLVE' | 'LOCK'
192192

193193
export type TTagMode = 'default' | 'label'
194+
195+
// for menu button
196+
export type TMenuOption = {
197+
title: string
198+
key: string
199+
icon?: string
200+
link?: string
201+
}

src/widgets/Buttons/IconButton.tsx

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@ import { ICON } from '@/config'
44
import { SVG } from '@/constant'
55

66
import Tooltip from '@/widgets/Tooltip'
7-
import { Wrapper, Icon, Hint, getIcon } from './styles/icon_button'
7+
import {
8+
Wrapper,
9+
Content,
10+
Icon,
11+
Hint,
12+
getIcon,
13+
HoverBg,
14+
} from './styles/icon_button'
815

916
export type TProps = {
1017
path?: string | null
@@ -66,18 +73,21 @@ const IconButton: FC<TProps> = ({
6673
mBottom={mBottom}
6774
onClick={onClick}
6875
>
69-
{hint ? (
70-
<Tooltip
71-
placement={hintPlacement}
72-
content={<Hint>{hint}</Hint>}
73-
noPadding
74-
delay={hintDelay}
75-
>
76-
{realIcon}
77-
</Tooltip>
78-
) : (
79-
<>{realIcon}</>
80-
)}
76+
<>
77+
{hint ? (
78+
<Tooltip
79+
placement={hintPlacement}
80+
content={<Hint>{hint}</Hint>}
81+
noPadding
82+
delay={hintDelay}
83+
>
84+
<Content>{realIcon}</Content>
85+
</Tooltip>
86+
) : (
87+
<Content>{realIcon}</Content>
88+
)}
89+
<HoverBg size={size} />
90+
</>
8191
</Wrapper>
8292
)
8393
}

src/widgets/Buttons/MenuButton/Menu.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { FC, memo } from 'react'
22
import { isEmpty } from 'ramda'
33

4+
import type { TMenuOption } from '@/spec'
5+
46
import { ICON } from '@/config'
57
import { cutRest } from '@/utils/helper'
6-
import type { TOption } from './index'
78

89
import {
910
Wrapper,
@@ -40,8 +41,8 @@ const OptionBlock = ({ item, onClick }) => {
4041
}
4142

4243
type TProps = {
43-
options: TOption[]
44-
extraOptions: TOption[]
44+
options: TMenuOption[]
45+
extraOptions: TMenuOption[]
4546
panelMinWidth: string
4647
onClick?: (key?: string) => void
4748
}

src/widgets/Buttons/MenuButton/index.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { FC, ReactNode, memo } from 'react'
22

33
import { buildLog } from '@/utils/logger'
44

5-
import type { TTooltipPlacement } from '@/spec'
5+
import type { TTooltipPlacement, TMenuOption } from '@/spec'
66

77
import Tooltip from '@/widgets/Tooltip'
88

@@ -12,17 +12,10 @@ import Menu from './Menu'
1212

1313
const log = buildLog('C:MenuButton')
1414

15-
export type TOption = {
16-
title: string
17-
key: string
18-
icon?: string
19-
link?: string
20-
}
21-
2215
type TProps = {
2316
children: ReactNode
24-
options: TOption[]
25-
extraOptions?: TOption[]
17+
options: TMenuOption[]
18+
extraOptions?: TMenuOption[]
2619
placement?: TTooltipPlacement
2720
panelMinWidth?: string
2821
onClick?: (key?: string) => void

src/widgets/Buttons/styles/icon_button.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import ArchivedIcon from '@/icons/article/Archived'
2121

2222
import CollectionIcon from '@/icons/CollectionBookmark'
2323
import ShareIcon from '@/icons/Share'
24+
import MoreLIcon from '@/icons/MoreL'
25+
import MoreIcon from '@/icons/More'
2426

2527
// import CloseCross from '@/icons/CloseCross'
2628
// import AirBalloon from '@/icons/AirBalloon'
@@ -37,14 +39,37 @@ const AirBalloon = dynamic(() => import('@/icons/AirBalloon'), {
3739

3840
type TWrapper = Omit<TIconButtonProps, 'path'>
3941
export const Wrapper = styled.div<TWrapper>`
42+
position: relative;
43+
${({ size }) => css.size(size)}
4044
${css.flex('align-both')};
41-
width: ${({ size }) => `${size}px`};
42-
height: ${({ size }) => `${size}px`};
4345
4446
margin-left: ${({ mLeft }) => `${mLeft}px`};
4547
margin-right: ${({ mRight }) => `${mRight}px`};
4648
margin-top: ${({ mTop }) => `${mTop}px`};
4749
margin-bottom: ${({ mBottom }) => `${mBottom}px`};
50+
51+
/* &:before {
52+
content: '';
53+
${({ size }) => css.circle(size + 2)};
54+
background: ${theme('hoverBg')};
55+
} */
56+
`
57+
export const Content = styled.div`
58+
z-index: 2;
59+
`
60+
export const HoverBg = styled.div<{ size: number }>`
61+
position: absolute;
62+
${({ size }) => css.circle(size + 4)};
63+
left: -2px;
64+
top: -2px;
65+
background: ${theme('hoverBg')};
66+
opacity: 0;
67+
68+
${Wrapper}:hover & {
69+
opacity: 1;
70+
}
71+
72+
transition: 0.25s;
4873
`
4974
type TIcon = { size: number; $dimWhenIdle: boolean } & TSpace & TActive
5075
export const Icon = styled(Img)<TIcon>`
@@ -116,7 +141,12 @@ export const getIcon = (type: string): FC<TIcon> => {
116141
case SVG.COMMENT: {
117142
return getStyledIcon(CommentIcon)
118143
}
119-
144+
case SVG.MOREL: {
145+
return getStyledIcon(MoreLIcon)
146+
}
147+
case SVG.MORE: {
148+
return getStyledIcon(MoreIcon)
149+
}
120150
default: {
121151
return getStyledIcon(UpvoteIcon)
122152
}

src/widgets/Buttons/styles/menu_button/menu.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ export const Block = styled.div`
1717
padding-left: 15px;
1818
1919
&:hover {
20-
background: #0d3e4e;
20+
background: ${theme('hoverBg')};
2121
cursor: pointer;
2222
}
2323
`
2424
export const Divider = styled.div`
2525
width: 100%;
2626
height: 1px;
27-
background: #0d3e4e;
27+
background: ${theme('border')};
2828
margin-top: 3px;
2929
margin-bottom: 3px;
3030
`

src/widgets/FaqList/Collapse.tsx

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { FC, memo, useCallback } from 'react'
2+
import { pluck } from 'ramda'
3+
4+
import type { TID, TMenuOption, TArticle } from '@/spec'
5+
6+
import { SVG } from '@/constant'
7+
8+
import IconButton from '@/widgets/Buttons/IconButton'
9+
import MenuButton from '@/widgets/Buttons/MenuButton'
10+
11+
import { Wrapper, Title, MenuWrapper } from '../styles/collapse/banner'
12+
13+
type TProps = {
14+
menuOptions: TMenuOption[]
15+
setOpenedIDs: (ids: TID[]) => void
16+
articles: TArticle[]
17+
}
18+
19+
const Banner: FC<TProps> = ({ menuOptions, setOpenedIDs, articles }) => {
20+
const foldAll = useCallback(() => setOpenedIDs([]), [])
21+
const unFoldAll = useCallback(
22+
() => setOpenedIDs(pluck('id', articles)),
23+
[articles, setOpenedIDs],
24+
)
25+
26+
const handleMenu = useCallback(
27+
(key) => {
28+
switch (key) {
29+
case 'fold': {
30+
return foldAll()
31+
}
32+
case 'unfold': {
33+
return unFoldAll()
34+
}
35+
36+
default: {
37+
console.log('todo')
38+
}
39+
}
40+
},
41+
[foldAll, unFoldAll],
42+
)
43+
44+
return (
45+
<Wrapper>
46+
<Title>常见问题</Title>
47+
<MenuWrapper>
48+
<MenuButton
49+
placement="bottom-end"
50+
options={menuOptions}
51+
onClick={(key) => handleMenu(key)}
52+
>
53+
<IconButton icon={SVG.MORE} mRight={0} />
54+
</MenuButton>
55+
</MenuWrapper>
56+
</Wrapper>
57+
)
58+
}
59+
60+
export default memo(Banner)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { FC, memo } from 'react'
2+
3+
import { includes } from 'ramda'
4+
5+
import type { TID, TArticle } from '@/spec'
6+
import {
7+
Wrapper,
8+
Header,
9+
Title,
10+
ArrowIcon,
11+
Body,
12+
} from '../styles/collapse/section'
13+
14+
type TProps = {
15+
item: TArticle
16+
openedIDs: TID[]
17+
toggle: (id: TID) => void
18+
}
19+
20+
const Section: FC<TProps> = ({ item, openedIDs, toggle }) => {
21+
const isOpened = includes(item.id, openedIDs)
22+
23+
return (
24+
<Wrapper>
25+
<Header onClick={() => toggle(item.id)}>
26+
<Title $active={isOpened}>{item.title}</Title>
27+
<ArrowIcon $active={isOpened} />
28+
</Header>
29+
30+
<Body show={isOpened}>{item.body}</Body>
31+
</Wrapper>
32+
)
33+
}
34+
35+
export default memo(Section)

0 commit comments

Comments
 (0)