Skip to content

Commit

Permalink
feat: ProgressionSidebar component (nodejs#6104)
Browse files Browse the repository at this point in the history
* feat: ProgressionSidebar component

* fix: safari content-fit not working as expected

* refactor: review updates

* refactor: revert pseudo notation

* refactor: pseudo class and content added

* refactor: self review

* refactor: review updates
  • Loading branch information
canerakdas committed Nov 15, 2023
1 parent 33f1824 commit 8aace7d
Show file tree
Hide file tree
Showing 8 changed files with 266 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
.group {
@apply flex
flex-col
gap-4
text-sm
font-medium
text-neutral-800
dark:text-neutral-200;

.items {
@apply relative
-left-1
flex
flex-col
gap-2;

&::after {
@apply absolute
left-[calc(0.5rem-0.5px)]
top-0
z-10
h-full
w-px
bg-neutral-200
content-['']
dark:bg-neutral-800;
}

a {
&:first-child::before {
@apply absolute
bottom-[calc(50%+0.25rem)]
left-0
h-20
w-4
bg-white
content-['']
dark:bg-neutral-950;
}

&:last-child::after {
@apply absolute
left-0
top-[calc(50%+0.25rem)]
h-20
w-4
bg-white
content-['']
dark:bg-neutral-950;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { ComponentProps, FC } from 'react';

import ProgressionSidebarItem from '@/components/Containers/ProgressionSidebar/ProgressionSidebarItem';

import styles from './index.module.css';

type ProgressionSidebarGroupProps = {
name: string;
items: ComponentProps<typeof ProgressionSidebarItem>[];
};

const ProgressionSidebarGroup: FC<ProgressionSidebarGroupProps> = ({
name,
items,
}) => (
<div className={styles.group}>
{name}
<div className={styles.items}>
{items.map(({ url, title }) => (
<ProgressionSidebarItem key={url} url={url} title={title} />
))}
</div>
</div>
);

export default ProgressionSidebarGroup;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { FC, SVGAttributes } from 'react';

const ProgressionSidebarIcon: FC<SVGAttributes<SVGSVGElement>> = props => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="18"
viewBox="0 0 16 18"
fill="none"
{...props}
>
<path d="M9 3.26795L8 2.6906L7 3.26795L3.5359 5.26795L2.5359 5.8453V7V11V12.1547L3.5359 12.7321L7 14.7321L8 15.3094L9 14.7321L12.4641 12.7321L13.4641 12.1547V11V7V5.8453L12.4641 5.26795L9 3.26795Z" />
</svg>
);

export default ProgressionSidebarIcon;
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
a.item {
@apply relative
z-20
flex
w-full
items-center
gap-1
overflow-hidden
text-sm
font-regular
text-neutral-800
hover:text-neutral-900
dark:text-neutral-200
dark:hover:text-white;

svg {
@apply flex-shrink-0
fill-neutral-200
stroke-white
stroke-[4]
dark:fill-neutral-800
dark:stroke-neutral-950;
}

&.active {
@apply text-neutral-900
dark:text-white;

svg {
@apply fill-green-500;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { FC } from 'react';

import ActiveLink from '@/components/Common/ActiveLink';
import ProgressionSidebarIcon from '@/components/Containers/ProgressionSidebar/ProgressionSidebarIcon';

import styles from './index.module.css';

type ProgressionSidebarItemProps = {
url: string;
title: string;
};

const ProgressionSidebarItem: FC<ProgressionSidebarItemProps> = ({
url,
title,
}) => (
<ActiveLink
className={styles.item}
activeClassName={styles.active}
href={url}
>
<ProgressionSidebarIcon />
{title}
</ActiveLink>
);

export default ProgressionSidebarItem;
13 changes: 13 additions & 0 deletions components/Containers/ProgressionSidebar/index.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.wrapper {
@apply flex
flex-col
gap-8
overflow-auto
border-r
border-neutral-200
bg-white
p-6
dark:border-neutral-900
dark:bg-neutral-950
md:max-w-xs;
}
79 changes: 79 additions & 0 deletions components/Containers/ProgressionSidebar/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import type { Meta as MetaObj, StoryObj } from '@storybook/react';

import ProgressionSidebar from '@/components/Containers/ProgressionSidebar';

type Story = StoryObj<typeof ProgressionSidebar>;
type Meta = MetaObj<typeof ProgressionSidebar>;

export const Default: Story = {
args: {
groups: [
{
name: 'Getting Started',
items: [
{
title: 'Introduction to Node.js',
url: '/',
},
{
title: 'How to install Node.js',
url: '/how-to-install-nodejs',
},
{
title: 'How much JavaScript do you need to know to use Node.js?',
url: '/how-much-javascript-do-you-need-to-know-to-use-nodejs',
},
{
title: 'Differences between Node.js and the Browser',
url: '/differences-between-nodejs-and-the-browser',
},
{
title: 'The V8 JavaScript Engine',
url: '/the-v8-javascript-engine',
},
{
title: 'An introduction to the NPM package manager',
url: '/an-introduction-to-the-npm-package-manager',
},
],
},
{
name: 'Asynchronous Work',
items: [
{
title: 'Asynchronous flow control',
url: '/asynchronous-flow-control',
},
{
title: 'Overview of Blocking vs Non-Blocking',
url: '/overview-of-blocking-vs-non-blocking',
},
],
},
{
name: 'Manipulating Files',
items: [
{
title: 'Node.js file stats',
url: '/nodejs-file-stats',
},
{
title: 'Node.js File Paths',
url: '/nodejs-file-paths',
},
],
},
{
name: 'Single item',
items: [
{
title: 'Item',
url: '/item',
},
],
},
],
},
};

export default { component: ProgressionSidebar } as Meta;
19 changes: 19 additions & 0 deletions components/Containers/ProgressionSidebar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { ComponentProps, FC } from 'react';

import ProgressionSidebarGroup from '@/components/Containers/ProgressionSidebar/ProgressionSidebarGroup';

import styles from './index.module.css';

type ProgressionSidebarProps = {
groups: ComponentProps<typeof ProgressionSidebarGroup>[];
};

const ProgressionSidebar: FC<ProgressionSidebarProps> = ({ groups }) => (
<nav className={styles.wrapper}>
{groups.map(({ name, items }) => (
<ProgressionSidebarGroup key={name} name={name} items={items} />
))}
</nav>
);

export default ProgressionSidebar;

0 comments on commit 8aace7d

Please sign in to comment.