mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-17 23:44:39 -05:00
Updated sidebar menu and search
This commit is contained in:
parent
912664625f
commit
0abc6381f7
6 changed files with 89 additions and 41 deletions
|
@ -35,7 +35,7 @@ const MainContent = () => {
|
||||||
<div className='z-0 pt-[102px]'>
|
<div className='z-0 pt-[102px]'>
|
||||||
<Content route={mainRoute} />
|
<Content route={mainRoute} />
|
||||||
</div>
|
</div>
|
||||||
<Sidebar />
|
<Sidebar route={mainRoute} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -704,7 +704,7 @@ const ArticleModal: React.FC<ArticleModalProps> = ({
|
||||||
width={modalSize === MODAL_SIZE_LG ? 'toSidebar' : modalSize}
|
width={modalSize === MODAL_SIZE_LG ? 'toSidebar' : modalSize}
|
||||||
>
|
>
|
||||||
<div className='flex h-full flex-col'>
|
<div className='flex h-full flex-col'>
|
||||||
<div className='sticky top-0 z-50 flex h-[97px] items-center justify-center border-b border-gray-200 bg-white'>
|
<div className='sticky top-0 z-50 flex h-[102px] items-center justify-center border-b border-gray-200 bg-white'>
|
||||||
<div
|
<div
|
||||||
className={`w-full ${modalSize === MODAL_SIZE_LG ? 'grid px-8' : 'flex justify-between gap-2 px-8'}`}
|
className={`w-full ${modalSize === MODAL_SIZE_LG ? 'grid px-8' : 'flex justify-between gap-2 px-8'}`}
|
||||||
style={modalSize === MODAL_SIZE_LG ? {
|
style={modalSize === MODAL_SIZE_LG ? {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {H1} from '@tryghost/shade';
|
import {Button, H1, LucideIcon} from '@tryghost/shade';
|
||||||
|
import {useRouting} from '@tryghost/admin-x-framework/routing';
|
||||||
|
|
||||||
interface HeaderProps {
|
interface HeaderProps {
|
||||||
route: string;
|
route: string;
|
||||||
|
@ -20,6 +21,9 @@ const getTitle = (route: string) => {
|
||||||
case 'notifications':
|
case 'notifications':
|
||||||
return 'Notifications';
|
return 'Notifications';
|
||||||
break;
|
break;
|
||||||
|
case 'search':
|
||||||
|
return 'Search';
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 'Inbox';
|
return 'Inbox';
|
||||||
|
@ -28,12 +32,17 @@ const getTitle = (route: string) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const Header: React.FC<HeaderProps> = ({route}) => {
|
const Header: React.FC<HeaderProps> = ({route}) => {
|
||||||
|
const {updateRoute} = useRouting();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='fixed left-[320px] right-0 top-0 z-10 bg-white px-8'>
|
className='fixed left-[320px] right-0 top-0 z-10 bg-white px-8'>
|
||||||
<div className='flex h-[102px] items-center justify-between gap-5 border-b border-gray-200'>
|
<div className='flex h-[102px] items-center justify-between gap-5 border-b border-gray-200'>
|
||||||
<H1>{getTitle(route)}</H1>
|
<H1>{getTitle(route)}</H1>
|
||||||
<span className='flex h-9 w-[274px] items-center rounded-full bg-gray-200 px-4 text-gray-600'>Search</span>
|
<Button className='h-9 w-[274px] justify-start rounded-full bg-gray-100 text-md text-gray-600 hover:bg-gray-200 hover:text-gray-600 [&_svg]:size-[18px]' variant='ghost' onClick={() => updateRoute('search')}>
|
||||||
|
<LucideIcon.Search size={18} strokeWidth={1.5} />
|
||||||
|
Search
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,46 +1,58 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import Recommendations from './Recommendations';
|
import Recommendations from './Recommendations';
|
||||||
import {Button, Separator, cn} from '@tryghost/shade';
|
import SidebarButton from './SidebarButton';
|
||||||
|
import {Button, LucideIcon, Separator, cn} from '@tryghost/shade';
|
||||||
import {useRouting} from '@tryghost/admin-x-framework/routing';
|
import {useRouting} from '@tryghost/admin-x-framework/routing';
|
||||||
|
|
||||||
interface SidebarProps
|
interface SidebarProps {
|
||||||
extends React.HTMLAttributes<HTMLDivElement> {}
|
route: string;
|
||||||
|
}
|
||||||
|
|
||||||
const Sidebar = React.forwardRef<HTMLDivElement, SidebarProps>(
|
const Sidebar: React.FC<SidebarProps> = ({route}) => {
|
||||||
({className, ...props}, ref) => {
|
const {updateRoute} = useRouting();
|
||||||
const {updateRoute} = useRouting();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={ref}
|
className={cn(
|
||||||
className={cn(
|
'border-l border-gray-200 fixed top-[102px] right-8 w-[294px] min-h-[calc(100vh-102px-32px)]',
|
||||||
'border-l border-gray-200 fixed top-[102px] right-8 w-[294px] min-h-[calc(100vh-102px-32px)]',
|
'pointer-events-none',
|
||||||
'pointer-events-none',
|
'[&>*]:pointer-events-auto'
|
||||||
'[&>*]:pointer-events-auto',
|
)}
|
||||||
className
|
>
|
||||||
)}
|
<div className='flex flex-col gap-8 pl-5 pt-5'>
|
||||||
{...props}
|
<div className='flex flex-col gap-px'>
|
||||||
>
|
<SidebarButton active={route === 'inbox'} onClick={() => updateRoute('inbox')}>
|
||||||
<div className='flex flex-col gap-8 pl-5 pt-5'>
|
<LucideIcon.Inbox size={18} strokeWidth={1.5} />
|
||||||
<div className='flex flex-col gap-2'>
|
Inbox
|
||||||
<Button className='justify-start' variant='ghost' onClick={() => updateRoute('inbox')}>Inbox</Button>
|
</SidebarButton>
|
||||||
<Button className='justify-start' variant='ghost' onClick={() => updateRoute('feed')}>Feed</Button>
|
<SidebarButton active={route === 'feed'} onClick={() => updateRoute('feed')}>
|
||||||
<Button className='justify-start' variant='ghost' onClick={() => updateRoute('notifications')}>Notifications</Button>
|
<LucideIcon.Hash size={18} strokeWidth={1.5} />
|
||||||
<Button className='justify-start' variant='ghost' onClick={() => updateRoute('profile')}>Profile</Button>
|
Feed
|
||||||
</div>
|
</SidebarButton>
|
||||||
|
<SidebarButton active={route === 'notifications'} onClick={() => updateRoute('notifications')}>
|
||||||
<div>
|
<LucideIcon.Bell size={18} strokeWidth={1.5} />
|
||||||
<Button onClick={() => updateRoute('feed')}>New note</Button>
|
Notifications
|
||||||
</div>
|
</SidebarButton>
|
||||||
|
<SidebarButton active={route === 'profile'} onClick={() => updateRoute('profile')}>
|
||||||
<Separator />
|
<LucideIcon.User size={18} strokeWidth={1.5} />
|
||||||
|
Profile
|
||||||
<Recommendations />
|
</SidebarButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Button className='rounded-full bg-purple-500' onClick={() => updateRoute('feed')}>
|
||||||
|
<LucideIcon.FilePen />
|
||||||
|
New note
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Separator />
|
||||||
|
|
||||||
|
<Recommendations />
|
||||||
</div>
|
</div>
|
||||||
);
|
</div>
|
||||||
}
|
);
|
||||||
);
|
};
|
||||||
|
|
||||||
Sidebar.displayName = 'Sidebar';
|
Sidebar.displayName = 'Sidebar';
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import {Button, ButtonProps, cn} from '@tryghost/shade';
|
||||||
|
|
||||||
|
interface SidebarButtonProps extends ButtonProps {
|
||||||
|
active: boolean;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SidebarButton = React.forwardRef<HTMLButtonElement, SidebarButtonProps>(
|
||||||
|
({active, children, ...props}, ref) => {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'justify-start text-md font-medium text-gray-800 h-9 [&_svg]:size-[18px]',
|
||||||
|
active ? 'bg-gray-100 text-black font-semibold' : ''
|
||||||
|
)}
|
||||||
|
variant='ghost'
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
SidebarButton.displayName = 'SidebarButton';
|
||||||
|
|
||||||
|
export default SidebarButton;
|
|
@ -8,7 +8,6 @@ import {useDebounce} from 'use-debounce';
|
||||||
import APAvatar from '@components/global/APAvatar';
|
import APAvatar from '@components/global/APAvatar';
|
||||||
import ActivityItem from '@components/activities/ActivityItem';
|
import ActivityItem from '@components/activities/ActivityItem';
|
||||||
import FollowButton from '@components/global/FollowButton';
|
import FollowButton from '@components/global/FollowButton';
|
||||||
import MainNavigation from '@components/navigation/MainNavigation';
|
|
||||||
import Separator from '@components/global/Separator';
|
import Separator from '@components/global/Separator';
|
||||||
import ViewProfileModal from '@components/modals/ViewProfileModal';
|
import ViewProfileModal from '@components/modals/ViewProfileModal';
|
||||||
|
|
||||||
|
@ -206,7 +205,6 @@ const Search: React.FC<SearchProps> = ({}) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MainNavigation page='search' />
|
|
||||||
<div className='z-0 mx-auto flex w-full max-w-[560px] flex-col items-center pt-8'>
|
<div className='z-0 mx-auto flex w-full max-w-[560px] flex-col items-center pt-8'>
|
||||||
<div className='relative flex w-full items-center'>
|
<div className='relative flex w-full items-center'>
|
||||||
<Icon className='absolute left-3 top-3 z-10' colorClass='text-gray-500' name='magnifying-glass' size='sm' />
|
<Icon className='absolute left-3 top-3 z-10' colorClass='text-gray-500' name='magnifying-glass' size='sm' />
|
||||||
|
|
Loading…
Add table
Reference in a new issue