Skip to content

Commit

Permalink
feat: side context links
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Jun 1, 2020
1 parent c8857e6 commit 9f8dd0c
Show file tree
Hide file tree
Showing 14 changed files with 255 additions and 232 deletions.
1 change: 1 addition & 0 deletions integrations/gatsby-theme-stories/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
},
"license": "MIT",
"dependencies": {
"@component-controls/app": "^1.1.0",
"@component-controls/app-components": "^1.1.0",
"@component-controls/components": "^1.1.0",
"@component-controls/blocks": "^1.1.0",
Expand Down
6 changes: 5 additions & 1 deletion integrations/gatsby-theme-stories/src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** @jsx jsx */
import { FC } from 'react';
import { FC, useRef } from 'react';
import { jsx, Container, Flex } from 'theme-ui';
import { Global } from '@emotion/core';
import {
Expand All @@ -9,6 +9,7 @@ import {
TabList,
TabPanel,
} from '@component-controls/components';
import { SideContext } from '@component-controls/app';
import { SidebarContextProvider } from '@component-controls/app-components';
import { PageContainer } from '@component-controls/blocks';
import { Store } from '@component-controls/store';
Expand All @@ -33,6 +34,7 @@ export const Layout: FC<LayoutProps> = ({
kindPath,
}) => {
const pages = pagesFn ? pagesFn('') : null;
const pageRef = useRef<HTMLDivElement>(null);
return (
<ThemeProvider>
<Global
Expand Down Expand Up @@ -61,6 +63,7 @@ export const Layout: FC<LayoutProps> = ({
store={storyStore}
storyId={storyId}
maxWidth={1200}
ref={pageRef}
>
{pages &&
pages.map(page => (
Expand All @@ -71,6 +74,7 @@ export const Layout: FC<LayoutProps> = ({
</PageContainer>
</Tabs>
</Container>
<SideContext pageRef={pageRef} />
</Flex>
</SidebarContextProvider>
</ThemeProvider>
Expand Down
94 changes: 11 additions & 83 deletions integrations/gatsby-theme-stories/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
/** @jsx jsx */
import { FC, useState, useMemo, useContext } from 'react';
import { jsx, Input, LinkProps, Box, Theme } from 'theme-ui';
import { FC } from 'react';
import { jsx, LinkProps, Theme } from 'theme-ui';

import { graphql, useStaticQuery, Link as GatsbyLink } from 'gatsby';
import { StoriesKind } from '@component-controls/specification';
import {
Sidebar as AppSidebar,
ColorMode,
SidebarContext,
Navmenu,
MenuItems,
MenuItem,
Header,
} from '@component-controls/app-components';
import { Sidebar as AppSidebar } from '@component-controls/app';

import { useSiteMetadata } from '../hooks/use-site-metadata';

Expand All @@ -37,40 +29,8 @@ export interface SidebarProps {
kindPath?: string;
}

const createMenuItem = (
levels: string[],
allLevels: string[],
parent?: MenuItems,
item?: MenuItem,
): MenuItem => {
if (levels.length < 1) {
return item || {};
}
const newItem: MenuItem = {
id: levels[0],
label: levels[0],
};
const sibling = parent && parent.find(i => i.id === newItem.id);
if (parent && !sibling) {
if (levels.length > 1) {
newItem.items = [];
} else {
newItem.id = allLevels.join('/');
//@ts-ignore
newItem.to = `/docs/${allLevels.join('/')}`;
}
parent.push(newItem);
}
return createMenuItem(
levels.slice(1),
levels,
sibling ? sibling.items : newItem.items,
newItem,
);
};
export const Sidebar: FC<SidebarProps> = ({ kindPath }) => {
const { siteTitle } = useSiteMetadata();
const { SidebarClose, responsive } = useContext(SidebarContext);
const data = useStaticQuery(graphql`
query {
allStoryKind {
Expand All @@ -82,48 +42,16 @@ export const Sidebar: FC<SidebarProps> = ({ kindPath }) => {
}
}
`);
const kinds = data.allStoryKind.edges;

const menuItems = useMemo(() => {
const menuItems = kinds.reduce(
(acc: MenuItems, { node: kind }: { node: StoriesKind }) => {
const levels = kind.title.split('/');
createMenuItem(levels, levels, acc);
return acc;
},
[],
);
return menuItems;
}, [kinds]);
const kinds = data.allStoryKind.edges.map(
({ node }: { node: StoriesKind }) => node,
);

const [search, setSearch] = useState<string | undefined>(undefined);
return (
<AppSidebar
sx={{ borderRight: (t: Theme) => `1px solid ${t.colors?.shadow}` }}
width={380}
>
{responsive && (
<Header shadow={false}>
<SidebarClose />
<ColorMode />
</Header>
)}
<Box sx={{ px: 2 }}>
{siteTitle}
<Box sx={{ py: 2, px: 3 }}>
<Input
placeholder="filter stories..."
value={search}
onChange={e => setSearch(e.target.value)}
/>
</Box>
<Navmenu
buttonClass={Link}
activeItem={{ id: kindPath }}
search={search}
items={menuItems}
/>
</Box>
</AppSidebar>
title={siteTitle}
kinds={kinds}
kindPath={kindPath}
buttonClass={Link}
/>
);
};
1 change: 0 additions & 1 deletion ui/app-components/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ Third-party libraries used in no particular order:

- [theme-ui](https://theme-ui.com) as the theming and components foundation.
- [octicons](https://octicons.github.com) for icons used in the components.
- [react-simple-resizer](https://github.com/LeetCode-OpenSource/react-simple-resizer) for panels resizing.

# List of components

Expand Down
37 changes: 23 additions & 14 deletions ui/app-components/src/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const Sidebar: FC<SidebarProps & BoxProps> = ({
overflowY: 'auto',
overflowX: 'hidden',
width,
position: 'relative',
};
const style: SxStyleProp = !responsive
? defaultStyle
Expand All @@ -53,21 +54,29 @@ export const Sidebar: FC<SidebarProps & BoxProps> = ({
};
return collapsed ? null : (
<Box sx={style} {...rest}>
<Flex sx={{ pb: 1, flexDirection: 'row', alignItems: 'center' }}>
{title && (
<Box as="header">
{typeof title === 'string' ? (
<Heading as="h3" sx={{ pl: 2 }}>
{title}
</Heading>
) : (
title
)}
</Box>
)}
</Flex>
<div sx={{ position: 'fixed' }}>
<Flex
sx={{
pb: 1,
flexDirection: 'row',
alignItems: 'center',
}}
>
{title && (
<Box as="header">
{typeof title === 'string' ? (
<Heading as="h3" sx={{ pl: 2 }}>
{title}
</Heading>
) : (
title
)}
</Box>
)}
</Flex>

{children}
{children}
</div>
</Box>
);
};
2 changes: 1 addition & 1 deletion ui/app/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@component-controls/app",
"version": "1.2.0",
"description": "Component controls application.",
"description": "Component controls standalone application.",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"typings": "dist/index.d.ts",
Expand Down
61 changes: 61 additions & 0 deletions ui/app/src/SideContext/SideContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/** @jsx jsx */
import { FC, ReactNode, RefObject, useEffect, useState } from 'react';
import { jsx, Box, NavLink, Flex, Theme } from 'theme-ui';

import {
Sidebar as AppSidebar,
SidebarContext,
SidebarContextProvider,
Header,
} from '@component-controls/app-components';

export interface SideContext {
pageRef?: RefObject<HTMLDivElement>;
}

export const SideContext: FC<SideContext> = ({ pageRef }) => {
const [items, setItems] = useState<ReactNode[] | undefined>();
useEffect(() => {
const links: ReactNode[] = [];
const pageEl = pageRef?.current;
if (pageEl) {
const anchors = pageEl.querySelectorAll('a[data-title]');
if (anchors.length > 0) {
anchors.forEach((anchor, index) => {
const href = anchor.getAttribute('href');
if (href) {
links.push(
<NavLink key={`context_link_${index}`} href={href}>
{anchor.getAttribute('data-title')}
</NavLink>,
);
}
});
}
}
setItems(links.length ? links : undefined);
}, [pageRef]);
return (
<SidebarContextProvider>
<SidebarContext.Consumer>
{({ SidebarClose, responsive }) => (
<AppSidebar width={380}>
{responsive && (
<Header shadow={false}>
<SidebarClose />
</Header>
)}
<Box
sx={{
px: 2,
borderLeft: (t: Theme) => `1px solid ${t.colors?.shadow}`,
}}
>
<Flex sx={{ flexDirection: 'column' }}>{items}</Flex>
</Box>
</AppSidebar>
)}
</SidebarContext.Consumer>
</SidebarContextProvider>
);
};
1 change: 1 addition & 0 deletions ui/app/src/SideContext/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './SideContext';
Loading

0 comments on commit 9f8dd0c

Please sign in to comment.