Skip to content
Merged
15 changes: 7 additions & 8 deletions apps/site/components/Common/Partners/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Tooltip from '@node-core/ui-components/Common/Tooltip';
import * as PartnerLogos from '@node-core/ui-components/Icons/PartnerLogos';

import providePartners from '#site/next-data/providers/partners';
Expand Down Expand Up @@ -36,15 +35,15 @@ const renderSmallPartner = (partner: Partner) => {
const Logo = PartnerLogos[partner.id];

return (
<Tooltip
<PartnerButton
aria-label={partner.name}
key={partner.id}
asChild
content={<div className={style.tooltip}>{partner.name}</div>}
size="small"
href={partner.href}
data-tooltip={partner.name}
>
<PartnerButton aria-label={partner.name} size="small" href={partner.href}>
<Logo.Favicon />
</PartnerButton>
</Tooltip>
<Logo.Favicon />
</PartnerButton>
);
};

Expand Down
8 changes: 2 additions & 6 deletions apps/site/components/withMetaBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,7 @@ const WithMetaBar: FC = () => {
// Since we cannot show the same number of avatars in Mobile / Tablet
// resolution as we do on desktop and there is overflow, we are adjusting
// the number of avatars manually for the resolutions below
const isMobileResolution = useMediaQuery('(max-width: 890px)');

const isTabletResolution = useMediaQuery(
'(min-width: 890px) and (max-width: 1280px)'
);
const isSmallerThanDesktop = useMediaQuery('(max-width: 1280px)');

return (
<MetaBar
Expand All @@ -55,7 +51,7 @@ const WithMetaBar: FC = () => {
)]: (
<WithAvatarGroup
usernames={usernames}
limit={isMobileResolution ? 7 : isTabletResolution ? 5 : 9}
limit={isSmallerThanDesktop ? 5 : 8}
/>
),
}),
Expand Down
8 changes: 4 additions & 4 deletions apps/site/layouts/layouts.module.css
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
@reference "../styles/index.css";

.baseLayout {
@apply grid
@apply ml:grid
ml:grid-cols-[1fr]
ml:grid-rows-[auto_1fr_auto]
h-max
min-h-full
w-full
grid-cols-[1fr]
grid-rows-[auto_1fr_auto];
w-full;
}

.centeredLayout {
Expand Down
2 changes: 1 addition & 1 deletion apps/site/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />
import './.next/types/routes.d.ts';
import './.next/dev/types/routes.d.ts';

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
2 changes: 1 addition & 1 deletion apps/site/next.fetch.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const fetchWithRetry = async (
const backoff = Math.max(0, Number(delay) || 0);

const attemptFetch = attempt =>
fetch(url, options).catch(e => {
fetch(url, { ...options, signal: AbortSignal.timeout(30000) }).catch(e => {
if (attempt === retries || !isTimeoutError(e)) {
throw e;
}
Expand Down
12 changes: 10 additions & 2 deletions packages/rehype-shiki/src/plugin.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ const languagePrefix = 'language-';
// The regex to match metadata
const rMeta = /(\w+)(?:=(?:"([^"]+)"|(\S+)))?/g;

const getLineCount = value =>
value
.split('\n')
.filter((_, i, arr) => !(i === arr.length - 1 && arr[i] === '')).length;

/**
* Parses a fenced code block metadata string into a JavaScript object.
* @param {string} meta - The metadata string from a Markdown code fence.
Expand Down Expand Up @@ -163,7 +168,9 @@ export default async function rehypeShikiji(options) {
const meta = parseMeta(preElement.data?.meta);

// Retrieve the whole <pre> contents as a parsed DOM string
const preElementContents = toString(preElement);
const preElementContents = toString(preElement).replace(/\n$/, '');

const lineCount = getLineCount(preElementContents);

// Grabs the relevant alias/name of the language
const languageId = codeLanguage.slice(languagePrefix.length);
Expand All @@ -178,7 +185,8 @@ export default async function rehypeShikiji(options) {
// Adds the original language back to the <pre> element
children[0].properties.class = classNames(
children[0].properties.class,
codeLanguage
codeLanguage,
{ 'no-line-numbers': lineCount < 5, 'no-footer': lineCount === 1 }
);

// Replaces the <pre> element with the updated one
Expand Down
20 changes: 20 additions & 0 deletions packages/ui-components/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,23 @@ The components are based on [this design file](https://www.figma.com/design/a10c
Most components in this package are available on [Chromatic](https://www.chromatic.com/library?appId=64c7d71358830e9105808652).

For additional details regarding specific components, refer to the [nodejs/nodejs.org](https://github.com/nodejs/nodejs.org) repository.

## Local development

To use this package via `npm link` in another repo (for example, doc-kit), build the
compiled outputs and keep them updated while you work.

```bash
# From nodejs.org/packages/ui-components
pnpm install
node --run compile:watch

# In another terminal, still in nodejs.org/packages/ui-components
npm link

# From the consumer repo (for example doc-kit)
npm link @node-core/ui-components
```

The `compile:watch` script keeps `dist/` up to date so consumers resolve compiled
CSS and JavaScript instead of the raw Tailwind source.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
px-4.5
py-2.5
text-center
font-semibold
motion-safe:transition-colors;
font-semibold;

svg {
@apply size-5;
Expand Down Expand Up @@ -124,7 +123,7 @@
after:mx-auto
after:h-px
after:w-2/5
after:bg-gradient-to-r
after:bg-linear-to-r
after:from-green-600/0
after:via-green-600
after:to-green-600/0
Expand Down
27 changes: 23 additions & 4 deletions packages/ui-components/src/Common/BaseCodeBox/index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@
[counter-increment:line];
}
}

&[class*='plain-text'] {
@apply font-mono;
}
}

&[class*='no-line-numbers'] > code > [class='line'] {
@apply pl-0;

&:not(:empty:last-child)::after {
@apply content-none
[counter-reset:none];
}
}
}

Expand All @@ -62,8 +75,8 @@
justify-between
border-t
border-t-neutral-900
px-4
py-3
px-3
py-2
text-sm
font-medium;

Expand All @@ -72,9 +85,15 @@
}

& > .action {
@apply px-3
py-1.5
@apply px-2.5
py-1
text-xs
font-medium;

> svg {
@apply h-4
w-4;
}
}
}
}
49 changes: 25 additions & 24 deletions packages/ui-components/src/Common/BaseCodeBox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,31 +39,27 @@ const transformCode = <T extends ReactElement<PropsWithChildren>>(
// being an empty string, so we need to remove it
const lines = content.split('\n');

const extraStyle = language.length === 0 ? { fontFamily: 'monospace' } : {};
const extraClasses = classNames({ 'plain-text': language.length === 0 });

return (
<code style={extraStyle}>
{lines
.flatMap((line, lineIndex) => {
const columns = line.split(' ');

return [
<span key={lineIndex} className="line">
{columns.map((column, columnIndex) => (
<Fragment key={columnIndex}>
<span>{column}</span>
{columnIndex < columns.length - 1 && <span> </span>}
</Fragment>
))}
</span>,
// Add a break line so the text content is formatted correctly
// when copying to clipboard
'\n',
];
})
// Here we remove that empty line from before and
// the last flatMap entry which is an `\n`
.slice(0, -2)}
<code className={extraClasses}>
{lines.flatMap((line, lineIndex) => {
const columns = line.split(' ');

return [
<span key={lineIndex} className="line">
{columns.map((column, columnIndex) => (
<Fragment key={columnIndex}>
<span>{column}</span>
{columnIndex < columns.length - 1 && <span> </span>}
</Fragment>
))}
</span>,
// Add a break line so the text content is formatted correctly
// when copying to clipboard
'\n',
];
})}
</code>
);
};
Expand All @@ -89,8 +85,11 @@ const BaseCodeBox: FC<PropsWithChildren<CodeBoxProps>> = ({
const containerRef = useRef<HTMLPreElement>(null);

const handleCopy = () => copy(containerRef.current?.textContent);

const ButtonIcon = copied ? DocumentDuplicateIcon : CodeBracketIcon;

const hideFooter = className?.includes('no-footer');

return (
<div className={styles.root}>
<pre
Expand All @@ -100,9 +99,11 @@ const BaseCodeBox: FC<PropsWithChildren<CodeBoxProps>> = ({
>
{transformCode(children as ReactElement<PropsWithChildren>, language)}
</pre>
{language && (

{!language || hideFooter || (
<div className={styles.footer}>
<span className={styles.language}>{language}</span>

<BaseButton
as={as}
className={styles.action}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
border-neutral-900
bg-neutral-950
px-2
pt-3
pt-2
md:px-4;

.trigger {
Expand Down
18 changes: 17 additions & 1 deletion packages/ui-components/src/Common/DataTag/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,24 @@ const symbolMap = {
ctor: 'C',
} as const;

const labelMap = {
event: 'Event',
method: 'Method',
property: 'Property',
class: 'Class',
module: 'Module',
classMethod: 'Class method',
global: 'Global',
ctor: 'Constructor',
} as const;

const DataTag: FC<DataTagProps> = ({ kind, size = 'md' }) => (
<div className={classNames(styles.dataTag, styles[size], styles[kind])}>
<div
className={classNames(styles.dataTag, styles[size], styles[kind])}
data-tooltip={labelMap[kind]}
aria-label={labelMap[kind]}
tabIndex={0}
>
<span>{symbolMap[kind]}</span>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@
p-1.5
text-neutral-900
hover:bg-neutral-100
motion-safe:transition-colors
dark:border-neutral-900
dark:bg-neutral-950
dark:text-neutral-200;

&:hover {
@apply bg-neutral-100
motion-safe:transition-colors
motion-safe:duration-300
dark:bg-neutral-900;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
block
rounded-md
bg-neutral-200
lg:hidden
xl:hidden
dark:bg-neutral-900;

&[open] {
Expand Down Expand Up @@ -49,6 +49,11 @@
dark:hover:text-neutral-500;
}

.codeLink {
@apply font-ibm-plex-mono
font-medium;
}

.depthThree {
@apply pl-2;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const depthClasses: Record<number, string> = {
4: styles.depthFour,
};

const CODE_LIKE_TYPES = new Set(['method', 'classMethod', 'function', 'ctor']);

type TableOfContentsProps = ComponentProps<'details'> & {
headings: Array<Heading>;
summaryTitle: string;
Expand Down Expand Up @@ -44,7 +46,12 @@ const TableOfContents: FC<TableOfContentsProps> = ({
<li key={head.data?.id ?? index}>
<Component
href={head.data?.id && `#${head.data.id}`}
className={classNames(styles.link, depthClasses[head.depth])}
className={classNames(
styles.link,
depthClasses[head.depth],
CODE_LIKE_TYPES.has((head.data?.type as string) ?? '') &&
styles.codeLink
)}
>
{head.value}
</Component>
Expand Down
5 changes: 3 additions & 2 deletions packages/ui-components/src/Common/Tabs/index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
@apply border-b-2
border-b-transparent
px-1
pb-[11px]
pt-0
pb-2
text-sm
font-semibold
whitespace-nowrap
Expand All @@ -28,7 +29,7 @@
border
border-neutral-200
px-1
py-0.5
py-0
text-xs
font-normal
text-neutral-200;
Expand Down
Loading
Loading