diff --git a/.storybook/main.ts b/.storybook/main.ts index 4a7916483dd7c..33f8c99ed932d 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -34,9 +34,15 @@ const config: StorybookConfig = { framework: { name: '@storybook/nextjs', options: {} }, webpack: async config => ({ ...config, + // We want to conform as much as possible with our target settings target: 'browserslist', + // Performance Hints do not make sense on Storybook as it is bloated by design performance: { hints: false }, + // `nodevu` is a Node.js-specific package that requires Node.js modules + // this is incompatible with Storybook. So we just mock the module resolve: { ...config.resolve, alias: { '@nodevu/core': false } }, + // Removes Pesky Critical Dependency Warnings due to `next/font` + ignoreWarnings: [e => e.message.includes('Critical dep')], }), }; diff --git a/.stylelintrc.mjs b/.stylelintrc.mjs index 948909856063e..3fea6d8b268c8 100644 --- a/.stylelintrc.mjs +++ b/.stylelintrc.mjs @@ -27,7 +27,13 @@ export default { 'selector-class-pattern': ONLY_ALLOW_CAMEL_CASE_SELECTORS, // Enforces Element IDs to be camelCase 'selector-id-pattern': ONLY_ALLOW_CAMEL_CASE_SELECTORS, + // Allow Tailwind-based CSS Rules 'at-rule-no-unknown': [true, { ignoreAtRules: CUSTOM_AT_RULES }], + // Allow the Global CSS Selector + 'selector-pseudo-class-no-unknown': [ + true, + { ignorePseudoClasses: ['global'] }, + ], // Enforces the order of the CSS properties to be in alphabetical order 'order/properties-alphabetical-order': true, 'no-descending-specificity': null, diff --git a/components/Common/AvatarGroup/Avatar/index.stories.tsx b/components/Common/AvatarGroup/Avatar/index.stories.tsx index c70c047e7445e..5b92b1cf20568 100644 --- a/components/Common/AvatarGroup/Avatar/index.stories.tsx +++ b/components/Common/AvatarGroup/Avatar/index.stories.tsx @@ -15,7 +15,7 @@ export const Default: Story = { export const NoSquare: Story = { args: { - src: '/static/images/logos/stacked-dark.svg', + src: '/static/images/logos/nodejs.png', alt: 'SD', }, }; diff --git a/components/Common/Banner/index.module.css b/components/Common/Banner/index.module.css index bb08e2ed46944..72af521b96ab7 100644 --- a/components/Common/Banner/index.module.css +++ b/components/Common/Banner/index.module.css @@ -17,12 +17,14 @@ a { @apply w-fit - underline; + underline + decoration-white-opaque; } svg { @apply h-4 - w-4; + w-4 + text-white-opaque; } } diff --git a/components/Common/Banner/index.stories.tsx b/components/Common/Banner/index.stories.tsx index 1bafc10b2d006..4a823cd36cc9f 100644 --- a/components/Common/Banner/index.stories.tsx +++ b/components/Common/Banner/index.stories.tsx @@ -7,7 +7,7 @@ type Meta = MetaObj; export const Default: Story = { args: { - text: 'Nodejs collaborator summitNode.js Collaborator Summit 2023 - Bilbao, Spain (OpenJS World EU) 2023', + text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', type: 'default', url: 'https://github.com/openjs-foundation/summit/issues/360', }, @@ -15,7 +15,7 @@ export const Default: Story = { export const Error: Story = { args: { - text: 'STOP creating issue for error 500 on download', + text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', type: 'error', url: 'https://github.com/nodejs/nodejs.org/issues/4495', }, @@ -23,7 +23,7 @@ export const Error: Story = { export const Warning: Story = { args: { - text: 'STOP creating issue for error 500 on download', + text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', type: 'warning', url: 'https://github.com/nodejs/nodejs.org/issues/4495', }, @@ -31,16 +31,9 @@ export const Warning: Story = { export const NoLink: Story = { args: { - text: 'Claudio is the best maintainer', + text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', type: 'default', }, }; -export const NoType: Story = { - args: { - text: 'Claudio is the best maintainer', - url: 'https://github.com/ovflowd', - }, -}; - export default { component: Banner } as Meta; diff --git a/components/Common/Breadcrumbs/BreadcrumbItem/index.module.css b/components/Common/Breadcrumbs/BreadcrumbItem/index.module.css index 8f34d7b973d50..2f5852c6df7fd 100644 --- a/components/Common/Breadcrumbs/BreadcrumbItem/index.module.css +++ b/components/Common/Breadcrumbs/BreadcrumbItem/index.module.css @@ -5,6 +5,11 @@ text-sm font-medium; + a { + @apply flex-shrink + flex-grow; + } + &, > a, > a:hover { @@ -19,6 +24,8 @@ .separator { @apply h-4 w-4 + flex-shrink-0 + flex-grow text-neutral-600 dark:text-neutral-400; } diff --git a/components/Common/MetaBar/index.stories.tsx b/components/Common/MetaBar/index.stories.tsx index c9d5803dbf879..6d44953721fba 100644 --- a/components/Common/MetaBar/index.stories.tsx +++ b/components/Common/MetaBar/index.stories.tsx @@ -1,9 +1,9 @@ import { CodeBracketIcon } from '@heroicons/react/24/outline'; import type { Meta as MetaObj, StoryObj } from '@storybook/react'; -import Image from 'next/image'; import AvatarGroup from '@/components/Common/AvatarGroup'; import MetaBar from '@/components/Common/MetaBar'; +import GitHub from '@/components/Icons/Social/GitHub'; import Link from '@/components/Link'; type Story = StoryObj; @@ -38,20 +38,7 @@ export const Default: Story = { ), 'components.metabar.contribute': ( <> - GitHub Logo - GitHub Logo + Edit this page ), diff --git a/components/Common/Pagination/Ellipsis/index.module.css b/components/Common/Pagination/Ellipsis/index.module.css index 24f0d37d354a6..b4ce7ce86b786 100644 --- a/components/Common/Pagination/Ellipsis/index.module.css +++ b/components/Common/Pagination/Ellipsis/index.module.css @@ -2,6 +2,7 @@ @apply w-10 px-3 py-2.5 + leading-none text-neutral-800 dark:text-neutral-200; } diff --git a/components/Common/Preview/index.tsx b/components/Common/Preview/index.tsx index 5fa645ee925bb..44a829269529b 100644 --- a/components/Common/Preview/index.tsx +++ b/components/Common/Preview/index.tsx @@ -1,8 +1,7 @@ import classNames from 'classnames'; -import Image from 'next/image'; import type { CSSProperties, ComponentProps, FC, ReactNode } from 'react'; -import { BASE_PATH } from '@/next.constants.mjs'; +import JsIconWhite from '@/components/Icons/Logos/JsIconWhite'; import styles from './index.module.css'; @@ -26,14 +25,7 @@ const Preview: FC = ({ className={classNames(styles.root, styles[type], props.className)} >
- Node.js +

{title}

diff --git a/components/Common/Select/index.stories.tsx b/components/Common/Select/index.stories.tsx index 6e349a85169de..379d4b5b65bbe 100644 --- a/components/Common/Select/index.stories.tsx +++ b/components/Common/Select/index.stories.tsx @@ -1,6 +1,9 @@ import type { Meta as MetaObj, StoryObj } from '@storybook/react'; import Select from '@/components/Common/Select'; +import Apple from '@/components/Icons/Platform/Apple'; +import Linux from '@/components/Icons/Platform/Linux'; +import Microsoft from '@/components/Icons/Platform/Microsoft'; type Story = StoryObj; type Meta = MetaObj; @@ -68,17 +71,17 @@ export const InlineSelect: Story = { { value: 'linux', label: 'Linux', - iconImageUrl: '/static/images/logos/platform-linux.svg', + iconImage: , }, { value: 'macos', label: 'MacOS', - iconImageUrl: '/static/images/logos/platform-apple.svg', + iconImage: , }, { value: 'windows', label: 'Windows', - iconImageUrl: '/static/images/logos/platform-microsoft.svg', + iconImage: , }, ], dropdownLabel: 'Platform', diff --git a/components/Common/Select/index.tsx b/components/Common/Select/index.tsx index b5e37fb3f59b9..a4399bc3ab1d0 100644 --- a/components/Common/Select/index.tsx +++ b/components/Common/Select/index.tsx @@ -1,7 +1,6 @@ import { ChevronDownIcon } from '@heroicons/react/24/outline'; import * as Primitive from '@radix-ui/react-select'; import classNames from 'classnames'; -import Image from 'next/image'; import { useId, useMemo } from 'react'; import type { FC } from 'react'; @@ -10,7 +9,7 @@ import styles from './index.module.css'; type SelectValue = { label: string; value: string; - iconImageUrl?: string; + iconImage?: React.ReactNode; }; type SelectProps = { @@ -72,21 +71,14 @@ const Select: FC = ({ {dropdownLabel} )} - {mappedValues.map(({ value, label, iconImageUrl }) => ( + {mappedValues.map(({ value, label, iconImage }) => ( - {iconImageUrl && ( - {label} - )} + {iconImage} {label} diff --git a/components/Containers/Footer/index.module.css b/components/Containers/Footer/index.module.css index b0cd6da94e0de..6335deef1adea 100644 --- a/components/Containers/Footer/index.module.css +++ b/components/Containers/Footer/index.module.css @@ -36,14 +36,4 @@ gap-1; } } - - .darkImage { - @apply hidden - dark:block; - } - - .lightImage { - @apply block - dark:hidden; - } } diff --git a/components/Containers/Footer/index.tsx b/components/Containers/Footer/index.tsx index 847d6836a170f..1ae84e4d0196a 100644 --- a/components/Containers/Footer/index.tsx +++ b/components/Containers/Footer/index.tsx @@ -1,13 +1,24 @@ -import classNames from 'classnames'; -import Image from 'next/image'; import { useTranslations } from 'next-intl'; -import type { FC } from 'react'; +import type { FC, SVGProps } from 'react'; import NavItem from '@/components/Containers/NavItem'; +import GitHub from '@/components/Icons/Social/GitHub'; +import LinkedIn from '@/components/Icons/Social/LinkedIn'; +import Mastodon from '@/components/Icons/Social/Mastodon'; +import Slack from '@/components/Icons/Social/Slack'; +import Twitter from '@/components/Icons/Social/Twitter'; import { siteConfig } from '@/next.json.mjs'; import styles from './index.module.css'; +const footerSocialIcons: Record>> = { + github: GitHub, + mastodon: Mastodon, + twitter: Twitter, + slack: Slack, + linkedin: LinkedIn, +}; + const Footer: FC = () => { const t = useTranslations(); @@ -22,30 +33,19 @@ const Footer: FC = () => { ))} +
© {t(openJSlink.text)} +
{siteConfig.socialLinks.map(link => { - const navClass = classNames({ - [styles.darkImage]: link.kind === 'dark', - [styles.lightImage]: link.kind === 'light', - }); + const SocialIcon = footerSocialIcons[link.icon]; return ( - - {link.alt + + ); })} diff --git a/components/Containers/NavigationBar/index.stories.tsx b/components/Containers/NavigationBar/index.stories.tsx index b9a6d9629fb28..33f6be374c248 100644 --- a/components/Containers/NavigationBar/index.stories.tsx +++ b/components/Containers/NavigationBar/index.stories.tsx @@ -10,7 +10,7 @@ export const Default: Story = { navItems: [ { text: 'Learn', - href: '/learn', + href: '/', }, { text: 'About', diff --git a/components/Containers/NavigationBar/index.tsx b/components/Containers/NavigationBar/index.tsx index 0f2dbeb338ed6..b2e77f5a9b78f 100644 --- a/components/Containers/NavigationBar/index.tsx +++ b/components/Containers/NavigationBar/index.tsx @@ -9,9 +9,9 @@ import type { FC, ComponentProps } from 'react'; import LanguageDropdown from '@/components/Common/LanguageDropDown'; import ThemeToggle from '@/components/Common/ThemeToggle'; import NavItem from '@/components/Containers/NavItem'; -import GithubLogo from '@/components/Icons/GitHubLogo'; -import NodejsLogoDark from '@/components/Icons/NodejsLogoDark'; -import NodejsLogoLight from '@/components/Icons/NodejsLogoLight'; +import NodejsDark from '@/components/Icons/Logos/NodejsDark'; +import NodejsLight from '@/components/Icons/Logos/NodejsLight'; +import GitHub from '@/components/Icons/Social/GitHub'; import style from './index.module.css'; @@ -38,8 +38,8 @@ const NavigationBar: FC = ({
diff --git a/components/Containers/ProgressionSidebar/ProgressionSidebarGroup/index.module.css b/components/Containers/ProgressionSidebar/ProgressionSidebarGroup/index.module.css index 6ba28a1398b69..b9a9678173251 100644 --- a/components/Containers/ProgressionSidebar/ProgressionSidebarGroup/index.module.css +++ b/components/Containers/ProgressionSidebar/ProgressionSidebarGroup/index.module.css @@ -16,7 +16,7 @@ &::after { @apply absolute - left-[calc(0.5rem-0.5px)] + left-[0.45rem] top-0 z-10 h-full diff --git a/components/Downloads/ChangelogModal/index.module.css b/components/Downloads/ChangelogModal/index.module.css index ad304916c6947..78825ea92050e 100644 --- a/components/Downloads/ChangelogModal/index.module.css +++ b/components/Downloads/ChangelogModal/index.module.css @@ -16,7 +16,7 @@ inline-flex w-full flex-col - overflow-scroll + overflow-y-scroll rounded border border-neutral-200 @@ -82,27 +82,18 @@ } .wrapper { - @apply flex - flex-col - gap-4; - - h1, - h2, - h3, - h4, - h5, - p, - a { - @apply text-neutral-900 - dark:text-white; - } + :global(.mdxContent) { + @apply flex + flex-col + gap-4; - a { - @apply underline; - } + a { + @apply underline; + } - pre { - @apply overflow-auto; + pre { + @apply overflow-auto; + } } } } diff --git a/components/Icons/Logos/JsIconGreen.tsx b/components/Icons/Logos/JsIconGreen.tsx new file mode 100644 index 0000000000000..dc835cb1d2af7 --- /dev/null +++ b/components/Icons/Logos/JsIconGreen.tsx @@ -0,0 +1,24 @@ +import type { FC, SVGProps } from 'react'; + +const JsIconGreen: FC> = props => ( + + + + + + + + + + + +); + +export default JsIconGreen; diff --git a/components/Icons/Logos/JsIconWhite.tsx b/components/Icons/Logos/JsIconWhite.tsx new file mode 100644 index 0000000000000..17b38b4543698 --- /dev/null +++ b/components/Icons/Logos/JsIconWhite.tsx @@ -0,0 +1,35 @@ +import type { FC, SVGProps } from 'react'; + +const JsIconWhite: FC> = props => ( + + + + + + + + + + + +); + +export default JsIconWhite; diff --git a/components/Icons/NodejsLogoDark.tsx b/components/Icons/Logos/NodejsDark.tsx similarity index 98% rename from components/Icons/NodejsLogoDark.tsx rename to components/Icons/Logos/NodejsDark.tsx index 068f70892c8de..f913d72cf8a4a 100644 --- a/components/Icons/NodejsLogoDark.tsx +++ b/components/Icons/Logos/NodejsDark.tsx @@ -1,6 +1,6 @@ -import type { FC, HTMLAttributes } from 'react'; +import type { FC, SVGProps } from 'react'; -const NodejsLogoDark: FC> = props => ( +const NodejsDark: FC> = props => ( > = props => ( ); -export default NodejsLogoDark; +export default NodejsDark; diff --git a/components/Icons/NodejsLogoLight.tsx b/components/Icons/Logos/NodejsLight.tsx similarity index 98% rename from components/Icons/NodejsLogoLight.tsx rename to components/Icons/Logos/NodejsLight.tsx index 8b6207311960a..d541b971f362a 100644 --- a/components/Icons/NodejsLogoLight.tsx +++ b/components/Icons/Logos/NodejsLight.tsx @@ -1,6 +1,6 @@ -import type { FC, HTMLAttributes } from 'react'; +import type { FC, SVGProps } from 'react'; -const NodejsLogoLight: FC> = props => ( +const NodejsLight: FC> = props => ( > = props => ( ); -export default NodejsLogoLight; +export default NodejsLight; diff --git a/components/Icons/Logos/NodejsStackedBlack.tsx b/components/Icons/Logos/NodejsStackedBlack.tsx new file mode 100644 index 0000000000000..1401ff613303d --- /dev/null +++ b/components/Icons/Logos/NodejsStackedBlack.tsx @@ -0,0 +1,98 @@ +import type { FC, SVGProps } from 'react'; + +const NodejsStackedBlack: FC> = props => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +export default NodejsStackedBlack; diff --git a/components/Icons/Logos/NodejsStackedDark.tsx b/components/Icons/Logos/NodejsStackedDark.tsx new file mode 100644 index 0000000000000..b4082253c667b --- /dev/null +++ b/components/Icons/Logos/NodejsStackedDark.tsx @@ -0,0 +1,124 @@ +import type { FC, SVGProps } from 'react'; + +const NodejsStackedDark: FC> = props => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +export default NodejsStackedDark; diff --git a/components/Icons/Logos/NodejsStackedLight.tsx b/components/Icons/Logos/NodejsStackedLight.tsx new file mode 100644 index 0000000000000..6e47796744849 --- /dev/null +++ b/components/Icons/Logos/NodejsStackedLight.tsx @@ -0,0 +1,123 @@ +import type { FC, SVGProps } from 'react'; + +const NodejsStackedLight: FC> = props => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +export default NodejsStackedLight; diff --git a/components/Icons/Logos/NodejsStackedWhite.tsx b/components/Icons/Logos/NodejsStackedWhite.tsx new file mode 100644 index 0000000000000..19d83835bb149 --- /dev/null +++ b/components/Icons/Logos/NodejsStackedWhite.tsx @@ -0,0 +1,98 @@ +import type { FC, SVGProps } from 'react'; + +const NodejsStackedWhite: FC> = props => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +export default NodejsStackedWhite; diff --git a/components/Icons/Platform/Apple.tsx b/components/Icons/Platform/Apple.tsx new file mode 100644 index 0000000000000..fa15ee4df2abf --- /dev/null +++ b/components/Icons/Platform/Apple.tsx @@ -0,0 +1,23 @@ +import type { FC, SVGProps } from 'react'; + +const Apple: FC> = props => ( + + + + +); + +export default Apple; diff --git a/components/Icons/Platform/Generic.tsx b/components/Icons/Platform/Generic.tsx new file mode 100644 index 0000000000000..bdae9102b252d --- /dev/null +++ b/components/Icons/Platform/Generic.tsx @@ -0,0 +1,22 @@ +import type { FC, SVGProps } from 'react'; + +const Generic: FC> = props => ( + + + +); + +export default Generic; diff --git a/components/Icons/Platform/Homebrew.tsx b/components/Icons/Platform/Homebrew.tsx new file mode 100644 index 0000000000000..b3961dda92af5 --- /dev/null +++ b/components/Icons/Platform/Homebrew.tsx @@ -0,0 +1,69 @@ +import type { FC, SVGProps } from 'react'; + +const Homebrew: FC> = props => ( + + + + + + + + + + + + + + + +); + +export default Homebrew; diff --git a/components/Icons/Platform/Linux.tsx b/components/Icons/Platform/Linux.tsx new file mode 100644 index 0000000000000..974d1efc46f56 --- /dev/null +++ b/components/Icons/Platform/Linux.tsx @@ -0,0 +1,27 @@ +import type { FC, SVGProps } from 'react'; + +const Linux: FC> = props => ( + + + + + + +); + +export default Linux; diff --git a/components/Icons/Platform/Microsoft.tsx b/components/Icons/Platform/Microsoft.tsx new file mode 100644 index 0000000000000..4567525dd2170 --- /dev/null +++ b/components/Icons/Platform/Microsoft.tsx @@ -0,0 +1,19 @@ +import type { FC, SVGProps } from 'react'; + +const Microsoft: FC> = props => ( + + + + + + +); + +export default Microsoft; diff --git a/components/Icons/Platform/NVM.tsx b/components/Icons/Platform/NVM.tsx new file mode 100644 index 0000000000000..04e4e0e9f43ca --- /dev/null +++ b/components/Icons/Platform/NVM.tsx @@ -0,0 +1,63 @@ +import type { FC, SVGProps } from 'react'; + +const NVM: FC> = props => ( + + + + + + + + + + + + + + + + + + + +); + +export default NVM; diff --git a/components/Icons/GitHubLogo.tsx b/components/Icons/Social/GitHub.tsx similarity index 90% rename from components/Icons/GitHubLogo.tsx rename to components/Icons/Social/GitHub.tsx index 459cd56c5890b..54c4cef57ba19 100644 --- a/components/Icons/GitHubLogo.tsx +++ b/components/Icons/Social/GitHub.tsx @@ -1,16 +1,16 @@ -import type { FC, HTMLAttributes } from 'react'; +import type { FC, SVGProps } from 'react'; -const GitHubLogo: FC> = props => ( +const GitHub: FC> = props => ( ); -export default GitHubLogo; +export default GitHub; diff --git a/components/Icons/Social/LinkedIn.tsx b/components/Icons/Social/LinkedIn.tsx new file mode 100644 index 0000000000000..0d9bfac853667 --- /dev/null +++ b/components/Icons/Social/LinkedIn.tsx @@ -0,0 +1,32 @@ +import type { FC, SVGProps } from 'react'; + +const LinkedIn: FC> = props => ( + + + + + + + + + + +); + +export default LinkedIn; diff --git a/components/Icons/Social/Mastodon.tsx b/components/Icons/Social/Mastodon.tsx new file mode 100644 index 0000000000000..50a64c1792958 --- /dev/null +++ b/components/Icons/Social/Mastodon.tsx @@ -0,0 +1,28 @@ +import type { FC, SVGProps } from 'react'; + +const Mastodon: FC> = props => ( + + + + + + + + + + +); + +export default Mastodon; diff --git a/components/Icons/Social/Slack.tsx b/components/Icons/Social/Slack.tsx new file mode 100644 index 0000000000000..afe504a20cb59 --- /dev/null +++ b/components/Icons/Social/Slack.tsx @@ -0,0 +1,31 @@ +import type { FC, SVGProps } from 'react'; + +const Slack: FC> = props => ( + + + + + + +); + +export default Slack; diff --git a/components/Icons/Social/Twitter.tsx b/components/Icons/Social/Twitter.tsx new file mode 100644 index 0000000000000..bedee9bce710b --- /dev/null +++ b/components/Icons/Social/Twitter.tsx @@ -0,0 +1,19 @@ +import type { FC, SVGProps } from 'react'; + +const Twitter: FC> = props => ( + + + +); + +export default Twitter; diff --git a/components/__design__/list.stories.tsx b/components/__design__/list.stories.tsx index 888d232fa8b0f..668cb4616be10 100644 --- a/components/__design__/list.stories.tsx +++ b/components/__design__/list.stories.tsx @@ -2,7 +2,7 @@ import type { Meta as MetaObj, StoryObj } from '@storybook/react'; export const OrderedLists: StoryObj = { render: () => ( -
+
  1. Ordered lists
  2. Like this
  3. @@ -14,7 +14,7 @@ export const OrderedLists: StoryObj = { export const UnorderedLists: StoryObj = { render: () => ( -
    +