Improve the toggle buttons on the library menu

This commit is contained in:
Jackson Harper 2023-08-29 15:55:01 +08:00
parent 8851017100
commit 32b52efba7
3 changed files with 169 additions and 107 deletions

View file

@ -0,0 +1,32 @@
/* eslint-disable functional/no-class */
/* eslint-disable functional/no-this-expression */
import { IconProps } from './IconProps'
import React from 'react'
export class ToggleCaretDownIcon extends React.Component<IconProps> {
render() {
const size = (this.props.size || 26).toString()
const color = (this.props.color || '#2A2A2A').toString()
return (
<svg
width={size}
height={size}
viewBox="0 0 26 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M6.57812 10.3379L12.8281 16.5879L19.0781 10.3379"
stroke={color}
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
</svg>
)
}
}

View file

@ -0,0 +1,32 @@
/* eslint-disable functional/no-class */
/* eslint-disable functional/no-this-expression */
import { IconProps } from './IconProps'
import React from 'react'
export class ToggleCaretLeftIcon extends React.Component<IconProps> {
render() {
const size = (this.props.size || 26).toString()
const color = (this.props.color || '#2A2A2A').toString()
return (
<svg
width={size}
height={size}
viewBox="0 0 26 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M15.9531 6.77344L9.70312 13.0234L15.9531 19.2734"
stroke={color}
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</g>
</svg>
)
}
}

View file

@ -1,9 +1,8 @@
import { ReactNode, useMemo, useState } from 'react'
import { ReactNode, useMemo } from 'react'
import { StyledText } from '../../elements/StyledText'
import { Box, HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives'
import { Dropdown, DropdownOption } from '../../elements/DropdownElements'
import { Button } from '../../elements/Button'
import { CaretRight, Circle, DotsThree, Plus } from 'phosphor-react'
import { CaretRight, Circle } from 'phosphor-react'
import { useGetSubscriptionsQuery } from '../../../lib/networking/queries/useGetSubscriptionsQuery'
import { useGetLabelsQuery } from '../../../lib/networking/queries/useGetLabelsQuery'
import { Label } from '../../../lib/networking/fragments/labelFragment'
@ -11,6 +10,10 @@ import { theme } from '../../tokens/stitches.config'
import { useRegisterActions } from 'kbar'
import { LogoBox } from '../../elements/LogoBox'
import { usePersistedState } from '../../../lib/hooks/usePersistedState'
import { ToggleCaretDownIcon } from '../../elements/icons/ToggleCaretDownIcon'
import { ToggleCaretLeftIcon } from '../../elements/icons/ToggleCaretLeftIcon'
import Link from 'next/link'
import { ArrowRightIcon } from '../../elements/icons/ArrowRightIcon'
export const LIBRARY_LEFT_MENU_WIDTH = '233px'
@ -130,16 +133,26 @@ function SavedSearches(props: LibraryFilterMenuProps): JSX.Element {
[]
)
const [collapsed, setCollapsed] = usePersistedState<boolean>({
key: `--saved-searches-collapsed`,
initialValue: false,
})
return (
<MenuPanel title="Saved Searches">
{items.map((item) => (
<FilterButton
key={item.name}
text={item.name}
filterTerm={item.term}
{...props}
/>
))}
<MenuPanel
title="Saved Searches"
collapsed={collapsed}
setCollapsed={setCollapsed}
>
{!collapsed &&
items.map((item) => (
<FilterButton
key={item.name}
text={item.name}
filterTerm={item.term}
{...props}
/>
))}
<Box css={{ height: '10px' }}></Box>
</MenuPanel>
@ -148,8 +161,8 @@ function SavedSearches(props: LibraryFilterMenuProps): JSX.Element {
function Subscriptions(props: LibraryFilterMenuProps): JSX.Element {
const { subscriptions } = useGetSubscriptionsQuery()
const [viewAll, setViewAll] = usePersistedState<boolean>({
key: `--subscriptions-view-all`,
const [collapsed, setCollapsed] = usePersistedState<boolean>({
key: `--subscriptions-collapsed`,
initialValue: false,
})
@ -173,15 +186,10 @@ function Subscriptions(props: LibraryFilterMenuProps): JSX.Element {
return (
<MenuPanel
title="Subscriptions"
editTitle="Edit Subscriptions"
editFunc={() => {
window.location.href = '/settings/subscriptions'
}}
viewAll={() => {
setViewAll(true)
}}
collapsed={collapsed}
setCollapsed={setCollapsed}
>
{viewAll ? (
{!collapsed ? (
<>
<FilterButton filterTerm={`label:RSS`} text="Feeds" {...props} />
<FilterButton
@ -199,7 +207,10 @@ function Subscriptions(props: LibraryFilterMenuProps): JSX.Element {
/>
)
})}
<ViewAllButton state={viewAll} setState={setViewAll} />
<EditButton
title="Edit Subscriptions"
destination="/settings/subscriptions"
/>
</>
) : (
<SpanBox css={{ mb: '10px' }} />
@ -210,8 +221,8 @@ function Subscriptions(props: LibraryFilterMenuProps): JSX.Element {
function Labels(props: LibraryFilterMenuProps): JSX.Element {
const { labels } = useGetLabelsQuery()
const [viewAll, setViewAll] = usePersistedState<boolean>({
key: `--labels-view-all`,
const [collapsed, setCollapsed] = usePersistedState<boolean>({
key: `--labels-collapsed`,
initialValue: false,
})
@ -224,16 +235,18 @@ function Labels(props: LibraryFilterMenuProps): JSX.Element {
return (
<MenuPanel
title="Labels"
editTitle="Edit Labels"
hideBottomBorder={true}
editFunc={() => {
window.location.href = '/settings/labels'
}}
collapsed={collapsed}
setCollapsed={setCollapsed}
>
{sortedLabels.slice(0, viewAll ? undefined : 4).map((item) => {
return <LabelButton key={item.id} label={item} {...props} />
})}
<ViewAllButton state={viewAll} setState={setViewAll} />
{!collapsed && (
<>
{sortedLabels.map((item) => {
return <LabelButton key={item.id} label={item} {...props} />
})}
<EditButton title="Edit Labels" destination="/settings/labels" />
</>
)}
</MenuPanel>
)
}
@ -241,10 +254,11 @@ function Labels(props: LibraryFilterMenuProps): JSX.Element {
type MenuPanelProps = {
title: string
children: ReactNode
editFunc?: () => void
editTitle?: string
hideBottomBorder?: boolean
viewAll?: () => void
collapsed: boolean
setCollapsed: (collapsed: boolean) => void
}
function MenuPanel(props: MenuPanelProps): JSX.Element {
@ -278,57 +292,32 @@ function MenuPanel(props: MenuPanelProps): JSX.Element {
</StyledText>
<SpanBox
css={{
mt: '15px',
mt: '17px',
mr: '-2px',
marginLeft: 'auto',
height: '100%',
verticalAlign: 'middle',
}}
>
{props.editTitle && props.editFunc && (
<Dropdown
triggerElement={
<Box
css={{
display: 'flex',
height: '30px',
width: '30px',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '1000px',
cursor: 'pointer',
'&:hover': {
bg: '$thBackground4',
},
}}
>
<DotsThree
size={25}
weight="bold"
color={theme.colors.thTextSubtle2.toString()}
/>
</Box>
}
>
{props.viewAll && (
<DropdownOption
title="View All"
onSelect={() => {
if (props.viewAll) {
props.viewAll()
}
}}
/>
)}
<DropdownOption
title={props.editTitle}
onSelect={() => {
if (props.editFunc) {
props.editFunc()
}
}}
<Button
style="articleActionIcon"
onClick={(event) => {
props.setCollapsed(!props.collapsed)
event.preventDefault()
}}
>
{props.collapsed ? (
<ToggleCaretLeftIcon
size={15}
color={theme.colors.thLibraryMenuPrimary.toString()}
/>
</Dropdown>
)}
) : (
<ToggleCaretDownIcon
size={15}
color={theme.colors.thLibraryMenuPrimary.toString()}
/>
)}
</Button>
</SpanBox>
</HStack>
{props.children}
@ -492,34 +481,43 @@ function LabelButton(props: LabelButtonProps): JSX.Element {
)
}
type ViewAllButtonProps = {
state: boolean
setState: (state: boolean) => void
type EditButtonProps = {
title: string
destination: string
}
function ViewAllButton(props: ViewAllButtonProps): JSX.Element {
function EditButton(props: EditButtonProps): JSX.Element {
return (
<Button
style="ghost"
css={{
display: 'flex',
pl: '10px',
color: '#898989',
fontWeight: '600',
fontSize: '12px',
py: '20px',
gap: '2px',
alignItems: 'center',
}}
onClick={(e) => {
props.setState(!props.state)
e.preventDefault()
}}
>
{props.state ? 'Hide' : 'View All'}
{props.state ? null : (
<CaretRight size={12} color="#898989" weight="bold" />
)}
</Button>
<Link href={props.destination} passHref>
<SpanBox
css={{
ml: '10px',
mb: '10px',
display: 'flex',
alignItems: 'center',
gap: '2px',
'&:hover': {
textDecoration: 'underline',
},
width: '100%',
maxWidth: '100%',
height: '32px',
fontSize: '14px',
fontWeight: 'regular',
fontFamily: '$display',
color: '$thLibraryMenuUnselected',
verticalAlign: 'middle',
borderRadius: '3px',
cursor: 'pointer',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}
>
{props.title}
</SpanBox>
</Link>
)
}