diff --git a/apps/site/pages/en/blog/npm/2013-outage-postmortem.md b/apps/site/pages/en/blog/npm/2013-outage-postmortem.md index b44b879645b32..e3bf49c6f3758 100644 --- a/apps/site/pages/en/blog/npm/2013-outage-postmortem.md +++ b/apps/site/pages/en/blog/npm/2013-outage-postmortem.md @@ -14,9 +14,7 @@ We know the availability and overall health of The npm Registry is paramount to The root cause of these downtime was insufficient resources: both hardware and human. This is a full post-mortem where we will be look at how npmjs.org works, what went wrong, how we changed the previous architecture of The npm Registry to fix it, as well next steps we are taking to prevent this from happening again. -All of the next steps require additional expenditure from Nodejitsu: both servers and labor. This is why along with this post-mortem we are announcing our [crowdfunding campaign: scalenpm.org](https://scalenpm.org)! Our goal is to raise enough funds so that Nodejitsu can continue to run The npm Registry as a free service for _you, the community._ - -Please take a minute now to donate at [https://scalenpm.org](https://scalenpm.org)! +All of the next steps require additional expenditure from Nodejitsu: both servers and labor. This is why along with this post-mortem we are announcing our crowdfunding campaign! Our goal is to raise enough funds so that Nodejitsu can continue to run The npm Registry as a free service for _you, the community._ ## How does npmjs.org work? @@ -73,8 +71,6 @@ The npm Registry has had a 10x year. In November 2012 there were 13.5 million do _**But we need your help!**_ All of these necessary improvements require more servers, more time from Nodejitsu staff and an overall increase to what we spend maintaining the public npm registry as a free service for the Node.js community. -Please take a minute now to donate at [https://scalenpm.org](https://scalenpm.org)! - [browserify]: http://browserify.org/ [dotc]: https://github.com/substack/dotc [npm-rubygems]: http://andrew.ghost.io/emulating-node-js-modules-in-ruby/ diff --git a/packages/ui-components/package.json b/packages/ui-components/package.json index 87c217cd3fae4..07244719cccae 100644 --- a/packages/ui-components/package.json +++ b/packages/ui-components/package.json @@ -1,6 +1,6 @@ { "name": "@node-core/ui-components", - "version": "1.5.5", + "version": "1.5.6", "type": "module", "exports": { "./*": [ diff --git a/packages/ui-components/src/Common/TableOfContents/index.module.css b/packages/ui-components/src/Common/TableOfContents/index.module.css new file mode 100644 index 0000000000000..9d838e502d79b --- /dev/null +++ b/packages/ui-components/src/Common/TableOfContents/index.module.css @@ -0,0 +1,39 @@ +@reference "../../styles/index.css"; + +.details { + @apply my-2 + block + rounded-md + bg-neutral-200 + lg:hidden + dark:bg-neutral-900; + + .summary { + @apply px-4 + py-2; + } + + .list { + @apply space-y-1 + px-4 + pb-2; + } + + .link { + @apply text-sm + font-semibold + text-neutral-900 + underline + hover:text-neutral-700 + dark:text-white + dark:hover:text-neutral-500; + } + + .depthThree { + @apply pl-2; + } + + .depthFour { + @apply pl-4; + } +} diff --git a/packages/ui-components/src/Common/TableOfContents/index.stories.tsx b/packages/ui-components/src/Common/TableOfContents/index.stories.tsx new file mode 100644 index 0000000000000..2c05585f189aa --- /dev/null +++ b/packages/ui-components/src/Common/TableOfContents/index.stories.tsx @@ -0,0 +1,65 @@ +import TableOfContents from '#ui/Common/TableOfContents'; + +import type { Meta as MetaObj, StoryObj } from '@storybook/react-webpack5'; + +type Story = StoryObj; +type Meta = MetaObj; + +export const Default: Story = {}; + +export const CustomDepth: Story = { + args: { + minDepth: 1, + maxDepth: 6, + }, +}; + +export default { + component: TableOfContents, + args: { + ariaLabel: 'Table of Contents', + summaryTitle: 'On this page', + headings: [ + { + 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' }, + }, + { + value: 'Email', + depth: 4, + data: { id: 'email' }, + }, + { + value: 'Slack', + depth: 4, + data: { id: 'slack' }, + }, + { + value: '#node-website', + depth: 5, // h5s do not get shown + data: { id: 'node-website' }, + }, + ], + }, +} as Meta; diff --git a/packages/ui-components/src/Common/TableOfContents/index.tsx b/packages/ui-components/src/Common/TableOfContents/index.tsx new file mode 100644 index 0000000000000..a1271ae789f59 --- /dev/null +++ b/packages/ui-components/src/Common/TableOfContents/index.tsx @@ -0,0 +1,55 @@ +import classNames from 'classnames'; + +import { LinkLike } from '#ui/types'; + +import type { Heading } from '@vcarl/remark-headings'; +import type { ComponentProps, FC } from 'react'; + +import styles from './index.module.css'; + +const depthClasses: Record = { + 3: styles.depthThree, + 4: styles.depthFour, +}; + +type TableOfContentsProps = ComponentProps<'details'> & { + headings: Array; + summaryTitle: string; + minDepth?: number; + maxDepth?: number; + as?: LinkLike; +}; + +const TableOfContents: FC = ({ + headings, + summaryTitle, + minDepth = 2, + className, + maxDepth = 4, + as: Component = 'a', + ...props +}) => { + const filteredHeadings = headings.filter( + ({ depth }) => depth >= minDepth && depth <= maxDepth + ); + + return ( +
+ {summaryTitle} +
    + {filteredHeadings.map((head, index) => ( +
  • + + {head.value} + +
  • + ))} +
+
+ ); +}; + +export default TableOfContents;