Skip to content

Commit

Permalink
feat: MetaBar Component (#6010)
Browse files Browse the repository at this point in the history
* feat: MetaBar component

* fix: AvatarGroup layout shift

* refactor: Unordered list to ordered list

* refactor: Unnecessary condition removed

* refactor: Heading depth control

* refactor: Metabar type imports

* refactor: More generic prop types for MetaBar component

* chore: Constant naming

* refactor: Link hover state styling

* refactor: Heading default depth

* refactor: Unnecessary constant
  • Loading branch information
canerakdas authored Oct 17, 2023
1 parent 930344d commit 3c59de3
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 0 deletions.
1 change: 1 addition & 0 deletions components/Common/AvatarGroup/index.module.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.avatarGroup {
@apply flex
h-8
items-center;
}
67 changes: 67 additions & 0 deletions components/Common/MetaBar/index.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
.wrapper {
@apply flex
w-80
flex-col
items-start
gap-8
border-l
border-neutral-200
p-6
dark:border-neutral-900;

dt {
@apply mb-2
text-sm
font-medium
text-neutral-800
dark:text-neutral-200;
}

dd {
@apply mb-8
flex
items-center
gap-2
text-sm
text-neutral-900
dark:text-white;

a {
@apply font-semibold
text-neutral-900
underline
hover:text-neutral-800
dark:text-white
dark:hover:text-neutral-200;
}

ol {
@apply flex
list-none
flex-col
gap-1.5
p-0;
}

svg {
@apply h-4
w-4
text-neutral-600
dark:text-neutral-400;
}

&:last-child {
@apply mb-0;
}
}

[data-on-dark] {
@apply hidden
dark:block;
}

[data-on-light] {
@apply block
dark:hidden;
}
}
99 changes: 99 additions & 0 deletions components/Common/MetaBar/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { CodeBracketIcon } from '@heroicons/react/24/outline';
import type { Meta as MetaObj, StoryObj } from '@storybook/react';
import Image from 'next/image';
import { FormattedMessage } from 'react-intl';

import AvatarGroup from '@/components/Common/AvatarGroup';
import LocalizedLink from '@/components/LocalizedLink';

import MetaBar from './index';

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

export const Default: Story = {
args: {
items: {
'components.metabar.lastUpdated': new Date().toLocaleDateString(),
'components.metabar.readingTime': '15 minutes',
'components.metabar.addedIn': 'v1.0.0',
'components.metabar.author': 'The Node.js Project',
'components.metabar.authors': (
<AvatarGroup
avatars={[
{
src: 'https://avatars.githubusercontent.com/canerakdas',
alt: 'Caner Akdas',
},
{
src: 'https://avatars.githubusercontent.com/bmuenzenmeyer',
alt: 'Brian Muenzenmeyer',
},
{
src: 'https://avatars.githubusercontent.com/ovflowd',
alt: 'Claudio W',
},
]}
/>
),
'components.metabar.contribute': (
<>
<Image
src="/static/images/logos/social-github-dark.svg"
alt="GitHub Logo"
width={16}
height={16}
data-on-light
/>
<Image
src="/static/images/logos/social-github.svg"
alt="GitHub Logo"
width={16}
height={16}
data-on-dark
/>
<LocalizedLink href="/contribute">
<FormattedMessage id="components.metabar.contributeText" />
</LocalizedLink>
</>
),
'components.metabar.viewAs': (
<>
<CodeBracketIcon />
<LocalizedLink href="/json">JSON</LocalizedLink>
</>
),
},
headings: {
items: [
{
value: 'OpenSSL update assessment, and Node.js project plans',
depth: 1,
data: { id: 'heading-1' },
},
{
value: 'Summary',
depth: 2,
data: { id: 'summary' },
},
{
value: 'Analysis',
depth: 2,
data: { id: 'analysis' },
},
{
value: 'The c_rehash script allows command injection (CVE-2022-2068)',
depth: 3,
data: { id: 'the_c_rehash' },
},
{
value: 'Contact and future updates',
depth: 3,
data: { id: 'contact_and_future_updates' },
},
],
},
},
};

export default { component: MetaBar } as Meta;
61 changes: 61 additions & 0 deletions components/Common/MetaBar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { Heading } from '@vcarl/remark-headings';
import { Fragment, useMemo } from 'react';
import type { FC } from 'react';
import { FormattedMessage } from 'react-intl';

import LocalizedLink from '@/components/LocalizedLink';

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

type MetaBarProps = {
items: Record<string, React.ReactNode>;
headings?: {
items: Heading[];
depth?: number;
};
};

const MetaBar: FC<MetaBarProps> = ({ items, headings }) => {
// The default depth of headings to display in the table of contents.
const { depth = 2, items: headingItems = [] } = headings || {};

const heading = useMemo(
() => headingItems.filter(head => head.depth === depth),
[depth, headingItems]
);

return (
<div className={styles.wrapper}>
<dl>
{Object.entries(items).map(([key, value]) => (
<Fragment key={key}>
<dt>
<FormattedMessage id={key} />
</dt>
<dd>{value}</dd>
</Fragment>
))}
{heading.length > 0 && (
<Fragment key="tableOfContents">
<dt>
<FormattedMessage id="components.metabar.tableOfContents" />
</dt>
<dd>
<ol>
{heading.map(head => (
<li key={head.value}>
<LocalizedLink href={`#${head?.data?.id || head.value}`}>
{head.value}
</LocalizedLink>
</li>
))}
</ol>
</dd>
</Fragment>
)}
</dl>
</div>
);
};

export default MetaBar;
9 changes: 9 additions & 0 deletions i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@
"components.common.crossLink.previous": "Prev",
"components.common.crossLink.next": "Next",
"components.common.codebox.copied": "Copied to clipboard!",
"components.metabar.lastUpdated": "Last Updated",
"components.metabar.readingTime": "Reading Time",
"components.metabar.addedIn": "Added In",
"components.metabar.author": "Author",
"components.metabar.authors": "Authors",
"components.metabar.contribute": "Contribute",
"components.metabar.contributeText": "Edit this page",
"components.metabar.viewAs": "View as",
"components.metabar.tableOfContents": "Table of Contents",
"layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}",
"layouts.blogIndex.currentYear": "News from {year}",
"components.api.jsonLink.title": "View as JSON",
Expand Down

0 comments on commit 3c59de3

Please sign in to comment.