Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

refactor(help-center): design basic UI/UX#1012

Merged
mydearxym merged 11 commits intodevfromredesign-help-center
Mar 9, 2021
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
11 commits
Select commitHold shift + click to select a range
216109c
chore(redesign): peeklist basic ui/ux
mydearxymMar 6, 2021
c440dde
fix(tags-bar): remove bottom sticky holder
mydearxymMar 6, 2021
022fcab
fix(tags-bar): margin adjust
mydearxymMar 7, 2021
f8d41c1
refactor: re-org tags bar && basic collapse menu comp
mydearxymMar 8, 2021
ce04123
refactor: community banner, join -> member
mydearxymMar 8, 2021
9eafd14
refactor(help-center): basic page UI
mydearxymMar 8, 2021
03e9355
chore(help-center): add size-limit config
mydearxymMar 8, 2021
5ac1c0b
chore(help-center): display real community info on banner
mydearxymMar 9, 2021
e6892e8
chore(help-center): adjust color on banner
mydearxymMar 9, 2021
592d986
refactor(help-center): basic cover/detail view UI/UX
mydearxymMar 9, 2021
e4bcc8c
refactor(help-center): use common LinksCard in FaqList
mydearxymMar 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletionsserver/routes.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -119,6 +119,11 @@ router.route('/discovery/:category').get((req, res) => {
return renderAndCache({ req, res, path: '/discovery' })
})

// 帮助中心
router.route('/:community/help-center').get((req, res) => {
return renderAndCache({ req, res, path: '/help-center' })
})

// 社区主页
router.route('/:community/:thread').get((req, res) => {
if (
Expand Down
4 changes: 4 additions & 0 deletionssize-limit.config.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -51,6 +51,10 @@
{
"path": ".next/server/pages/create/article.js",
"maxSize": "280 kB"
},
{
"path": ".next/server/pages/help-center.js",
"maxSize": "280 kB"
}
],
"ci": {
Expand Down
139 changes: 139 additions & 0 deletionssrc/components/CollapseMenu/Group.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
import React, { useState, useRef, useEffect } from 'react'
import T from 'prop-types'

import { findIndex } from 'ramda'

import { ICON } from '@/config'
import { buildLog } from '@/utils'

import Item from './Item'

import {
Wrapper,
TagsWrapper,
Header,
ArrowIcon,
Title,
Content,
SubToggle,
SubToggleTitle,
SubTogglePrefixIcon,
} from './styles/group'

/* eslint-disable-next-line */
const log = buildLog('c:CollapseMenu:Group')

const Group = ({
title,
groupItems,
items,
activeItem,
onSelect,
maxDisplayCount,
totalToggleThrold,
}) => {
// 决定是否显示 '展示更多' 的时候参考标签总数
const needSubToggle =
items?.length > totalToggleThrold && groupItems.length > maxDisplayCount

const initDisplayCount = needSubToggle ? maxDisplayCount : groupItems.length

const [isFolderOpen, toggleFolder] = useState(true)
const [curDisplayCount, setCurDisplayCount] = useState(initDisplayCount)

const sortedItems = groupItems // sortByColor(groupItems)

const isActiveTagInFolder =
findIndex((item) => item.id === activeItem.id, groupItems) >= 0

const subToggleRef = useRef(null)
// 当选中的 Tag 被折叠在展示更多里面时,将其展开
useEffect(() => {
if (subToggleRef && isActiveTagInFolder) {
setCurDisplayCount(groupItems.length)
}
}, [subToggleRef, isActiveTagInFolder, groupItems])

return (
<Wrapper>
<Header
onClick={() => {
toggleFolder(!isFolderOpen)

// 当关闭 Folder 的时候,如果当前 Folder 没有被激活的 Tag, 那么就回到折叠状态
// 如果有,那么保持原来的状态
if (isFolderOpen && !isActiveTagInFolder) {
setCurDisplayCount(maxDisplayCount)
}
}}
>
<ArrowIcon
isOpen={isFolderOpen}
src={`${ICON}/shape/arrow-simple.svg`}
/>
<Title>{title}</Title>
</Header>

<Content isOpen={isFolderOpen}>
<TagsWrapper>
{sortedItems.slice(0, curDisplayCount).map((item) => (
<Item
key={item.id}
item={item}
active={activeItem.id === item.id}
activeId={activeItem.id}
onSelect={onSelect}
/>
))}
</TagsWrapper>
{needSubToggle && (
<SubToggle
ref={subToggleRef}
onClick={() => {
setCurDisplayCount(
curDisplayCount === maxDisplayCount
? groupItems.length
: maxDisplayCount,
)
}}
>
<SubTogglePrefixIcon src={`${ICON}/shape/more.svg`} />
<SubToggleTitle>
{curDisplayCount === maxDisplayCount ? '展开更多' : '收起'}
</SubToggleTitle>
</SubToggle>
)}
</Content>
</Wrapper>
)
}

Group.propTypes = {
// title, groupItems, items, activeItem, onSelect
title: T.string,
groupItems: T.arrayOf(
T.shape({
id: T.number,
title: T.string,
}),
).isRequired,
items: T.arrayOf(
T.shape({
id: T.number,
title: T.string,
}),
).isRequired,
activeItem: T.shape({
id: T.number,
title: T.string,
}).isRequired,
maxDisplayCount: T.number.isRequired,
totalToggleThrold: T.number.isRequired,
onSelect: T.func.isRequired,
}

Group.defaultProps = {
title: '',
}

export default React.memo(Group)
16 changes: 16 additions & 0 deletionssrc/components/CollapseMenu/Item.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
import React from 'react'

import { Wrapper, Title } from './styles/item'

// const Item = ({ item, active, activeId, onSelect }) => {
const Item = ({ item, active, onSelect }) => {
return (
<Wrapper active={active}>
<Title active={active} onClick={() => onSelect(item)}>
{item.title}
</Title>
</Wrapper>
)
}

export default Item
137 changes: 137 additions & 0 deletionssrc/components/CollapseMenu/index.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
/*
*
* CollapseMenu
*
*/

import React from 'react'
import T from 'prop-types'
import { keys } from 'ramda'

import { buildLog, groupByKey } from '@/utils'

import Group from './Group'

import { Wrapper } from './styles'

const MAX_DISPLAY_COUNT = 5
const TOTAL_TOGGLE_THROLD = 8 // 15

/* eslint-disable-next-line */
const log = buildLog('c:CollapseMenu:index')

const defaultActiveItem = { id: 2 }
const defaultItems = [
{
id: 1,
title: 'coderplanets 是什么?',
group: '基础问答',
},
{
id: 2,
title: '持续部署项目实践',
group: '基础问答',
},
{
id: 3,
title: 'coderplanets 是什么 3?',
group: '基础问答',
},

{
id: 4,
title: 'coderplanets 是什么 4?',
group: '进阶问答',
},
{
id: 5,
title: 'coderplanets 是什么 5?',
group: '进阶问答',
},
{
id: 6,
title: 'coderplanets 是什么 6?',
group: '进阶问答',
},
{
id: 7,
title: 'coderplanets 是什么 7?',
group: '进阶问答',
},
{
id: 8,
title: 'coderplanets 是什么 8?',
group: '进阶问答',
},
{
id: 9,
title: 'coderplanets 是什么 9?',
group: '进阶问答',
},
{
id: 10,
title: 'coderplanets 是什么 10?',
group: '进阶问答',
},
]

const CollapseMenu = ({
testId,
items,
activeItem,
onSelect,
maxDisplayCount,
totalToggleThrold,
}) => {
const groupedItems = groupByKey(items, 'group')
const groupsKeys = keys(groupedItems)

return (
<Wrapper testId={testId}>
{groupsKeys.map((groupKey) => (
<Group
key={groupKey}
title={groupKey}
items={items}
groupItems={groupedItems[groupKey]}
activeItem={activeItem}
maxDisplayCount={maxDisplayCount}
totalToggleThrold={totalToggleThrold}
onSelect={onSelect}
/>
))}
</Wrapper>
)
}

CollapseMenu.propTypes = {
testId: T.string,
items: T.arrayOf(
T.shape({
id: T.number,
title: T.string,
group: T.string,
}),
), // .isRequired,
activeItem: T.shape({
id: T.number,
title: T.string,
group: T.string,
}), // .isRequired,
maxDisplayCount: T.number,
totalToggleThrold: T.number,
onSelect: T.func,
}

CollapseMenu.defaultProps = {
testId: 'collapse-menu',
items: defaultItems,
activeItem: defaultActiveItem,
// default display count in each group, the remaining part will be folded
maxDisplayCount: MAX_DISPLAY_COUNT,
// if items count < than this, will not be folded in each group
totalToggleThrold: TOTAL_TOGGLE_THROLD,
onSelect: console.log,
}

export default React.memo(CollapseMenu)
67 changes: 67 additions & 0 deletionssrc/components/CollapseMenu/styles/group.js
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
import styled from 'styled-components'

import Img from '@/Img'
import { css, theme } from '@/utils'

export const Wrapper = styled.div``

export const TagsWrapper = styled.div``

export const Header = styled.div`
${css.flex('align-center')};
margin-bottom: 8px;
margin-left: 3px;
&:hover {
cursor: pointer;
/* opacity: 0.65; */
}
`
export const ArrowIcon = styled(Img)`
fill: ${theme('tags.text')};
${css.size(16)};
opacity: 0.5;
transform: ${({ isOpen }) => (isOpen ? 'rotate(270deg)' : 'rotate(180deg)')};
transition: transform 0.5s;
${Header}:hover & {
opacity: 0.65;
}
`
export const Title = styled.div`
color: ${theme('tags.text')};
opacity: 0.5;
margin-left: 4px;
font-size: 14px;
margin-right: 8px;
${css.cutFrom('85px')};

${Header}:hover & {
opacity: 0.65;
}
`
export const Content = styled.div`
display: ${({ isOpen }) => (isOpen ? 'block' : 'none')};
width: 100%;
margin-bottom: 15px;
`
export const SubToggle = styled.div`
${css.flex('align-center')};
margin-left: 5px;
opacity: 0.5;

&:hover {
opacity: 0.8;
cursor: pointer;
}
`
export const SubToggleTitle = styled.div`
color: ${theme('tags.text')};
font-size: 12px;
margin-left: 5px;
padding: 2px;
border-radius: 5px;
`
export const SubTogglePrefixIcon = styled(Img)`
fill: ${theme('tags.text')};
${css.size(14)};
transform: rotate(90deg);
`
Loading

[8]ページ先頭

©2009-2025 Movatter.jp