eslint-plugin-etc-misc 1.1.6 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +135 -135
- package/dist/_internal/casing.js +2 -2
- package/dist/_internal/casing.js.map +1 -1
- package/dist/_internal/get-core-rule.d.ts.map +1 -1
- package/dist/_internal/get-core-rule.js +1 -2
- package/dist/_internal/get-core-rule.js.map +1 -1
- package/dist/_internal/rule-deprecation.d.ts +2 -2
- package/dist/_internal/rule-deprecation.d.ts.map +1 -1
- package/dist/_internal/rule-deprecation.js +10 -12
- package/dist/_internal/rule-deprecation.js.map +1 -1
- package/dist/plugin.cjs +17 -17
- package/dist/plugin.cjs.map +2 -2
- package/dist/rules/no-const-enum.d.ts.map +1 -1
- package/dist/rules/no-const-enum.js +9 -11
- package/dist/rules/no-const-enum.js.map +1 -1
- package/dist/rules/no-misused-generics.d.ts.map +1 -1
- package/dist/rules/no-misused-generics.js.map +1 -1
- package/dist/rules/no-single-line-comment.d.ts.map +1 -1
- package/dist/rules/no-single-line-comment.js +11 -15
- package/dist/rules/no-single-line-comment.js.map +1 -1
- package/dist/rules/no-use-extend-native.js +2 -2
- package/dist/rules/no-use-extend-native.js.map +1 -1
- package/dist/rules/throw-error.d.ts.map +1 -1
- package/dist/rules/throw-error.js +8 -10
- package/dist/rules/throw-error.js.map +1 -1
- package/dist/rules/typescript-no-redundant-undefined-let.js +1 -1
- package/dist/rules/typescript-no-redundant-undefined-let.js.map +1 -1
- package/dist/rules/typescript-no-redundant-undefined-var.js +1 -1
- package/dist/rules/typescript-no-redundant-undefined-var.js.map +1 -1
- package/dist/rules/typescript-prefer-readonly-property.d.ts.map +1 -1
- package/dist/rules/typescript-prefer-readonly-property.js +9 -11
- package/dist/rules/typescript-prefer-readonly-property.js.map +1 -1
- package/dist/rules/typescript-require-prop-type-annotation.d.ts.map +1 -1
- package/dist/rules/typescript-require-prop-type-annotation.js +9 -11
- package/dist/rules/typescript-require-prop-type-annotation.js.map +1 -1
- package/dist/rules/typescript-require-this-void.d.ts.map +1 -1
- package/dist/rules/typescript-require-this-void.js +9 -11
- package/dist/rules/typescript-require-this-void.js.map +1 -1
- package/docs/AGENTS.md +19 -18
- package/docs/docusaurus/blog/authors.yml +11 -11
- package/docs/docusaurus/docusaurus.config.ts +23 -25
- package/docs/docusaurus/package.json +1 -0
- package/docs/docusaurus/sidebars.rules.ts +40 -42
- package/docs/docusaurus/sidebars.ts +20 -20
- package/docs/docusaurus/src/components/GitHubStats.jsx +4 -4
- package/docs/docusaurus/src/js/modernEnhancements.ts +55 -55
- package/docs/docusaurus/src/pages/index.jsx +12 -12
- package/docs/docusaurus/typedoc-plugins/hashToBangLinksCore.d.mts +4 -2
- package/docs/docusaurus/typedoc.config.json +7 -586
- package/docs/rules/consistent-enum-members.md +3 -3
- package/docs/rules/consistent-filename.md +1 -1
- package/docs/rules/getting-started.md +19 -21
- package/docs/rules/no-assign-mutated-array.md +5 -25
- package/docs/rules/no-expression-empty-lines.md +2 -4
- package/docs/rules/no-foreach.md +1 -5
- package/docs/rules/no-function-declare-after-return.md +45 -36
- package/docs/rules/no-use-extend-native.md +6 -6
- package/docs/rules/no-vulnerable.md +11 -11
- package/docs/rules/prefer-includes.md +2 -11
- package/docs/rules/presets/all.md +1 -1
- package/docs/rules/presets/recommended.md +1 -1
- package/docs/rules/require-jsdoc.md +1 -7
- package/docs/rules/sort-array.md +2 -10
- package/docs/rules/typescript-array-callback-return-type.md +5 -17
- package/package.json +13 -5
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { themes as prismThemes } from "prism-react-renderer";
|
|
2
|
-
|
|
3
|
-
import type { Config } from "@docusaurus/types";
|
|
4
1
|
import type { Options as DocsPluginOptions } from "@docusaurus/plugin-content-docs";
|
|
5
2
|
import type * as Preset from "@docusaurus/preset-classic";
|
|
3
|
+
import type { Config } from "@docusaurus/types";
|
|
4
|
+
|
|
6
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { themes as prismThemes } from "prism-react-renderer";
|
|
7
7
|
|
|
8
8
|
/** Canonical site origin used for sitemap/canonical URL generation. */
|
|
9
9
|
const siteUrl =
|
|
@@ -44,16 +44,14 @@ const removeHeadAttrFlagKey = [
|
|
|
44
44
|
|
|
45
45
|
/** Docusaurus future flags, including optional experimental fast path. */
|
|
46
46
|
const futureConfig = {
|
|
47
|
-
...(enableExperimentalFaster
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
: {}),
|
|
47
|
+
...(enableExperimentalFaster && {
|
|
48
|
+
experimental_faster: {
|
|
49
|
+
mdxCrossCompilerCache: true,
|
|
50
|
+
rspackBundler: true,
|
|
51
|
+
rspackPersistentCache: true,
|
|
52
|
+
ssgWorkerThreads: true,
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
57
55
|
v4: {
|
|
58
56
|
[removeHeadAttrFlagKey]: true,
|
|
59
57
|
// NOTE: Enabling cascade layers currently breaks our production CSS output
|
|
@@ -68,11 +66,11 @@ const futureConfig = {
|
|
|
68
66
|
const config = {
|
|
69
67
|
baseUrl,
|
|
70
68
|
baseUrlIssueBanner: true,
|
|
69
|
+
clientModules: [modernEnhancementsClientModule],
|
|
71
70
|
deploymentBranch: "gh-pages",
|
|
72
71
|
favicon: "img/favicon.ico",
|
|
73
72
|
// Future flags, see https://docusaurus.io/docs/api/docusaurus-config#future
|
|
74
73
|
future: futureConfig,
|
|
75
|
-
clientModules: [modernEnhancementsClientModule],
|
|
76
74
|
i18n: {
|
|
77
75
|
defaultLocale: "en",
|
|
78
76
|
locales: ["en"],
|
|
@@ -189,9 +187,9 @@ const config = {
|
|
|
189
187
|
docs: {
|
|
190
188
|
breadcrumbs: true,
|
|
191
189
|
editUrl: `https://github.com/${organizationName}/${projectName}/blob/main/docs/docusaurus/`,
|
|
192
|
-
path: "site-docs",
|
|
193
190
|
includeCurrentVersion: true,
|
|
194
191
|
onInlineTags: "ignore",
|
|
192
|
+
path: "site-docs",
|
|
195
193
|
routeBasePath: "docs",
|
|
196
194
|
showLastUpdateAuthor: true,
|
|
197
195
|
showLastUpdateTime: true,
|
|
@@ -233,7 +231,7 @@ const config = {
|
|
|
233
231
|
svgr: {
|
|
234
232
|
svgrConfig: {
|
|
235
233
|
dimensions: false, // Remove width/height so CSS controls size
|
|
236
|
-
expandProps: "start", // Spread props at the start: <
|
|
234
|
+
expandProps: "start", // Spread props at the start: <SVG {...props}>
|
|
237
235
|
icon: true, // Treat SVGs as icons (scales via viewBox)
|
|
238
236
|
memo: true, // Wrap component with React.memo
|
|
239
237
|
native: false, // Produce web React components (not React Native)
|
|
@@ -269,12 +267,6 @@ const config = {
|
|
|
269
267
|
disableSwitch: false,
|
|
270
268
|
respectPrefersColorScheme: true,
|
|
271
269
|
},
|
|
272
|
-
metadata: [
|
|
273
|
-
{
|
|
274
|
-
content: "eslint-plugin-etc-misc",
|
|
275
|
-
name: "keywords",
|
|
276
|
-
},
|
|
277
|
-
],
|
|
278
270
|
footer: {
|
|
279
271
|
copyright: footerCopyright,
|
|
280
272
|
links: [
|
|
@@ -310,12 +302,12 @@ const config = {
|
|
|
310
302
|
label: "🔍 ESLint Inspector",
|
|
311
303
|
},
|
|
312
304
|
{
|
|
313
|
-
to: "/docs/rules/overview",
|
|
314
305
|
label: "📏 Rule Docs",
|
|
306
|
+
to: "/docs/rules/overview",
|
|
315
307
|
},
|
|
316
308
|
{
|
|
317
|
-
to: "/docs/rules/presets/all",
|
|
318
309
|
label: "🟣 All Preset",
|
|
310
|
+
to: "/docs/rules/presets/all",
|
|
319
311
|
},
|
|
320
312
|
],
|
|
321
313
|
title: "🚀 Project",
|
|
@@ -344,14 +336,20 @@ const config = {
|
|
|
344
336
|
],
|
|
345
337
|
logo: {
|
|
346
338
|
alt: "eslint-plugin-etc-misc logo",
|
|
339
|
+
height: "auto",
|
|
347
340
|
href: `https://github.com/${organizationName}/${projectName}`,
|
|
348
341
|
src: "img/logo_128x128.png",
|
|
349
342
|
width: "auto",
|
|
350
|
-
height: "auto",
|
|
351
343
|
},
|
|
352
344
|
style: "dark",
|
|
353
345
|
},
|
|
354
346
|
image: "img/logo.png",
|
|
347
|
+
metadata: [
|
|
348
|
+
{
|
|
349
|
+
content: "eslint-plugin-etc-misc",
|
|
350
|
+
name: "keywords",
|
|
351
|
+
},
|
|
352
|
+
],
|
|
355
353
|
navbar: {
|
|
356
354
|
items: [
|
|
357
355
|
{
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
+
import type { SidebarsConfig } from "@docusaurus/plugin-content-docs";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* @packageDocumentation
|
|
3
5
|
* Dynamic sidebar generation for plugin rule documentation sections.
|
|
4
6
|
*/
|
|
5
|
-
import {
|
|
7
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
6
8
|
import { dirname, join } from "node:path";
|
|
7
9
|
import { fileURLToPath } from "node:url";
|
|
8
10
|
|
|
9
|
-
import type { SidebarsConfig } from "@docusaurus/plugin-content-docs";
|
|
10
|
-
|
|
11
|
-
/** Minimal document item shape used by generated rule categories. */
|
|
12
|
-
type SidebarDocItem = {
|
|
13
|
-
readonly id: string;
|
|
14
|
-
readonly label?: string;
|
|
15
|
-
readonly type: "doc";
|
|
16
|
-
};
|
|
17
|
-
|
|
18
11
|
type RuleCatalogMapEntry = Readonly<{
|
|
19
12
|
catalogId: string;
|
|
20
13
|
docId: string;
|
|
21
14
|
ruleName: string;
|
|
22
15
|
}>;
|
|
23
16
|
|
|
17
|
+
/** Minimal document item shape used by generated rule categories. */
|
|
18
|
+
interface SidebarDocItem {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly label?: string;
|
|
21
|
+
readonly type: "doc";
|
|
22
|
+
}
|
|
23
|
+
|
|
24
24
|
/** Directory containing this sidebar module. */
|
|
25
25
|
const sidebarDirectoryPath = dirname(fileURLToPath(import.meta.url));
|
|
26
26
|
/** Directory containing generated rule docs consumed by the sidebar. */
|
|
@@ -39,7 +39,7 @@ const sourceRulesDirectoryPath = join(
|
|
|
39
39
|
);
|
|
40
40
|
|
|
41
41
|
/** Docs that are part of the rules docs plugin but are not individual rule docs. */
|
|
42
|
-
const nonRuleDocIds = new Set(["
|
|
42
|
+
const nonRuleDocIds = new Set(["getting-started", "overview"]);
|
|
43
43
|
|
|
44
44
|
const ruleCatalogMap = JSON.parse(
|
|
45
45
|
readFileSync(ruleCatalogMapFilePath, "utf8")
|
|
@@ -62,7 +62,7 @@ const toRuleId = (fileName: string): string => fileName.slice(0, -3);
|
|
|
62
62
|
|
|
63
63
|
/** Convert a markdown path (e.g. `foo/bar.md`) to a Docusaurus doc id. */
|
|
64
64
|
const toDocIdFromRelativePath = (relativePath: string): string =>
|
|
65
|
-
relativePath.
|
|
65
|
+
relativePath.replaceAll("\\", "/").replace(/\.md$/u, "");
|
|
66
66
|
|
|
67
67
|
/** Collect markdown doc ids recursively from a docs directory. */
|
|
68
68
|
const collectMarkdownDocIdsRecursively = (
|
|
@@ -112,11 +112,9 @@ const allRulesMarkdownDocIds = readdirSync(rulesDocsDirectoryPath, {
|
|
|
112
112
|
.sort((left, right) => left.localeCompare(right));
|
|
113
113
|
|
|
114
114
|
/** Sorted markdown doc ids discovered from `docs/rules/**`. */
|
|
115
|
-
const allRulesPluginDocIds =
|
|
116
|
-
rulesDocsDirectoryPath
|
|
117
|
-
)
|
|
118
|
-
.slice()
|
|
119
|
-
.sort((left, right) => left.localeCompare(right));
|
|
115
|
+
const allRulesPluginDocIds = [
|
|
116
|
+
...collectMarkdownDocIdsRecursively(rulesDocsDirectoryPath),
|
|
117
|
+
].sort((left, right) => left.localeCompare(right));
|
|
120
118
|
const allRulesPluginDocIdSet = new Set(allRulesPluginDocIds);
|
|
121
119
|
|
|
122
120
|
const hasRulesPluginDocId = (docId: string): boolean =>
|
|
@@ -224,15 +222,15 @@ if (guideItems.length > 0) {
|
|
|
224
222
|
customProps: {
|
|
225
223
|
badge: "guides",
|
|
226
224
|
},
|
|
227
|
-
|
|
225
|
+
items: guideItems,
|
|
228
226
|
label: "🧭 Adoption & Rollout",
|
|
229
227
|
link: {
|
|
230
|
-
type: "generated-index",
|
|
231
|
-
title: "Adoption & Rollout",
|
|
232
228
|
description:
|
|
233
229
|
"Shared migration, rollout, and fix-safety guidance for rule adoption.",
|
|
230
|
+
title: "Adoption & Rollout",
|
|
231
|
+
type: "generated-index",
|
|
234
232
|
},
|
|
235
|
-
|
|
233
|
+
type: "category",
|
|
236
234
|
});
|
|
237
235
|
}
|
|
238
236
|
|
|
@@ -293,15 +291,15 @@ if (presetItems.length > 0) {
|
|
|
293
291
|
customProps: {
|
|
294
292
|
badge: "presets",
|
|
295
293
|
},
|
|
296
|
-
|
|
294
|
+
items: presetItems,
|
|
297
295
|
label: "🎛 Presets",
|
|
298
296
|
link: {
|
|
299
|
-
type: "generated-index",
|
|
300
|
-
title: "Presets",
|
|
301
297
|
description:
|
|
302
298
|
"Predefined flat-config preset bundles for different adoption levels.",
|
|
299
|
+
title: "Presets",
|
|
300
|
+
type: "generated-index",
|
|
303
301
|
},
|
|
304
|
-
|
|
302
|
+
type: "category",
|
|
305
303
|
});
|
|
306
304
|
}
|
|
307
305
|
|
|
@@ -337,15 +335,6 @@ const sidebars = {
|
|
|
337
335
|
customProps: {
|
|
338
336
|
badge: "rules",
|
|
339
337
|
},
|
|
340
|
-
type: "category",
|
|
341
|
-
label: "📏 Rules",
|
|
342
|
-
link: {
|
|
343
|
-
type: "generated-index",
|
|
344
|
-
title: "Rule Reference",
|
|
345
|
-
slug: "/",
|
|
346
|
-
description:
|
|
347
|
-
"Rule documentation for every eslint-plugin-etc-misc rule.",
|
|
348
|
-
},
|
|
349
338
|
items: [
|
|
350
339
|
{
|
|
351
340
|
className: "sb-cat-rules-core",
|
|
@@ -353,15 +342,15 @@ const sidebars = {
|
|
|
353
342
|
customProps: {
|
|
354
343
|
badge: "core",
|
|
355
344
|
},
|
|
356
|
-
|
|
345
|
+
items: createRuleItems(coreRuleDocIds),
|
|
357
346
|
label: "🧱 Core Rules",
|
|
358
347
|
link: {
|
|
359
|
-
type: "generated-index",
|
|
360
|
-
title: "Core Rules",
|
|
361
348
|
description:
|
|
362
349
|
"General-purpose etc-misc rules for safer and clearer TypeScript code.",
|
|
350
|
+
title: "Core Rules",
|
|
351
|
+
type: "generated-index",
|
|
363
352
|
},
|
|
364
|
-
|
|
353
|
+
type: "category",
|
|
365
354
|
},
|
|
366
355
|
{
|
|
367
356
|
className: "sb-cat-rules-typescript",
|
|
@@ -369,17 +358,26 @@ const sidebars = {
|
|
|
369
358
|
customProps: {
|
|
370
359
|
badge: "typescript",
|
|
371
360
|
},
|
|
372
|
-
|
|
361
|
+
items: createRuleItems(typeScriptRuleDocIds),
|
|
373
362
|
label: "🧠 TypeScript Rules",
|
|
374
363
|
link: {
|
|
375
|
-
type: "generated-index",
|
|
376
|
-
title: "TypeScript Rules",
|
|
377
364
|
description:
|
|
378
365
|
"Rules focused on stronger TypeScript-only constraints and type-level consistency.",
|
|
366
|
+
title: "TypeScript Rules",
|
|
367
|
+
type: "generated-index",
|
|
379
368
|
},
|
|
380
|
-
|
|
369
|
+
type: "category",
|
|
381
370
|
},
|
|
382
371
|
],
|
|
372
|
+
label: "📏 Rules",
|
|
373
|
+
link: {
|
|
374
|
+
description:
|
|
375
|
+
"Rule documentation for every eslint-plugin-etc-misc rule.",
|
|
376
|
+
slug: "/",
|
|
377
|
+
title: "Rule Reference",
|
|
378
|
+
type: "generated-index",
|
|
379
|
+
},
|
|
380
|
+
type: "category",
|
|
383
381
|
},
|
|
384
382
|
],
|
|
385
383
|
} as const satisfies SidebarsConfig;
|
|
@@ -25,7 +25,12 @@ const sidebars = {
|
|
|
25
25
|
customProps: {
|
|
26
26
|
badge: "playbooks",
|
|
27
27
|
},
|
|
28
|
-
|
|
28
|
+
items: [
|
|
29
|
+
{
|
|
30
|
+
dirName: "guides",
|
|
31
|
+
type: "autogenerated",
|
|
32
|
+
},
|
|
33
|
+
],
|
|
29
34
|
label: "🧭 Guides",
|
|
30
35
|
link: {
|
|
31
36
|
description:
|
|
@@ -33,12 +38,7 @@ const sidebars = {
|
|
|
33
38
|
title: "Guides",
|
|
34
39
|
type: "generated-index",
|
|
35
40
|
},
|
|
36
|
-
|
|
37
|
-
{
|
|
38
|
-
dirName: "guides",
|
|
39
|
-
type: "autogenerated",
|
|
40
|
-
},
|
|
41
|
-
],
|
|
41
|
+
type: "category",
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
44
|
className: "sb-cat-architecture",
|
|
@@ -46,7 +46,12 @@ const sidebars = {
|
|
|
46
46
|
customProps: {
|
|
47
47
|
badge: "adr",
|
|
48
48
|
},
|
|
49
|
-
|
|
49
|
+
items: [
|
|
50
|
+
{
|
|
51
|
+
dirName: "architecture/adr",
|
|
52
|
+
type: "autogenerated",
|
|
53
|
+
},
|
|
54
|
+
],
|
|
50
55
|
label: "🏗️ Architecture",
|
|
51
56
|
link: {
|
|
52
57
|
description:
|
|
@@ -54,12 +59,7 @@ const sidebars = {
|
|
|
54
59
|
title: "Architecture Decisions",
|
|
55
60
|
type: "generated-index",
|
|
56
61
|
},
|
|
57
|
-
|
|
58
|
-
{
|
|
59
|
-
dirName: "architecture/adr",
|
|
60
|
-
type: "autogenerated",
|
|
61
|
-
},
|
|
62
|
-
],
|
|
62
|
+
type: "category",
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
className: "sb-cat-developer",
|
|
@@ -67,12 +67,6 @@ const sidebars = {
|
|
|
67
67
|
customProps: {
|
|
68
68
|
badge: "api",
|
|
69
69
|
},
|
|
70
|
-
type: "category",
|
|
71
|
-
label: "🛠 Dev",
|
|
72
|
-
link: {
|
|
73
|
-
type: "doc",
|
|
74
|
-
id: "developer/api/index",
|
|
75
|
-
},
|
|
76
70
|
items: [
|
|
77
71
|
{
|
|
78
72
|
className: "sb-doc-releasing",
|
|
@@ -129,6 +123,12 @@ const sidebars = {
|
|
|
129
123
|
type: "category",
|
|
130
124
|
},
|
|
131
125
|
],
|
|
126
|
+
label: "🛠 Dev",
|
|
127
|
+
link: {
|
|
128
|
+
id: "developer/api/index",
|
|
129
|
+
type: "doc",
|
|
130
|
+
},
|
|
131
|
+
type: "category",
|
|
132
132
|
},
|
|
133
133
|
],
|
|
134
134
|
} as const satisfies SidebarsConfig;
|
|
@@ -57,19 +57,19 @@ export default function GitHubStats({ className = "" } = {}) {
|
|
|
57
57
|
return (
|
|
58
58
|
<ul className={badgeListClassName}>
|
|
59
59
|
{liveBadges.map((badge) => (
|
|
60
|
-
<li
|
|
60
|
+
<li className={styles.liveBadgeListItem} key={badge.src}>
|
|
61
61
|
<Link
|
|
62
62
|
className={styles.liveBadgeAnchor}
|
|
63
63
|
href={badge.href}
|
|
64
|
-
target="_blank"
|
|
65
64
|
rel="noopener noreferrer"
|
|
65
|
+
target="_blank"
|
|
66
66
|
>
|
|
67
67
|
<img
|
|
68
68
|
alt={badge.alt}
|
|
69
69
|
className={styles.liveBadgeImage}
|
|
70
|
-
src={badge.src}
|
|
71
|
-
loading="lazy"
|
|
72
70
|
decoding="async"
|
|
71
|
+
loading="lazy"
|
|
72
|
+
src={badge.src}
|
|
73
73
|
/>
|
|
74
74
|
</Link>
|
|
75
75
|
</li>
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
type CleanupFunction = () => void;
|
|
8
8
|
|
|
9
9
|
/** Mutable holder used to swap active cleanup handlers between route refreshes. */
|
|
10
|
-
|
|
10
|
+
interface CleanupRef {
|
|
11
11
|
current: CleanupFunction | null;
|
|
12
|
-
}
|
|
12
|
+
}
|
|
13
13
|
|
|
14
14
|
declare global {
|
|
15
15
|
interface Window {
|
|
@@ -21,14 +21,47 @@ declare global {
|
|
|
21
21
|
const ROUTE_REFRESH_DELAY_MS = 100;
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* @param element - DOM element candidate.
|
|
24
|
+
* Apply a subtle animation to the theme toggle control.
|
|
27
25
|
*
|
|
28
|
-
* @returns
|
|
26
|
+
* @returns Cleanup callback that removes click listeners and pending timers.
|
|
29
27
|
*/
|
|
30
|
-
function
|
|
31
|
-
|
|
28
|
+
function applyThemeToggleAnimation(): CleanupFunction {
|
|
29
|
+
const themeToggle = document.querySelector(
|
|
30
|
+
'[aria-label*="color mode"], [title*="Switch"]'
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
if (!isHTMLElement(themeToggle)) {
|
|
34
|
+
return (): void => {
|
|
35
|
+
// No-op when theme toggle is not present.
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let animationTimer: null | ReturnType<typeof setTimeout> = null;
|
|
40
|
+
|
|
41
|
+
const handleClick = (): void => {
|
|
42
|
+
themeToggle.style.transform = "scale(0.94)";
|
|
43
|
+
themeToggle.style.transition = "transform 120ms ease";
|
|
44
|
+
|
|
45
|
+
if (animationTimer) {
|
|
46
|
+
clearTimeout(animationTimer);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
animationTimer = setTimeout(() => {
|
|
50
|
+
themeToggle.style.transform = "scale(1)";
|
|
51
|
+
animationTimer = null;
|
|
52
|
+
}, 90);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
themeToggle.addEventListener("click", handleClick);
|
|
56
|
+
|
|
57
|
+
return (): void => {
|
|
58
|
+
if (animationTimer) {
|
|
59
|
+
clearTimeout(animationTimer);
|
|
60
|
+
animationTimer = null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
themeToggle.removeEventListener("click", handleClick);
|
|
64
|
+
};
|
|
32
65
|
}
|
|
33
66
|
|
|
34
67
|
/**
|
|
@@ -72,57 +105,13 @@ function createScrollIndicator(): CleanupFunction {
|
|
|
72
105
|
};
|
|
73
106
|
}
|
|
74
107
|
|
|
75
|
-
/**
|
|
76
|
-
* Apply a subtle animation to the theme toggle control.
|
|
77
|
-
*
|
|
78
|
-
* @returns Cleanup callback that removes click listeners and pending timers.
|
|
79
|
-
*/
|
|
80
|
-
function applyThemeToggleAnimation(): CleanupFunction {
|
|
81
|
-
const themeToggle = document.querySelector(
|
|
82
|
-
'[aria-label*="color mode"], [title*="Switch"]'
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
if (!isHTMLElement(themeToggle)) {
|
|
86
|
-
return (): void => {
|
|
87
|
-
// No-op when theme toggle is not present.
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
let animationTimer: null | ReturnType<typeof setTimeout> = null;
|
|
92
|
-
|
|
93
|
-
const handleClick = (): void => {
|
|
94
|
-
themeToggle.style.transform = "scale(0.94)";
|
|
95
|
-
themeToggle.style.transition = "transform 120ms ease";
|
|
96
|
-
|
|
97
|
-
if (animationTimer) {
|
|
98
|
-
clearTimeout(animationTimer);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
animationTimer = setTimeout(() => {
|
|
102
|
-
themeToggle.style.transform = "scale(1)";
|
|
103
|
-
animationTimer = null;
|
|
104
|
-
}, 90);
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
themeToggle.addEventListener("click", handleClick);
|
|
108
|
-
|
|
109
|
-
return (): void => {
|
|
110
|
-
if (animationTimer) {
|
|
111
|
-
clearTimeout(animationTimer);
|
|
112
|
-
animationTimer = null;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
themeToggle.removeEventListener("click", handleClick);
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
108
|
/**
|
|
120
109
|
* Initialize modern interaction features and return cleanup hooks.
|
|
121
110
|
*
|
|
122
111
|
* @returns Cleanup callback for all registered enhancement handlers.
|
|
123
112
|
*/
|
|
124
113
|
function initializeAdvancedFeatures(): CleanupFunction {
|
|
125
|
-
const prefersReducedMotion =
|
|
114
|
+
const prefersReducedMotion = globalThis.matchMedia(
|
|
126
115
|
"(prefers-reduced-motion: reduce)"
|
|
127
116
|
).matches;
|
|
128
117
|
const cleanupFunctions: CleanupFunction[] = [];
|
|
@@ -134,9 +123,9 @@ function initializeAdvancedFeatures(): CleanupFunction {
|
|
|
134
123
|
}
|
|
135
124
|
|
|
136
125
|
return (): void => {
|
|
137
|
-
|
|
126
|
+
for (const cleanup of cleanupFunctions) {
|
|
138
127
|
cleanup();
|
|
139
|
-
}
|
|
128
|
+
}
|
|
140
129
|
};
|
|
141
130
|
}
|
|
142
131
|
|
|
@@ -210,6 +199,17 @@ function initializeEnhancements(): CleanupFunction {
|
|
|
210
199
|
};
|
|
211
200
|
}
|
|
212
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Check whether a node is an {@link HTMLElement}.
|
|
204
|
+
*
|
|
205
|
+
* @param element - DOM element candidate.
|
|
206
|
+
*
|
|
207
|
+
* @returns `true` when element is an `HTMLElement` instance.
|
|
208
|
+
*/
|
|
209
|
+
function isHTMLElement(element: Element | null): element is HTMLElement {
|
|
210
|
+
return element instanceof HTMLElement;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
213
|
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
214
214
|
initializeEnhancements();
|
|
215
215
|
window.initializeAdvancedFeatures = initializeAdvancedFeatures;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import Link from "@docusaurus/Link";
|
|
2
2
|
import useBaseUrl from "@docusaurus/useBaseUrl";
|
|
3
|
-
import Layout from "@theme/Layout";
|
|
4
3
|
import Heading from "@theme/Heading";
|
|
5
|
-
import
|
|
4
|
+
import Layout from "@theme/Layout";
|
|
6
5
|
|
|
6
|
+
import GitHubStats from "../components/GitHubStats";
|
|
7
7
|
import styles from "./index.module.css";
|
|
8
8
|
|
|
9
9
|
const heroBadges = [
|
|
@@ -47,24 +47,24 @@ const heroStats = [
|
|
|
47
47
|
|
|
48
48
|
const homeCards = [
|
|
49
49
|
{
|
|
50
|
-
icon: "\uf135",
|
|
51
|
-
title: "Get Started",
|
|
52
50
|
description:
|
|
53
51
|
"Install the plugin, enable a preset, and start enforcing consistent TypeScript-first conventions.",
|
|
52
|
+
icon: "\u{F135}",
|
|
53
|
+
title: "Get Started",
|
|
54
54
|
to: "/docs/rules/getting-started",
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
|
-
icon: "\uf14e",
|
|
58
|
-
title: "Presets",
|
|
59
57
|
description:
|
|
60
58
|
"Choose between the focused recommended preset and the complete all-rules preset.",
|
|
59
|
+
icon: "\u{F14E}",
|
|
60
|
+
title: "Presets",
|
|
61
61
|
to: "/docs/rules/presets/all",
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
|
-
icon: "\uf02d",
|
|
65
|
-
title: "Rule Reference",
|
|
66
64
|
description:
|
|
67
65
|
"Browse every rule with concrete incorrect/correct examples and migration guidance.",
|
|
66
|
+
icon: "\u{F02D}",
|
|
67
|
+
title: "Rule Reference",
|
|
68
68
|
to: "/docs/rules",
|
|
69
69
|
},
|
|
70
70
|
];
|
|
@@ -79,8 +79,8 @@ export default function Home() {
|
|
|
79
79
|
|
|
80
80
|
return (
|
|
81
81
|
<Layout
|
|
82
|
-
title="eslint-plugin-etc-misc docs"
|
|
83
82
|
description="Documentation for eslint-plugin-etc-misc"
|
|
83
|
+
title="eslint-plugin-etc-misc docs"
|
|
84
84
|
>
|
|
85
85
|
<header className={styles.heroBanner}>
|
|
86
86
|
<div className={`container ${styles.heroContent}`}>
|
|
@@ -102,8 +102,8 @@ export default function Home() {
|
|
|
102
102
|
<div className={styles.heroBadgeRow}>
|
|
103
103
|
{heroBadges.map((badge) => (
|
|
104
104
|
<article
|
|
105
|
-
key={badge.label}
|
|
106
105
|
className={styles.heroBadge}
|
|
106
|
+
key={badge.label}
|
|
107
107
|
>
|
|
108
108
|
<p className={styles.heroBadgeLabel}>
|
|
109
109
|
<span
|
|
@@ -159,8 +159,8 @@ export default function Home() {
|
|
|
159
159
|
<div className={styles.heroStats}>
|
|
160
160
|
{heroStats.map((stat) => (
|
|
161
161
|
<article
|
|
162
|
-
key={stat.headline}
|
|
163
162
|
className={styles.heroStatCard}
|
|
163
|
+
key={stat.headline}
|
|
164
164
|
>
|
|
165
165
|
<p className={styles.heroStatHeading}>
|
|
166
166
|
{stat.headline}
|
|
@@ -178,7 +178,7 @@ export default function Home() {
|
|
|
178
178
|
<section className="container">
|
|
179
179
|
<div className={styles.cardGrid}>
|
|
180
180
|
{homeCards.map((card) => (
|
|
181
|
-
<article
|
|
181
|
+
<article className={styles.card} key={card.title}>
|
|
182
182
|
<div className={styles.cardHeader}>
|
|
183
183
|
<p className={styles.cardIcon}>
|
|
184
184
|
{card.icon}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Rewrites `module#Export` to `module!Export` for module-source-like
|
|
6
|
+
* Rewrites `module#Export` to `module!Export` for module-source-like
|
|
7
|
+
* references.
|
|
7
8
|
*
|
|
8
9
|
* @param inlineTagText - The inline-tag payload stored by TypeDoc.
|
|
9
10
|
*/
|
|
@@ -24,7 +25,8 @@ export declare function convertHashLinksToBangLinksInComment(
|
|
|
24
25
|
/**
|
|
25
26
|
* Mutates an array of TypeDoc comment display parts in-place.
|
|
26
27
|
*
|
|
27
|
-
* @param parts - Display parts collection whose inline-tag text may be
|
|
28
|
+
* @param parts - Display parts collection whose inline-tag text may be
|
|
29
|
+
* rewritten.
|
|
28
30
|
*/
|
|
29
31
|
export declare function convertHashLinksToBangLinksInParts(
|
|
30
32
|
parts: Array<Record<string, unknown>>
|