update sidebar styling, closes #48
This commit is contained in:
parent
080d422222
commit
d52c9766ec
5 changed files with 135 additions and 18 deletions
60
src/components/ModuleLayout/SidebarNav/Accordion.tsx
Normal file
60
src/components/ModuleLayout/SidebarNav/Accordion.tsx
Normal file
|
@ -0,0 +1,60 @@
|
|||
import * as React from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import tw from 'twin.macro';
|
||||
import useStickyState from '../../../hooks/useStickyState';
|
||||
|
||||
const Container = styled.div`
|
||||
&:last-of-type {
|
||||
${tw`border-b`}
|
||||
}
|
||||
`;
|
||||
|
||||
const Label = styled.div`
|
||||
&:hover {
|
||||
background-color: #f7faff;
|
||||
}
|
||||
`;
|
||||
|
||||
export default function Accordion({ label, isActive, children }) {
|
||||
const [expanded, setExpanded] = useStickyState(
|
||||
true,
|
||||
'guide:sidebarnav:isexpanded:' + label
|
||||
);
|
||||
useEffect(() => {
|
||||
if (isActive) setExpanded(true);
|
||||
}, [isActive]);
|
||||
return (
|
||||
<Container
|
||||
className="border-t border-gray-200"
|
||||
style={isActive ? { backgroundColor: '#f7faff' } : null}
|
||||
>
|
||||
<Label
|
||||
className="font-medium cursor-pointer text-gray-600 relative flex items-center px-6 py-3 text-sm leading-5"
|
||||
onClick={() => setExpanded(!expanded)}
|
||||
>
|
||||
<span className="flex-1">{label}</span>
|
||||
<svg
|
||||
className="h-5 w-5 flex-shrink-0 text-gray-600"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
{expanded ? (
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
) : (
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
)}
|
||||
</svg>
|
||||
</Label>
|
||||
{expanded && children}
|
||||
</Container>
|
||||
);
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import * as React from 'react';
|
||||
import { Link } from 'gatsby';
|
||||
import { ModuleLinkInfo } from '../../../module';
|
||||
import StyledLink from './StyledLink';
|
||||
|
||||
const ItemLink = ({
|
||||
link,
|
||||
|
@ -13,19 +14,15 @@ const ItemLink = ({
|
|||
|
||||
React.useEffect(() => {
|
||||
if (isActive) {
|
||||
console.log(itemRef);
|
||||
itemRef.current.scrollIntoView({ block: `center` });
|
||||
}
|
||||
}, [isActive]);
|
||||
|
||||
return (
|
||||
<Link
|
||||
to={link.url}
|
||||
className={`flex items-center px-6 py-3 text-sm leading-5 text-gray-600 hover:text-gray-900 hover:bg-gray-100 focus:outline-none focus:bg-gray-200 transition ease-in-out duration-150`}
|
||||
key={link.url}
|
||||
ref={itemRef}
|
||||
>
|
||||
{link.title}
|
||||
<Link to={link.url} key={link.url}>
|
||||
<StyledLink isActive={isActive} ref={itemRef}>
|
||||
{link.title}
|
||||
</StyledLink>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@ import * as React from 'react';
|
|||
import { ModuleLinkInfo } from '../../../module';
|
||||
import { Link } from 'gatsby';
|
||||
import ItemLink from './ItemLink';
|
||||
import Accordion from './Accordion';
|
||||
|
||||
export interface NavLinkGroup {
|
||||
label: string;
|
||||
|
@ -23,18 +24,25 @@ export const SidebarNav = ({
|
|||
const renderLink = (link: NavLinkItem) => {
|
||||
if (link instanceof ModuleLinkInfo) {
|
||||
return (
|
||||
<ItemLink key={link.url} link={link} isActive={link === activeLink} />
|
||||
<ItemLink
|
||||
key={link.url}
|
||||
link={link}
|
||||
isActive={link.id === activeLink.id}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="bg-gray-100 mb-4" key={link.label}>
|
||||
<div
|
||||
className={`flex items-center px-6 py-3 text-sm leading-5 font-medium text-gray-600 border-b border-gray-200`}
|
||||
>
|
||||
{link.label}
|
||||
</div>
|
||||
<Accordion
|
||||
key={link.label}
|
||||
label={link.label}
|
||||
isActive={
|
||||
link.children.findIndex(
|
||||
x => x instanceof ModuleLinkInfo && x.id === activeLink.id
|
||||
) !== -1
|
||||
}
|
||||
>
|
||||
{link.children.map(renderLink)}
|
||||
</div>
|
||||
</Accordion>
|
||||
);
|
||||
};
|
||||
return <>{links.map(renderLink)}</>;
|
||||
|
|
52
src/components/ModuleLayout/SidebarNav/StyledLink.tsx
Normal file
52
src/components/ModuleLayout/SidebarNav/StyledLink.tsx
Normal file
|
@ -0,0 +1,52 @@
|
|||
import styled, { css } from 'styled-components';
|
||||
import tw from 'twin.macro';
|
||||
import { Link } from 'gatsby';
|
||||
|
||||
// Almost entirely copy pasted from https://gatsbyjs.org/ oops
|
||||
|
||||
const StyledLink = styled.span`
|
||||
${tw`focus:outline-none transition ease-in-out duration-150 hover:text-blue-700 focus:bg-blue-100 relative flex items-center px-6 py-3 text-sm leading-5`}
|
||||
|
||||
${({ isActive }) =>
|
||||
isActive
|
||||
? tw`text-blue-700 font-semibold`
|
||||
: tw`text-gray-600`}
|
||||
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
left: 0.5rem;
|
||||
top: 1.3em;
|
||||
height: 8px;
|
||||
width: 8px;
|
||||
position: absolute;
|
||||
transition: all 250ms cubic-bezier(0.4, 0, 0.2, 1) 0s;
|
||||
}
|
||||
|
||||
${props =>
|
||||
props.isActive &&
|
||||
css`
|
||||
&::after {
|
||||
transform: ${props =>
|
||||
props.isActive ? 'translateX(-92px)' : 'translateX(-100px)'};
|
||||
width: 100px;
|
||||
border-radius: 4px;
|
||||
${tw`bg-blue-600`}
|
||||
}
|
||||
`}
|
||||
|
||||
&::before {
|
||||
transform: scale(0.1);
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::before {
|
||||
transform: scale(1);
|
||||
${tw`bg-blue-600`}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default StyledLink;
|
|
@ -29,10 +29,10 @@ export const LanguageSection = props => {
|
|||
return (
|
||||
<>
|
||||
{Object.keys(sections).map(lang => (
|
||||
<>
|
||||
<div key={lang}>
|
||||
<p className="text-lg font-bold">{languages[lang]}</p>
|
||||
{sections[lang]}
|
||||
</>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
|
|
Reference in a new issue