Skip to content

docs: overhaul homepage #11345

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

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ docs/packages/*/generated
packages/website/.docusaurus
packages/website/.cache-loader
packages/website/build
packages/website/data/recent-blog-posts.json
packages/website/static/sandbox

# Runtime data
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<h1 align="center">typescript-eslint</h1>

<p align="center">Monorepo for the tooling that enables ESLint and Prettier to support TypeScript</p>
<p align="center">Monorepo for typescript-eslint: powerful static analysis for JavaScript and TypeScript</p>

<p align="center">
<img src="https://github.com/typescript-eslint/typescript-eslint/workflows/CI/badge.svg" alt="CI" />
Expand Down
2 changes: 1 addition & 1 deletion docs/maintenance/Branding.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Combining lowercase with a dash helps differentiate us.

### Slogan

> The tooling that enables ESLint and Prettier to support TypeScript.
> Powerful static analysis for JavaScript and TypeScript.

## Visuals

Expand Down
1 change: 1 addition & 0 deletions knip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export default {
'src/components/**/*.tsx',

// used by Docusaurus
'plugins/recent-blog-posts/index.ts',
'src/theme/**/*.tsx',
'src/theme/prism-include-languages.js',
],
Expand Down
4 changes: 2 additions & 2 deletions packages/website/docusaurus.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,7 @@ const redirects: PluginRedirectOptions = {

const config: Config = {
baseUrl: '/',
tagline:
'The tooling that enables ESLint and Prettier to support TypeScript.',
tagline: 'Powerful static analysis for JavaScript and TypeScript.',
title: 'typescript-eslint',
url: 'https://typescript-eslint.io',

Expand All @@ -368,6 +367,7 @@ const config: Config = {
onBrokenMarkdownLinks: 'throw',
organizationName: 'typescript-eslint',
plugins: [
'./plugins/recent-blog-posts/index.ts',
...['ast-spec', 'project-service', 'tsconfig-utils', 'type-utils'].map(
packageName => [
'docusaurus-plugin-typedoc',
Expand Down
5 changes: 4 additions & 1 deletion packages/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"clsx": "^2.1.0",
"docusaurus-plugin-typedoc": "^1.4.0",
"eslint": "^9.15.0",
"gray-matter": "^4.0.3",
"json5": "^2.2.3",
"konamimojisplosion": "^0.5.2",
"lz-string": "^1.5.0",
Expand All @@ -49,10 +50,12 @@
"react-dom": "^18.2.0",
"react-markdown": "^10.0.0",
"react-resizable-panels": "^3.0.0",
"reading-time": "^1.5.0",
"semver": "^7.6.0",
"typedoc": "^0.28.4",
"typedoc-plugin-markdown": "^4.6.3",
"typescript": "*"
"typescript": "*",
"zod": "^3.25.67"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "~3.7.0",
Expand Down
46 changes: 46 additions & 0 deletions packages/website/plugins/recent-blog-posts/index.ts
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was much more work than I'd hoped it would be. There's no exported way to get blog posts from @docusaurus/plugin-content-docs that I could find. https://www.cheehow.dev/blog/2024/04/01/show-recent-posts-in-docusaurus has a suggested strategy & links to more info. I did that at first but kept hitting tricky edge cases with the plugin. So in the end I just went with this more direct approach: manually re-reading and re-parsing the files. 🤷

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { Plugin } from '@docusaurus/types';

import matter from 'gray-matter';
import * as fs from 'node:fs/promises';
import readingTime from 'reading-time';
import { z } from 'zod';

const storageFile = `data/recent-blog-posts.json`;

const matterSchema = z.object({
description: z.string(),
slug: z.string(),
title: z.string(),
});

export default async function blogPluginEnhanced(): Promise<Plugin> {
const blogHandles = (await fs.readdir('blog', { withFileTypes: true }))
.filter(handle => handle.isFile() && /.mdx?$/.test(handle.name))
.map(handle => ({
date: new Date(/\d+-\d+-\d+/.exec(handle.name)?.[0] || '1970-01-01'),
handle,
}))
.sort((a, b) => b.date.getTime() - a.date.getTime())
.slice(0, 3);

const blogPosts = await Promise.all(
blogHandles.map(async ({ date, handle }) => {
const content = await fs.readFile(`blog/${handle.name}`, 'utf-8');
const data = matterSchema.parse(matter(content).data);

return {
date,
description: data.description,
readingTime: Math.round(readingTime(content).minutes),
slug: data.slug,
title: data.title,
};
}),
);

await fs.writeFile(storageFile, JSON.stringify(blogPosts, null, 2));

return {
name: 'recent-blog-posts',
};
}
65 changes: 0 additions & 65 deletions packages/website/src/components/FinancialContributors/index.tsx

This file was deleted.

26 changes: 26 additions & 0 deletions packages/website/src/components/home/ExplainerSpotlight/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Heading from '@theme/Heading';
import React from 'react';

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

export interface ExplainerSpotlightProps extends React.PropsWithChildren {
header: string;
emoji: string;
href: string;
}

export function ExplainerSpotlight({
children,
emoji,
header,
href,
}: ExplainerSpotlightProps): React.JSX.Element {
return (
<a className={styles.explainerSpotlight} href={href}>
<Heading as="h3" className={styles.heading}>
{header} <span className={styles.emoji}>{emoji}</span>
</Heading>
<div>{children}</div>
</a>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.explainerSpotlight {
background: var(--ifm-color-emphasis-100);
border-radius: var(--ifm-global-radius);
color: var(--ifm-heading-color);
padding: 1rem 1.5rem;
text-decoration: none;
transition: box-shadow 0.3s ease;
width: 100%;
}

[data-theme='dark'] .explainerSpotlight {
background: var(--ifm-color-emphasis-200);
}

.explainerSpotlight:hover {
color: var(--ifm-heading-color);
text-decoration: none;
box-shadow: 0 3px 3px 0 var(--gray-border-shadow);
}

.heading {
display: flex;
justify-content: space-between;
}

.emoji {
user-select: none;
}
83 changes: 83 additions & 0 deletions packages/website/src/components/home/Explainers/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
import Heading from '@theme/Heading';
import clsx from 'clsx';
import React from 'react';

import { ExplainerSpotlight } from '../ExplainerSpotlight';
import styles from './styles.module.css';

const explanations = [
{
children:
'The parser and services for linting TypeScript code with ESLint, as well as how tools such as Prettier read TypeScript code.',
emoji: '⚙️',
header: 'Language Support',
href: '/getting-started',
},
{
children:
'Over 100 rules that check for best practices, likely bugs, and stylistic consistency in modern JavaScript and TypeScript codebases.',
emoji: '🧠',
header: 'Standard Rules',
href: '/rules',
},
{
children:
"Industry-leading services that use TypeScript's type APIs to make a more powerful breed of lint rules for deeper insights into code.",
emoji: '⚡️',
header: 'Typed Linting',
href: '/getting-started/typed-linting',
},
];

export function Explainers(): React.JSX.Element {
return (
<section className={clsx('padding-vert--lg', styles.explainers)}>
<Heading as="h2" className="col col--12 text--center">
<strong>typescript-eslint</strong> enables ESLint, Prettier, and more to
support TypeScript code.
</Heading>
<ul className={clsx('col col--10', styles.explainerSpotlights)}>
{explanations.map(({ header, ...rest }) => (
<ExplainerSpotlight header={header} key={header} {...rest} />
))}
</ul>
<div className={styles.explainerTexts}>
<p>
<strong>ESLint</strong> is a linter. It runs a set of rules to find
likely problems and suggested fixes to improve your code.
</p>
<p>
<strong>TypeScript</strong> is a language and a type checker. The
language adds syntax for types to JavaScript.
<br />
The type checker analyzes code to find mismatches between uses of
values and types.
</p>
<p>
<strong>typescript-eslint</strong> is necessary for JavaScript tools
such as ESLint to work with TypeScript's new syntax.
<br />
It also adds lint rules for TypeScript, including many that use the
power of types to better analyze code.
</p>
</div>

<div className={styles.buttons}>
<Link
className="button button--primary"
to={useBaseUrl('getting-started')}
>
Learn More
</Link>
<Link
className="button button--primary button--outline"
to={useBaseUrl('rules')}
>
See the Rules
</Link>
</div>
</section>
);
}
56 changes: 56 additions & 0 deletions packages/website/src/components/home/Explainers/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
.explainers {
--ifm-button-size-multiplier: 1.3;

align-items: center;
display: flex;
flex-direction: column;
margin: 1rem;
}

.explainerTexts {
font-size: 1.1rem;
margin: 1rem 2rem;
text-align: left;
display: flex;
gap: 1rem;
flex-direction: column;
}

.explainerTexts p {
margin: 0;
}

.explainerSpotlights {
display: flex;
flex-direction: column;
gap: 1rem;
margin: 2rem auto 2.5rem;
}

.buttons {
margin: 1rem auto 0;
display: flex;
flex-direction: column;
gap: 1rem;
}

@media (width >= 996px) {
.explainers {
margin-bottom: 2rem;
}

.explainerSpotlights {
flex-direction: row;
max-width: var(--ifm-container-width);
}

.explainerTexts {
margin: 0.5rem 2rem 2rem;
text-align: center;
}

.buttons {
flex-direction: row;
gap: 2rem;
}
}
6 changes: 6 additions & 0 deletions packages/website/src/components/home/Feature.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.buttons {
align-items: center;
display: flex;
width: 100%;
justify-content: center;
}
Loading
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy