Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: doc-layout components merge classes from props #1618

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
11 changes: 9 additions & 2 deletions packages/theme-default/src/layout/DocLayout/docComponents/hr.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import type { ComponentProps } from 'react';

import clsx from '../../../utils/tailwind';

export const Hr = (props: ComponentProps<'hr'>) => {
const { className, ...restProps } = props;

return (
<hr
{...props}
className="my-12 border-t border-solid border-divider-light"
{...restProps}
className={clsx(
'my-12 border-t border-solid border-divider-light',
className,
)}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ import styles from './index.module.scss';
import { Link } from '@theme';
import { usePathUtils } from '../../../logic';

import clsx from '../../../utils/tailwind';

export const A = (props: ComponentProps<'a'>) => {
const { href = '', className = '' } = props;
const { normalizeLinkHref } = usePathUtils();
const hasHeaderAnchor = className.includes('header-anchor');

if (hasHeaderAnchor || href.startsWith('#')) {
return <a {...props} className={`${styles.link} ${className}`} />;
return <a {...props} className={clsx(styles.link, className)} />;
}

return (
<Link
{...props}
className={`${className} ${styles.link} ${styles['inline-link']}`}
className={clsx(className, styles.link, styles['inline-link'])}
href={normalizeLinkHref(href)}
/>
);
Expand Down
29 changes: 26 additions & 3 deletions packages/theme-default/src/layout/DocLayout/docComponents/list.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
import type { ComponentProps } from 'react';

import clsx from '../../../utils/tailwind';

export const Ol = (props: ComponentProps<'ol'>) => {
return <ol {...props} className="list-decimal pl-5 my-4 leading-7" />;
const { className, ...restProps } = props;

return (
<ol
{...restProps}
className={clsx('list-decimal pl-5 my-4 leading-7', className)}
/>
);
};

export const Ul = (props: ComponentProps<'ul'>) => {
return <ul {...props} className="list-disc pl-5 my-4 leading-7" />;
const { className, ...restProps } = props;

return (
<ul
{...restProps}
className={clsx('list-disc pl-5 my-4 leading-7', className)}
/>
);
};

export const Li = (props: ComponentProps<'li'>) => {
return <li {...props} className="[&:not(:first-child)]:mt-2" />;
const { className, ...restProps } = props;

return (
<li
{...restProps}
className={clsx('[&:not(:first-child)]:mt-2', className)}
/>
);
};
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
import type { ComponentProps } from 'react';
import styles from './index.module.scss';

import clsx from '../../../utils/tailwind';

export const P = (props: ComponentProps<'p'>) => {
return <p {...props} className="my-4 leading-7" />;
const { className, ...restProps } = props;

return <p {...restProps} className={clsx('my-4 leading-7', className)} />;
};

export const Blockquote = (props: ComponentProps<'blockquote'>) => {
const { className, ...restProps } = props;

return (
<blockquote
{...props}
className={`border-l-2 border-solid border-divider pl-4 my-6 transition-colors duration-500 ${styles.blockquote}`}
{...restProps}
className={clsx(
'border-l-2 border-solid border-divider pl-4 my-6 transition-colors duration-500',
styles.blockquote,
className,
)}
/>
);
};

export const Strong = (props: ComponentProps<'strong'>) => {
return <strong {...props} className="font-semibold" />;
const { className, ...restProps } = props;

return <strong {...restProps} className={clsx('font-semibold', className)} />;
};
47 changes: 33 additions & 14 deletions packages/theme-default/src/layout/DocLayout/docComponents/pre.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import type { CodeProps } from './code';

import clsx from '../../../utils/tailwind';

const DEFAULT_LANGUAGE_CLASS = 'language-bash';

export interface PreProps {
children: React.ReactElement[] | React.ReactElement;
className?: string;
}

export function parseTitleFromMeta(meta: string): string {
if (!meta) {
return '';
Expand All @@ -16,24 +23,36 @@ export function parseTitleFromMeta(meta: string): string {
return result?.replace(/["'`]/g, '');
}

const renderChildren = (children: React.ReactElement) => {
const { className, meta, ...restProps } = children.props as CodeProps;
const codeTitle = parseTitleFromMeta(meta);
return (
<>
{codeTitle && <div className="rspress-code-title">{codeTitle}</div>}
<div
{...restProps}
className={clsx('rspress-code-content rspress-scrollbar', className)}
>
{children}
</div>
</>
);
};

export function Pre({
children,
}: {
children: React.ReactElement[] | React.ReactElement;
}) {
const renderChildren = (children: React.ReactElement) => {
const { className, meta } = children.props as CodeProps;
const codeTitle = parseTitleFromMeta(meta);
className = DEFAULT_LANGUAGE_CLASS,
}: PreProps) {
if (Array.isArray(children)) {
return (
<div className={className || DEFAULT_LANGUAGE_CLASS}>
{codeTitle && <div className="rspress-code-title">{codeTitle}</div>}
<div className="rspress-code-content rspress-scrollbar">{children}</div>
<div>
{children.map((child, index) => (
<div key={index} className={className}>
{renderChildren(child)}
</div>
))}
</div>
);
};

if (Array.isArray(children)) {
return <div>{children.map(child => renderChildren(child))}</div>;
}
return renderChildren(children);
return <div className={className}>{renderChildren(children)}</div>;
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,59 @@
import type { ComponentProps } from 'react';

import clsx from '../../../utils/tailwind';

export const Table = (props: ComponentProps<'table'>) => {
const { className, ...restProps } = props;

return (
<table
{...props}
className="block border-collapse text-base my-5 overflow-x-auto leading-7 border-gray-light-3 dark:border-divider"
{...restProps}
className={clsx(
'block border-collapse text-base my-5 overflow-x-auto leading-7 border-gray-light-3 dark:border-divider',
className,
)}
/>
);
};

export const Tr = (props: ComponentProps<'tr'>) => {
const { className, ...restProps } = props;

return (
<tr
{...props}
className="border border-solid transition-colors duration-500 even:bg-soft border-gray-light-3 dark:border-divider"
{...restProps}
className={clsx(
'border border-solid transition-colors duration-500 even:bg-soft border-gray-light-3 dark:border-divider',
className,
)}
/>
);
};

export const Td = (props: ComponentProps<'td'>) => {
const { className, ...restProps } = props;

return (
<td
{...props}
className="border border-solid px-4 py-2 border-gray-light-3 dark:border-divider"
{...restProps}
className={clsx(
'border border-solid px-4 py-2 border-gray-light-3 dark:border-divider',
className,
)}
/>
);
};

export const Th = (props: ComponentProps<'th'>) => {
const { className, ...restProps } = props;

return (
<th
{...props}
className="border border-solid px-4 py-2 text-text-1 text-base font-semibold border-gray-light-3 dark:border-divider"
{...restProps}
className={clsx(
'border border-solid px-4 py-2 text-text-1 text-base font-semibold border-gray-light-3 dark:border-divider',
className,
)}
/>
);
};
Original file line number Diff line number Diff line change
@@ -1,38 +1,68 @@
import type React from 'react';
import styles from './index.module.scss';

import clsx from '../../../utils/tailwind';

export const H1 = (props: React.ComponentProps<'h1'>) => {
const { className, ...restProps } = props;

return (
<h1
{...props}
className={`text-3xl mb-10 leading-10 tracking-tight ${styles.title}`}
{...restProps}
className={clsx(
'text-3xl mb-10 leading-10 tracking-tight',
styles.title,
className,
)}
/>
);
};

export const H2 = (props: React.ComponentProps<'h2'>) => {
const { className, ...restProps } = props;

return (
<h2
{...props}
className={`mt-12 mb-6 pt-8 text-2xl tracking-tight border-t-[1px] border-divider-light ${styles.title}`}
{...restProps}
className={clsx(
'mt-12 mb-6 pt-8 text-2xl tracking-tight border-t-[1px] border-divider-light',
styles.title,
className,
)}
/>
);
};

export const H3 = (props: React.ComponentProps<'h3'>) => {
const { className, ...restProps } = props;

return (
<h3 {...props} className={`mt-10 mb-2 leading-7 text-xl ${styles.title}`} />
<h3
{...restProps}
className={clsx('mt-10 mb-2 leading-7 text-xl', styles.title, className)}
/>
);
};

export const H4 = (props: React.ComponentProps<'h4'>) => {
return <h4 {...props} className={`mt-8 leading-6 text-lg ${styles.title}`} />;
const { className, ...restProps } = props;

return (
<h4
{...restProps}
className={clsx('mt-8 leading-6 text-lg', styles.title, className)}
/>
);
};

export const H5 = (props: React.ComponentProps<'h5'>) => {
return <h5 {...props} className={styles.title} />;
const { className, ...restProps } = props;

return <h5 {...restProps} className={clsx(styles.title, className)} />;
};

export const H6 = (props: React.ComponentProps<'h6'>) => {
return <h6 {...props} className={styles.title} />;
const { className, ...restProps } = props;

return <h6 {...restProps} className={clsx(styles.title, className)} />;
};
26 changes: 26 additions & 0 deletions packages/theme-default/src/utils/tailwind.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Utility for merging class names.
*
* @see https://github.com/lukeed/clsx/blob/925494cf31bcd97d3337aacd34e659e80cae7fe2/src/lite.js
*
* @example
*
* ```ts
* const defaultClasses = 'm-8'
* const indented = true
* const classNames = clsx('w-4 h-4', indented && 'pl-8', defaultClasses)
* ```
*/
export function clsx(...args: unknown[]) {
let str = '';

for (const arg of args) {
if (typeof arg === 'string') {
str += (str && ' ') + arg;
}
}

return str;
}

export default clsx;
Loading