From 3668dc29f15aa4cdbc8bf8831c2e1bfcab50b0a7 Mon Sep 17 00:00:00 2001 From: Simek Date: Mon, 18 Aug 2025 22:38:21 +0200 Subject: [PATCH 01/12] migrate to ESLint flat config, convert to ESM --- .eslintrc.json | 27 - .github/workflows/pre-merge.yml | 6 +- .gitignore | 4 - .prettierrc.json | 2 +- eslint.config.js | 109 ++++ package.json | 17 +- plugins/remark-lint-no-dead-urls/src/index.js | 5 +- plugins/remark-snackplayer/src/index.js | 4 +- plugins/remark-snackplayer/tests/index.js | 8 +- scripts/generate-llms-txt.js | 57 +- scripts/update-redirect/package.json | 8 - .../index.js => update-redirects.js} | 9 +- sync-api-docs/generateMarkdown.js | 8 +- sync-api-docs/methodFormatter.js | 3 - sync-api-docs/package.json | 2 +- sync-api-docs/preprocessGeneratedApiDocs.js | 15 - sync-api-docs/propFormatter.js | 3 - sync-api-docs/sync-api-docs.js | 2 +- .../contributing/how-to-build-from-source.md | 2 +- .../how-to-run-and-write-tests.md | 2 +- .../contributing/labeling-github-issues.md | 8 +- .../contributing/managing-pull-requests.md | 2 +- website/docusaurus.config.ts | 19 +- website/image-check.js | 15 +- website/modules/snackPlayerInitializer.js | 6 +- website/package.json | 20 +- .../Blog/Components/Author/styles.module.css | 3 +- website/tsconfig.json | 1 - yarn.lock | 517 +++++++++++++++--- 29 files changed, 660 insertions(+), 224 deletions(-) delete mode 100644 .eslintrc.json create mode 100644 eslint.config.js delete mode 100644 scripts/update-redirect/package.json rename scripts/{update-redirect/index.js => update-redirects.js} (89%) diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 39cdbb61165..00000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "plugins": ["prettier"], - "extends": ["plugin:prettier/recommended"], - "overrides": [ - { - "files": ["*.yaml", "*.yml"], - "plugins": ["yml"], - "extends": ["plugin:yml/standard"] - }, - { - "files": ["*.md", "*.mdx"], - "extends": ["plugin:mdx/recommended"] - } - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "sourceType": "module", - "ecmaVersion": "latest", - "ecmaFeatures": { - "jsx": true, - "modules": true - } - }, - "settings": { - "mdx/code-blocks": false - } -} diff --git a/.github/workflows/pre-merge.yml b/.github/workflows/pre-merge.yml index 246ac118ac3..a6afd5bab5a 100644 --- a/.github/workflows/pre-merge.yml +++ b/.github/workflows/pre-merge.yml @@ -19,7 +19,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: "20" - cache: "yarn" + cache: yarn - name: Check lock for duplications run: yarn dedupe --check @@ -47,7 +47,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: "20" - cache: "yarn" + cache: yarn - name: Install dependencies run: yarn install --immutable @@ -56,4 +56,4 @@ jobs: run: yarn build working-directory: website env: - NODE_OPTIONS: "--max_old_space_size=8192" + NODE_OPTIONS: --max_old_space_size=8192 diff --git a/.gitignore b/.gitignore index 740757303ec..756a0b16d4f 100644 --- a/.gitignore +++ b/.gitignore @@ -36,7 +36,3 @@ website/build/ !.yarn/releases !.yarn/sdks !.yarn/versions - - -# Generated file(s) for llms -llms.txt diff --git a/.prettierrc.json b/.prettierrc.json index 8772ae7f1ce..d854bba2731 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -13,7 +13,7 @@ } }, { - "files": "*.md", + "files": ["*.md", "*.mdx"], "options": { "arrowParens": "avoid", "bracketSpacing": false, diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000000..27775b151af --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,109 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {defineConfig, globalIgnores} from 'eslint/config'; +import globals from 'globals'; + +import eslintCss from '@eslint/css'; +import eslintJs from '@eslint/js'; +import eslintPluginYml from 'eslint-plugin-yml'; +import * as eslintPluginMdx from 'eslint-plugin-mdx'; +import eslintPluginPrettier from 'eslint-plugin-prettier/recommended'; +import eslintTs from 'typescript-eslint'; +import tsParser from '@typescript-eslint/parser'; + +export default defineConfig([ + globalIgnores([ + '**/.yarn', + '**/node_modules', + // TODO(simek): move `lint-examples` to 'packages' directory, refactor ESLint setup + 'scripts/lint-examples/out', + // TODO(simek): move `sync-api-docs` to 'packages' directory, refactor ESLint setup + 'sync-api-docs', + 'website/.docusaurus', + 'website/build', + 'website/static', + 'README.md', + ]), + + eslintTs.configs.recommended, + ...eslintPluginYml.configs['flat/standard'], + eslintPluginPrettier, + + { + languageOptions: { + globals: { + ...globals.jest, + ...globals.node, + window: 'readonly', + document: 'readonly', + console: 'readonly', + MutationObserver: 'readonly', + }, + }, + }, + + { + files: ['**/*.js', '**/*.mjs'], + ...eslintJs.configs.recommended, + rules: { + 'no-unused-vars': 'off', + }, + }, + + { + files: ['**/*.ts', '**/*.tsx', '**/*.d.ts'], + settings: { + 'import/resolver': { + typescript: { + project: 'website/tsconfig.json', + }, + }, + }, + languageOptions: { + parser: tsParser, + parserOptions: { + sourceType: 'module', + ecmaVersion: 'es2023', + ecmaFeatures: { + jsx: true, + modules: true, + }, + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + }, + + { + // TODO(simek): figure out SCSS linting, since `@eslint/css` does not support it yet + // @see https://github.com/eslint/css/issues/90 + files: ['**/*.css'], + ...eslintCss.configs.recommended, + language: 'css/css', + plugins: { + css: eslintCss, + }, + rules: { + 'css/no-invalid-properties': [ + 'error', + { + allowUnknownVariables: true, + }, + ], + }, + }, + + { + files: ['**/*.md', '**/*.mdx'], + ...eslintPluginMdx.flat, + processor: eslintPluginMdx.createRemarkProcessor({ + lintCodeBlocks: false, + remarkConfigPath: 'website/.remarkrc.mjs', + }), + }, +]); diff --git a/package.json b/package.json index b9b830cf016..fc9b3584bed 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "react-native-website-monorepo", "private": true, + "type": "module", "engines": { "node": ">=20" }, @@ -18,22 +19,28 @@ "build:fast": "yarn --cwd website build:fast", "serve": "yarn --cwd website serve", "prepare": "husky", + "lint": "eslint .", + "lint:plugins": "eslint ./plugins", + "lint:scripts": "eslint ./scripts", + "lint:website": "eslint ./website", "check-dependencies": "manypkg check" }, "devDependencies": { + "@eslint/css": "^0.10.0", + "@eslint/js": "^9.33.0", "@manypkg/cli": "^0.25.0", - "eslint": "^8.57.1", + "@typescript-eslint/parser": "^8.40.0", + "eslint": "^9.33.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-mdx": "^3.6.2", "eslint-plugin-prettier": "^5.5.4", "eslint-plugin-yml": "^1.18.0", + "globals": "^16.3.0", "husky": "^9.1.7", "netlify-plugin-cache": "^1.0.3", "prettier": "^3.6.2", - "pretty-quick": "^4.2.2" - }, - "resolutions": { - "@typescript-eslint/typescript-estree": "8.39.1" + "pretty-quick": "^4.2.2", + "typescript-eslint": "^8.40.0" }, "packageManager": "yarn@4.9.2" } diff --git a/plugins/remark-lint-no-dead-urls/src/index.js b/plugins/remark-lint-no-dead-urls/src/index.js index 03a6648dea0..de41965ffe4 100644 --- a/plugins/remark-lint-no-dead-urls/src/index.js +++ b/plugins/remark-lint-no-dead-urls/src/index.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import assert from 'node:assert'; import {URL} from 'node:url'; import {lintRule} from 'unified-lint-rule'; import {visit} from 'unist-util-visit'; @@ -46,7 +45,7 @@ async function naiveLinkCheck(urls, options) { urls.map(async url => { try { return await cacheFetch(url, 'HEAD', options); - } catch (e) { + } catch { try { // Fallback, some endpoints don't support HEAD requests return await cacheFetch(url, 'GET', options); @@ -96,7 +95,7 @@ async function noDeadUrls(ast, file, options = {}) { const results = await naiveLinkCheck([...urlToNodes.keys()], clientOptions); - for (const {value, ...other} of results) { + for (const {value} of results) { const [url, statusCode] = value; const nodes = urlToNodes.get(url) ?? []; diff --git a/plugins/remark-snackplayer/src/index.js b/plugins/remark-snackplayer/src/index.js index c366f726ad2..507e5329faa 100644 --- a/plugins/remark-snackplayer/src/index.js +++ b/plugins/remark-snackplayer/src/index.js @@ -7,8 +7,8 @@ 'use strict'; -const visit = require('unist-util-visit-parents'); -const fromEntries = require('object.fromentries'); +import visit from 'unist-util-visit-parents'; +import fromEntries from 'object.fromentries'; const parseParams = (paramString = '') => { const params = fromEntries(new URLSearchParams(paramString)); diff --git a/plugins/remark-snackplayer/tests/index.js b/plugins/remark-snackplayer/tests/index.js index fd874e4c849..64d77e96da3 100644 --- a/plugins/remark-snackplayer/tests/index.js +++ b/plugins/remark-snackplayer/tests/index.js @@ -5,10 +5,10 @@ * LICENSE file in the root directory of this source tree. */ -const path = require('path'); -const fs = require('fs'); -const test = require('tape'); -const snackplayer = require('../'); +import path from 'node:path'; +import fs from 'node:fs'; +import test from 'tape'; +import snackplayer from '../'; const read = name => fs.readFileSync(path.join(__dirname, name), 'utf8'); const normalizeLineEndings = str => str.replace(/\r\n/g, '\n'); diff --git a/scripts/generate-llms-txt.js b/scripts/generate-llms-txt.js index 02bc24fb687..f7488671a82 100644 --- a/scripts/generate-llms-txt.js +++ b/scripts/generate-llms-txt.js @@ -1,8 +1,8 @@ -const fs = require('fs'); -const https = require('https'); -const url = require('url'); -const path = require('path'); -const ts = require('typescript'); +import fs from 'node:fs'; +import https from 'node:https'; +import path from 'node:path'; +import url from 'node:url'; +import ts from 'typescript'; const OUTPUT_FILENAME = 'llms.txt'; const TITLE = 'React Native Documentation'; @@ -10,27 +10,32 @@ const DESCRIPTION = 'React Native is a framework for building native apps using React. It lets you create mobile apps using only JavaScript and React.'; const URL_PREFIX = 'https://reactnative.dev'; +const SLUG_TO_URL = { + 'architecture-overview': 'overview', + 'architecture-glossary': 'glossary', +}; + // Function to convert the TypeScript sidebar config to JSON -function convertSidebarConfigToJson(filePath) { - const inputFileContent = fs.readFileSync(filePath, 'utf8'); - const tempFilePath = path.join(__dirname, 'temp-sidebar.js'); +async function convertSidebarConfigToJson(fileName) { + const inputFileContent = fs.readFileSync( + path.join(import.meta.dirname, '../website', fileName), + 'utf8' + ); + const tempFilePath = path.join(import.meta.dirname, `temp-${fileName}.cjs`); try { const {outputText} = ts.transpileModule(inputFileContent, { compilerOptions: { - module: ts.ModuleKind.CommonJS, - target: ts.ScriptTarget.ES2015, + module: ts.ModuleKind.NodeNext, + target: ts.ScriptTarget.ES2023, }, }); fs.writeFileSync(tempFilePath, outputText); - // Clear require cache for the temp file - delete require.cache[require.resolve(tempFilePath)]; - - const sidebarModule = require(tempFilePath); + const sidebarModule = await import(`${tempFilePath}?update=${Date.now()}`); - return sidebarModule.default; + return sidebarModule.default.default; } catch (error) { console.error('Error converting sidebar config:', error); return null; @@ -41,18 +46,13 @@ function convertSidebarConfigToJson(filePath) { } } -const SLUG_TO_URL = { - 'architecture-overview': 'overview', - 'architecture-glossary': 'glossary', -}; - // Function to extract URLs from sidebar config function extractUrlsFromSidebar(sidebarConfig, prefix) { const urls = []; // Process each section (docs, api, components) - Object.entries(sidebarConfig).forEach(([_, categories]) => { - Object.entries(categories).forEach(([_, items]) => { + Object.entries(sidebarConfig).forEach(([, categories]) => { + Object.entries(categories).forEach(([, items]) => { processItemsForUrls(items, urls, prefix); }); }); @@ -310,14 +310,13 @@ let output = `# ${TITLE}\n\n`; output += `> ${DESCRIPTION}\n\n`; output += `This documentation covers all aspects of using React Native, from installation to advanced usage.\n\n`; -const generateOutput = () => { +async function generateOutput() { const results = []; const promises = []; for (const {name, docPath, prefix} of inputFilePaths) { - const inputFilePath = `./${name}`; + const sidebarConfig = await convertSidebarConfigToJson(name); - const sidebarConfig = convertSidebarConfigToJson(inputFilePath); if (sidebarConfig) { const urls = extractUrlsFromSidebar(sidebarConfig, prefix); @@ -337,7 +336,7 @@ const generateOutput = () => { ); results.push({markdown, prefix}); - console.log(`Successfully generated output from ${inputFilePath}`); + console.log(`Successfully generated output from ${name}`); }) .catch(err => { console.error('Error processing URLs:', err); @@ -373,7 +372,7 @@ const generateOutput = () => { console.error('Error during processing:', err); process.exit(1); }); -}; +} function isEntryUnavailable(unavailableUrls, docPath) { return !unavailableUrls.find(entry => @@ -381,4 +380,6 @@ function isEntryUnavailable(unavailableUrls, docPath) { ); } -generateOutput(); +generateOutput().catch(error => { + console.error(error); +}); diff --git a/scripts/update-redirect/package.json b/scripts/update-redirect/package.json deleted file mode 100644 index 8cddfd49c3f..00000000000 --- a/scripts/update-redirect/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@react-native-website/update-redirects", - "version": "0.0.0", - "private": true, - "bin": { - "update-redirect": "./index.js" - } -} diff --git a/scripts/update-redirect/index.js b/scripts/update-redirects.js similarity index 89% rename from scripts/update-redirect/index.js rename to scripts/update-redirects.js index 38c99fc1df9..668fa3dd80e 100755 --- a/scripts/update-redirect/index.js +++ b/scripts/update-redirects.js @@ -4,13 +4,10 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - * - * @format */ -const fs = require('fs'); -const path = require('path'); -const assert = require('assert'); +import assert from 'node:assert'; +import fs from 'node:fs'; if (process.argv.length < 4) { console.log( @@ -28,7 +25,7 @@ assert.match( assert.match( versions, /versions.json$/, - 'Expects versions.jsoon path as 3nd argument' + 'Expects versions.json path as 3nd argument' ); const latestPublicVersion = JSON.parse(fs.readFileSync(versions, 'utf8'))[0]; diff --git a/sync-api-docs/generateMarkdown.js b/sync-api-docs/generateMarkdown.js index f688865eae4..24374c0e2df 100644 --- a/sync-api-docs/generateMarkdown.js +++ b/sync-api-docs/generateMarkdown.js @@ -12,13 +12,7 @@ const { formatMethodDescription, } = require('./methodFormatter'); -const { - formatMultiplePlatform, - stringToInlineCodeForTable, - maybeLinkifyType, - maybeLinkifyTypeName, - formatType, -} = require('./utils'); +const {formatMultiplePlatform, maybeLinkifyTypeName} = require('./utils'); // Formats an array of rows as a Markdown table function generateTable(rows) { diff --git a/sync-api-docs/methodFormatter.js b/sync-api-docs/methodFormatter.js index 9ff28eb165b..f88736b9ede 100644 --- a/sync-api-docs/methodFormatter.js +++ b/sync-api-docs/methodFormatter.js @@ -7,7 +7,6 @@ 'use strict'; -const {typeOf} = require('tokenize-comment/lib/utils'); const magic = require('./magic'); const {formatMultiplePlatform} = require('./utils'); @@ -47,8 +46,6 @@ function formatMethodDescription(param) { let tag = param.description; const isMatch = tag.match(/{@platform [a-z ,]*}/); if (isMatch) { - const platform = isMatch[0].match(/ [a-z ,]*/); - // Replaces @platform strings with empty string // and appends type with formatted platform tag = tag.replace(/{@platform [a-z ,]*}/g, ''); diff --git a/sync-api-docs/package.json b/sync-api-docs/package.json index 90375ad6fba..373ade3d4f0 100644 --- a/sync-api-docs/package.json +++ b/sync-api-docs/package.json @@ -8,7 +8,7 @@ }, "devDependencies": { "@motiz88/react-native-docgen": "0.0.3", - "fs-extra": "^11.2.0", + "fs-extra": "^11.3.1", "glob": "^11.0.0", "he": "^1.2.0", "react-docgen-markdown-renderer": "^2.1.3", diff --git a/sync-api-docs/preprocessGeneratedApiDocs.js b/sync-api-docs/preprocessGeneratedApiDocs.js index 41510f8611f..a5e553a03f3 100644 --- a/sync-api-docs/preprocessGeneratedApiDocs.js +++ b/sync-api-docs/preprocessGeneratedApiDocs.js @@ -12,21 +12,6 @@ // `generate-api-docs` script. const tokenizeComment = require('tokenize-comment'); -const {typeOf} = require('tokenize-comment/lib/utils'); - -function joinDescriptionAndExamples(tokenized) { - let sections = []; - if (tokenized.description) { - sections.push(tokenized.description); - } - for (const {raw} of tokenized.examples) { - sections.push(raw); - } - if (tokenized.footer) { - sections.push(tokenized.footer); - } - return sections.join('\n\n'); -} function preprocessTagsInDescription(obj) { if (obj && obj.description) { diff --git a/sync-api-docs/propFormatter.js b/sync-api-docs/propFormatter.js index 32d326ba032..d1ba12a9bf3 100644 --- a/sync-api-docs/propFormatter.js +++ b/sync-api-docs/propFormatter.js @@ -7,13 +7,10 @@ 'use strict'; -const {typeOf} = require('tokenize-comment/lib/utils'); const magic = require('./magic'); const { formatMultiplePlatform, stringToInlineCodeForTable, - maybeLinkifyType, - maybeLinkifyTypeName, formatType, } = require('./utils'); diff --git a/sync-api-docs/sync-api-docs.js b/sync-api-docs/sync-api-docs.js index b9b407010e9..d92e327a558 100644 --- a/sync-api-docs/sync-api-docs.js +++ b/sync-api-docs/sync-api-docs.js @@ -25,7 +25,7 @@ async function generateApiDocs(rnPath) { const apiDocs = await extractDocsFromRN(rnPath); preprocessGeneratedApiDocs(apiDocs); await Promise.all( - apiDocs.map(async ({component, file}, index) => { + apiDocs.map(async ({component, file}) => { if (!component.displayName) { console.log( `react-docgen data for ${path.basename(file)} was malformed, skipping` diff --git a/website/contributing/how-to-build-from-source.md b/website/contributing/how-to-build-from-source.md index fe54f579b0c..57b42f30ddc 100644 --- a/website/contributing/how-to-build-from-source.md +++ b/website/contributing/how-to-build-from-source.md @@ -30,7 +30,7 @@ Both with stable releases and nightlies, you will be consuming **precompiled** a // ... include ':app' includeBuild('../node_modules/@react-native/gradle-plugin') - + + includeBuild('../node_modules/react-native') { + dependencySubstitution { + substitute(module("com.facebook.react:react-android")).using(project(":packages:react-native:ReactAndroid")) diff --git a/website/contributing/how-to-run-and-write-tests.md b/website/contributing/how-to-run-and-write-tests.md index 5b38a19ecd0..fe1cee3603f 100644 --- a/website/contributing/how-to-run-and-write-tests.md +++ b/website/contributing/how-to-run-and-write-tests.md @@ -109,7 +109,7 @@ To do this, change `recordMode` flag to `_runner.recordMode = YES;` in [RNTester ### Android Unit Tests -It's a good idea to add an Android unit test whenever you are working on code that can be tested by Java/Kotlin code alone. The Android unit tests are located in `packages/react-native/ReactAndroid/src/test/`. +It's a good idea to add an Android unit test whenever you are working on code that can be tested by Java/Kotlin code alone. The Android unit tests are located in `packages/react-native/ReactAndroid/src/test/`. We recommend browsing through these to get an idea of what a good unit test might look like. diff --git a/website/contributing/labeling-github-issues.md b/website/contributing/labeling-github-issues.md index da89a487f77..ff71019e783 100644 --- a/website/contributing/labeling-github-issues.md +++ b/website/contributing/labeling-github-issues.md @@ -2,11 +2,11 @@ title: Labeling GitHub Issues --- -Most of [our labels](https://github.com/facebook/react-native/issues/labels) have a prefix that provides a hint of their purpose. +Most of [our labels](https://github.com/facebook/react-native/issues/labels) have a prefix that provides a hint of their purpose. -You'll notice right away there's two label prefixes that dominate the list, [API:](https://github.com/facebook/react-native/labels?utf8=%E2%9C%93&q=API%3A), and [Component:](https://github.com/facebook/react-native/labels?utf8=%E2%9C%93&q=Component%3A). +You'll notice right away there's two label prefixes that dominate the list, [API:](https://github.com/facebook/react-native/labels?utf8=%E2%9C%93&q=API%3A), and [Component:](https://github.com/facebook/react-native/labels?utf8=%E2%9C%93&q=Component%3A). -These generally denote issues and pull requests related to an API or Component in the core React Native library. It helps us understand, at a glance, which components are in dire need of documentation or support. +These generally denote issues and pull requests related to an API or Component in the core React Native library. It helps us understand, at a glance, which components are in dire need of documentation or support. These labels are added automatically by one of our [bots](/contributing/bots-reference), but feel free to adjust them if the bot mis-attributes an issue. @@ -24,14 +24,12 @@ When unsure of the meaning of a particular label, go to https://github.com/faceb Applying one of the following labels may result in a bot interaction. The goal of these is to ease aid in issue triage by providing a canned response when deemed necessary. - Labels that instruct the bot to leave a comment with next steps: - - `Needs: Issue Template` - `Needs: Environment Info` - `Needs: Verify on Latest Version` - `Needs: Repro` - Labels that instruct the bot to close the issue after leaving an explanatory comment: - - `Resolution: For Stack Overflow` - `Type: Question` - `Type: Docs` diff --git a/website/contributing/managing-pull-requests.md b/website/contributing/managing-pull-requests.md index 63dc5f3b554..518b902d7b3 100644 --- a/website/contributing/managing-pull-requests.md +++ b/website/contributing/managing-pull-requests.md @@ -40,7 +40,7 @@ Members of the React Native team at Meta aim to review pull requests quickly and ## How does a PR get merged? -The React Native GitHub repository is actually a mirror of a subdirectory from one of Meta's monorepos. Pull requests are therefore not merged in the traditional sense. Instead, they need to be imported into Meta's internal code review system as a ["diff"](https://www.phacility.com/phabricator/differential/). +The React Native GitHub repository is actually a mirror of a subdirectory from one of Meta's monorepos. Pull requests are therefore not merged in the traditional sense. Instead, they need to be imported into Meta's internal code review system as a ["diff"](https://www.phacility.com/phabricator/differential/). Once imported, the changes will go through a suite of tests. Some of these tests are land-blocking, meaning they need to succeed before the contents of the diff can be merged. Meta always runs React Native from `main` and some changes may require a Facebook employee to attach internal changes to your pull request before it can be merged. For example, if you rename a module name, all Facebook internal callsites have to be updated in the same change in order to merge it. If the diff lands successfully, the changes will eventually get synced back to GitHub by [ShipIt](https://github.com/facebook/fbshipit) as a single commit. diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 83a37862d39..d0c77daf5ad 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -12,6 +12,10 @@ import path from 'path'; import users from './showcase.json'; import versions from './versions.json'; +import prismTheme from './core/PrismTheme'; + +import remarkSnackPlayer from '@react-native-website/remark-snackplayer'; +import remarkCodeblockLanguageTitle from '@react-native-website/remark-codeblock-language-as-title'; // See https://docs.netlify.com/configure-builds/environment-variables/ const isProductionDeployment = @@ -20,10 +24,10 @@ const isProductionDeployment = const lastVersion = versions[0]; const copyright = `Copyright © ${new Date().getFullYear()} Meta Platforms, Inc.`; -export interface EditUrlButton { +export type EditUrlButton = { label: string; href: string; -} +}; const commonDocsOptions = { breadcrumbs: false, @@ -57,10 +61,7 @@ const commonDocsOptions = { } return JSON.stringify(buttons); }) as PluginContentDocs.EditUrlFunction, - remarkPlugins: [ - require('@react-native-website/remark-snackplayer'), - require('@react-native-website/remark-codeblock-language-as-title'), - ], + remarkPlugins: [remarkSnackPlayer, remarkCodeblockLanguageTitle], }; const isDeployPreview = process.env.PREVIEW_DEPLOY === 'true'; @@ -83,8 +84,8 @@ const config: Config = { url: 'https://reactnative.dev', baseUrl: '/', clientModules: [ - require.resolve('./modules/snackPlayerInitializer.js'), - require.resolve('./modules/jumpToFragment.js'), + './modules/snackPlayerInitializer.js', + './modules/jumpToFragment.js', ], trailingSlash: false, // because trailing slashes can break some existing relative links scripts: [ @@ -277,7 +278,7 @@ const config: Config = { }, prism: { defaultLanguage: 'tsx', - theme: require('./core/PrismTheme'), + theme: prismTheme, additionalLanguages: [ 'diff', 'bash', diff --git a/website/image-check.js b/website/image-check.js index 1bcc12b776c..ff689984eb5 100644 --- a/website/image-check.js +++ b/website/image-check.js @@ -5,15 +5,17 @@ * LICENSE file in the root directory of this source tree. */ -const glob = require('glob'); -const fs = require('fs-extra'); -const path = require('path'); -const siteConfig = require('./docusaurus.config.js'); +import glob from 'glob'; +import fs from 'fs-extra'; +import path from 'path'; + +import siteConfig from './docusaurus.config.js'; const imageReferenceRegExp = new RegExp(/!\[.*?\]\((.*)\)/g); -let missingAssets = []; +const missingAssets = []; let queue = Promise.resolve(); + glob .glob('./docs/**/*.md') .then(files => { @@ -43,8 +45,7 @@ glob .then(() => { return fs.stat('./static/' + imagePath); }) - .then(stats => {}) - .catch(e => { + .catch(() => { console.error( 'Could not find ' + 'static/' + diff --git a/website/modules/snackPlayerInitializer.js b/website/modules/snackPlayerInitializer.js index 65469b7d97e..9570267a116 100644 --- a/website/modules/snackPlayerInitializer.js +++ b/website/modules/snackPlayerInitializer.js @@ -21,7 +21,7 @@ export default (() => { const initSnackPlayers = () => { updateSnacksTheme(); - window.ExpoSnack && window.ExpoSnack.initialize(); + window?.ExpoSnack?.initialize(); }; const setupTabPanelsMutationObservers = () => { @@ -53,8 +53,8 @@ export default (() => { if ('ExpoSnack' in window) { document.querySelectorAll('.snack-player').forEach(container => { updateSnacksTheme(); - window.ExpoSnack && window.ExpoSnack.remove(container); - window.ExpoSnack && window.ExpoSnack.append(container); + window?.ExpoSnack?.remove(container); + window?.ExpoSnack?.append(container); }); } }).observe(document.getElementsByTagName('html')[0], { diff --git a/website/package.json b/website/package.json index 7ddc0c99383..1086e1fa110 100644 --- a/website/package.json +++ b/website/package.json @@ -12,7 +12,7 @@ "scripts": { "docusaurus": "docusaurus", "start": "docusaurus start", - "build": "docusaurus build && yarn run update-redirect ./build/_redirects ./versions.json && yarn run generate-llms-txt", + "build": "docusaurus build && node ../scripts/update-redirects.js ./build/_redirects ./versions.json && yarn run generate-llms-txt", "build:fast": "PREVIEW_DEPLOY=true yarn run build", "tsc": "npx tsc --noEmit", "swizzle": "docusaurus swizzle", @@ -21,20 +21,16 @@ "clear": "docusaurus clear", "test": "yarn build", "version:cut": "docusaurus docs:version", - "format:source": "prettier --write '{core,src}/**/*.{js,jsx,ts,tsx}'", - "format:markdown": "prettier --write ../docs/*.md && prettier --write {versioned_docs/**/*.md,blog/*.md}", - "format:style": "prettier --write src/**/*.{scss,css}", + "format:style": "prettier --write src/**/*.{scss}", "format:examples": "eslint-examples-js --fix && eslint-examples-tsx --fix", - "prettier": "yarn format:source && yarn format:markdown && yarn format:style", - "lint": "eslint ../docs/** blog/** \"{core,src}/**/*.{js,jsx,ts,tsx}\"", + "prettier": "yarn format:style", + "lint": "eslint .", "lint:examples": "eslint-examples-js && eslint-examples-tsx && tsc-examples", - "lint:versioned": "eslint versioned_docs/**", "lint:markdown": "remark ../docs --quiet -r .remarkrc.mjs", "lint:markdown:versioned": "remark ./versioned_docs --quiet -r .remarkrc.mjs", - "lint:format": "prettier --check '{core,src}/**/*.{js,jsx,ts,tsx}' ../docs/*.md {versioned_docs/**/*.md,blog/*.md} src/**/*.{scss,css}", "language:lint": "cd ../ && alex && case-police 'docs/*.md' -d ./website/react-native-dict.json --disable SDK,URI", "language:lint:versioned": "cd ../ && alex . && case-police '**/*.md' -d ./website/react-native-dict.json --disable SDK,URI", - "ci:lint": "yarn lint && yarn lint:examples && yarn lint:versioned && yarn language:lint:versioned && yarn lint:markdown && yarn lint:format", + "ci:lint": "yarn lint && yarn lint:examples && yarn language:lint:versioned && yarn lint:markdown && prettier --check src/**/*.{scss}", "pwa:generate": "npx pwa-asset-generator ./static/img/header_logo.svg ./static/img/pwa --padding '40px' --background 'rgb(32, 35, 42)' --icon-only --opaque true", "generate-llms-txt": "node ../scripts/generate-llms-txt.js" }, @@ -67,13 +63,13 @@ "@docusaurus/tsconfig": "3.8.1", "@docusaurus/types": "3.8.1", "@react-native-website/lint-examples": "0.0.0", - "@react-native-website/update-redirects": "0.0.0", + "@types/fs-extra": "^11.0.4", "@types/google.analytics": "^0.0.46", "@types/react": "^19.1.10", "alex": "^11.0.1", "case-police": "^1.0.0", - "eslint": "^8.57.1", - "fs-extra": "^11.2.0", + "eslint": "^9.33.0", + "fs-extra": "^11.3.1", "glob": "^11.0.0", "prettier": "^3.6.2", "remark-cli": "^12.0.1", diff --git a/website/src/theme/Blog/Components/Author/styles.module.css b/website/src/theme/Blog/Components/Author/styles.module.css index 5251af55a11..c9ef82c5625 100644 --- a/website/src/theme/Blog/Components/Author/styles.module.css +++ b/website/src/theme/Blog/Components/Author/styles.module.css @@ -79,7 +79,8 @@ svg[class^="authorSocialLink"] { fill: var(--subtle) !important; - &:hover, &:focus { + &:hover, + &:focus { fill: var(--ifm-hero-text-color) !important; } } diff --git a/website/tsconfig.json b/website/tsconfig.json index 5a5af974b6b..5503c1ec3a1 100644 --- a/website/tsconfig.json +++ b/website/tsconfig.json @@ -2,7 +2,6 @@ "extends": "@docusaurus/tsconfig", "compilerOptions": { "baseUrl": "." - // "esModuleInterop": true }, "exclude": ["node_modules", "build"] } diff --git a/yarn.lock b/yarn.lock index fd32d4acfed..201c346260c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2966,24 +2966,81 @@ __metadata: languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": - version: 4.4.1 - resolution: "@eslint-community/eslint-utils@npm:4.4.1" +"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0, @eslint-community/eslint-utils@npm:^4.7.0": + version: 4.7.0 + resolution: "@eslint-community/eslint-utils@npm:4.7.0" dependencies: eslint-visitor-keys: "npm:^3.4.3" peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10c0/2aa0ac2fc50ff3f234408b10900ed4f1a0b19352f21346ad4cc3d83a1271481bdda11097baa45d484dd564c895e0762a27a8240be7a256b3ad47129e96528252 + checksum: 10c0/c0f4f2bd73b7b7a9de74b716a664873d08ab71ab439e51befe77d61915af41a81ecec93b408778b3a7856185244c34c2c8ee28912072ec14def84ba2dec70adf languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.6.1": +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.12.1, @eslint-community/regexpp@npm:^4.6.1": version: 4.12.1 resolution: "@eslint-community/regexpp@npm:4.12.1" checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 languageName: node linkType: hard +"@eslint/config-array@npm:^0.21.0": + version: 0.21.0 + resolution: "@eslint/config-array@npm:0.21.0" + dependencies: + "@eslint/object-schema": "npm:^2.1.6" + debug: "npm:^4.3.1" + minimatch: "npm:^3.1.2" + checksum: 10c0/0ea801139166c4aa56465b309af512ef9b2d3c68f9198751bbc3e21894fe70f25fbf26e1b0e9fffff41857bc21bfddeee58649ae6d79aadcd747db0c5dca771f + languageName: node + linkType: hard + +"@eslint/config-helpers@npm:^0.3.1": + version: 0.3.1 + resolution: "@eslint/config-helpers@npm:0.3.1" + checksum: 10c0/f6c5b3a0b76a0d7d84cc93e310c259e6c3e0792ddd0a62c5fc0027796ffae44183432cb74b2c2b1162801ee1b1b34a6beb5d90a151632b4df7349f994146a856 + languageName: node + linkType: hard + +"@eslint/core@npm:^0.14.0": + version: 0.14.0 + resolution: "@eslint/core@npm:0.14.0" + dependencies: + "@types/json-schema": "npm:^7.0.15" + checksum: 10c0/259f279445834ba2d2cbcc18e9d43202a4011fde22f29d5fb802181d66e0f6f0bd1f6b4b4b46663451f545d35134498231bd5e656e18d9034a457824b92b7741 + languageName: node + linkType: hard + +"@eslint/core@npm:^0.15.2": + version: 0.15.2 + resolution: "@eslint/core@npm:0.15.2" + dependencies: + "@types/json-schema": "npm:^7.0.15" + checksum: 10c0/c17a6dc4f5a6006ecb60165cc38bcd21fefb4a10c7a2578a0cfe5813bbd442531a87ed741da5adab5eb678e8e693fda2e2b14555b035355537e32bcec367ea17 + languageName: node + linkType: hard + +"@eslint/css-tree@npm:^3.6.1": + version: 3.6.3 + resolution: "@eslint/css-tree@npm:3.6.3" + dependencies: + mdn-data: "npm:2.21.0" + source-map-js: "npm:^1.0.1" + checksum: 10c0/5025d106e2a61d14e807f0d26f20e1aa766ef8f2b6fe9ef02ce84c2ff463cbc57022b38d740d56d0683484adf3ac8795f7565f1955f2ee75c0f3a5cc4b3dd47d + languageName: node + linkType: hard + +"@eslint/css@npm:^0.10.0": + version: 0.10.0 + resolution: "@eslint/css@npm:0.10.0" + dependencies: + "@eslint/core": "npm:^0.14.0" + "@eslint/css-tree": "npm:^3.6.1" + "@eslint/plugin-kit": "npm:^0.3.1" + checksum: 10c0/43ffbabea89a6ff1df61c668d966a37d83b65e2466c87a87dae310bfae2119cbebf9de9a91569c2e1eb11fbaebbb8e707971ea6fffe0f323621109f61f636d22 + languageName: node + linkType: hard + "@eslint/eslintrc@npm:^2.1.4": version: 2.1.4 resolution: "@eslint/eslintrc@npm:2.1.4" @@ -3001,6 +3058,23 @@ __metadata: languageName: node linkType: hard +"@eslint/eslintrc@npm:^3.3.1": + version: 3.3.1 + resolution: "@eslint/eslintrc@npm:3.3.1" + dependencies: + ajv: "npm:^6.12.4" + debug: "npm:^4.3.2" + espree: "npm:^10.0.1" + globals: "npm:^14.0.0" + ignore: "npm:^5.2.0" + import-fresh: "npm:^3.2.1" + js-yaml: "npm:^4.1.0" + minimatch: "npm:^3.1.2" + strip-json-comments: "npm:^3.1.1" + checksum: 10c0/b0e63f3bc5cce4555f791a4e487bf999173fcf27c65e1ab6e7d63634d8a43b33c3693e79f192cbff486d7df1be8ebb2bd2edc6e70ddd486cbfa84a359a3e3b41 + languageName: node + linkType: hard + "@eslint/js@npm:8.57.1": version: 8.57.1 resolution: "@eslint/js@npm:8.57.1" @@ -3008,6 +3082,30 @@ __metadata: languageName: node linkType: hard +"@eslint/js@npm:9.33.0, @eslint/js@npm:^9.33.0": + version: 9.33.0 + resolution: "@eslint/js@npm:9.33.0" + checksum: 10c0/4c42c9abde76a183b8e47205fd6c3116b058f82f07b6ad4de40de56cdb30a36e9ecd40efbea1b63a84d08c206aadbb0aa39a890197e1ad6455a8e542df98f186 + languageName: node + linkType: hard + +"@eslint/object-schema@npm:^2.1.6": + version: 2.1.6 + resolution: "@eslint/object-schema@npm:2.1.6" + checksum: 10c0/b8cdb7edea5bc5f6a96173f8d768d3554a628327af536da2fc6967a93b040f2557114d98dbcdbf389d5a7b290985ad6a9ce5babc547f36fc1fde42e674d11a56 + languageName: node + linkType: hard + +"@eslint/plugin-kit@npm:^0.3.1, @eslint/plugin-kit@npm:^0.3.5": + version: 0.3.5 + resolution: "@eslint/plugin-kit@npm:0.3.5" + dependencies: + "@eslint/core": "npm:^0.15.2" + levn: "npm:^0.4.1" + checksum: 10c0/c178c1b58c574200c0fd125af3e4bc775daba7ce434ba6d1eeaf9bcb64b2e9fea75efabffb3ed3ab28858e55a016a5efa95f509994ee4341b341199ca630b89e + languageName: node + linkType: hard + "@hapi/hoek@npm:^9.0.0, @hapi/hoek@npm:^9.3.0": version: 9.3.0 resolution: "@hapi/hoek@npm:9.3.0" @@ -3024,6 +3122,23 @@ __metadata: languageName: node linkType: hard +"@humanfs/core@npm:^0.19.1": + version: 0.19.1 + resolution: "@humanfs/core@npm:0.19.1" + checksum: 10c0/aa4e0152171c07879b458d0e8a704b8c3a89a8c0541726c6b65b81e84fd8b7564b5d6c633feadc6598307d34564bd53294b533491424e8e313d7ab6c7bc5dc67 + languageName: node + linkType: hard + +"@humanfs/node@npm:^0.16.6": + version: 0.16.6 + resolution: "@humanfs/node@npm:0.16.6" + dependencies: + "@humanfs/core": "npm:^0.19.1" + "@humanwhocodes/retry": "npm:^0.3.0" + checksum: 10c0/8356359c9f60108ec204cbd249ecd0356667359b2524886b357617c4a7c3b6aace0fd5a369f63747b926a762a88f8a25bc066fa1778508d110195ce7686243e1 + languageName: node + linkType: hard + "@humanwhocodes/config-array@npm:^0.13.0": version: 0.13.0 resolution: "@humanwhocodes/config-array@npm:0.13.0" @@ -3049,6 +3164,20 @@ __metadata: languageName: node linkType: hard +"@humanwhocodes/retry@npm:^0.3.0": + version: 0.3.1 + resolution: "@humanwhocodes/retry@npm:0.3.1" + checksum: 10c0/f0da1282dfb45e8120480b9e2e275e2ac9bbe1cf016d046fdad8e27cc1285c45bb9e711681237944445157b430093412b4446c1ab3fc4bb037861b5904101d3b + languageName: node + linkType: hard + +"@humanwhocodes/retry@npm:^0.4.2": + version: 0.4.3 + resolution: "@humanwhocodes/retry@npm:0.4.3" + checksum: 10c0/3775bb30087d4440b3f7406d5a057777d90e4b9f435af488a4923ef249e93615fb78565a85f173a186a076c7706a81d0d57d563a2624e4de2c5c9c66c486ce42 + languageName: node + linkType: hard + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -3865,7 +3994,7 @@ __metadata: resolution: "@react-native-website/sync-api@workspace:sync-api-docs" dependencies: "@motiz88/react-native-docgen": "npm:0.0.3" - fs-extra: "npm:^11.2.0" + fs-extra: "npm:^11.3.1" glob: "npm:^11.0.0" he: "npm:^1.2.0" react-docgen-markdown-renderer: "npm:^2.1.3" @@ -3873,14 +4002,6 @@ __metadata: languageName: unknown linkType: soft -"@react-native-website/update-redirects@npm:0.0.0, @react-native-website/update-redirects@workspace:scripts/update-redirect": - version: 0.0.0-use.local - resolution: "@react-native-website/update-redirects@workspace:scripts/update-redirect" - bin: - update-redirect: ./index.js - languageName: unknown - linkType: soft - "@react-native/assets-registry@npm:0.81.0": version: 0.81.0 resolution: "@react-native/assets-registry@npm:0.81.0" @@ -5021,6 +5142,16 @@ __metadata: languageName: node linkType: hard +"@types/fs-extra@npm:^11.0.4": + version: 11.0.4 + resolution: "@types/fs-extra@npm:11.0.4" + dependencies: + "@types/jsonfile": "npm:*" + "@types/node": "npm:*" + checksum: 10c0/9e34f9b24ea464f3c0b18c3f8a82aefc36dc524cc720fc2b886e5465abc66486ff4e439ea3fb2c0acebf91f6d3f74e514f9983b1f02d4243706bdbb7511796ad + languageName: node + linkType: hard + "@types/google.analytics@npm:^0.0.46": version: 0.0.46 resolution: "@types/google.analytics@npm:0.0.46" @@ -5131,13 +5262,22 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db languageName: node linkType: hard +"@types/jsonfile@npm:*": + version: 6.1.4 + resolution: "@types/jsonfile@npm:6.1.4" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/b12d068b021e4078f6ac4441353965769be87acf15326173e2aea9f3bf8ead41bd0ad29421df5bbeb0123ec3fc02eb0a734481d52903704a1454a1845896b9eb + languageName: node + linkType: hard + "@types/mdast@npm:^3.0.0": version: 3.0.15 resolution: "@types/mdast@npm:3.0.15" @@ -5432,6 +5572,27 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/eslint-plugin@npm:8.40.0": + version: 8.40.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.40.0" + dependencies: + "@eslint-community/regexpp": "npm:^4.10.0" + "@typescript-eslint/scope-manager": "npm:8.40.0" + "@typescript-eslint/type-utils": "npm:8.40.0" + "@typescript-eslint/utils": "npm:8.40.0" + "@typescript-eslint/visitor-keys": "npm:8.40.0" + graphemer: "npm:^1.4.0" + ignore: "npm:^7.0.0" + natural-compare: "npm:^1.4.0" + ts-api-utils: "npm:^2.1.0" + peerDependencies: + "@typescript-eslint/parser": ^8.40.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/dc8889c3255bce6956432f099059179dd13826ba29670f81ba9238ecde46764ee63459eb73a7d88f4f30e1144a2f000d79c9e3f256fa759689d9b3b74d423bda + languageName: node + linkType: hard + "@typescript-eslint/eslint-plugin@npm:^7.1.1": version: 7.18.0 resolution: "@typescript-eslint/eslint-plugin@npm:7.18.0" @@ -5455,6 +5616,22 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/parser@npm:8.40.0, @typescript-eslint/parser@npm:^8.40.0": + version: 8.40.0 + resolution: "@typescript-eslint/parser@npm:8.40.0" + dependencies: + "@typescript-eslint/scope-manager": "npm:8.40.0" + "@typescript-eslint/types": "npm:8.40.0" + "@typescript-eslint/typescript-estree": "npm:8.40.0" + "@typescript-eslint/visitor-keys": "npm:8.40.0" + debug: "npm:^4.3.4" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/43ca9589b8a1f3f4b30a214c0e2254fa0ad43458ef1258b1d62c5aad52710ad11b9315b124cda79163274147b82201a5d76fab7de413e34bfe8e377142b71e98 + languageName: node + linkType: hard + "@typescript-eslint/parser@npm:^7.1.1": version: 7.18.0 resolution: "@typescript-eslint/parser@npm:7.18.0" @@ -5473,16 +5650,16 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/project-service@npm:8.39.1": - version: 8.39.1 - resolution: "@typescript-eslint/project-service@npm:8.39.1" +"@typescript-eslint/project-service@npm:8.40.0": + version: 8.40.0 + resolution: "@typescript-eslint/project-service@npm:8.40.0" dependencies: - "@typescript-eslint/tsconfig-utils": "npm:^8.39.1" - "@typescript-eslint/types": "npm:^8.39.1" + "@typescript-eslint/tsconfig-utils": "npm:^8.40.0" + "@typescript-eslint/types": "npm:^8.40.0" debug: "npm:^4.3.4" peerDependencies: typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/40207af4f4e2a260ea276766d502c4736f6dc5488e84bbab6444e2786289ece2dbca2686323c48d4e9c265e409a309bf3d97d4aa03767dff8cc7642b436bda35 + checksum: 10c0/23d62e9ada9750136d0251f268bbe1f9784442ef258bb340a2e1e866749d8076730a14749d9a320d94d7c76df2d108caf21fe35e5dc100385f04be846dc979cb languageName: node linkType: hard @@ -5506,12 +5683,22 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/tsconfig-utils@npm:8.39.1, @typescript-eslint/tsconfig-utils@npm:^8.39.1": - version: 8.39.1 - resolution: "@typescript-eslint/tsconfig-utils@npm:8.39.1" +"@typescript-eslint/scope-manager@npm:8.40.0": + version: 8.40.0 + resolution: "@typescript-eslint/scope-manager@npm:8.40.0" + dependencies: + "@typescript-eslint/types": "npm:8.40.0" + "@typescript-eslint/visitor-keys": "npm:8.40.0" + checksum: 10c0/48af81f9cdcec466994d290561e8d2fa3f6b156a898b71dd0e65633c896543b44729c5353596e84de2ae61bfd20e1398c3309cdfe86714a9663fd5aded4c9cd0 + languageName: node + linkType: hard + +"@typescript-eslint/tsconfig-utils@npm:8.40.0, @typescript-eslint/tsconfig-utils@npm:^8.40.0": + version: 8.40.0 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.40.0" peerDependencies: typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/664dff0b4ae908cb98c78f9ca73c36cf57c3a2206965d9d0659649ffc02347eb30e1452499671a425592f14a2a5c5eb82ae389b34f3c415a12119506b4ebb61c + checksum: 10c0/c2366dcd802901d5cd4f59fc4eab7a00ed119aa4591ba59c507fe495d9af4cfca19431a603602ea675e4c861962230d1c2f100896903750cd1fcfc134702a7d0 languageName: node linkType: hard @@ -5532,6 +5719,22 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/type-utils@npm:8.40.0": + version: 8.40.0 + resolution: "@typescript-eslint/type-utils@npm:8.40.0" + dependencies: + "@typescript-eslint/types": "npm:8.40.0" + "@typescript-eslint/typescript-estree": "npm:8.40.0" + "@typescript-eslint/utils": "npm:8.40.0" + debug: "npm:^4.3.4" + ts-api-utils: "npm:^2.1.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/660b77d801b2538a4ccb65065269ad0e8370d0be985172b5ecb067f3eea22e64aa8af9e981b31bf2a34002339fe3253b09b55d181ce6d8242fc7daa80ac4aaca + languageName: node + linkType: hard + "@typescript-eslint/types@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/types@npm:5.62.0" @@ -5546,21 +5749,58 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:8.39.1, @typescript-eslint/types@npm:^8.39.1": - version: 8.39.1 - resolution: "@typescript-eslint/types@npm:8.39.1" - checksum: 10c0/0e188d2d52509a24c500a87adf561387ffcac56b62cb9fd0ca1f929bb3d4eedb6b8f9d516c1890855d39930c9dd8d502d5b4600b8c9cc832d3ebb595d81c7533 +"@typescript-eslint/types@npm:8.40.0, @typescript-eslint/types@npm:^8.40.0": + version: 8.40.0 + resolution: "@typescript-eslint/types@npm:8.40.0" + checksum: 10c0/225374fff36d59288a5780667a7a1316c75090d5d60b70a8035ac18786120333ccd08dfdf0e05e30d5a82217e44c57b8708b769dd1eed89f12f2ac4d3a769f76 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.39.1": - version: 8.39.1 - resolution: "@typescript-eslint/typescript-estree@npm:8.39.1" +"@typescript-eslint/typescript-estree@npm:5.62.0": + version: 5.62.0 + resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" dependencies: - "@typescript-eslint/project-service": "npm:8.39.1" - "@typescript-eslint/tsconfig-utils": "npm:8.39.1" - "@typescript-eslint/types": "npm:8.39.1" - "@typescript-eslint/visitor-keys": "npm:8.39.1" + "@typescript-eslint/types": "npm:5.62.0" + "@typescript-eslint/visitor-keys": "npm:5.62.0" + debug: "npm:^4.3.4" + globby: "npm:^11.1.0" + is-glob: "npm:^4.0.3" + semver: "npm:^7.3.7" + tsutils: "npm:^3.21.0" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/d7984a3e9d56897b2481940ec803cb8e7ead03df8d9cfd9797350be82ff765dfcf3cfec04e7355e1779e948da8f02bc5e11719d07a596eb1cb995c48a95e38cf + languageName: node + linkType: hard + +"@typescript-eslint/typescript-estree@npm:7.18.0": + version: 7.18.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.18.0" + dependencies: + "@typescript-eslint/types": "npm:7.18.0" + "@typescript-eslint/visitor-keys": "npm:7.18.0" + debug: "npm:^4.3.4" + globby: "npm:^11.1.0" + is-glob: "npm:^4.0.3" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^1.3.0" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/0c7f109a2e460ec8a1524339479cf78ff17814d23c83aa5112c77fb345e87b3642616291908dcddea1e671da63686403dfb712e4a4435104f92abdfddf9aba81 + languageName: node + linkType: hard + +"@typescript-eslint/typescript-estree@npm:8.40.0": + version: 8.40.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.40.0" + dependencies: + "@typescript-eslint/project-service": "npm:8.40.0" + "@typescript-eslint/tsconfig-utils": "npm:8.40.0" + "@typescript-eslint/types": "npm:8.40.0" + "@typescript-eslint/visitor-keys": "npm:8.40.0" debug: "npm:^4.3.4" fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" @@ -5569,7 +5809,7 @@ __metadata: ts-api-utils: "npm:^2.1.0" peerDependencies: typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/1de1a37fed354600a08bc971492c2f14238f0a4bf07a43bedb416c17b7312d18bec92c68c8f2790bb0a1bffcd757f7962914be9f6213068f18f6c4fdde259af4 + checksum: 10c0/6c1ffc17947cb36cbd987cf9705f85223ed1cce584b5244840e36a2b8480861f4dfdb0312f96afbc12e7d1ba586005f0d959042baa0a96a1913ac7ace8e8f6d4 languageName: node linkType: hard @@ -5587,6 +5827,21 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/utils@npm:8.40.0": + version: 8.40.0 + resolution: "@typescript-eslint/utils@npm:8.40.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.7.0" + "@typescript-eslint/scope-manager": "npm:8.40.0" + "@typescript-eslint/types": "npm:8.40.0" + "@typescript-eslint/typescript-estree": "npm:8.40.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/6b3858b8725083fe7db7fb9bcbde930e758a6ba8ddedd1ed27d828fc1cbe04f54b774ef9144602f8eeaafeea9b19b4fd4c46fdad52a10ade99e6b282c7d0df92 + languageName: node + linkType: hard + "@typescript-eslint/utils@npm:^5.10.0": version: 5.62.0 resolution: "@typescript-eslint/utils@npm:5.62.0" @@ -5625,13 +5880,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.39.1": - version: 8.39.1 - resolution: "@typescript-eslint/visitor-keys@npm:8.39.1" +"@typescript-eslint/visitor-keys@npm:8.40.0": + version: 8.40.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.40.0" dependencies: - "@typescript-eslint/types": "npm:8.39.1" + "@typescript-eslint/types": "npm:8.40.0" eslint-visitor-keys: "npm:^4.2.1" - checksum: 10c0/4d81f6826a211bc2752e25cd16d1f415f28ebc92b35142402ec23f3765f2d00963b75ac06266ad9c674ca5b057d07d8c114116e5bf14f5465dde1d1aa60bc72f + checksum: 10c0/592f1c8c2d3da43a7f74f8ead14f05fafc2e4609d5df36811cf92ead5dc94f6f669556a494048e4746cb3774c60bc52a8c83d75369d5e196778d935c70e7d3a1 languageName: node linkType: hard @@ -7467,7 +7722,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -8878,6 +9133,16 @@ __metadata: languageName: node linkType: hard +"eslint-scope@npm:^8.4.0": + version: 8.4.0 + resolution: "eslint-scope@npm:8.4.0" + dependencies: + esrecurse: "npm:^4.3.0" + estraverse: "npm:^5.2.0" + checksum: 10c0/407f6c600204d0f3705bd557f81bd0189e69cd7996f408f8971ab5779c0af733d1af2f1412066b40ee1588b085874fc37a2333986c6521669cdbdd36ca5058e0 + languageName: node + linkType: hard + "eslint-visitor-keys@npm:^2.1.0": version: 2.1.0 resolution: "eslint-visitor-keys@npm:2.1.0" @@ -8947,18 +9212,57 @@ __metadata: languageName: node linkType: hard -"espree@npm:^9.6.0, espree@npm:^9.6.1": - version: 9.6.1 - resolution: "espree@npm:9.6.1" +"eslint@npm:^9.33.0": + version: 9.33.0 + resolution: "eslint@npm:9.33.0" dependencies: - acorn: "npm:^8.9.0" - acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^3.4.1" - checksum: 10c0/1a2e9b4699b715347f62330bcc76aee224390c28bb02b31a3752e9d07549c473f5f986720483c6469cf3cfb3c9d05df612ffc69eb1ee94b54b739e67de9bb460 + "@eslint-community/eslint-utils": "npm:^4.2.0" + "@eslint-community/regexpp": "npm:^4.12.1" + "@eslint/config-array": "npm:^0.21.0" + "@eslint/config-helpers": "npm:^0.3.1" + "@eslint/core": "npm:^0.15.2" + "@eslint/eslintrc": "npm:^3.3.1" + "@eslint/js": "npm:9.33.0" + "@eslint/plugin-kit": "npm:^0.3.5" + "@humanfs/node": "npm:^0.16.6" + "@humanwhocodes/module-importer": "npm:^1.0.1" + "@humanwhocodes/retry": "npm:^0.4.2" + "@types/estree": "npm:^1.0.6" + "@types/json-schema": "npm:^7.0.15" + ajv: "npm:^6.12.4" + chalk: "npm:^4.0.0" + cross-spawn: "npm:^7.0.6" + debug: "npm:^4.3.2" + escape-string-regexp: "npm:^4.0.0" + eslint-scope: "npm:^8.4.0" + eslint-visitor-keys: "npm:^4.2.1" + espree: "npm:^10.4.0" + esquery: "npm:^1.5.0" + esutils: "npm:^2.0.2" + fast-deep-equal: "npm:^3.1.3" + file-entry-cache: "npm:^8.0.0" + find-up: "npm:^5.0.0" + glob-parent: "npm:^6.0.2" + ignore: "npm:^5.2.0" + imurmurhash: "npm:^0.1.4" + is-glob: "npm:^4.0.0" + json-stable-stringify-without-jsonify: "npm:^1.0.1" + lodash.merge: "npm:^4.6.2" + minimatch: "npm:^3.1.2" + natural-compare: "npm:^1.4.0" + optionator: "npm:^0.9.3" + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true + bin: + eslint: bin/eslint.js + checksum: 10c0/1e1f60d2b62d9d65553e9af916a8dccf00eeedd982103f35bf58c205803907cb1fda73ef595178d47384ea80d8624a182b63682a6b15d8387e9a5d86904a2a2d languageName: node linkType: hard -"espree@npm:^9.6.1 || ^10.4.0": +"espree@npm:^10.0.1, espree@npm:^10.4.0, espree@npm:^9.6.1 || ^10.4.0": version: 10.4.0 resolution: "espree@npm:10.4.0" dependencies: @@ -8969,6 +9273,17 @@ __metadata: languageName: node linkType: hard +"espree@npm:^9.6.0, espree@npm:^9.6.1": + version: 9.6.1 + resolution: "espree@npm:9.6.1" + dependencies: + acorn: "npm:^8.9.0" + acorn-jsx: "npm:^5.3.2" + eslint-visitor-keys: "npm:^3.4.1" + checksum: 10c0/1a2e9b4699b715347f62330bcc76aee224390c28bb02b31a3752e9d07549c473f5f986720483c6469cf3cfb3c9d05df612ffc69eb1ee94b54b739e67de9bb460 + languageName: node + linkType: hard + "esprima@npm:^4.0.0": version: 4.0.1 resolution: "esprima@npm:4.0.1" @@ -8979,7 +9294,7 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.4.2": +"esquery@npm:^1.4.2, esquery@npm:^1.5.0": version: 1.6.0 resolution: "esquery@npm:1.6.0" dependencies: @@ -9408,6 +9723,15 @@ __metadata: languageName: node linkType: hard +"file-entry-cache@npm:^8.0.0": + version: 8.0.0 + resolution: "file-entry-cache@npm:8.0.0" + dependencies: + flat-cache: "npm:^4.0.0" + checksum: 10c0/9e2b5938b1cd9b6d7e3612bdc533afd4ac17b2fc646569e9a8abbf2eb48e5eb8e316bc38815a3ef6a1b456f4107f0d0f055a614ca613e75db6bf9ff4d72c1638 + languageName: node + linkType: hard + "file-loader@npm:^6.2.0": version: 6.2.0 resolution: "file-loader@npm:6.2.0" @@ -9519,6 +9843,16 @@ __metadata: languageName: node linkType: hard +"flat-cache@npm:^4.0.0": + version: 4.0.1 + resolution: "flat-cache@npm:4.0.1" + dependencies: + flatted: "npm:^3.2.9" + keyv: "npm:^4.5.4" + checksum: 10c0/2c59d93e9faa2523e4fda6b4ada749bed432cfa28c8e251f33b25795e426a1c6dbada777afb1f74fcfff33934fdbdea921ee738fcc33e71adc9d6eca984a1cfc + languageName: node + linkType: hard + "flat@npm:^5.0.2": version: 5.0.2 resolution: "flat@npm:5.0.2" @@ -9613,14 +9947,14 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^11.1.1, fs-extra@npm:^11.2.0": - version: 11.3.0 - resolution: "fs-extra@npm:11.3.0" +"fs-extra@npm:^11.1.1, fs-extra@npm:^11.2.0, fs-extra@npm:^11.3.1": + version: 11.3.1 + resolution: "fs-extra@npm:11.3.1" dependencies: graceful-fs: "npm:^4.2.0" jsonfile: "npm:^6.0.1" universalify: "npm:^2.0.0" - checksum: 10c0/5f95e996186ff45463059feb115a22fb048bdaf7e487ecee8a8646c78ed8fdca63630e3077d4c16ce677051f5e60d3355a06f3cd61f3ca43f48cc58822a44d0a + checksum: 10c0/61e5b7285b1ca72c68dfe1058b2514294a922683afac2a80aa90540f9bd85370763d675e3b408ef500077d355956fece3bd24b546790e261c3d3015967e2b2d9 languageName: node linkType: hard @@ -9925,6 +10259,20 @@ __metadata: languageName: node linkType: hard +"globals@npm:^14.0.0": + version: 14.0.0 + resolution: "globals@npm:14.0.0" + checksum: 10c0/b96ff42620c9231ad468d4c58ff42afee7777ee1c963013ff8aabe095a451d0ceeb8dcd8ef4cbd64d2538cef45f787a78ba3a9574f4a634438963e334471302d + languageName: node + linkType: hard + +"globals@npm:^16.3.0": + version: 16.3.0 + resolution: "globals@npm:16.3.0" + checksum: 10c0/c62dc20357d1c0bf2be4545d6c4141265d1a229bf1c3294955efb5b5ef611145391895e3f2729f8603809e81b30b516c33e6c2597573844449978606aad6eb38 + languageName: node + linkType: hard + "globalthis@npm:^1.0.4": version: 1.0.4 resolution: "globalthis@npm:1.0.4" @@ -10754,7 +11102,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^7.0.5": +"ignore@npm:^7.0.0, ignore@npm:^7.0.5": version: 7.0.5 resolution: "ignore@npm:7.0.5" checksum: 10c0/ae00db89fe873064a093b8999fe4cc284b13ef2a178636211842cceb650b9c3e390d3339191acb145d81ed5379d2074840cf0c33a20bdbd6f32821f79eb4ad5d @@ -12216,7 +12564,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.3": +"keyv@npm:^4.5.3, keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -13228,6 +13576,13 @@ __metadata: languageName: node linkType: hard +"mdn-data@npm:2.21.0": + version: 2.21.0 + resolution: "mdn-data@npm:2.21.0" + checksum: 10c0/cd26902551af2cc29f06f130893cb04bca9ee278939fce3ffbcb759497cc80d53a6f4abdef2ae2f3ed3c95ac8d651f53fc141defd580ebf4ae2f93aea325957b + languageName: node + linkType: hard + "media-typer@npm:0.3.0": version: 0.3.0 resolution: "media-typer@npm:0.3.0" @@ -17062,16 +17417,21 @@ __metadata: version: 0.0.0-use.local resolution: "react-native-website-monorepo@workspace:." dependencies: + "@eslint/css": "npm:^0.10.0" + "@eslint/js": "npm:^9.33.0" "@manypkg/cli": "npm:^0.25.0" - eslint: "npm:^8.57.1" + "@typescript-eslint/parser": "npm:^8.40.0" + eslint: "npm:^9.33.0" eslint-config-prettier: "npm:^10.1.8" eslint-plugin-mdx: "npm:^3.6.2" eslint-plugin-prettier: "npm:^5.5.4" eslint-plugin-yml: "npm:^1.18.0" + globals: "npm:^16.3.0" husky: "npm:^9.1.7" netlify-plugin-cache: "npm:^1.0.3" prettier: "npm:^3.6.2" pretty-quick: "npm:^4.2.2" + typescript-eslint: "npm:^8.40.0" languageName: unknown linkType: soft @@ -17088,14 +17448,14 @@ __metadata: "@docusaurus/tsconfig": "npm:3.8.1" "@docusaurus/types": "npm:3.8.1" "@react-native-website/lint-examples": "npm:0.0.0" - "@react-native-website/update-redirects": "npm:0.0.0" + "@types/fs-extra": "npm:^11.0.4" "@types/google.analytics": "npm:^0.0.46" "@types/react": "npm:^19.1.10" alex: "npm:^11.0.1" case-police: "npm:^1.0.0" docusaurus-plugin-sass: "npm:^0.2.6" - eslint: "npm:^8.57.1" - fs-extra: "npm:^11.2.0" + eslint: "npm:^9.33.0" + fs-extra: "npm:^11.3.1" glob: "npm:^11.0.0" prettier: "npm:^3.6.2" react: "npm:^19.1.1" @@ -19493,6 +19853,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:^1.8.1": + version: 1.14.1 + resolution: "tslib@npm:1.14.1" + checksum: 10c0/69ae09c49eea644bc5ebe1bca4fa4cc2c82b7b3e02f43b84bd891504edf66dbc6b2ec0eef31a957042de2269139e4acff911e6d186a258fb14069cd7f6febce2 + languageName: node + linkType: hard + "tslib@npm:^2.0.3, tslib@npm:^2.4.0, tslib@npm:^2.6.0, tslib@npm:^2.8.1": version: 2.8.1 resolution: "tslib@npm:2.8.1" @@ -19500,6 +19867,17 @@ __metadata: languageName: node linkType: hard +"tsutils@npm:^3.21.0": + version: 3.21.0 + resolution: "tsutils@npm:3.21.0" + dependencies: + tslib: "npm:^1.8.1" + peerDependencies: + typescript: ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + checksum: 10c0/02f19e458ec78ead8fffbf711f834ad8ecd2cc6ade4ec0320790713dccc0a412b99e7fd907c4cda2a1dc602c75db6f12e0108e87a5afad4b2f9e90a24cabd5a2 + languageName: node + linkType: hard + "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -19644,6 +20022,21 @@ __metadata: languageName: node linkType: hard +"typescript-eslint@npm:^8.40.0": + version: 8.40.0 + resolution: "typescript-eslint@npm:8.40.0" + dependencies: + "@typescript-eslint/eslint-plugin": "npm:8.40.0" + "@typescript-eslint/parser": "npm:8.40.0" + "@typescript-eslint/typescript-estree": "npm:8.40.0" + "@typescript-eslint/utils": "npm:8.40.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10c0/b9bf9cbe13a89348ae2a13a7839238b1b058c1e188d9cc1028810c43f1b48cf256f5255ca94c38acf3cd5a405c918ad96d5b7f7a6ad3f82fa7429122a7883a83 + languageName: node + linkType: hard + "typescript@npm:^5.9.2": version: 5.9.2 resolution: "typescript@npm:5.9.2" From 36ccbd1a12d8bb3705806750d99f280fe530c037 Mon Sep 17 00:00:00 2001 From: Simek Date: Mon, 25 Aug 2025 13:19:20 +0200 Subject: [PATCH 02/12] reorganize structure, migrate lint-example to flat config, apply fixes --- .gitignore | 7 +- docs/animated.md | 8 +- docs/animations.md | 6 +- docs/checkbox.md | 2 +- docs/drawerlayoutandroid.md | 2 +- docs/easing.md | 2 +- docs/flatlist.md | 4 +- docs/flexbox.md | 22 +- docs/i18nmanager.md | 36 ++- docs/improvingux.md | 4 +- docs/interactionmanager.md | 4 +- docs/intro-react.md | 6 +- docs/layout-props.md | 2 +- docs/legacy/direct-manipulation.md | 8 +- docs/linking.md | 8 +- docs/network.md | 2 +- docs/props.md | 2 +- docs/segmentedcontrolios.md | 2 +- docs/shadow-props.md | 2 +- docs/share.md | 2 +- docs/state.md | 2 +- docs/statusbar.md | 2 +- docs/text-style-props.md | 2 +- .../direct-manipulation.md | 2 +- docs/transforms.md | 7 +- docs/tutorial.md | 2 +- docs/virtualizedlist.md | 2 +- eslint.config.js | 11 +- package.json | 7 +- packages/lint-examples/.prettierrc.json | 7 + {scripts => packages}/lint-examples/README.md | 0 .../lint-examples/babel.config.js | 0 .../lint-examples/bin/eslint-examples-jsx.js | 4 +- .../lint-examples/bin/eslint-examples-tsx.js | 2 +- .../lint-examples/bin/tsc-examples.js | 2 +- packages/lint-examples/eslint.config.js | 90 ++++++ .../lint-examples/package.json | 13 +- .../lint-examples/src/lintExamples.js | 18 +- .../lint-examples/tsconfig.json | 0 .../sync-api-docs}/extractDocsFromRN.js | 16 +- .../sync-api-docs}/generateMarkdown.js | 38 +-- .../sync-api-docs}/magic.js | 2 +- .../sync-api-docs}/methodFormatter.js | 18 +- .../sync-api-docs}/package.json | 4 +- .../preprocessGeneratedApiDocs.js | 8 +- .../sync-api-docs}/propFormatter.js | 28 +- .../sync-api-docs}/sync-api-docs.js | 22 +- .../sync-api-docs}/utils.js | 27 +- scripts/lint-examples/.eslintignore | 1 - scripts/lint-examples/.eslintrc.js | 8 - scripts/lint-examples/.prettierrc.js | 7 - website/package.json | 5 +- yarn.lock | 277 ++++++------------ 53 files changed, 335 insertions(+), 430 deletions(-) create mode 100644 packages/lint-examples/.prettierrc.json rename {scripts => packages}/lint-examples/README.md (100%) rename {scripts => packages}/lint-examples/babel.config.js (100%) rename scripts/lint-examples/bin/eslint-examples-js.js => packages/lint-examples/bin/eslint-examples-jsx.js (81%) rename {scripts => packages}/lint-examples/bin/eslint-examples-tsx.js (86%) rename {scripts => packages}/lint-examples/bin/tsc-examples.js (85%) create mode 100644 packages/lint-examples/eslint.config.js rename {scripts => packages}/lint-examples/package.json (68%) rename {scripts => packages}/lint-examples/src/lintExamples.js (93%) rename {scripts => packages}/lint-examples/tsconfig.json (100%) rename {sync-api-docs => packages/sync-api-docs}/extractDocsFromRN.js (83%) rename {sync-api-docs => packages/sync-api-docs}/generateMarkdown.js (89%) rename {sync-api-docs => packages/sync-api-docs}/magic.js (98%) rename {sync-api-docs => packages/sync-api-docs}/methodFormatter.js (80%) rename {sync-api-docs => packages/sync-api-docs}/package.json (78%) rename {sync-api-docs => packages/sync-api-docs}/preprocessGeneratedApiDocs.js (91%) rename {sync-api-docs => packages/sync-api-docs}/propFormatter.js (93%) rename {sync-api-docs => packages/sync-api-docs}/sync-api-docs.js (69%) rename {sync-api-docs => packages/sync-api-docs}/utils.js (82%) delete mode 100644 scripts/lint-examples/.eslintignore delete mode 100644 scripts/lint-examples/.eslintrc.js delete mode 100644 scripts/lint-examples/.prettierrc.js diff --git a/.gitignore b/.gitignore index 756a0b16d4f..253573a7f13 100644 --- a/.gitignore +++ b/.gitignore @@ -19,10 +19,9 @@ node_modules *.tsbuildinfo -scripts/lint-examples/out/ - -sync-api-docs/generatedComponentApiDocs.js -sync-api-docs/extracted.json +packages/lint-examples/out/ +packages/sync-api-docs/generatedComponentApiDocs.js +packages/sync-api-docs/extracted.json website/.docusaurus website/.cache-loader diff --git a/docs/animated.md b/docs/animated.md index e20ad3ee247..064942121bc 100644 --- a/docs/animated.md +++ b/docs/animated.md @@ -16,13 +16,7 @@ The following example contains a `View` which will fade in and fade out based on ```SnackPlayer name=Animated%20Example import React, {useRef} from 'react'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; -import { - Animated, - Text, - View, - StyleSheet, - Button, -} from 'react-native'; +import {Animated, Text, View, StyleSheet, Button} from 'react-native'; const App = () => { // fadeAnim will be used as the value for opacity. Initial Value: 0 diff --git a/docs/animations.md b/docs/animations.md index f4438b7a0a8..f1b76aac66d 100644 --- a/docs/animations.md +++ b/docs/animations.md @@ -20,7 +20,7 @@ For example, a container view that fades in when it is mounted may look like thi -```SnackPlayer ext=js +```SnackPlayer ext=jsx import React, {useEffect, useRef} from 'react'; import {Animated, Text, View} from 'react-native'; @@ -622,9 +622,7 @@ export default function App() { return ( - + Press me! diff --git a/docs/checkbox.md b/docs/checkbox.md index f9558d0f48d..e97c21fd32c 100644 --- a/docs/checkbox.md +++ b/docs/checkbox.md @@ -11,7 +11,7 @@ This is a controlled component that requires an `onValueChange` callback that up ## Example -```SnackPlayer name=CheckBox%20Component%20Example&supportedPlatforms=android,web&ext=js +```SnackPlayer name=CheckBox%20Component%20Example&supportedPlatforms=android,web&ext=jsx import React, {useState} from 'react'; import {CheckBox, Text, StyleSheet, View} from 'react-native'; diff --git a/docs/drawerlayoutandroid.md b/docs/drawerlayoutandroid.md index 3714318df5c..736f6cc8d6f 100644 --- a/docs/drawerlayoutandroid.md +++ b/docs/drawerlayoutandroid.md @@ -12,7 +12,7 @@ React component that wraps the platform `DrawerLayout` (Android only). The Drawe -```SnackPlayer name=DrawerLayoutAndroid%20Component%20Example&supportedPlatforms=android&ext=js +```SnackPlayer name=DrawerLayoutAndroid%20Component%20Example&supportedPlatforms=android&ext=jsx import React, {useRef, useState} from 'react'; import {Button, DrawerLayoutAndroid, Text, StyleSheet} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; diff --git a/docs/easing.md b/docs/easing.md index bb31dd0e4fa..1bc08e8d55b 100644 --- a/docs/easing.md +++ b/docs/easing.md @@ -48,7 +48,7 @@ The following helpers are used to modify other easing functions. -```SnackPlayer name=Easing%20Demo&ext=js +```SnackPlayer name=Easing%20Demo&ext=jsx import React, {useRef} from 'react'; import { Animated, diff --git a/docs/flatlist.md b/docs/flatlist.md index 6c299ca26bb..afbc2502fa1 100644 --- a/docs/flatlist.md +++ b/docs/flatlist.md @@ -25,7 +25,7 @@ If you need section support, use [``](sectionlist.md). -```SnackPlayer name=Simple%20FlatList%20Example&ext=js +```SnackPlayer name=Simple%20FlatList%20Example&ext=jsx import React from 'react'; import {View, FlatList, StyleSheet, Text, StatusBar} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; @@ -157,7 +157,7 @@ More complex, selectable example below. -```SnackPlayer name=flatlist-selectable&ext=js +```SnackPlayer name=flatlist-selectable&ext=jsx import React, {useState} from 'react'; import { FlatList, diff --git a/docs/flexbox.md b/docs/flexbox.md index 039a7bdf60b..58b4c701d60 100644 --- a/docs/flexbox.md +++ b/docs/flexbox.md @@ -68,7 +68,7 @@ You can learn more [here](https://www.yogalayout.dev/docs/styling/flex-direction -```SnackPlayer name=Flex%20Direction&ext=js +```SnackPlayer name=Flex%20Direction&ext=jsx import React, {useState} from 'react'; import {StyleSheet, Text, TouchableOpacity, View} from 'react-native'; @@ -285,7 +285,7 @@ Layout [`direction`](layout-props#direction) specifies the direction in which ch -```SnackPlayer name=Flex%20Direction&ext=js +```SnackPlayer name=Flex%20Direction&ext=jsx import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; @@ -512,7 +512,7 @@ You can learn more [here](https://www.yogalayout.dev/docs/styling/justify-conten -```SnackPlayer name=Justify%20Content&ext=js +```SnackPlayer name=Justify%20Content&ext=jsx import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; @@ -755,7 +755,7 @@ You can learn more [here](https://www.yogalayout.dev/docs/styling/align-items-se -```SnackPlayer name=Align%20Items&ext=js +```SnackPlayer name=Align%20Items&ext=jsx import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; @@ -988,7 +988,7 @@ export default AlignItemsLayout; -```SnackPlayer name=Align%20Self&ext=js +```SnackPlayer name=Align%20Self&ext=jsx import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; @@ -1240,7 +1240,7 @@ You can learn more [here](https://www.yogalayout.dev/docs/styling/align-content) -```SnackPlayer name=Align%20Content&ext=js +```SnackPlayer name=Align%20Content&ext=jsx import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; @@ -1481,7 +1481,7 @@ When wrapping lines, `alignContent` can be used to specify how the lines are pla -```SnackPlayer name=Flex%20Wrap&ext=js +```SnackPlayer name=Flex%20Wrap&ext=jsx import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; @@ -1712,7 +1712,7 @@ You can learn more [here](https://www.yogalayout.dev/docs/styling/flex-basis-gro -```SnackPlayer name=Flex%20Basis%2C%20Grow%2C%20and%20Shrink&ext=js +```SnackPlayer name=Flex%20Basis%2C%20Grow%2C%20and%20Shrink&ext=jsx import React, {useState} from 'react'; import {View, Text, TextInput, StyleSheet} from 'react-native'; @@ -2085,7 +2085,7 @@ You can use `flexWrap` and `alignContent` along with `gap` to add consistent spa -```SnackPlayer name=Row%20Gap%20and%20Column%20Gap&ext=js +```SnackPlayer name=Row%20Gap%20and%20Column%20Gap&ext=jsx import React, {useState} from 'react'; import {View, Text, StyleSheet, TextInput} from 'react-native'; @@ -2312,7 +2312,7 @@ Both `width` and `height` can take the following values: -```SnackPlayer name=Width%20and%20Height&ext=js +```SnackPlayer name=Width%20and%20Height&ext=jsx import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; @@ -2588,7 +2588,7 @@ The `position` type of an element defines how it is positioned relative to eithe -```SnackPlayer name=Position&ext=js +```SnackPlayer name=Position&ext=jsx import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; diff --git a/docs/i18nmanager.md b/docs/i18nmanager.md index 66841b845d4..80ccd2ccd72 100644 --- a/docs/i18nmanager.md +++ b/docs/i18nmanager.md @@ -24,12 +24,13 @@ const App = () => { return ( - - {isRTL ? ( - Back > - ) : ( - < Back - )} + + {isRTL ? Back > : < Back} @@ -54,16 +55,19 @@ const App = () => { Force RTL in Development: - { - setRTL(value); - I18nManager.forceRTL(value); - Alert.alert( - 'Reload this page', - 'Please reload this page to change the UI direction! ' + - 'All examples in this app will be affected. ' + - 'Check them out to see what they look like in RTL layout.', - ); - }} /> + { + setRTL(value); + I18nManager.forceRTL(value); + Alert.alert( + 'Reload this page', + 'Please reload this page to change the UI direction! ' + + 'All examples in this app will be affected. ' + + 'Check them out to see what they look like in RTL layout.', + ); + }} + /> diff --git a/docs/improvingux.md b/docs/improvingux.md index 462f5f0ce1c..2f0c36a1ac6 100644 --- a/docs/improvingux.md +++ b/docs/improvingux.md @@ -20,7 +20,7 @@ Check out [`TextInput` docs](textinput.md) for more configuration options. -```SnackPlayer name=TextInput%20form%20example&ext=js +```SnackPlayer name=TextInput%20form%20example&ext=jsx import React, {useState, useRef} from 'react'; import { Alert, @@ -215,7 +215,7 @@ Software keyboard takes almost half of the screen. If you have interactive eleme -```SnackPlayer name=KeyboardAvoidingView%20example&ext=js +```SnackPlayer name=KeyboardAvoidingView%20example&ext=jsx import React, {useState, useRef} from 'react'; import { Alert, diff --git a/docs/interactionmanager.md b/docs/interactionmanager.md index f9265e7db16..37b7b2de613 100644 --- a/docs/interactionmanager.md +++ b/docs/interactionmanager.md @@ -46,7 +46,7 @@ By default, queued tasks are executed together in a loop in one `setImmediate` b -```SnackPlayer name=InteractionManager%20Function%20Component%20Basic%20Example&supportedPlatforms=ios,android&ext=js +```SnackPlayer name=InteractionManager%20Function%20Component%20Basic%20Example&supportedPlatforms=ios,android&ext=jsx import React, {useEffect} from 'react'; import { Alert, @@ -219,7 +219,7 @@ export default App; -```SnackPlayer name=InteractionManager%20Function%20Component%20Advanced%20Example&supportedPlatforms=ios,android&ext=js +```SnackPlayer name=InteractionManager%20Function%20Component%20Advanced%20Example&supportedPlatforms=ios,android&ext=jsx import React, {useEffect} from 'react'; import { Alert, diff --git a/docs/intro-react.md b/docs/intro-react.md index 8eb487be3ec..4072c5bcf07 100644 --- a/docs/intro-react.md +++ b/docs/intro-react.md @@ -92,7 +92,7 @@ Any JavaScript expression will work between curly braces, including function cal -```SnackPlayer name=Curly%20Braces&ext=js +```SnackPlayer name=Curly%20Braces&ext=jsx import React from 'react'; import {Text} from 'react-native'; @@ -226,7 +226,7 @@ You can put as many cats in your cafe as you like. Each `` renders a unique -```SnackPlayer name=Multiple%20Props&ext=js +```SnackPlayer name=Multiple%20Props&ext=jsx import React from 'react'; import {Text, View} from 'react-native'; @@ -332,7 +332,7 @@ You can add state to a component by calling [React’s `useState` Hook](https:// -```SnackPlayer name=State&ext=js +```SnackPlayer name=State&ext=jsx import React, {useState} from 'react'; import {Button, Text, View} from 'react-native'; diff --git a/docs/layout-props.md b/docs/layout-props.md index 114ff5da96a..a0ea61aa1ea 100644 --- a/docs/layout-props.md +++ b/docs/layout-props.md @@ -14,7 +14,7 @@ The following example shows how different properties can affect or shape a React -```SnackPlayer name=LayoutProps%20Example&ext=js +```SnackPlayer name=LayoutProps%20Example&ext=jsx import React, {useState} from 'react'; import {Button, ScrollView, StyleSheet, Text, View} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; diff --git a/docs/legacy/direct-manipulation.md b/docs/legacy/direct-manipulation.md index b3e7e063414..5e01bf5602d 100644 --- a/docs/legacy/direct-manipulation.md +++ b/docs/legacy/direct-manipulation.md @@ -66,7 +66,7 @@ Composite components are not backed by a native view, so you cannot call `setNat -```SnackPlayer name=setNativeProps%20with%20Composite%20Components&ext=js +```SnackPlayer name=setNativeProps%20with%20Composite%20Components&ext=jsx import React from 'react'; import {Text, TouchableOpacity, View} from 'react-native'; @@ -119,7 +119,7 @@ Since the `setNativeProps` method exists on any ref to a `View` component, it is -```SnackPlayer name=Forwarding%20setNativeProps&ext=js +```SnackPlayer name=Forwarding%20setNativeProps&ext=jsx import React from 'react'; import {Text, TouchableOpacity, View} from 'react-native'; @@ -174,7 +174,7 @@ Another very common use case of `setNativeProps` is to edit the value of the Tex -```SnackPlayer name=Clear%20text&ext=js +```SnackPlayer name=Clear%20text&ext=jsx import React from 'react'; import {useCallback, useRef} from 'react'; import { @@ -319,7 +319,7 @@ This method can also be called with a `relativeToNativeNode` handler (instead of -```SnackPlayer name=measureLayout%20example&supportedPlatforms=android,ios&ext=js +```SnackPlayer name=measureLayout%20example&supportedPlatforms=android,ios&ext=jsx import React, {useEffect, useRef, useState} from 'react'; import {Text, View, StyleSheet} from 'react-native'; diff --git a/docs/linking.md b/docs/linking.md index 2851237295d..5b8dc53e36d 100644 --- a/docs/linking.md +++ b/docs/linking.md @@ -131,7 +131,7 @@ You can handle these events with `Linking.getInitialURL()` - it returns a Promis -```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=js +```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=jsx import React, {useCallback} from 'react'; import {Alert, Button, Linking, StyleSheet, View} from 'react-native'; @@ -237,7 +237,7 @@ export default App; -```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=js +```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=jsx import React, {useCallback} from 'react'; import {Button, Linking, StyleSheet, View} from 'react-native'; @@ -316,7 +316,7 @@ export default App; -```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=js +```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=jsx import React, {useState, useEffect} from 'react'; import {Linking, StyleSheet, Text, View} from 'react-native'; @@ -429,7 +429,7 @@ export default App; -```SnackPlayer name=Linking%20Example&supportedPlatforms=android&ext=js +```SnackPlayer name=Linking%20Example&supportedPlatforms=android&ext=jsx import React, {useCallback} from 'react'; import {Alert, Button, Linking, StyleSheet, View} from 'react-native'; diff --git a/docs/network.md b/docs/network.md index 160c8e8d56f..5e3dea806c6 100644 --- a/docs/network.md +++ b/docs/network.md @@ -77,7 +77,7 @@ Don't forget to catch any errors that may be thrown by `fetch`, otherwise they w -```SnackPlayer name=Fetch%20Example&ext=js +```SnackPlayer name=Fetch%20Example&ext=jsx import React, {useEffect, useState} from 'react'; import {ActivityIndicator, FlatList, Text, View} from 'react-native'; diff --git a/docs/props.md b/docs/props.md index 490eb214632..9eac9854e4f 100644 --- a/docs/props.md +++ b/docs/props.md @@ -32,7 +32,7 @@ Your own components can also use `props`. This lets you make a single component -```SnackPlayer name=Props&ext=js +```SnackPlayer name=Props&ext=jsx import React from 'react'; import {Text, View} from 'react-native'; diff --git a/docs/segmentedcontrolios.md b/docs/segmentedcontrolios.md index eb7ec3a49d3..0017a145fc5 100644 --- a/docs/segmentedcontrolios.md +++ b/docs/segmentedcontrolios.md @@ -13,7 +13,7 @@ The selected index can be changed on the fly by assigning the selectedIndex prop ## Example -```SnackPlayer name=SegmentedControlIOS%20Example&supportedPlatforms=ios&ext=js +```SnackPlayer name=SegmentedControlIOS%20Example&supportedPlatforms=ios&ext=jsx import React, {useState} from 'react'; import {SegmentedControlIOS, StyleSheet, Text, View} from 'react-native'; diff --git a/docs/shadow-props.md b/docs/shadow-props.md index d5e8a037059..6a323076680 100644 --- a/docs/shadow-props.md +++ b/docs/shadow-props.md @@ -8,7 +8,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con -```SnackPlayer name=Shadow%20Props&supportedPlatforms=ios&ext=js&dependencies=@react-native-community/slider +```SnackPlayer name=Shadow%20Props&supportedPlatforms=ios&ext=jsx&dependencies=@react-native-community/slider import React, {useState} from 'react'; import {Text, View, StyleSheet} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; diff --git a/docs/share.md b/docs/share.md index 1fc5823361f..16f3e0f5997 100644 --- a/docs/share.md +++ b/docs/share.md @@ -10,7 +10,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con -```SnackPlayer name=Example&supportedPlatforms=ios,android&ext=js +```SnackPlayer name=Example&supportedPlatforms=ios,android&ext=jsx import React from 'react'; import {Alert, Share, Button} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; diff --git a/docs/state.md b/docs/state.md index bc162f44b40..c021a669a37 100644 --- a/docs/state.md +++ b/docs/state.md @@ -14,7 +14,7 @@ For example, let's say we want to make text that blinks all the time. The text i -```SnackPlayer name=State&ext=js +```SnackPlayer name=State&ext=jsx import React, {useState, useEffect} from 'react'; import {Text, View} from 'react-native'; diff --git a/docs/statusbar.md b/docs/statusbar.md index 639b5c9e682..40f29aaa656 100644 --- a/docs/statusbar.md +++ b/docs/statusbar.md @@ -14,7 +14,7 @@ It is possible to have multiple `StatusBar` components mounted at the same time. -```SnackPlayer name=StatusBar%20Component%20Example&supportedPlatforms=android,ios&ext=js +```SnackPlayer name=StatusBar%20Component%20Example&supportedPlatforms=android,ios&ext=jsx import React, {useState} from 'react'; import { Button, diff --git a/docs/text-style-props.md b/docs/text-style-props.md index 93c978a9ae7..a0f16cd23b1 100644 --- a/docs/text-style-props.md +++ b/docs/text-style-props.md @@ -10,7 +10,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con -```SnackPlayer name=TextStyleProps&supportedPlatforms=ios,android&ext=js&dependencies=@react-native-community/slider +```SnackPlayer name=TextStyleProps&supportedPlatforms=ios,android&ext=jsx&dependencies=@react-native-community/slider import React, {useState} from 'react'; import { FlatList, diff --git a/docs/the-new-architecture/direct-manipulation.md b/docs/the-new-architecture/direct-manipulation.md index 6708a643cba..5bcf88656fb 100644 --- a/docs/the-new-architecture/direct-manipulation.md +++ b/docs/the-new-architecture/direct-manipulation.md @@ -25,7 +25,7 @@ For example, the following code demonstrates editing the input when you tap a bu -```SnackPlayer name=setNativeProps%20on%20TextInput&ext=js +```SnackPlayer name=setNativeProps%20on%20TextInput&ext=jsx import React from 'react'; import {useCallback, useRef} from 'react'; import { diff --git a/docs/transforms.md b/docs/transforms.md index a88c207ad7a..d2ff9a47ccf 100644 --- a/docs/transforms.md +++ b/docs/transforms.md @@ -213,12 +213,7 @@ The `transformOrigin` property sets the origin for a view's transformations. The ```SnackPlayer name=TransformOrigin%20Example import React, {useEffect, useRef} from 'react'; -import { - Animated, - View, - StyleSheet, - Easing, -} from 'react-native'; +import {Animated, View, StyleSheet, Easing} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; const App = () => { diff --git a/docs/tutorial.md b/docs/tutorial.md index d1a92919cd7..e28f2cfd2b7 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -66,7 +66,7 @@ Your own components can also use `props`. This lets you make a single component -```SnackPlayer name=Hello%20Props&ext=js +```SnackPlayer name=Hello%20Props&ext=jsx import React from 'react'; import {Text, View, StyleSheet} from 'react-native'; diff --git a/docs/virtualizedlist.md b/docs/virtualizedlist.md index 1bf19aa1806..349ce94b6e4 100644 --- a/docs/virtualizedlist.md +++ b/docs/virtualizedlist.md @@ -14,7 +14,7 @@ Virtualization massively improves memory consumption and performance of large li -```SnackPlayer name=VirtualizedListExample&ext=js +```SnackPlayer name=VirtualizedListExample&ext=jsx import React from 'react'; import {View, VirtualizedList, StyleSheet, Text, StatusBar} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; diff --git a/eslint.config.js b/eslint.config.js index 27775b151af..ec594fe9d50 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -20,10 +20,7 @@ export default defineConfig([ globalIgnores([ '**/.yarn', '**/node_modules', - // TODO(simek): move `lint-examples` to 'packages' directory, refactor ESLint setup - 'scripts/lint-examples/out', - // TODO(simek): move `sync-api-docs` to 'packages' directory, refactor ESLint setup - 'sync-api-docs', + 'packages/lint-examples/out', 'website/.docusaurus', 'website/build', 'website/static', @@ -48,7 +45,7 @@ export default defineConfig([ }, { - files: ['**/*.js', '**/*.mjs'], + files: ['**/*.{js,mjs}'], ...eslintJs.configs.recommended, rules: { 'no-unused-vars': 'off', @@ -56,7 +53,7 @@ export default defineConfig([ }, { - files: ['**/*.ts', '**/*.tsx', '**/*.d.ts'], + files: ['**/*.{ts,tsx,d.ts}'], settings: { 'import/resolver': { typescript: { @@ -99,7 +96,7 @@ export default defineConfig([ }, { - files: ['**/*.md', '**/*.mdx'], + files: ['**/*.{md,mdx}'], ...eslintPluginMdx.flat, processor: eslintPluginMdx.createRemarkProcessor({ lintCodeBlocks: false, diff --git a/package.json b/package.json index fc9b3584bed..71662126f4f 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,8 @@ }, "workspaces": [ "website", - "plugins/*", - "scripts/*", - "sync-api-docs" + "packages/*", + "plugins/*" ], "scripts": { "update-lock": "yarn dedupe", @@ -20,8 +19,8 @@ "serve": "yarn --cwd website serve", "prepare": "husky", "lint": "eslint .", + "lint:packages": "eslint ./packages", "lint:plugins": "eslint ./plugins", - "lint:scripts": "eslint ./scripts", "lint:website": "eslint ./website", "check-dependencies": "manypkg check" }, diff --git a/packages/lint-examples/.prettierrc.json b/packages/lint-examples/.prettierrc.json new file mode 100644 index 00000000000..fe440a6a0ed --- /dev/null +++ b/packages/lint-examples/.prettierrc.json @@ -0,0 +1,7 @@ +{ + "arrowParens": "avoid", + "bracketSameLine": true, + "bracketSpacing": false, + "singleQuote": true, + "trailingComma": "all" +} diff --git a/scripts/lint-examples/README.md b/packages/lint-examples/README.md similarity index 100% rename from scripts/lint-examples/README.md rename to packages/lint-examples/README.md diff --git a/scripts/lint-examples/babel.config.js b/packages/lint-examples/babel.config.js similarity index 100% rename from scripts/lint-examples/babel.config.js rename to packages/lint-examples/babel.config.js diff --git a/scripts/lint-examples/bin/eslint-examples-js.js b/packages/lint-examples/bin/eslint-examples-jsx.js similarity index 81% rename from scripts/lint-examples/bin/eslint-examples-js.js rename to packages/lint-examples/bin/eslint-examples-jsx.js index 9419e83002f..9f6636124ae 100755 --- a/scripts/lint-examples/bin/eslint-examples-js.js +++ b/packages/lint-examples/bin/eslint-examples-jsx.js @@ -8,11 +8,11 @@ * @format */ -const lintExamples = require('../src/lintExamples'); +import lintExamples from '../src/lintExamples.js'; lintExamples({ command: 'eslint', args: ['--max-warnings=0', '.'], - extension: 'js', + extension: 'jsx', writeBack: true, }); diff --git a/scripts/lint-examples/bin/eslint-examples-tsx.js b/packages/lint-examples/bin/eslint-examples-tsx.js similarity index 86% rename from scripts/lint-examples/bin/eslint-examples-tsx.js rename to packages/lint-examples/bin/eslint-examples-tsx.js index 79aa4333f6c..f89540cbaf4 100755 --- a/scripts/lint-examples/bin/eslint-examples-tsx.js +++ b/packages/lint-examples/bin/eslint-examples-tsx.js @@ -8,7 +8,7 @@ * @format */ -const lintExamples = require('../src/lintExamples'); +import lintExamples from '../src/lintExamples.js'; lintExamples({ command: 'eslint', diff --git a/scripts/lint-examples/bin/tsc-examples.js b/packages/lint-examples/bin/tsc-examples.js similarity index 85% rename from scripts/lint-examples/bin/tsc-examples.js rename to packages/lint-examples/bin/tsc-examples.js index 491106b4b82..097eda4f773 100755 --- a/scripts/lint-examples/bin/tsc-examples.js +++ b/packages/lint-examples/bin/tsc-examples.js @@ -8,7 +8,7 @@ * @format */ -const lintExamples = require('../src/lintExamples'); +import lintExamples from '../src/lintExamples.js'; lintExamples({ command: 'tsc', diff --git a/packages/lint-examples/eslint.config.js b/packages/lint-examples/eslint.config.js new file mode 100644 index 00000000000..0d951d402b6 --- /dev/null +++ b/packages/lint-examples/eslint.config.js @@ -0,0 +1,90 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {defineConfig, globalIgnores} from 'eslint/config'; +import globals from 'globals'; +import {fixupPluginRules} from '@eslint/compat'; +import commentsPlugin from 'eslint-plugin-eslint-comments'; +import reactPlugin from 'eslint-plugin-react'; +import reactHooksPlugin from 'eslint-plugin-react-hooks'; +import reactNativePlugin from '@react-native/eslint-plugin'; +import reactNativeConfig from '@react-native/eslint-config'; +import eslintJs from '@eslint/js'; +import eslintPluginPrettier from 'eslint-plugin-prettier/recommended'; +import tsParser from '@typescript-eslint/parser'; +import jestPlugin from 'eslint-plugin-jest'; + +export default defineConfig([ + globalIgnores(['**/node_modules']), + + eslintPluginPrettier, + + { + plugins: { + 'eslint-comments': fixupPluginRules(commentsPlugin), + jest: fixupPluginRules(jestPlugin), + react: reactPlugin, + 'react-hooks': reactHooksPlugin, + 'react-native': fixupPluginRules(reactNativePlugin), + }, + languageOptions: { + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + globals: { + ...reactNativeConfig.globals, + ...globals.jest, + ...globals.node, + window: 'readonly', + document: 'readonly', + console: 'readonly', + MutationObserver: 'readonly', + }, + }, + }, + + { + files: ['**/*.{js,jsx}'], + ...eslintJs.configs.recommended, + rules: { + ...reactNativeConfig.rules, + // Many existing inline styles in examples + 'react-native/no-inline-styles': 'off', + }, + + settings: { + react: { + version: 'detect', + }, + }, + }, + + { + files: ['**/*.{ts,tsx}'], + settings: { + 'import/resolver': { + typescript: { + project: './tsconfig.json', + }, + }, + }, + languageOptions: { + parser: tsParser, + parserOptions: { + sourceType: 'module', + ecmaVersion: 'es2023', + ecmaFeatures: { + modules: true, + }, + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + }, +]); diff --git a/scripts/lint-examples/package.json b/packages/lint-examples/package.json similarity index 68% rename from scripts/lint-examples/package.json rename to packages/lint-examples/package.json index 45399d5401a..cbb96175ac4 100644 --- a/scripts/lint-examples/package.json +++ b/packages/lint-examples/package.json @@ -2,21 +2,30 @@ "name": "@react-native-website/lint-examples", "version": "0.0.0", "private": true, + "type": "module", "bin": { - "eslint-examples-js": "./bin/eslint-examples-js.js", + "eslint-examples-jsx": "./bin/eslint-examples-jsx.js", "eslint-examples-tsx": "./bin/eslint-examples-tsx.js", "tsc-examples": "./bin/tsc-examples.js" }, + "scripts": { + "lint": "eslint" + }, "devDependencies": { "@babel/core": "^7.28.3", "@babel/preset-env": "^7.28.3", "@babel/runtime": "^7.28.3", + "@eslint/compat": "^1.3.2", "@react-native-community/slider": "^4.5.7", "@react-native/babel-preset": "^0.81.0", "@react-native/eslint-config": "^0.81.0", + "@react-native/eslint-plugin": "^0.81.0", "@react-native/typescript-config": "^0.81.0", "@types/react": "^19.1.10", - "eslint": "^8.57.1", + "eslint": "^9.33.0", + "eslint-plugin-eslint-comments": "^3.2.0", + "eslint-plugin-jest": "^29.0.1", + "eslint-plugin-react": "^7.37.5", "glob": "^11.0.0", "prettier": "^3.6.2", "react": "^19.1.1", diff --git a/scripts/lint-examples/src/lintExamples.js b/packages/lint-examples/src/lintExamples.js similarity index 93% rename from scripts/lint-examples/src/lintExamples.js rename to packages/lint-examples/src/lintExamples.js index 0b0c38c1a3c..daa2e8b0d56 100755 --- a/scripts/lint-examples/src/lintExamples.js +++ b/packages/lint-examples/src/lintExamples.js @@ -7,20 +7,20 @@ * @format */ -const {execSync} = require('child_process'); -const {promises: fs} = require('fs'); -const path = require('path'); -const glob = require('glob'); +import {execSync} from 'node:child_process'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import {glob} from 'glob'; /** * The root document to search for documents */ -const documentsRoot = path.join(__dirname, '..', '..', '..', 'docs'); +const documentsRoot = path.join(import.meta.dirname, '..', '..', '..', 'docs'); /** * The directory to output generated files to */ -const outputRoot = path.join(__dirname, '..', 'out'); +const outputRoot = path.join(import.meta.dirname, '..', 'out'); /** * Process arguments to be forwarded to the linter @@ -30,7 +30,7 @@ const processArgs = process.argv.slice(2); /** * Valid extensions for snack examples */ -const validExtensions = ['js', 'tsx']; +const validExtensions = ['jsx', 'tsx']; /** * Extracts snack examples based on extension to output files, then runs an @@ -54,7 +54,7 @@ async function lintExamples({command, args, extension, writeBack}) { } try { - const mappings = await extractExamples(extension ?? 'js'); + const mappings = await extractExamples(extension ?? 'jsx'); process.exitCode = await runLinter(command, args ?? []); if (writeBack) { @@ -223,4 +223,4 @@ async function updateDocuments(mappings) { ); } -module.exports = lintExamples; +export default lintExamples; diff --git a/scripts/lint-examples/tsconfig.json b/packages/lint-examples/tsconfig.json similarity index 100% rename from scripts/lint-examples/tsconfig.json rename to packages/lint-examples/tsconfig.json diff --git a/sync-api-docs/extractDocsFromRN.js b/packages/sync-api-docs/extractDocsFromRN.js similarity index 83% rename from sync-api-docs/extractDocsFromRN.js rename to packages/sync-api-docs/extractDocsFromRN.js index 2c8214d8204..e6b8511764d 100644 --- a/sync-api-docs/extractDocsFromRN.js +++ b/packages/sync-api-docs/extractDocsFromRN.js @@ -7,18 +7,14 @@ * @format */ -'use strict'; - -const fs = require('fs-extra'); -const glob = require('glob'); -const path = require('path'); -const reactDocs = require('@motiz88/react-native-docgen'); +import fs from 'node:fs/promises'; +import {glob} from 'glob'; +import path from 'node:path'; +import reactDocs from '@motiz88/react-native-docgen'; const GENERATE_ANNOTATION = '@' + 'generate-docs'; -module.exports = extractDocsFromRN; - -async function extractDocsFromRN(rnRoot) { +export default async function extractDocsFromRN(rnRoot) { const allComponentFiles = await glob.glob( path.join(rnRoot, '/Libraries/{Components,Image,}/**/*.js'), { @@ -59,7 +55,7 @@ async function extractDocsFromRN(rnRoot) { // Make sure output is JSON-safe const docsSerialized = JSON.parse(JSON.stringify(docs)); await fs.writeFile( - path.join(__dirname, 'extracted.json'), + path.join(import.meta.dirname, 'extracted.json'), JSON.stringify(docsSerialized, null, 2), 'utf8' ); diff --git a/sync-api-docs/generateMarkdown.js b/packages/sync-api-docs/generateMarkdown.js similarity index 89% rename from sync-api-docs/generateMarkdown.js rename to packages/sync-api-docs/generateMarkdown.js index 24374c0e2df..9d8640457f1 100644 --- a/sync-api-docs/generateMarkdown.js +++ b/packages/sync-api-docs/generateMarkdown.js @@ -4,15 +4,15 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -const tokenizeComment = require('tokenize-comment'); -const {formatTypeColumn, formatDefaultColumn} = require('./propFormatter'); -const { +import tokenizeComment from 'tokenize-comment'; +import {formatTypeColumn, formatDefaultColumn} from './propFormatter.js'; +import { formatMethodType, formatMethodName, formatMethodDescription, -} = require('./methodFormatter'); +} from './methodFormatter.js'; -const {formatMultiplePlatform, maybeLinkifyTypeName} = require('./utils'); +import {formatMultiplePlatform, maybeLinkifyTypeName} from './utils.js'; // Formats an array of rows as a Markdown table function generateTable(rows) { @@ -108,7 +108,6 @@ function generateMethod(method, component) { }) .join('\n'); const docblockTokenized = tokenizeComment(dblock); - dblock = dblock.replace(/@platform .*/g, ''); method.rnTags = {}; const platformTag = docblockTokenized.tags.find( ({key}) => key === 'platform' @@ -134,28 +133,7 @@ function generateMethod(method, component) { ).trim(); } -function lowerFirst(s) { - return s[0].toLowerCase() + s.slice(1); -} - -function generateMethodSignatureBlock(method, component) { - return ( - '```jsx\n' + - (method.modifiers.includes('static') - ? component.displayName + '.' - : lowerFirst(component.displayName + '.')) + - method.name + - '(' + - method.params - .map(param => (param.optional ? `[${param.name}]` : param.name)) - .join(', ') + - ');' + - '\n' + - '```\n\n' - ); -} - -function generateMethodSignatureTable(method, component) { +function generateMethodSignatureTable(method) { if (!method.params.length) { return ''; } @@ -303,7 +281,7 @@ function preprocessDescription(desc) { } } -function generateMarkdown({id, title}, component) { +export default function generateMarkdown({id, title}, component) { const markdownString = generateHeader({id, title}) + '\n' + @@ -316,5 +294,3 @@ function generateMarkdown({id, title}, component) { return markdownString.replace(/\n{3,}/g, '\n\n'); } - -module.exports = generateMarkdown; diff --git a/sync-api-docs/magic.js b/packages/sync-api-docs/magic.js similarity index 98% rename from sync-api-docs/magic.js rename to packages/sync-api-docs/magic.js index 0127a955bf5..de2098445ca 100644 --- a/sync-api-docs/magic.js +++ b/packages/sync-api-docs/magic.js @@ -8,7 +8,7 @@ // Hard-coded knowledge about the React Native codebase and how to document it // Ideally this file should go away. -module.exports = { +export default { linkableTypeAliases: { NativeColorValue: { text: 'color', diff --git a/sync-api-docs/methodFormatter.js b/packages/sync-api-docs/methodFormatter.js similarity index 80% rename from sync-api-docs/methodFormatter.js rename to packages/sync-api-docs/methodFormatter.js index f88736b9ede..6d4fe063b4e 100644 --- a/sync-api-docs/methodFormatter.js +++ b/packages/sync-api-docs/methodFormatter.js @@ -5,12 +5,10 @@ * LICENSE file in the root directory of this source tree. */ -'use strict'; +import magic from './magic.js'; +import {formatMultiplePlatform} from './utils.js'; -const magic = require('./magic'); -const {formatMultiplePlatform} = require('./utils'); - -function formatMethodType(param) { +export function formatMethodType(param) { let text, url; if (param?.type?.name === 'union') { if (param?.type?.alias) { @@ -28,7 +26,7 @@ function formatMethodType(param) { } } -function formatMethodName(param) { +export function formatMethodName(param) { let tag = param.description; if (tag) { const isMatch = tag.match(/{@platform [a-z ,]*}/); @@ -42,7 +40,7 @@ function formatMethodName(param) { return param.name; } -function formatMethodDescription(param) { +export function formatMethodDescription(param) { let tag = param.description; const isMatch = tag.match(/{@platform [a-z ,]*}/); if (isMatch) { @@ -52,9 +50,3 @@ function formatMethodDescription(param) { } return tag; } - -module.exports = { - formatMethodType, - formatMethodName, - formatMethodDescription, -}; diff --git a/sync-api-docs/package.json b/packages/sync-api-docs/package.json similarity index 78% rename from sync-api-docs/package.json rename to packages/sync-api-docs/package.json index 373ade3d4f0..186711e64f8 100644 --- a/sync-api-docs/package.json +++ b/packages/sync-api-docs/package.json @@ -2,13 +2,13 @@ "name": "@react-native-website/sync-api", "version": "0.0.1", "private": true, + "type": "module", "scripts": { "prettier": "prettier --write \"**/*.js\"", - "sync": "node sync-api-docs ../../react-native" + "sync": "node sync-api-docs ../../../react-native/packages/react-native" }, "devDependencies": { "@motiz88/react-native-docgen": "0.0.3", - "fs-extra": "^11.3.1", "glob": "^11.0.0", "he": "^1.2.0", "react-docgen-markdown-renderer": "^2.1.3", diff --git a/sync-api-docs/preprocessGeneratedApiDocs.js b/packages/sync-api-docs/preprocessGeneratedApiDocs.js similarity index 91% rename from sync-api-docs/preprocessGeneratedApiDocs.js rename to packages/sync-api-docs/preprocessGeneratedApiDocs.js index a5e553a03f3..00b9883852b 100644 --- a/sync-api-docs/preprocessGeneratedApiDocs.js +++ b/packages/sync-api-docs/preprocessGeneratedApiDocs.js @@ -5,13 +5,11 @@ * LICENSE file in the root directory of this source tree. */ -'use strict'; - // Preprocess the react-docgen artifact before rendering it to Markdown. // This file may end up in the React Native repo, as part of the // `generate-api-docs` script. -const tokenizeComment = require('tokenize-comment'); +import tokenizeComment from 'tokenize-comment'; function preprocessTagsInDescription(obj) { if (obj && obj.description) { @@ -54,7 +52,7 @@ function preprocessTagsInDescription(obj) { } // NOTE: This function mutates `docs`. -function preprocessGeneratedApiDocs(docs) { +export default function preprocessGeneratedApiDocs(docs) { for (const {component} of docs) { if (component.props && component.description) { for (const prop of Object.values(component.props)) { @@ -66,5 +64,3 @@ function preprocessGeneratedApiDocs(docs) { } } } - -module.exports = preprocessGeneratedApiDocs; diff --git a/sync-api-docs/propFormatter.js b/packages/sync-api-docs/propFormatter.js similarity index 93% rename from sync-api-docs/propFormatter.js rename to packages/sync-api-docs/propFormatter.js index d1ba12a9bf3..9bfb3eb60ad 100644 --- a/sync-api-docs/propFormatter.js +++ b/packages/sync-api-docs/propFormatter.js @@ -7,14 +7,14 @@ 'use strict'; -const magic = require('./magic'); -const { +import magic from './magic.js'; +import { formatMultiplePlatform, stringToInlineCodeForTable, formatType, -} = require('./utils'); +} from './utils.js'; -function formatTypeColumn(prop) { +export function formatTypeColumn(prop) { // Checks for @type pragma comment if (prop.rnTags && prop.rnTags.type) { let tableRows = ''; @@ -93,14 +93,11 @@ function formatTypeColumn(prop) { return prop.flowType.type; } } else if (prop.flowType.name.includes('$ReadOnlyArray')) { - prop?.flowType?.elements[0]?.elements && - prop?.flowType?.elements[0]?.elements.forEach(elem => { - if ( - Object.hasOwnProperty.call(magic.linkableTypeAliases, elem.name) - ) { - ({url, text} = magic.linkableTypeAliases[elem.name]); - } - }); + prop?.flowType?.elements[0]?.elements.forEach(elem => { + if (Object.hasOwnProperty.call(magic.linkableTypeAliases, elem.name)) { + ({url, text} = magic.linkableTypeAliases[elem.name]); + } + }); if (url) return `array of [${text}](${url})`; else if (prop?.flowType?.elements[0].name === 'union') { const unionTypes = prop?.flowType?.elements[0]?.elements.reduce( @@ -195,7 +192,7 @@ function formatTypeColumn(prop) { } // Adds proper markdown formatting to component's default value. -function formatDefaultColumn(prop) { +export function formatDefaultColumn(prop) { if (prop?.rnTags?.default) { // Parse from @default annotation let tableRows = ''; @@ -236,8 +233,3 @@ function formatDefaultColumn(prop) { : ''; } } - -module.exports = { - formatTypeColumn, - formatDefaultColumn, -}; diff --git a/sync-api-docs/sync-api-docs.js b/packages/sync-api-docs/sync-api-docs.js similarity index 69% rename from sync-api-docs/sync-api-docs.js rename to packages/sync-api-docs/sync-api-docs.js index d92e327a558..ec2ba152f92 100644 --- a/sync-api-docs/sync-api-docs.js +++ b/packages/sync-api-docs/sync-api-docs.js @@ -8,18 +8,16 @@ // ***** EXPERIMENTAL ***** // Updates the API docs from the React Native source code. -'use strict'; +import fs from 'node:fs/promises'; +import process from 'node:process'; +import path from 'node:path'; -const process = require('process'); -const fs = require('fs-extra'); -const path = require('path'); +import extractDocsFromRN from './extractDocsFromRN.js'; +import preprocessGeneratedApiDocs from './preprocessGeneratedApiDocs.js'; +import generateMarkdown from './generateMarkdown.js'; +import {titleToId} from './utils.js'; -const extractDocsFromRN = require('./extractDocsFromRN'); -const preprocessGeneratedApiDocs = require('./preprocessGeneratedApiDocs'); -const generateMarkdown = require('./generateMarkdown'); -const {titleToId} = require('./utils'); - -const DOCS_ROOT_DIR = path.resolve(__dirname, '..', 'docs'); +const DOCS_ROOT_DIR = path.resolve(import.meta.dirname, '..', '..', 'docs'); async function generateApiDocs(rnPath) { const apiDocs = await extractDocsFromRN(rnPath); @@ -48,4 +46,6 @@ async function main(args) { await generateApiDocs(args[0]); } -main(process.argv.slice(2)); +main(process.argv.slice(2)).catch(error => { + console.error(error); +}); diff --git a/sync-api-docs/utils.js b/packages/sync-api-docs/utils.js similarity index 82% rename from sync-api-docs/utils.js rename to packages/sync-api-docs/utils.js index 48e19ca9bda..e912fb567d5 100644 --- a/sync-api-docs/utils.js +++ b/packages/sync-api-docs/utils.js @@ -5,12 +5,12 @@ * LICENSE file in the root directory of this source tree. */ -'use strict'; -const he = require('he'); -const magic = require('./magic'); +import he from 'he'; + +import magic from './magic.js'; // Adds multiple platform tags for prop name -function formatMultiplePlatform(platforms) { +export function formatMultiplePlatform(platforms) { let platformString = ''; platforms.forEach(platform => { switch (platform.trim().toLowerCase()) { @@ -33,7 +33,7 @@ function formatMultiplePlatform(platforms) { // Wraps a string in an inline code block in a way that is safe to include in a // table cell, by wrapping it as HTML if necessary. -function stringToInlineCodeForTable(str) { +export function stringToInlineCodeForTable(str) { let useHtml = /[`|]/.test(str); str = str.replace(/\n/g, ' '); if (useHtml) { @@ -42,7 +42,7 @@ function stringToInlineCodeForTable(str) { return '`' + str + '`'; } -function maybeLinkifyType(flowType) { +export function maybeLinkifyType(flowType) { let url, text; flowType.elements?.forEach(elem => { if (Object.hasOwnProperty.call(magic.linkableTypeAliases, elem.name)) { @@ -60,14 +60,14 @@ function maybeLinkifyType(flowType) { return text; } -function formatType(name) { +export function formatType(name) { if (name.toLowerCase() === 'boolean') return 'bool'; if (name.toLowerCase() === 'stringish') return 'string'; if (name === '$ReadOnlyArray') return 'array'; return name; } -function maybeLinkifyTypeName(name) { +export function maybeLinkifyTypeName(name) { let url, text; if (Object.hasOwnProperty.call(magic.linkableTypeAliases, name)) { ({url, text} = magic.linkableTypeAliases[name]); @@ -81,15 +81,6 @@ function maybeLinkifyTypeName(name) { return text; } -function titleToId(title) { +export function titleToId(title) { return title.toLowerCase().replace(/[^a-z]+/g, '-'); } - -module.exports = { - formatMultiplePlatform, - stringToInlineCodeForTable, - maybeLinkifyType, - maybeLinkifyTypeName, - formatType, - titleToId, -}; diff --git a/scripts/lint-examples/.eslintignore b/scripts/lint-examples/.eslintignore deleted file mode 100644 index 3313571d92c..00000000000 --- a/scripts/lint-examples/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -!/out diff --git a/scripts/lint-examples/.eslintrc.js b/scripts/lint-examples/.eslintrc.js deleted file mode 100644 index 9997a0b9577..00000000000 --- a/scripts/lint-examples/.eslintrc.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - root: true, - extends: '@react-native', - rules: { - // Many existing inline styles in examples - 'react-native/no-inline-styles': 'off', - }, -}; diff --git a/scripts/lint-examples/.prettierrc.js b/scripts/lint-examples/.prettierrc.js deleted file mode 100644 index 2b540746a75..00000000000 --- a/scripts/lint-examples/.prettierrc.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - arrowParens: 'avoid', - bracketSameLine: true, - bracketSpacing: false, - singleQuote: true, - trailingComma: 'all', -}; diff --git a/website/package.json b/website/package.json index 1086e1fa110..dc37462d277 100644 --- a/website/package.json +++ b/website/package.json @@ -22,10 +22,10 @@ "test": "yarn build", "version:cut": "docusaurus docs:version", "format:style": "prettier --write src/**/*.{scss}", - "format:examples": "eslint-examples-js --fix && eslint-examples-tsx --fix", + "format:examples": "eslint-examples-jsx --fix && eslint-examples-tsx --fix", "prettier": "yarn format:style", "lint": "eslint .", - "lint:examples": "eslint-examples-js && eslint-examples-tsx && tsc-examples", + "lint:examples": "eslint-examples-jsx && eslint-examples-tsx && tsc-examples", "lint:markdown": "remark ../docs --quiet -r .remarkrc.mjs", "lint:markdown:versioned": "remark ./versioned_docs --quiet -r .remarkrc.mjs", "language:lint": "cd ../ && alex && case-police 'docs/*.md' -d ./website/react-native-dict.json --disable SDK,URI", @@ -62,7 +62,6 @@ "@docusaurus/module-type-aliases": "3.8.1", "@docusaurus/tsconfig": "3.8.1", "@docusaurus/types": "3.8.1", - "@react-native-website/lint-examples": "0.0.0", "@types/fs-extra": "^11.0.4", "@types/google.analytics": "^0.0.46", "@types/react": "^19.1.10", diff --git a/yarn.lock b/yarn.lock index 201c346260c..792ac0dc8ff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2977,13 +2977,25 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.12.1, @eslint-community/regexpp@npm:^4.6.1": +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.12.1": version: 4.12.1 resolution: "@eslint-community/regexpp@npm:4.12.1" checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 languageName: node linkType: hard +"@eslint/compat@npm:^1.3.2": + version: 1.3.2 + resolution: "@eslint/compat@npm:1.3.2" + peerDependencies: + eslint: ^8.40 || 9 + peerDependenciesMeta: + eslint: + optional: true + checksum: 10c0/9b95b49ee74c50adf8f0e45066b471bc76842c43d4721727ff93d186745bdd1679d18420c992a05eab3bb41762672cd3faa5c56c99325dbb97200f7533cbd2bf + languageName: node + linkType: hard + "@eslint/config-array@npm:^0.21.0": version: 0.21.0 resolution: "@eslint/config-array@npm:0.21.0" @@ -3041,23 +3053,6 @@ __metadata: languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/eslintrc@npm:2.1.4" - dependencies: - ajv: "npm:^6.12.4" - debug: "npm:^4.3.2" - espree: "npm:^9.6.0" - globals: "npm:^13.19.0" - ignore: "npm:^5.2.0" - import-fresh: "npm:^3.2.1" - js-yaml: "npm:^4.1.0" - minimatch: "npm:^3.1.2" - strip-json-comments: "npm:^3.1.1" - checksum: 10c0/32f67052b81768ae876c84569ffd562491ec5a5091b0c1e1ca1e0f3c24fb42f804952fdd0a137873bc64303ba368a71ba079a6f691cee25beee9722d94cc8573 - languageName: node - linkType: hard - "@eslint/eslintrc@npm:^3.3.1": version: 3.3.1 resolution: "@eslint/eslintrc@npm:3.3.1" @@ -3075,13 +3070,6 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:8.57.1": - version: 8.57.1 - resolution: "@eslint/js@npm:8.57.1" - checksum: 10c0/b489c474a3b5b54381c62e82b3f7f65f4b8a5eaaed126546520bf2fede5532a8ed53212919fed1e9048dcf7f37167c8561d58d0ba4492a4244004e7793805223 - languageName: node - linkType: hard - "@eslint/js@npm:9.33.0, @eslint/js@npm:^9.33.0": version: 9.33.0 resolution: "@eslint/js@npm:9.33.0" @@ -3139,17 +3127,6 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.13.0": - version: 0.13.0 - resolution: "@humanwhocodes/config-array@npm:0.13.0" - dependencies: - "@humanwhocodes/object-schema": "npm:^2.0.3" - debug: "npm:^4.3.1" - minimatch: "npm:^3.0.5" - checksum: 10c0/205c99e756b759f92e1f44a3dc6292b37db199beacba8f26c2165d4051fe73a4ae52fdcfd08ffa93e7e5cb63da7c88648f0e84e197d154bbbbe137b2e0dd332e - languageName: node - linkType: hard - "@humanwhocodes/module-importer@npm:^1.0.1": version: 1.0.1 resolution: "@humanwhocodes/module-importer@npm:1.0.1" @@ -3157,13 +3134,6 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.3": - version: 2.0.3 - resolution: "@humanwhocodes/object-schema@npm:2.0.3" - checksum: 10c0/80520eabbfc2d32fe195a93557cef50dfe8c8905de447f022675aaf66abc33ae54098f5ea78548d925aa671cd4ab7c7daa5ad704fe42358c9b5e7db60f80696c - languageName: node - linkType: hard - "@humanwhocodes/retry@npm:^0.3.0": version: 0.3.1 resolution: "@humanwhocodes/retry@npm:0.3.1" @@ -3750,7 +3720,7 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": +"@nodelib/fs.walk@npm:^1.2.3": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" dependencies: @@ -3929,19 +3899,24 @@ __metadata: languageName: node linkType: hard -"@react-native-website/lint-examples@npm:0.0.0, @react-native-website/lint-examples@workspace:scripts/lint-examples": +"@react-native-website/lint-examples@workspace:packages/lint-examples": version: 0.0.0-use.local - resolution: "@react-native-website/lint-examples@workspace:scripts/lint-examples" + resolution: "@react-native-website/lint-examples@workspace:packages/lint-examples" dependencies: "@babel/core": "npm:^7.28.3" "@babel/preset-env": "npm:^7.28.3" "@babel/runtime": "npm:^7.28.3" + "@eslint/compat": "npm:^1.3.2" "@react-native-community/slider": "npm:^4.5.7" "@react-native/babel-preset": "npm:^0.81.0" "@react-native/eslint-config": "npm:^0.81.0" + "@react-native/eslint-plugin": "npm:^0.81.0" "@react-native/typescript-config": "npm:^0.81.0" "@types/react": "npm:^19.1.10" - eslint: "npm:^8.57.1" + eslint: "npm:^9.33.0" + eslint-plugin-eslint-comments: "npm:^3.2.0" + eslint-plugin-jest: "npm:^29.0.1" + eslint-plugin-react: "npm:^7.37.5" glob: "npm:^11.0.0" prettier: "npm:^3.6.2" react: "npm:^19.1.1" @@ -3949,7 +3924,7 @@ __metadata: react-native-safe-area-context: "npm:^5.6.0" typescript: "npm:^5.9.2" bin: - eslint-examples-js: ./bin/eslint-examples-js.js + eslint-examples-jsx: ./bin/eslint-examples-jsx.js eslint-examples-tsx: ./bin/eslint-examples-tsx.js tsc-examples: ./bin/tsc-examples.js languageName: unknown @@ -3989,12 +3964,11 @@ __metadata: languageName: unknown linkType: soft -"@react-native-website/sync-api@workspace:sync-api-docs": +"@react-native-website/sync-api@workspace:packages/sync-api-docs": version: 0.0.0-use.local - resolution: "@react-native-website/sync-api@workspace:sync-api-docs" + resolution: "@react-native-website/sync-api@workspace:packages/sync-api-docs" dependencies: "@motiz88/react-native-docgen": "npm:0.0.3" - fs-extra: "npm:^11.3.1" glob: "npm:^11.0.0" he: "npm:^1.2.0" react-docgen-markdown-renderer: "npm:^2.1.3" @@ -4159,7 +4133,7 @@ __metadata: languageName: node linkType: hard -"@react-native/eslint-plugin@npm:0.81.0": +"@react-native/eslint-plugin@npm:0.81.0, @react-native/eslint-plugin@npm:^0.81.0": version: 0.81.0 resolution: "@react-native/eslint-plugin@npm:0.81.0" checksum: 10c0/418a59b25f49cc7d1ee921380e603a4281c63935e0de95de2d477778a1fe6ca44cbdf51b9288e1b51435b9405f92d31b9ab4e9b1463425dcdc4129d8b19c8bbd @@ -5827,7 +5801,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.40.0": +"@typescript-eslint/utils@npm:8.40.0, @typescript-eslint/utils@npm:^8.0.0": version: 8.40.0 resolution: "@typescript-eslint/utils@npm:8.40.0" dependencies: @@ -5890,7 +5864,7 @@ __metadata: languageName: node linkType: hard -"@ungap/structured-clone@npm:^1.0.0, @ungap/structured-clone@npm:^1.2.0": +"@ungap/structured-clone@npm:^1.0.0": version: 1.3.0 resolution: "@ungap/structured-clone@npm:1.3.0" checksum: 10c0/0fc3097c2540ada1fc340ee56d58d96b5b536a2a0dab6e3ec17d4bfc8c4c86db345f61a375a8185f9da96f01c69678f836a2b57eeaa9e4b8eeafd26428e57b0a @@ -6113,7 +6087,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.0.0, acorn@npm:^8.0.4, acorn@npm:^8.11.0, acorn@npm:^8.14.0, acorn@npm:^8.15.0, acorn@npm:^8.8.2, acorn@npm:^8.9.0": +"acorn@npm:^8.0.0, acorn@npm:^8.0.4, acorn@npm:^8.11.0, acorn@npm:^8.14.0, acorn@npm:^8.15.0, acorn@npm:^8.8.2": version: 8.15.0 resolution: "acorn@npm:8.15.0" bin: @@ -6989,13 +6963,13 @@ __metadata: languageName: node linkType: hard -"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1": - version: 1.0.1 - resolution: "call-bind-apply-helpers@npm:1.0.1" +"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind-apply-helpers@npm:1.0.2" dependencies: es-errors: "npm:^1.3.0" function-bind: "npm:^1.1.2" - checksum: 10c0/acb2ab68bf2718e68a3e895f0d0b73ccc9e45b9b6f210f163512ba76f91dab409eb8792f6dae188356f9095747512a3101646b3dea9d37fb8c7c6bf37796d18c + checksum: 10c0/47bd9901d57b857590431243fea704ff18078b16890a6b3e021e12d279bbf211d039155e27d7566b374d49ee1f8189344bac9833dec7a20cdec370506361c938 languageName: node linkType: hard @@ -7011,13 +6985,13 @@ __metadata: languageName: node linkType: hard -"call-bound@npm:^1.0.2, call-bound@npm:^1.0.3": - version: 1.0.3 - resolution: "call-bound@npm:1.0.3" +"call-bound@npm:^1.0.2, call-bound@npm:^1.0.3, call-bound@npm:^1.0.4": + version: 1.0.4 + resolution: "call-bound@npm:1.0.4" dependencies: - call-bind-apply-helpers: "npm:^1.0.1" - get-intrinsic: "npm:^1.2.6" - checksum: 10c0/45257b8e7621067304b30dbd638e856cac913d31e8e00a80d6cf172911acd057846572d0b256b45e652d515db6601e2974a1b1a040e91b4fc36fb3dd86fa69cf + call-bind-apply-helpers: "npm:^1.0.2" + get-intrinsic: "npm:^1.3.0" + checksum: 10c0/f4796a6a0941e71c766aea672f63b72bc61234c4f4964dc6d7606e3664c307e7d77845328a8f3359ce39ddb377fed67318f9ee203dea1d47e46165dcf2917644 languageName: node linkType: hard @@ -7722,7 +7696,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -8786,7 +8760,7 @@ __metadata: languageName: node linkType: hard -"es-object-atoms@npm:^1.0.0": +"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": version: 1.1.1 resolution: "es-object-atoms@npm:1.1.1" dependencies: @@ -9003,6 +8977,24 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-jest@npm:^29.0.1": + version: 29.0.1 + resolution: "eslint-plugin-jest@npm:29.0.1" + dependencies: + "@typescript-eslint/utils": "npm:^8.0.0" + peerDependencies: + "@typescript-eslint/eslint-plugin": ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 + jest: "*" + peerDependenciesMeta: + "@typescript-eslint/eslint-plugin": + optional: true + jest: + optional: true + checksum: 10c0/20edc166503a50c10b45f733797d530a5107c91efa25410ef405780d12222a796b5b41ed8f6d2b939632a1af273af6cc5732233463d1f36dbe7680bbb86c4eec + languageName: node + linkType: hard + "eslint-plugin-mdx@npm:^3.6.2": version: 3.6.2 resolution: "eslint-plugin-mdx@npm:3.6.2" @@ -9070,9 +9062,9 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react@npm:^7.30.1": - version: 7.37.4 - resolution: "eslint-plugin-react@npm:7.37.4" +"eslint-plugin-react@npm:^7.30.1, eslint-plugin-react@npm:^7.37.5": + version: 7.37.5 + resolution: "eslint-plugin-react@npm:7.37.5" dependencies: array-includes: "npm:^3.1.8" array.prototype.findlast: "npm:^1.2.5" @@ -9084,7 +9076,7 @@ __metadata: hasown: "npm:^2.0.2" jsx-ast-utils: "npm:^2.4.1 || ^3.0.0" minimatch: "npm:^3.1.2" - object.entries: "npm:^1.1.8" + object.entries: "npm:^1.1.9" object.fromentries: "npm:^2.0.8" object.values: "npm:^1.2.1" prop-types: "npm:^15.8.1" @@ -9094,7 +9086,7 @@ __metadata: string.prototype.repeat: "npm:^1.0.0" peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - checksum: 10c0/4acbbdb19669dfa9a162ed8847c3ad1918f6aea1ceb675ee320b5d903b4e463fdef25e15233295b6d0a726fef2ea8b015c527da769c7690932ddc52d5b82ba12 + checksum: 10c0/c850bfd556291d4d9234f5ca38db1436924a1013627c8ab1853f77cac73ec19b020e861e6c7b783436a48b6ffcdfba4547598235a37ad4611b6739f65fd8ad57 languageName: node linkType: hard @@ -9123,16 +9115,6 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^7.2.2": - version: 7.2.2 - resolution: "eslint-scope@npm:7.2.2" - dependencies: - esrecurse: "npm:^4.3.0" - estraverse: "npm:^5.2.0" - checksum: 10c0/613c267aea34b5a6d6c00514e8545ef1f1433108097e857225fed40d397dd6b1809dffd11c2fde23b37ca53d7bf935fe04d2a18e6fc932b31837b6ad67e1c116 - languageName: node - linkType: hard - "eslint-scope@npm:^8.4.0": version: 8.4.0 resolution: "eslint-scope@npm:8.4.0" @@ -9150,7 +9132,7 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.0.0, eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": +"eslint-visitor-keys@npm:^3.0.0, eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" checksum: 10c0/92708e882c0a5ffd88c23c0b404ac1628cf20104a108c745f240a13c332a11aac54f49a22d5762efbffc18ecbc9a580d1b7ad034bf5f3cc3307e5cbff2ec9820 @@ -9164,54 +9146,6 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8.57.1": - version: 8.57.1 - resolution: "eslint@npm:8.57.1" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.2.0" - "@eslint-community/regexpp": "npm:^4.6.1" - "@eslint/eslintrc": "npm:^2.1.4" - "@eslint/js": "npm:8.57.1" - "@humanwhocodes/config-array": "npm:^0.13.0" - "@humanwhocodes/module-importer": "npm:^1.0.1" - "@nodelib/fs.walk": "npm:^1.2.8" - "@ungap/structured-clone": "npm:^1.2.0" - ajv: "npm:^6.12.4" - chalk: "npm:^4.0.0" - cross-spawn: "npm:^7.0.2" - debug: "npm:^4.3.2" - doctrine: "npm:^3.0.0" - escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^7.2.2" - eslint-visitor-keys: "npm:^3.4.3" - espree: "npm:^9.6.1" - esquery: "npm:^1.4.2" - esutils: "npm:^2.0.2" - fast-deep-equal: "npm:^3.1.3" - file-entry-cache: "npm:^6.0.1" - find-up: "npm:^5.0.0" - glob-parent: "npm:^6.0.2" - globals: "npm:^13.19.0" - graphemer: "npm:^1.4.0" - ignore: "npm:^5.2.0" - imurmurhash: "npm:^0.1.4" - is-glob: "npm:^4.0.0" - is-path-inside: "npm:^3.0.3" - js-yaml: "npm:^4.1.0" - json-stable-stringify-without-jsonify: "npm:^1.0.1" - levn: "npm:^0.4.1" - lodash.merge: "npm:^4.6.2" - minimatch: "npm:^3.1.2" - natural-compare: "npm:^1.4.0" - optionator: "npm:^0.9.3" - strip-ansi: "npm:^6.0.1" - text-table: "npm:^0.2.0" - bin: - eslint: bin/eslint.js - checksum: 10c0/1fd31533086c1b72f86770a4d9d7058ee8b4643fd1cfd10c7aac1ecb8725698e88352a87805cf4b2ce890aa35947df4b4da9655fb7fdfa60dbb448a43f6ebcf1 - languageName: node - linkType: hard - "eslint@npm:^9.33.0": version: 9.33.0 resolution: "eslint@npm:9.33.0" @@ -9273,17 +9207,6 @@ __metadata: languageName: node linkType: hard -"espree@npm:^9.6.0, espree@npm:^9.6.1": - version: 9.6.1 - resolution: "espree@npm:9.6.1" - dependencies: - acorn: "npm:^8.9.0" - acorn-jsx: "npm:^5.3.2" - eslint-visitor-keys: "npm:^3.4.1" - checksum: 10c0/1a2e9b4699b715347f62330bcc76aee224390c28bb02b31a3752e9d07549c473f5f986720483c6469cf3cfb3c9d05df612ffc69eb1ee94b54b739e67de9bb460 - languageName: node - linkType: hard - "esprima@npm:^4.0.0": version: 4.0.1 resolution: "esprima@npm:4.0.1" @@ -9294,7 +9217,7 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.4.2, esquery@npm:^1.5.0": +"esquery@npm:^1.5.0": version: 1.6.0 resolution: "esquery@npm:1.6.0" dependencies: @@ -9714,15 +9637,6 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^6.0.1": - version: 6.0.1 - resolution: "file-entry-cache@npm:6.0.1" - dependencies: - flat-cache: "npm:^3.0.4" - checksum: 10c0/58473e8a82794d01b38e5e435f6feaf648e3f36fdb3a56e98f417f4efae71ad1c0d4ebd8a9a7c50c3ad085820a93fc7494ad721e0e4ebc1da3573f4e1c3c7cdd - languageName: node - linkType: hard - "file-entry-cache@npm:^8.0.0": version: 8.0.0 resolution: "file-entry-cache@npm:8.0.0" @@ -9832,17 +9746,6 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^3.0.4": - version: 3.2.0 - resolution: "flat-cache@npm:3.2.0" - dependencies: - flatted: "npm:^3.2.9" - keyv: "npm:^4.5.3" - rimraf: "npm:^3.0.2" - checksum: 10c0/b76f611bd5f5d68f7ae632e3ae503e678d205cf97a17c6ab5b12f6ca61188b5f1f7464503efae6dc18683ed8f0b41460beb48ac4b9ac63fe6201296a91ba2f75 - languageName: node - linkType: hard - "flat-cache@npm:^4.0.0": version: 4.0.1 resolution: "flat-cache@npm:4.0.1" @@ -10054,21 +9957,21 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.2, get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7": - version: 1.2.7 - resolution: "get-intrinsic@npm:1.2.7" +"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.2, get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7, get-intrinsic@npm:^1.3.0": + version: 1.3.0 + resolution: "get-intrinsic@npm:1.3.0" dependencies: - call-bind-apply-helpers: "npm:^1.0.1" + call-bind-apply-helpers: "npm:^1.0.2" es-define-property: "npm:^1.0.1" es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" + es-object-atoms: "npm:^1.1.1" function-bind: "npm:^1.1.2" - get-proto: "npm:^1.0.0" + get-proto: "npm:^1.0.1" gopd: "npm:^1.2.0" has-symbols: "npm:^1.1.0" hasown: "npm:^2.0.2" math-intrinsics: "npm:^1.1.0" - checksum: 10c0/b475dec9f8bff6f7422f51ff4b7b8d0b68e6776ee83a753c1d627e3008c3442090992788038b37eff72e93e43dceed8c1acbdf2d6751672687ec22127933080d + checksum: 10c0/52c81808af9a8130f581e6a6a83e1ba4a9f703359e7a438d1369a5267a25412322f03dcbd7c549edaef0b6214a0630a28511d7df0130c93cfd380f4fa0b5b66a languageName: node linkType: hard @@ -10250,15 +10153,6 @@ __metadata: languageName: node linkType: hard -"globals@npm:^13.19.0": - version: 13.24.0 - resolution: "globals@npm:13.24.0" - dependencies: - type-fest: "npm:^0.20.2" - checksum: 10c0/d3c11aeea898eb83d5ec7a99508600fbe8f83d2cf00cbb77f873dbf2bcb39428eff1b538e4915c993d8a3b3473fa71eeebfe22c9bb3a3003d1e26b1f2c8a42cd - languageName: node - linkType: hard - "globals@npm:^14.0.0": version: 14.0.0 resolution: "globals@npm:14.0.0" @@ -11611,7 +11505,7 @@ __metadata: languageName: node linkType: hard -"is-path-inside@npm:^3.0.2, is-path-inside@npm:^3.0.3": +"is-path-inside@npm:^3.0.2": version: 3.0.3 resolution: "is-path-inside@npm:3.0.3" checksum: 10c0/cf7d4ac35fb96bab6a1d2c3598fe5ebb29aafb52c0aaa482b5a3ed9d8ba3edc11631e3ec2637660c44b3ce0e61a08d54946e8af30dec0b60a7c27296c68ffd05 @@ -14899,7 +14793,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:3.1.2, minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": +"minimatch@npm:3.1.2, minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -15499,14 +15393,15 @@ __metadata: languageName: node linkType: hard -"object.entries@npm:^1.1.8": - version: 1.1.8 - resolution: "object.entries@npm:1.1.8" +"object.entries@npm:^1.1.9": + version: 1.1.9 + resolution: "object.entries@npm:1.1.9" dependencies: - call-bind: "npm:^1.0.7" + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10c0/db9ea979d2956a3bc26c262da4a4d212d36f374652cc4c13efdd069c1a519c16571c137e2893d1c46e1cb0e15c88fd6419eaf410c945f329f09835487d7e65d3 + es-object-atoms: "npm:^1.1.1" + checksum: 10c0/d4b8c1e586650407da03370845f029aa14076caca4e4d4afadbc69cfb5b78035fd3ee7be417141abdb0258fa142e59b11923b4c44d8b1255b28f5ffcc50da7db languageName: node linkType: hard @@ -17447,7 +17342,6 @@ __metadata: "@docusaurus/preset-classic": "npm:3.8.1" "@docusaurus/tsconfig": "npm:3.8.1" "@docusaurus/types": "npm:3.8.1" - "@react-native-website/lint-examples": "npm:0.0.0" "@types/fs-extra": "npm:^11.0.4" "@types/google.analytics": "npm:^0.0.46" "@types/react": "npm:^19.1.10" @@ -19901,13 +19795,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.20.2": - version: 0.20.2 - resolution: "type-fest@npm:0.20.2" - checksum: 10c0/dea9df45ea1f0aaa4e2d3bed3f9a0bfe9e5b2592bddb92eb1bf06e50bcf98dbb78189668cd8bc31a0511d3fc25539b4cd5c704497e53e93e2d40ca764b10bfc3 - languageName: node - linkType: hard - "type-fest@npm:^0.21.3": version: 0.21.3 resolution: "type-fest@npm:0.21.3" From 08113805ed4934890a7f4a1e280916ec8b2d0351 Mon Sep 17 00:00:00 2001 From: Simek Date: Mon, 25 Aug 2025 13:51:58 +0200 Subject: [PATCH 03/12] small tweaks, attempt to fix missing bin on CI --- .alexrc.js => .alexrc.cjs | 18 +++++++++--------- .github/workflows/pre-merge.yml | 1 - eslint.config.js | 2 +- .../lint-examples/bin/eslint-examples-jsx.js | 2 ++ .../lint-examples/bin/eslint-examples-tsx.js | 2 ++ packages/lint-examples/bin/tsc-examples.js | 2 ++ website/package.json | 4 ++-- 7 files changed, 18 insertions(+), 13 deletions(-) rename .alexrc.js => .alexrc.cjs (87%) diff --git a/.alexrc.js b/.alexrc.cjs similarity index 87% rename from .alexrc.js rename to .alexrc.cjs index 7e48e42440a..58d63eb5715 100644 --- a/.alexrc.js +++ b/.alexrc.cjs @@ -8,29 +8,29 @@ exports.allow = [ // We frequently refer to form props by their name "disabled". // Ideally we would alex-ignore only the valid uses (PRs accepted). - 'invalid', + "invalid", // Unfortunately "watchman" is a library name that we depend on. - 'watchman-watchwoman', + "watchman-watchwoman", // ignore rehab rule, Detox is an e2e testing library - 'rehab', + "rehab", // host refers to host objects in native code - 'host-hostess', + "host-hostess", // allowing this term to prevent reporting "primitive", which is a programming term - 'savage', + "savage", // allowing this term, since it seems to be used not in insensitive cases - 'straightforward', + "straightforward", // allowing those terms, since they refer to colors and the surname of one of core contributors - 'black', - 'white', + "black", + "white", // allowing this term, since we use it for expressing gratitude for certain contributors - 'special', + "special", ]; // Use a "maybe" level of profanity instead of the default "unlikely". diff --git a/.github/workflows/pre-merge.yml b/.github/workflows/pre-merge.yml index a6afd5bab5a..81567e5d2f7 100644 --- a/.github/workflows/pre-merge.yml +++ b/.github/workflows/pre-merge.yml @@ -32,7 +32,6 @@ jobs: - name: Run Lint run: yarn ci:lint - working-directory: website build: runs-on: ubuntu-latest diff --git a/eslint.config.js b/eslint.config.js index ec594fe9d50..25d46682cc5 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -45,7 +45,7 @@ export default defineConfig([ }, { - files: ['**/*.{js,mjs}'], + files: ['**/*.{js,mjs,cjs}'], ...eslintJs.configs.recommended, rules: { 'no-unused-vars': 'off', diff --git a/packages/lint-examples/bin/eslint-examples-jsx.js b/packages/lint-examples/bin/eslint-examples-jsx.js index 9f6636124ae..3df984ac595 100755 --- a/packages/lint-examples/bin/eslint-examples-jsx.js +++ b/packages/lint-examples/bin/eslint-examples-jsx.js @@ -10,6 +10,8 @@ import lintExamples from '../src/lintExamples.js'; +console.log('Linting JSX docs code examples...'); + lintExamples({ command: 'eslint', args: ['--max-warnings=0', '.'], diff --git a/packages/lint-examples/bin/eslint-examples-tsx.js b/packages/lint-examples/bin/eslint-examples-tsx.js index f89540cbaf4..628367a2fab 100755 --- a/packages/lint-examples/bin/eslint-examples-tsx.js +++ b/packages/lint-examples/bin/eslint-examples-tsx.js @@ -10,6 +10,8 @@ import lintExamples from '../src/lintExamples.js'; +console.log('Linting TSX docs code examples...'); + lintExamples({ command: 'eslint', args: ['--max-warnings=0', '.'], diff --git a/packages/lint-examples/bin/tsc-examples.js b/packages/lint-examples/bin/tsc-examples.js index 097eda4f773..fee57d0e582 100755 --- a/packages/lint-examples/bin/tsc-examples.js +++ b/packages/lint-examples/bin/tsc-examples.js @@ -10,6 +10,8 @@ import lintExamples from '../src/lintExamples.js'; +console.log('Typechecking TSX docs code examples...'); + lintExamples({ command: 'tsc', extension: 'tsx', diff --git a/website/package.json b/website/package.json index dc37462d277..5e3b19ec275 100644 --- a/website/package.json +++ b/website/package.json @@ -21,7 +21,7 @@ "clear": "docusaurus clear", "test": "yarn build", "version:cut": "docusaurus docs:version", - "format:style": "prettier --write src/**/*.{scss}", + "format:style": "prettier --write src/**/*.scss", "format:examples": "eslint-examples-jsx --fix && eslint-examples-tsx --fix", "prettier": "yarn format:style", "lint": "eslint .", @@ -30,7 +30,7 @@ "lint:markdown:versioned": "remark ./versioned_docs --quiet -r .remarkrc.mjs", "language:lint": "cd ../ && alex && case-police 'docs/*.md' -d ./website/react-native-dict.json --disable SDK,URI", "language:lint:versioned": "cd ../ && alex . && case-police '**/*.md' -d ./website/react-native-dict.json --disable SDK,URI", - "ci:lint": "yarn lint && yarn lint:examples && yarn language:lint:versioned && yarn lint:markdown && prettier --check src/**/*.{scss}", + "ci:lint": "yarn lint && yarn lint:examples && yarn language:lint:versioned && yarn lint:markdown && prettier --check src/**/*.scss", "pwa:generate": "npx pwa-asset-generator ./static/img/header_logo.svg ./static/img/pwa --padding '40px' --background 'rgb(32, 35, 42)' --icon-only --opaque true", "generate-llms-txt": "node ../scripts/generate-llms-txt.js" }, From 25392e977b32a32f7e8dbc7eb21074076dd530ea Mon Sep 17 00:00:00 2001 From: Simek Date: Mon, 25 Aug 2025 14:03:20 +0200 Subject: [PATCH 04/12] add debug CI bins step --- .github/workflows/pre-merge.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/pre-merge.yml b/.github/workflows/pre-merge.yml index 81567e5d2f7..60af19256e3 100644 --- a/.github/workflows/pre-merge.yml +++ b/.github/workflows/pre-merge.yml @@ -30,6 +30,22 @@ jobs: - name: Check dependencies alignment run: yarn check-dependencies + - name: "[TEMP] Debug bins" + run: | + yarn workspaces foreach \ + --all \ + --parallel \ + --topological \ + exec sh -c ' + test -f package.json || exit 0 + jq -r " + .bin? + | to_entries[] + | \"\(.key) → \(.value)\" + " package.json \ + | sed "s|^|$(pwd)/|" + ' + - name: Run Lint run: yarn ci:lint From 6d68b4278e11223c090c33d4bfb5e675961d0b53 Mon Sep 17 00:00:00 2001 From: Simek Date: Mon, 25 Aug 2025 14:07:25 +0200 Subject: [PATCH 05/12] remove debug CI bins step, temporarily ignore cache --- .github/workflows/pre-merge.yml | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/.github/workflows/pre-merge.yml b/.github/workflows/pre-merge.yml index 60af19256e3..de2b839d9b5 100644 --- a/.github/workflows/pre-merge.yml +++ b/.github/workflows/pre-merge.yml @@ -19,7 +19,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: "20" - cache: yarn + # cache: yarn - name: Check lock for duplications run: yarn dedupe --check @@ -30,22 +30,6 @@ jobs: - name: Check dependencies alignment run: yarn check-dependencies - - name: "[TEMP] Debug bins" - run: | - yarn workspaces foreach \ - --all \ - --parallel \ - --topological \ - exec sh -c ' - test -f package.json || exit 0 - jq -r " - .bin? - | to_entries[] - | \"\(.key) → \(.value)\" - " package.json \ - | sed "s|^|$(pwd)/|" - ' - - name: Run Lint run: yarn ci:lint From 9cad0c8fda5270b7aff5b0e2d2a70965b974e30e Mon Sep 17 00:00:00 2001 From: Simek Date: Mon, 25 Aug 2025 14:11:09 +0200 Subject: [PATCH 06/12] check if other bins are detected correctly --- .github/workflows/pre-merge.yml | 2 +- website/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pre-merge.yml b/.github/workflows/pre-merge.yml index de2b839d9b5..81567e5d2f7 100644 --- a/.github/workflows/pre-merge.yml +++ b/.github/workflows/pre-merge.yml @@ -19,7 +19,7 @@ jobs: uses: actions/setup-node@v4 with: node-version: "20" - # cache: yarn + cache: yarn - name: Check lock for duplications run: yarn dedupe --check diff --git a/website/package.json b/website/package.json index 5e3b19ec275..40675439d40 100644 --- a/website/package.json +++ b/website/package.json @@ -25,7 +25,7 @@ "format:examples": "eslint-examples-jsx --fix && eslint-examples-tsx --fix", "prettier": "yarn format:style", "lint": "eslint .", - "lint:examples": "eslint-examples-jsx && eslint-examples-tsx && tsc-examples", + "lint:examples": "eslint-examples-tsx && tsc-examples", "lint:markdown": "remark ../docs --quiet -r .remarkrc.mjs", "lint:markdown:versioned": "remark ./versioned_docs --quiet -r .remarkrc.mjs", "language:lint": "cd ../ && alex && case-police 'docs/*.md' -d ./website/react-native-dict.json --disable SDK,URI", From a57312e2828165a530156459f0809481bbc588d1 Mon Sep 17 00:00:00 2001 From: Simek Date: Mon, 25 Aug 2025 14:20:53 +0200 Subject: [PATCH 07/12] try workspace commands --- website/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/package.json b/website/package.json index 40675439d40..8e53f164689 100644 --- a/website/package.json +++ b/website/package.json @@ -22,10 +22,10 @@ "test": "yarn build", "version:cut": "docusaurus docs:version", "format:style": "prettier --write src/**/*.scss", - "format:examples": "eslint-examples-jsx --fix && eslint-examples-tsx --fix", + "format:examples": "yarn workspace @react-native-website/lint-examples eslint-examples-jsx --fix && yarn workspace @react-native-website/lint-examples eslint-examples-tsx --fix", "prettier": "yarn format:style", "lint": "eslint .", - "lint:examples": "eslint-examples-tsx && tsc-examples", + "lint:examples": "yarn workspace @react-native-website/lint-examples eslint-examples-jsx && yarn workspace @react-native-website/lint-examples eslint-examples-tsx && yarn workspace @react-native-website/lint-examples tsc-examples", "lint:markdown": "remark ../docs --quiet -r .remarkrc.mjs", "lint:markdown:versioned": "remark ./versioned_docs --quiet -r .remarkrc.mjs", "language:lint": "cd ../ && alex && case-police 'docs/*.md' -d ./website/react-native-dict.json --disable SDK,URI", From 0d0cf63be0c877992838ed0ead0853d07d9cbeb2 Mon Sep 17 00:00:00 2001 From: Simek Date: Tue, 26 Aug 2025 11:49:02 +0200 Subject: [PATCH 08/12] fix image check script, fix remark Snack plugin tests, tweaks --- .alexrc.cjs | 18 +++--- .prettierrc.json | 2 +- .../package.json | 2 +- plugins/remark-lint-no-dead-urls/package.json | 2 +- plugins/remark-snackplayer/package.json | 4 +- plugins/remark-snackplayer/src/index.js | 6 +- plugins/remark-snackplayer/tests/index.js | 39 ++++++------ .../tests/output/output1.html | 8 +-- .../tests/output/output2.html | 17 +++-- scripts/image-check.js | 62 +++++++++++++++++++ website/docusaurus.config.ts | 2 +- website/image-check.js | 60 ------------------ website/package.json | 10 +-- website/tsconfig.json | 3 +- yarn.lock | 27 ++------ 15 files changed, 121 insertions(+), 141 deletions(-) create mode 100644 scripts/image-check.js delete mode 100644 website/image-check.js diff --git a/.alexrc.cjs b/.alexrc.cjs index 58d63eb5715..7e48e42440a 100644 --- a/.alexrc.cjs +++ b/.alexrc.cjs @@ -8,29 +8,29 @@ exports.allow = [ // We frequently refer to form props by their name "disabled". // Ideally we would alex-ignore only the valid uses (PRs accepted). - "invalid", + 'invalid', // Unfortunately "watchman" is a library name that we depend on. - "watchman-watchwoman", + 'watchman-watchwoman', // ignore rehab rule, Detox is an e2e testing library - "rehab", + 'rehab', // host refers to host objects in native code - "host-hostess", + 'host-hostess', // allowing this term to prevent reporting "primitive", which is a programming term - "savage", + 'savage', // allowing this term, since it seems to be used not in insensitive cases - "straightforward", + 'straightforward', // allowing those terms, since they refer to colors and the surname of one of core contributors - "black", - "white", + 'black', + 'white', // allowing this term, since we use it for expressing gratitude for certain contributors - "special", + 'special', ]; // Use a "maybe" level of profanity instead of the default "unlikely". diff --git a/.prettierrc.json b/.prettierrc.json index d854bba2731..60675266573 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,7 +1,7 @@ { "overrides": [ { - "files": ["*.js", "*.jsx", "*.ts", "*.tsx"], + "files": ["*.js", "*.mjs", "*.cjs", "*.jsx", "*.ts", "*.tsx"], "options": { "arrowParens": "avoid", "bracketSpacing": false, diff --git a/plugins/remark-codeblock-language-as-title/package.json b/plugins/remark-codeblock-language-as-title/package.json index be91cf33673..945996c07b7 100644 --- a/plugins/remark-codeblock-language-as-title/package.json +++ b/plugins/remark-codeblock-language-as-title/package.json @@ -14,7 +14,7 @@ "src/*" ], "scripts": { - "prettier": "prettier --write '{src}/**/*.{md,js,jsx,ts,tsx}'" + "lint": "eslint ." }, "dependencies": { "unist-util-visit": "^5.0.0" diff --git a/plugins/remark-lint-no-dead-urls/package.json b/plugins/remark-lint-no-dead-urls/package.json index 14422d17861..11571c0b29a 100644 --- a/plugins/remark-lint-no-dead-urls/package.json +++ b/plugins/remark-lint-no-dead-urls/package.json @@ -14,7 +14,7 @@ "src/*" ], "scripts": { - "prettier": "prettier --write '{src,tests}/**/*.{md,js,jsx,ts,tsx}'", + "lint": "eslint .", "test": "yarn node --experimental-vm-modules $(yarn bin jest)" }, "dependencies": { diff --git a/plugins/remark-snackplayer/package.json b/plugins/remark-snackplayer/package.json index ea8b2175401..dae3772a351 100644 --- a/plugins/remark-snackplayer/package.json +++ b/plugins/remark-snackplayer/package.json @@ -4,6 +4,7 @@ "private": true, "description": "Remark Expo Snack Plugin", "main": "src/index.js", + "type": "module", "keywords": [ "remark", "react-native", @@ -15,7 +16,7 @@ "src" ], "scripts": { - "prettier": "prettier --write '{src,tests}/**/*.{md,js,jsx,ts,tsx}'", + "lint": "eslint .", "test": "yarn tape tests/index.js" }, "dependencies": { @@ -25,6 +26,7 @@ }, "devDependencies": { "remark": "^15.0.1", + "remark-mdx": "^3.1.0", "tape": "^5.7.0" } } diff --git a/plugins/remark-snackplayer/src/index.js b/plugins/remark-snackplayer/src/index.js index 507e5329faa..ae472996534 100644 --- a/plugins/remark-snackplayer/src/index.js +++ b/plugins/remark-snackplayer/src/index.js @@ -82,7 +82,7 @@ async function toJsxNode(node) { Object.keys(jsxNode).forEach(key => (node[key] = jsxNode[key])); } -const SnackPlayer = () => { +export default function SnackPlayer() { return async tree => { const nodesToProcess = []; visit(tree, 'code', (node, parent) => { @@ -92,6 +92,4 @@ const SnackPlayer = () => { }); await Promise.all(nodesToProcess); }; -}; - -module.exports = SnackPlayer; +} diff --git a/plugins/remark-snackplayer/tests/index.js b/plugins/remark-snackplayer/tests/index.js index 64d77e96da3..9db6faac712 100644 --- a/plugins/remark-snackplayer/tests/index.js +++ b/plugins/remark-snackplayer/tests/index.js @@ -7,31 +7,28 @@ import path from 'node:path'; import fs from 'node:fs'; +import {remark} from 'remark'; +import remarkMdx from 'remark-mdx'; import test from 'tape'; -import snackplayer from '../'; -const read = name => fs.readFileSync(path.join(__dirname, name), 'utf8'); -const normalizeLineEndings = str => str.replace(/\r\n/g, '\n'); +import SnackPlayer from '../src/index.js'; + +function read(name) { + return fs.readFileSync(path.join(import.meta.dirname, name), 'utf8'); +} test('remark-snackplayer', async t => { - const {remark} = await import('remark'); - const processor = remark().use(snackplayer); + const processor = remark().use(remarkMdx).use(SnackPlayer); + + const in1 = read('markdown/test1.md'); + const out1 = read('output/output1.html'); + const file1 = await processor.process(in1); + t.equal(String(file1), out1, 'With 1 Code Block'); - processor.process(read('markdown/test1.md'), (err, file) => { - if (err) t.fail('Failed to process markdown/test1.md'); - t.equal( - normalizeLineEndings(String(file)), - normalizeLineEndings(read('output/output1.html')), - 'With 1 Code Block' - ); - }); + const in2 = read('markdown/test2.md'); + const out2 = read('output/output2.html'); + const file2 = await processor.process(in2); + t.equal(String(file2), out2, 'With 2 Code Blocks'); - processor.process(read('markdown/test2.md'), (err, file) => { - if (err) t.fail('Failed to process markdown/test2.md'); - t.equal( - normalizeLineEndings(String(file)), - normalizeLineEndings(read('output/output2.html')), - 'With 2 Code Blocks' - ); - }); + t.end(); }); diff --git a/plugins/remark-snackplayer/tests/output/output1.html b/plugins/remark-snackplayer/tests/output/output1.html index 0b1c9d2b2ed..35faf9ece21 100644 --- a/plugins/remark-snackplayer/tests/output/output1.html +++ b/plugins/remark-snackplayer/tests/output/output1.html @@ -1,13 +1,13 @@
+/> diff --git a/plugins/remark-snackplayer/tests/output/output2.html b/plugins/remark-snackplayer/tests/output/output2.html index ba715f1a402..b0c485b813d 100644 --- a/plugins/remark-snackplayer/tests/output/output2.html +++ b/plugins/remark-snackplayer/tests/output/output2.html @@ -1,27 +1,26 @@
- +/>
+/> diff --git a/scripts/image-check.js b/scripts/image-check.js new file mode 100644 index 00000000000..cf72d36c8e7 --- /dev/null +++ b/scripts/image-check.js @@ -0,0 +1,62 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {glob} from 'glob'; +import fs from 'node:fs/promises'; +import path from 'node:path'; + +const imageReferenceRegExp = new RegExp(/!\[.*?\]\((.*)\)/g); + +async function main() { + const assets = []; + const missingAssets = []; + const queue = []; + + const files = await glob('../docs/**/*.md', {}); + + for (const file of files) { + const entry = (async () => { + const buffer = await fs.readFile(file); + const contents = buffer.toString('utf-8'); + let match; + while ((match = imageReferenceRegExp.exec(contents))) { + const rawPath = match[1].replace(/^\//, ''); + const imagePath = path.join('./', rawPath); + assets.push({imagePath, markdownPath: file}); + } + })(); + queue.push(entry); + } + + await Promise.all(queue); + + for (const {imagePath, markdownPath} of assets) { + try { + await fs.stat( + path.join(import.meta.dirname, '../website/static', imagePath) + ); + } catch { + missingAssets.push({imagePath, markdownPath}); + } + } + + if (missingAssets.length > 0) { + console.error('Found missing assets!'); + missingAssets.forEach(({imagePath, markdownPath}) => { + console.error( + `Could not find static/${imagePath} which has at least one ` + + `reference in ${markdownPath}. ` + + `Did you forget to add the asset to '/website/static/docs/assets'?` + ); + }); + } +} + +main().catch(err => { + console.error('Unhandled error:', err); + process.exit(1); +}); diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index d0c77daf5ad..e5c7adab75d 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -508,4 +508,4 @@ const config: Config = { } satisfies Preset.ThemeConfig, }; -module.exports = config; +export default config; diff --git a/website/image-check.js b/website/image-check.js deleted file mode 100644 index ff689984eb5..00000000000 --- a/website/image-check.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import glob from 'glob'; -import fs from 'fs-extra'; -import path from 'path'; - -import siteConfig from './docusaurus.config.js'; - -const imageReferenceRegExp = new RegExp(/!\[.*?\]\((.*)\)/g); - -const missingAssets = []; -let queue = Promise.resolve(); - -glob - .glob('./docs/**/*.md') - .then(files => { - files.forEach(file => { - queue = queue - .then(() => { - return fs.readFile(file); - }) - .then(contents => { - let matches; - while ((matches = imageReferenceRegExp.exec(contents))) { - const pathToFile = path.join( - './', - matches[1].replace(siteConfig.baseUrl, '') - ); - missingAssets.push({imagePath: pathToFile, markdownPath: file}); - } - }); - }); - return queue; - }) - .then(() => { - queue = Promise.resolve(); - missingAssets.forEach(missingAsset => { - const {imagePath, markdownPath} = missingAsset; - queue = queue - .then(() => { - return fs.stat('./static/' + imagePath); - }) - .catch(() => { - console.error( - 'Could not find ' + - 'static/' + - imagePath + - ' which has at least one reference in ' + - markdownPath + - ". Did you forget to add the asset to '/static/docs/assets'?" - ); - }); - }); - return queue; - }); diff --git a/website/package.json b/website/package.json index 8e53f164689..4f7aa4f8036 100644 --- a/website/package.json +++ b/website/package.json @@ -22,17 +22,18 @@ "test": "yarn build", "version:cut": "docusaurus docs:version", "format:style": "prettier --write src/**/*.scss", - "format:examples": "yarn workspace @react-native-website/lint-examples eslint-examples-jsx --fix && yarn workspace @react-native-website/lint-examples eslint-examples-tsx --fix", + "format:examples": "eslint-examples-jsx --fix && eslint-examples-tsx --fix", "prettier": "yarn format:style", "lint": "eslint .", - "lint:examples": "yarn workspace @react-native-website/lint-examples eslint-examples-jsx && yarn workspace @react-native-website/lint-examples eslint-examples-tsx && yarn workspace @react-native-website/lint-examples tsc-examples", + "lint:examples": "eslint-examples-jsx && eslint-examples-tsx && tsc-examples", "lint:markdown": "remark ../docs --quiet -r .remarkrc.mjs", "lint:markdown:versioned": "remark ./versioned_docs --quiet -r .remarkrc.mjs", "language:lint": "cd ../ && alex && case-police 'docs/*.md' -d ./website/react-native-dict.json --disable SDK,URI", "language:lint:versioned": "cd ../ && alex . && case-police '**/*.md' -d ./website/react-native-dict.json --disable SDK,URI", "ci:lint": "yarn lint && yarn lint:examples && yarn language:lint:versioned && yarn lint:markdown && prettier --check src/**/*.scss", "pwa:generate": "npx pwa-asset-generator ./static/img/header_logo.svg ./static/img/pwa --padding '40px' --background 'rgb(32, 35, 42)' --icon-only --opaque true", - "generate-llms-txt": "node ../scripts/generate-llms-txt.js" + "generate-llms-txt": "node ../scripts/generate-llms-txt.js", + "image-check": "node ../scripts/image-check.js" }, "browserslist": { "production": [ @@ -62,13 +63,12 @@ "@docusaurus/module-type-aliases": "3.8.1", "@docusaurus/tsconfig": "3.8.1", "@docusaurus/types": "3.8.1", - "@types/fs-extra": "^11.0.4", + "@react-native-website/lint-examples": "*", "@types/google.analytics": "^0.0.46", "@types/react": "^19.1.10", "alex": "^11.0.1", "case-police": "^1.0.0", "eslint": "^9.33.0", - "fs-extra": "^11.3.1", "glob": "^11.0.0", "prettier": "^3.6.2", "remark-cli": "^12.0.1", diff --git a/website/tsconfig.json b/website/tsconfig.json index 5503c1ec3a1..bc60642a7c8 100644 --- a/website/tsconfig.json +++ b/website/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "@docusaurus/tsconfig", "compilerOptions": { - "baseUrl": "." + "baseUrl": ".", + "allowImportingTsExtensions": true }, "exclude": ["node_modules", "build"] } diff --git a/yarn.lock b/yarn.lock index 792ac0dc8ff..09df54c473d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3899,7 +3899,7 @@ __metadata: languageName: node linkType: hard -"@react-native-website/lint-examples@workspace:packages/lint-examples": +"@react-native-website/lint-examples@npm:*, @react-native-website/lint-examples@workspace:packages/lint-examples": version: 0.0.0-use.local resolution: "@react-native-website/lint-examples@workspace:packages/lint-examples" dependencies: @@ -3959,6 +3959,7 @@ __metadata: dedent: "npm:^1.5.3" object.fromentries: "npm:^2.0.3" remark: "npm:^15.0.1" + remark-mdx: "npm:^3.1.0" tape: "npm:^5.7.0" unist-util-visit-parents: "npm:^3.1.1" languageName: unknown @@ -5116,16 +5117,6 @@ __metadata: languageName: node linkType: hard -"@types/fs-extra@npm:^11.0.4": - version: 11.0.4 - resolution: "@types/fs-extra@npm:11.0.4" - dependencies: - "@types/jsonfile": "npm:*" - "@types/node": "npm:*" - checksum: 10c0/9e34f9b24ea464f3c0b18c3f8a82aefc36dc524cc720fc2b886e5465abc66486ff4e439ea3fb2c0acebf91f6d3f74e514f9983b1f02d4243706bdbb7511796ad - languageName: node - linkType: hard - "@types/google.analytics@npm:^0.0.46": version: 0.0.46 resolution: "@types/google.analytics@npm:0.0.46" @@ -5243,15 +5234,6 @@ __metadata: languageName: node linkType: hard -"@types/jsonfile@npm:*": - version: 6.1.4 - resolution: "@types/jsonfile@npm:6.1.4" - dependencies: - "@types/node": "npm:*" - checksum: 10c0/b12d068b021e4078f6ac4441353965769be87acf15326173e2aea9f3bf8ead41bd0ad29421df5bbeb0123ec3fc02eb0a734481d52903704a1454a1845896b9eb - languageName: node - linkType: hard - "@types/mdast@npm:^3.0.0": version: 3.0.15 resolution: "@types/mdast@npm:3.0.15" @@ -9850,7 +9832,7 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^11.1.1, fs-extra@npm:^11.2.0, fs-extra@npm:^11.3.1": +"fs-extra@npm:^11.1.1, fs-extra@npm:^11.2.0": version: 11.3.1 resolution: "fs-extra@npm:11.3.1" dependencies: @@ -17315,6 +17297,7 @@ __metadata: "@eslint/css": "npm:^0.10.0" "@eslint/js": "npm:^9.33.0" "@manypkg/cli": "npm:^0.25.0" + "@react-native-website/lint-examples": "npm:*" "@typescript-eslint/parser": "npm:^8.40.0" eslint: "npm:^9.33.0" eslint-config-prettier: "npm:^10.1.8" @@ -17342,14 +17325,12 @@ __metadata: "@docusaurus/preset-classic": "npm:3.8.1" "@docusaurus/tsconfig": "npm:3.8.1" "@docusaurus/types": "npm:3.8.1" - "@types/fs-extra": "npm:^11.0.4" "@types/google.analytics": "npm:^0.0.46" "@types/react": "npm:^19.1.10" alex: "npm:^11.0.1" case-police: "npm:^1.0.0" docusaurus-plugin-sass: "npm:^0.2.6" eslint: "npm:^9.33.0" - fs-extra: "npm:^11.3.1" glob: "npm:^11.0.0" prettier: "npm:^3.6.2" react: "npm:^19.1.1" From 29cd4a65906e9b016d1dc8969bcc2065538a4fa4 Mon Sep 17 00:00:00 2001 From: Simek Date: Tue, 26 Aug 2025 11:51:05 +0200 Subject: [PATCH 09/12] update lock --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 09df54c473d..aca317dd536 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17297,7 +17297,6 @@ __metadata: "@eslint/css": "npm:^0.10.0" "@eslint/js": "npm:^9.33.0" "@manypkg/cli": "npm:^0.25.0" - "@react-native-website/lint-examples": "npm:*" "@typescript-eslint/parser": "npm:^8.40.0" eslint: "npm:^9.33.0" eslint-config-prettier: "npm:^10.1.8" @@ -17325,6 +17324,7 @@ __metadata: "@docusaurus/preset-classic": "npm:3.8.1" "@docusaurus/tsconfig": "npm:3.8.1" "@docusaurus/types": "npm:3.8.1" + "@react-native-website/lint-examples": "npm:*" "@types/google.analytics": "npm:^0.0.46" "@types/react": "npm:^19.1.10" alex: "npm:^11.0.1" From 47a3ed830495293a60f57015d9f8c7e7c72bd0b4 Mon Sep 17 00:00:00 2001 From: Simek Date: Tue, 26 Aug 2025 13:08:54 +0200 Subject: [PATCH 10/12] fix and re-enable `remark-lint-no-broken-external-links` check for base docs --- docs/_getting-started-linux-android.md | 2 +- docs/_getting-started-macos-android.md | 2 +- docs/_getting-started-windows-android.md | 2 +- docs/integration-with-android-fragment.md | 4 ++-- docs/legacy/native-modules-android.md | 4 ++-- docs/platform.md | 2 +- docs/turbo-native-modules.md | 4 ++-- plugins/remark-lint-no-dead-urls/src/index.js | 8 ++++--- website/.remarkrc.mjs | 21 ------------------- website/.remarkrc.withBrokenLinks.mjs | 20 ++++++++++++++++++ website/package.json | 9 ++++---- website/tsconfig.json | 3 +-- 12 files changed, 40 insertions(+), 41 deletions(-) create mode 100644 website/.remarkrc.withBrokenLinks.mjs diff --git a/docs/_getting-started-linux-android.md b/docs/_getting-started-linux-android.md index 6a2a95d5f96..f617f39046a 100644 --- a/docs/_getting-started-linux-android.md +++ b/docs/_getting-started-linux-android.md @@ -18,7 +18,7 @@ Setting up your development environment can be somewhat tedious if you're new to

1. Install Android Studio

-[Download and install Android Studio](https://developer.android.com/studio/index.html). While on Android Studio installation wizard, make sure the boxes next to all of the following items are checked: +[Download and install Android Studio](https://developer.android.com/studio). While on Android Studio installation wizard, make sure the boxes next to all of the following items are checked: - `Android SDK` - `Android SDK Platform` diff --git a/docs/_getting-started-macos-android.md b/docs/_getting-started-macos-android.md index c8247927854..10354907350 100644 --- a/docs/_getting-started-macos-android.md +++ b/docs/_getting-started-macos-android.md @@ -57,7 +57,7 @@ Setting up your development environment can be somewhat tedious if you're new to

1. Install Android Studio

-[Download and install Android Studio](https://developer.android.com/studio/index.html). While on Android Studio installation wizard, make sure the boxes next to all of the following items are checked: +[Download and install Android Studio](https://developer.android.com/studio). While on Android Studio installation wizard, make sure the boxes next to all of the following items are checked: - `Android SDK` - `Android SDK Platform` diff --git a/docs/_getting-started-windows-android.md b/docs/_getting-started-windows-android.md index 7ea485b92d6..76931999263 100644 --- a/docs/_getting-started-windows-android.md +++ b/docs/_getting-started-windows-android.md @@ -30,7 +30,7 @@ Setting up your development environment can be somewhat tedious if you're new to

1. Install Android Studio

-[Download and install Android Studio](https://developer.android.com/studio/index.html). While on Android Studio installation wizard, make sure the boxes next to all of the following items are checked: +[Download and install Android Studio](https://developer.android.com/studio). While on Android Studio installation wizard, make sure the boxes next to all of the following items are checked: - `Android SDK` - `Android SDK Platform` diff --git a/docs/integration-with-android-fragment.md b/docs/integration-with-android-fragment.md index 39a3d918f66..e9c385b3eb1 100644 --- a/docs/integration-with-android-fragment.md +++ b/docs/integration-with-android-fragment.md @@ -5,13 +5,13 @@ title: Integration with an Android Fragment import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; -The guide for [Integration with Existing Apps](https://reactnative.dev/docs/integration-with-existing-apps) details how to integrate a full-screen React Native app into an existing Android app as an **Activity**. +The guide for [Integration with Existing Apps](/docs/integration-with-existing-apps) details how to integrate a full-screen React Native app into an existing Android app as an **Activity**. To use React Native components within **Fragments** in an existing app requires some additional setup. ### 1. Add React Native to your app -Follow the guide for [Integration with Existing Apps](https://reactnative.dev/docs/integration-with-existing-apps) until the end to make sure you can safely run your React Native app in a full screen Activity. +Follow the guide for [Integration with Existing Apps](/docs/integration-with-existing-apps) until the end to make sure you can safely run your React Native app in a full screen Activity. ### 2. Add a FrameLayout for the React Native Fragment diff --git a/docs/legacy/native-modules-android.md b/docs/legacy/native-modules-android.md index 19126bbe58e..562b64c651d 100644 --- a/docs/legacy/native-modules-android.md +++ b/docs/legacy/native-modules-android.md @@ -267,7 +267,7 @@ class MyAppPackage : ReactPackage { This file imports the native module you created, `CalendarModule`. It then instantiates `CalendarModule` within the `createNativeModules()` function and returns it as a list of `NativeModules` to register. If you add more native modules down the line, you can also instantiate them and add them to the list returned here. -> It is worth noting that this way of registering native modules eagerly initializes all native modules when the application starts, which adds to the startup time of an application. You can use [TurboReactPackage](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/TurboReactPackage.java) as an alternative. Instead of `createNativeModules`, which return a list of instantiated native module objects, TurboReactPackage implements a `getModule(String name, ReactApplicationContext rac)` method that creates the native module object, when required. TurboReactPackage is a bit more complicated to implement at the moment. In addition to implementing a `getModule()` method, you have to implement a `getReactModuleInfoProvider()` method, which returns a list of all the native modules the package can instantiate along with a function that instantiates them, example [here](https://github.com/facebook/react-native/blob/8ac467c51b94c82d81930b4802b2978c85539925/ReactAndroid/src/main/java/com/facebook/react/CoreModulesPackage.java#L86-L165). Again, using TurboReactPackage will allow your application to have a faster startup time, but it is currently a bit cumbersome to write. So proceed with caution if you choose to use TurboReactPackages. +> It is worth noting that this way of registering native modules eagerly initializes all native modules when the application starts, which adds to the startup time of an application. You can use [TurboReactPackage](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/TurboReactPackage.kt) as an alternative. Instead of `createNativeModules`, which return a list of instantiated native module objects, TurboReactPackage implements a `getModule(String name, ReactApplicationContext rac)` method that creates the native module object, when required. TurboReactPackage is a bit more complicated to implement at the moment. In addition to implementing a `getModule()` method, you have to implement a `getReactModuleInfoProvider()` method, which returns a list of all the native modules the package can instantiate along with a function that instantiates them, example [here](https://github.com/facebook/react-native/blob/8ac467c51b94c82d81930b4802b2978c85539925/ReactAndroid/src/main/java/com/facebook/react/CoreModulesPackage.java#L86-L165). Again, using TurboReactPackage will allow your application to have a faster startup time, but it is currently a bit cumbersome to write. So proceed with caution if you choose to use TurboReactPackages. To register the `CalendarModule` package, you must add `MyAppPackage` to the list of packages returned in ReactNativeHost's `getPackages()` method. Open up your `MainApplication.java` or `MainApplication.kt` file, which can be found in the following path: `android/app/src/main/java/com/your-app-name/`. @@ -766,7 +766,7 @@ code: String, message: String, userInfo: WritableMap, throwable: Throwable
-For more detail, you can find the `Promise.java` interface [here](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/Promise.java). If `userInfo` is not provided, ReactNative will set it to null. For the rest of the parameters React Native will use a default value. The `message` argument provides the error `message` shown at the top of an error call stack. Below is an example of the error message shown in JavaScript from the following reject call in Java/Kotlin. +For more detail, you can find the `Promise.java` interface [here](https://github.com/facebook/react-native/blob/main/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/Promise.kt). If `userInfo` is not provided, ReactNative will set it to null. For the rest of the parameters React Native will use a default value. The `message` argument provides the error `message` shown at the top of an error call stack. Below is an example of the error message shown in JavaScript from the following reject call in Java/Kotlin. Java/Kotlin reject call: diff --git a/docs/platform.md b/docs/platform.md index af8b2cccb49..833edfa2de8 100644 --- a/docs/platform.md +++ b/docs/platform.md @@ -123,7 +123,7 @@ Returns a boolean which defines if device is a TV. static isVision: boolean; ``` -Returns a boolean which defines if device is an Apple Vision. _If you are using [Apple Vision Pro (Designed for iPad)](https://developer.apple.com/documentation/visionos/checking-whether-your-app-is-compatible-with-visionos) `isVision` will be `false` but `isPad` will be `true`_ +Returns a boolean which defines if device is an Apple Vision. _If you are using [Apple Vision Pro (Designed for iPad)](https://developer.apple.com/documentation/visionos/determining-whether-to-bring-your-app-to-visionos) `isVision` will be `false` but `isPad` will be `true`_ | Type | | ------- | diff --git a/docs/turbo-native-modules.md b/docs/turbo-native-modules.md index 8493c1febca..984c5c79462 100644 --- a/docs/turbo-native-modules.md +++ b/docs/turbo-native-modules.md @@ -34,7 +34,7 @@ To make this work on mobile, we need to use Android and iOS APIs: ### 1. Declare Typed Specification -React Native provides a tool called [Codegen](/the-new-architecture/what-is-codegen.md), which takes a specification written in TypeScript or Flow and generates platform specific code for Android and iOS. The specification declares the methods and data types that will pass back and forth between your native code and the React Native JavaScript runtime. A Turbo Native Module is both your specification, the native code you write, and the Codegen interfaces generated from your specification. +React Native provides a tool called [Codegen](/docs/the-new-architecture/what-is-codegen), which takes a specification written in TypeScript or Flow and generates platform specific code for Android and iOS. The specification declares the methods and data types that will pass back and forth between your native code and the React Native JavaScript runtime. A Turbo Native Module is both your specification, the native code you write, and the Codegen interfaces generated from your specification. To create a specs file: @@ -42,7 +42,7 @@ To create a specs file: 2. Create a new file called `NativeLocalStorage.ts`. :::info -You can see all of the types you can use in your specification and the native types that are generated in the [Appendix](/appendix.md) documentation. +You can see all of the types you can use in your specification and the native types that are generated in the [Appendix](/docs/appendix) documentation. ::: Here is an implementation of the `localStorage` specification: diff --git a/plugins/remark-lint-no-dead-urls/src/index.js b/plugins/remark-lint-no-dead-urls/src/index.js index de41965ffe4..005a406bc96 100644 --- a/plugins/remark-lint-no-dead-urls/src/index.js +++ b/plugins/remark-lint-no-dead-urls/src/index.js @@ -5,17 +5,19 @@ * LICENSE file in the root directory of this source tree. */ +// Forked from: https://github.com/davidtheclark/remark-lint-no-dead-urls + import {URL} from 'node:url'; import {lintRule} from 'unified-lint-rule'; import {visit} from 'unist-util-visit'; -import {fetch} from './lib.js'; -// Forked from: https://github.com/davidtheclark/remark-lint-no-dead-urls +import {fetch} from './lib.js'; const linkCache = new Map(); const HTTP = { OK: 200, + FOUND: 302, NOT_FOUND: 404, TOO_MANY_REQUESTS: 429, }; @@ -99,7 +101,7 @@ async function noDeadUrls(ast, file, options = {}) { const [url, statusCode] = value; const nodes = urlToNodes.get(url) ?? []; - if (statusCode === HTTP.OK) { + if (statusCode === HTTP.OK || statusCode === HTTP.FOUND) { continue; } diff --git a/website/.remarkrc.mjs b/website/.remarkrc.mjs index 7465ea4f97b..4ed8f62dd39 100644 --- a/website/.remarkrc.mjs +++ b/website/.remarkrc.mjs @@ -1,24 +1,3 @@ -// TODO: Enable the plugin once a more performant solution is found -// import packageJson from "./package.json" assert { type: "json" }; -// -// export default { -// plugins: [ -// "@react-native-website/remark-lint-no-broken-external-links", -// { -// skipUrlPatterns: [ -// // False positive, flagged as a bot and rate limited -// "www.apkfiles.com", -// // TODO: replace the 2048 example repository with another suitable project -// "github.com/JoelMarcey", -// ], -// baseUrl: "https://reactnative.dev/docs", -// headers: { -// "user-agent": `${packageJson.name}/${packageJson.version}`, -// }, -// }, -// ], -// } - export default { plugins: [], }; diff --git a/website/.remarkrc.withBrokenLinks.mjs b/website/.remarkrc.withBrokenLinks.mjs new file mode 100644 index 00000000000..ee50dfee8f4 --- /dev/null +++ b/website/.remarkrc.withBrokenLinks.mjs @@ -0,0 +1,20 @@ +// This check is not a performant one, and can output false-positives due to rate limiting, +// hence it should be only run manually via `yarn lint:markdown:links` script locally. +export default { + plugins: [ + [ + '@react-native-website/remark-lint-no-broken-external-links', + { + skipUrlPatterns: [ + 'www.apkfiles.com', + 'thehackernews.com', + 'github.com\/facebook\/react-native\/issues', + ], + baseUrl: 'https://reactnative.dev/docs', + headers: { + 'user-agent': `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36`, + }, + }, + ], + ], +}; diff --git a/website/package.json b/website/package.json index 4f7aa4f8036..cca1bfde821 100644 --- a/website/package.json +++ b/website/package.json @@ -26,14 +26,13 @@ "prettier": "yarn format:style", "lint": "eslint .", "lint:examples": "eslint-examples-jsx && eslint-examples-tsx && tsc-examples", - "lint:markdown": "remark ../docs --quiet -r .remarkrc.mjs", - "lint:markdown:versioned": "remark ./versioned_docs --quiet -r .remarkrc.mjs", + "lint:markdown:images": "node ../scripts/image-check.js", + "lint:markdown:links": "remark ../docs --quiet -r .remarkrc.withBrokenLinks.mjs", "language:lint": "cd ../ && alex && case-police 'docs/*.md' -d ./website/react-native-dict.json --disable SDK,URI", "language:lint:versioned": "cd ../ && alex . && case-police '**/*.md' -d ./website/react-native-dict.json --disable SDK,URI", - "ci:lint": "yarn lint && yarn lint:examples && yarn language:lint:versioned && yarn lint:markdown && prettier --check src/**/*.scss", + "ci:lint": "yarn lint && yarn lint:examples && yarn language:lint:versioned && lint:markdown:images && prettier --check src/**/*.scss", "pwa:generate": "npx pwa-asset-generator ./static/img/header_logo.svg ./static/img/pwa --padding '40px' --background 'rgb(32, 35, 42)' --icon-only --opaque true", - "generate-llms-txt": "node ../scripts/generate-llms-txt.js", - "image-check": "node ../scripts/image-check.js" + "generate-llms-txt": "node ../scripts/generate-llms-txt.js" }, "browserslist": { "production": [ diff --git a/website/tsconfig.json b/website/tsconfig.json index bc60642a7c8..5503c1ec3a1 100644 --- a/website/tsconfig.json +++ b/website/tsconfig.json @@ -1,8 +1,7 @@ { "extends": "@docusaurus/tsconfig", "compilerOptions": { - "baseUrl": ".", - "allowImportingTsExtensions": true + "baseUrl": "." }, "exclude": ["node_modules", "build"] } From bd6f80f91fdcc6d92546aa4ed14f4e0cdf22c39c Mon Sep 17 00:00:00 2001 From: Simek Date: Tue, 26 Aug 2025 13:12:57 +0200 Subject: [PATCH 11/12] fix image check invocation in CI lint script --- website/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/package.json b/website/package.json index cca1bfde821..925a101412a 100644 --- a/website/package.json +++ b/website/package.json @@ -30,7 +30,7 @@ "lint:markdown:links": "remark ../docs --quiet -r .remarkrc.withBrokenLinks.mjs", "language:lint": "cd ../ && alex && case-police 'docs/*.md' -d ./website/react-native-dict.json --disable SDK,URI", "language:lint:versioned": "cd ../ && alex . && case-police '**/*.md' -d ./website/react-native-dict.json --disable SDK,URI", - "ci:lint": "yarn lint && yarn lint:examples && yarn language:lint:versioned && lint:markdown:images && prettier --check src/**/*.scss", + "ci:lint": "yarn lint && yarn lint:examples && yarn language:lint:versioned && yarn lint:markdown:images && prettier --check src/**/*.scss", "pwa:generate": "npx pwa-asset-generator ./static/img/header_logo.svg ./static/img/pwa --padding '40px' --background 'rgb(32, 35, 42)' --icon-only --opaque true", "generate-llms-txt": "node ../scripts/generate-llms-txt.js" }, From 710da9ef7c49b023d189092d335e79d2b3be9ea5 Mon Sep 17 00:00:00 2001 From: Simek Date: Thu, 28 Aug 2025 11:10:42 +0200 Subject: [PATCH 12/12] revert JSX ext change in Snack params, it breaks the entry point --- docs/animations.md | 2 +- docs/checkbox.md | 2 +- docs/drawerlayoutandroid.md | 2 +- docs/easing.md | 2 +- docs/flatlist.md | 4 ++-- docs/flexbox.md | 22 +++++++++---------- docs/improvingux.md | 4 ++-- docs/interactionmanager.md | 4 ++-- docs/intro-react.md | 6 ++--- docs/layout-props.md | 2 +- docs/legacy/direct-manipulation.md | 8 +++---- docs/linking.md | 8 +++---- docs/network.md | 2 +- docs/props.md | 2 +- docs/segmentedcontrolios.md | 2 +- docs/shadow-props.md | 2 +- docs/share.md | 2 +- docs/state.md | 2 +- docs/statusbar.md | 2 +- docs/text-style-props.md | 2 +- .../direct-manipulation.md | 2 +- docs/tutorial.md | 2 +- docs/virtualizedlist.md | 2 +- .../lint-examples/bin/eslint-examples-jsx.js | 2 +- packages/lint-examples/src/lintExamples.js | 4 ++-- 25 files changed, 47 insertions(+), 47 deletions(-) diff --git a/docs/animations.md b/docs/animations.md index f1b76aac66d..2703dd31323 100644 --- a/docs/animations.md +++ b/docs/animations.md @@ -20,7 +20,7 @@ For example, a container view that fades in when it is mounted may look like thi -```SnackPlayer ext=jsx +```SnackPlayer ext=js import React, {useEffect, useRef} from 'react'; import {Animated, Text, View} from 'react-native'; diff --git a/docs/checkbox.md b/docs/checkbox.md index e97c21fd32c..f9558d0f48d 100644 --- a/docs/checkbox.md +++ b/docs/checkbox.md @@ -11,7 +11,7 @@ This is a controlled component that requires an `onValueChange` callback that up ## Example -```SnackPlayer name=CheckBox%20Component%20Example&supportedPlatforms=android,web&ext=jsx +```SnackPlayer name=CheckBox%20Component%20Example&supportedPlatforms=android,web&ext=js import React, {useState} from 'react'; import {CheckBox, Text, StyleSheet, View} from 'react-native'; diff --git a/docs/drawerlayoutandroid.md b/docs/drawerlayoutandroid.md index 736f6cc8d6f..3714318df5c 100644 --- a/docs/drawerlayoutandroid.md +++ b/docs/drawerlayoutandroid.md @@ -12,7 +12,7 @@ React component that wraps the platform `DrawerLayout` (Android only). The Drawe -```SnackPlayer name=DrawerLayoutAndroid%20Component%20Example&supportedPlatforms=android&ext=jsx +```SnackPlayer name=DrawerLayoutAndroid%20Component%20Example&supportedPlatforms=android&ext=js import React, {useRef, useState} from 'react'; import {Button, DrawerLayoutAndroid, Text, StyleSheet} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; diff --git a/docs/easing.md b/docs/easing.md index 1bc08e8d55b..bb31dd0e4fa 100644 --- a/docs/easing.md +++ b/docs/easing.md @@ -48,7 +48,7 @@ The following helpers are used to modify other easing functions. -```SnackPlayer name=Easing%20Demo&ext=jsx +```SnackPlayer name=Easing%20Demo&ext=js import React, {useRef} from 'react'; import { Animated, diff --git a/docs/flatlist.md b/docs/flatlist.md index afbc2502fa1..6c299ca26bb 100644 --- a/docs/flatlist.md +++ b/docs/flatlist.md @@ -25,7 +25,7 @@ If you need section support, use [``](sectionlist.md). -```SnackPlayer name=Simple%20FlatList%20Example&ext=jsx +```SnackPlayer name=Simple%20FlatList%20Example&ext=js import React from 'react'; import {View, FlatList, StyleSheet, Text, StatusBar} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; @@ -157,7 +157,7 @@ More complex, selectable example below. -```SnackPlayer name=flatlist-selectable&ext=jsx +```SnackPlayer name=flatlist-selectable&ext=js import React, {useState} from 'react'; import { FlatList, diff --git a/docs/flexbox.md b/docs/flexbox.md index 58b4c701d60..039a7bdf60b 100644 --- a/docs/flexbox.md +++ b/docs/flexbox.md @@ -68,7 +68,7 @@ You can learn more [here](https://www.yogalayout.dev/docs/styling/flex-direction -```SnackPlayer name=Flex%20Direction&ext=jsx +```SnackPlayer name=Flex%20Direction&ext=js import React, {useState} from 'react'; import {StyleSheet, Text, TouchableOpacity, View} from 'react-native'; @@ -285,7 +285,7 @@ Layout [`direction`](layout-props#direction) specifies the direction in which ch -```SnackPlayer name=Flex%20Direction&ext=jsx +```SnackPlayer name=Flex%20Direction&ext=js import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; @@ -512,7 +512,7 @@ You can learn more [here](https://www.yogalayout.dev/docs/styling/justify-conten -```SnackPlayer name=Justify%20Content&ext=jsx +```SnackPlayer name=Justify%20Content&ext=js import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; @@ -755,7 +755,7 @@ You can learn more [here](https://www.yogalayout.dev/docs/styling/align-items-se -```SnackPlayer name=Align%20Items&ext=jsx +```SnackPlayer name=Align%20Items&ext=js import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; @@ -988,7 +988,7 @@ export default AlignItemsLayout; -```SnackPlayer name=Align%20Self&ext=jsx +```SnackPlayer name=Align%20Self&ext=js import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; @@ -1240,7 +1240,7 @@ You can learn more [here](https://www.yogalayout.dev/docs/styling/align-content) -```SnackPlayer name=Align%20Content&ext=jsx +```SnackPlayer name=Align%20Content&ext=js import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; @@ -1481,7 +1481,7 @@ When wrapping lines, `alignContent` can be used to specify how the lines are pla -```SnackPlayer name=Flex%20Wrap&ext=jsx +```SnackPlayer name=Flex%20Wrap&ext=js import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; @@ -1712,7 +1712,7 @@ You can learn more [here](https://www.yogalayout.dev/docs/styling/flex-basis-gro -```SnackPlayer name=Flex%20Basis%2C%20Grow%2C%20and%20Shrink&ext=jsx +```SnackPlayer name=Flex%20Basis%2C%20Grow%2C%20and%20Shrink&ext=js import React, {useState} from 'react'; import {View, Text, TextInput, StyleSheet} from 'react-native'; @@ -2085,7 +2085,7 @@ You can use `flexWrap` and `alignContent` along with `gap` to add consistent spa -```SnackPlayer name=Row%20Gap%20and%20Column%20Gap&ext=jsx +```SnackPlayer name=Row%20Gap%20and%20Column%20Gap&ext=js import React, {useState} from 'react'; import {View, Text, StyleSheet, TextInput} from 'react-native'; @@ -2312,7 +2312,7 @@ Both `width` and `height` can take the following values: -```SnackPlayer name=Width%20and%20Height&ext=jsx +```SnackPlayer name=Width%20and%20Height&ext=js import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; @@ -2588,7 +2588,7 @@ The `position` type of an element defines how it is positioned relative to eithe -```SnackPlayer name=Position&ext=jsx +```SnackPlayer name=Position&ext=js import React, {useState} from 'react'; import {View, TouchableOpacity, Text, StyleSheet} from 'react-native'; diff --git a/docs/improvingux.md b/docs/improvingux.md index 2f0c36a1ac6..462f5f0ce1c 100644 --- a/docs/improvingux.md +++ b/docs/improvingux.md @@ -20,7 +20,7 @@ Check out [`TextInput` docs](textinput.md) for more configuration options. -```SnackPlayer name=TextInput%20form%20example&ext=jsx +```SnackPlayer name=TextInput%20form%20example&ext=js import React, {useState, useRef} from 'react'; import { Alert, @@ -215,7 +215,7 @@ Software keyboard takes almost half of the screen. If you have interactive eleme -```SnackPlayer name=KeyboardAvoidingView%20example&ext=jsx +```SnackPlayer name=KeyboardAvoidingView%20example&ext=js import React, {useState, useRef} from 'react'; import { Alert, diff --git a/docs/interactionmanager.md b/docs/interactionmanager.md index 37b7b2de613..f9265e7db16 100644 --- a/docs/interactionmanager.md +++ b/docs/interactionmanager.md @@ -46,7 +46,7 @@ By default, queued tasks are executed together in a loop in one `setImmediate` b -```SnackPlayer name=InteractionManager%20Function%20Component%20Basic%20Example&supportedPlatforms=ios,android&ext=jsx +```SnackPlayer name=InteractionManager%20Function%20Component%20Basic%20Example&supportedPlatforms=ios,android&ext=js import React, {useEffect} from 'react'; import { Alert, @@ -219,7 +219,7 @@ export default App; -```SnackPlayer name=InteractionManager%20Function%20Component%20Advanced%20Example&supportedPlatforms=ios,android&ext=jsx +```SnackPlayer name=InteractionManager%20Function%20Component%20Advanced%20Example&supportedPlatforms=ios,android&ext=js import React, {useEffect} from 'react'; import { Alert, diff --git a/docs/intro-react.md b/docs/intro-react.md index 4072c5bcf07..8eb487be3ec 100644 --- a/docs/intro-react.md +++ b/docs/intro-react.md @@ -92,7 +92,7 @@ Any JavaScript expression will work between curly braces, including function cal -```SnackPlayer name=Curly%20Braces&ext=jsx +```SnackPlayer name=Curly%20Braces&ext=js import React from 'react'; import {Text} from 'react-native'; @@ -226,7 +226,7 @@ You can put as many cats in your cafe as you like. Each `` renders a unique -```SnackPlayer name=Multiple%20Props&ext=jsx +```SnackPlayer name=Multiple%20Props&ext=js import React from 'react'; import {Text, View} from 'react-native'; @@ -332,7 +332,7 @@ You can add state to a component by calling [React’s `useState` Hook](https:// -```SnackPlayer name=State&ext=jsx +```SnackPlayer name=State&ext=js import React, {useState} from 'react'; import {Button, Text, View} from 'react-native'; diff --git a/docs/layout-props.md b/docs/layout-props.md index a0ea61aa1ea..114ff5da96a 100644 --- a/docs/layout-props.md +++ b/docs/layout-props.md @@ -14,7 +14,7 @@ The following example shows how different properties can affect or shape a React -```SnackPlayer name=LayoutProps%20Example&ext=jsx +```SnackPlayer name=LayoutProps%20Example&ext=js import React, {useState} from 'react'; import {Button, ScrollView, StyleSheet, Text, View} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; diff --git a/docs/legacy/direct-manipulation.md b/docs/legacy/direct-manipulation.md index 5e01bf5602d..b3e7e063414 100644 --- a/docs/legacy/direct-manipulation.md +++ b/docs/legacy/direct-manipulation.md @@ -66,7 +66,7 @@ Composite components are not backed by a native view, so you cannot call `setNat -```SnackPlayer name=setNativeProps%20with%20Composite%20Components&ext=jsx +```SnackPlayer name=setNativeProps%20with%20Composite%20Components&ext=js import React from 'react'; import {Text, TouchableOpacity, View} from 'react-native'; @@ -119,7 +119,7 @@ Since the `setNativeProps` method exists on any ref to a `View` component, it is -```SnackPlayer name=Forwarding%20setNativeProps&ext=jsx +```SnackPlayer name=Forwarding%20setNativeProps&ext=js import React from 'react'; import {Text, TouchableOpacity, View} from 'react-native'; @@ -174,7 +174,7 @@ Another very common use case of `setNativeProps` is to edit the value of the Tex -```SnackPlayer name=Clear%20text&ext=jsx +```SnackPlayer name=Clear%20text&ext=js import React from 'react'; import {useCallback, useRef} from 'react'; import { @@ -319,7 +319,7 @@ This method can also be called with a `relativeToNativeNode` handler (instead of -```SnackPlayer name=measureLayout%20example&supportedPlatforms=android,ios&ext=jsx +```SnackPlayer name=measureLayout%20example&supportedPlatforms=android,ios&ext=js import React, {useEffect, useRef, useState} from 'react'; import {Text, View, StyleSheet} from 'react-native'; diff --git a/docs/linking.md b/docs/linking.md index 5b8dc53e36d..2851237295d 100644 --- a/docs/linking.md +++ b/docs/linking.md @@ -131,7 +131,7 @@ You can handle these events with `Linking.getInitialURL()` - it returns a Promis -```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=jsx +```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=js import React, {useCallback} from 'react'; import {Alert, Button, Linking, StyleSheet, View} from 'react-native'; @@ -237,7 +237,7 @@ export default App; -```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=jsx +```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=js import React, {useCallback} from 'react'; import {Button, Linking, StyleSheet, View} from 'react-native'; @@ -316,7 +316,7 @@ export default App; -```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=jsx +```SnackPlayer name=Linking%20Example&supportedPlatforms=ios,android&ext=js import React, {useState, useEffect} from 'react'; import {Linking, StyleSheet, Text, View} from 'react-native'; @@ -429,7 +429,7 @@ export default App; -```SnackPlayer name=Linking%20Example&supportedPlatforms=android&ext=jsx +```SnackPlayer name=Linking%20Example&supportedPlatforms=android&ext=js import React, {useCallback} from 'react'; import {Alert, Button, Linking, StyleSheet, View} from 'react-native'; diff --git a/docs/network.md b/docs/network.md index 5e3dea806c6..160c8e8d56f 100644 --- a/docs/network.md +++ b/docs/network.md @@ -77,7 +77,7 @@ Don't forget to catch any errors that may be thrown by `fetch`, otherwise they w -```SnackPlayer name=Fetch%20Example&ext=jsx +```SnackPlayer name=Fetch%20Example&ext=js import React, {useEffect, useState} from 'react'; import {ActivityIndicator, FlatList, Text, View} from 'react-native'; diff --git a/docs/props.md b/docs/props.md index 9eac9854e4f..490eb214632 100644 --- a/docs/props.md +++ b/docs/props.md @@ -32,7 +32,7 @@ Your own components can also use `props`. This lets you make a single component -```SnackPlayer name=Props&ext=jsx +```SnackPlayer name=Props&ext=js import React from 'react'; import {Text, View} from 'react-native'; diff --git a/docs/segmentedcontrolios.md b/docs/segmentedcontrolios.md index 0017a145fc5..eb7ec3a49d3 100644 --- a/docs/segmentedcontrolios.md +++ b/docs/segmentedcontrolios.md @@ -13,7 +13,7 @@ The selected index can be changed on the fly by assigning the selectedIndex prop ## Example -```SnackPlayer name=SegmentedControlIOS%20Example&supportedPlatforms=ios&ext=jsx +```SnackPlayer name=SegmentedControlIOS%20Example&supportedPlatforms=ios&ext=js import React, {useState} from 'react'; import {SegmentedControlIOS, StyleSheet, Text, View} from 'react-native'; diff --git a/docs/shadow-props.md b/docs/shadow-props.md index 6a323076680..d5e8a037059 100644 --- a/docs/shadow-props.md +++ b/docs/shadow-props.md @@ -8,7 +8,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con -```SnackPlayer name=Shadow%20Props&supportedPlatforms=ios&ext=jsx&dependencies=@react-native-community/slider +```SnackPlayer name=Shadow%20Props&supportedPlatforms=ios&ext=js&dependencies=@react-native-community/slider import React, {useState} from 'react'; import {Text, View, StyleSheet} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; diff --git a/docs/share.md b/docs/share.md index 16f3e0f5997..1fc5823361f 100644 --- a/docs/share.md +++ b/docs/share.md @@ -10,7 +10,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con -```SnackPlayer name=Example&supportedPlatforms=ios,android&ext=jsx +```SnackPlayer name=Example&supportedPlatforms=ios,android&ext=js import React from 'react'; import {Alert, Share, Button} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; diff --git a/docs/state.md b/docs/state.md index c021a669a37..bc162f44b40 100644 --- a/docs/state.md +++ b/docs/state.md @@ -14,7 +14,7 @@ For example, let's say we want to make text that blinks all the time. The text i -```SnackPlayer name=State&ext=jsx +```SnackPlayer name=State&ext=js import React, {useState, useEffect} from 'react'; import {Text, View} from 'react-native'; diff --git a/docs/statusbar.md b/docs/statusbar.md index 40f29aaa656..639b5c9e682 100644 --- a/docs/statusbar.md +++ b/docs/statusbar.md @@ -14,7 +14,7 @@ It is possible to have multiple `StatusBar` components mounted at the same time. -```SnackPlayer name=StatusBar%20Component%20Example&supportedPlatforms=android,ios&ext=jsx +```SnackPlayer name=StatusBar%20Component%20Example&supportedPlatforms=android,ios&ext=js import React, {useState} from 'react'; import { Button, diff --git a/docs/text-style-props.md b/docs/text-style-props.md index a0f16cd23b1..93c978a9ae7 100644 --- a/docs/text-style-props.md +++ b/docs/text-style-props.md @@ -10,7 +10,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con -```SnackPlayer name=TextStyleProps&supportedPlatforms=ios,android&ext=jsx&dependencies=@react-native-community/slider +```SnackPlayer name=TextStyleProps&supportedPlatforms=ios,android&ext=js&dependencies=@react-native-community/slider import React, {useState} from 'react'; import { FlatList, diff --git a/docs/the-new-architecture/direct-manipulation.md b/docs/the-new-architecture/direct-manipulation.md index 5bcf88656fb..6708a643cba 100644 --- a/docs/the-new-architecture/direct-manipulation.md +++ b/docs/the-new-architecture/direct-manipulation.md @@ -25,7 +25,7 @@ For example, the following code demonstrates editing the input when you tap a bu -```SnackPlayer name=setNativeProps%20on%20TextInput&ext=jsx +```SnackPlayer name=setNativeProps%20on%20TextInput&ext=js import React from 'react'; import {useCallback, useRef} from 'react'; import { diff --git a/docs/tutorial.md b/docs/tutorial.md index e28f2cfd2b7..d1a92919cd7 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -66,7 +66,7 @@ Your own components can also use `props`. This lets you make a single component -```SnackPlayer name=Hello%20Props&ext=jsx +```SnackPlayer name=Hello%20Props&ext=js import React from 'react'; import {Text, View, StyleSheet} from 'react-native'; diff --git a/docs/virtualizedlist.md b/docs/virtualizedlist.md index 349ce94b6e4..1bf19aa1806 100644 --- a/docs/virtualizedlist.md +++ b/docs/virtualizedlist.md @@ -14,7 +14,7 @@ Virtualization massively improves memory consumption and performance of large li -```SnackPlayer name=VirtualizedListExample&ext=jsx +```SnackPlayer name=VirtualizedListExample&ext=js import React from 'react'; import {View, VirtualizedList, StyleSheet, Text, StatusBar} from 'react-native'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; diff --git a/packages/lint-examples/bin/eslint-examples-jsx.js b/packages/lint-examples/bin/eslint-examples-jsx.js index 3df984ac595..803a295f41d 100755 --- a/packages/lint-examples/bin/eslint-examples-jsx.js +++ b/packages/lint-examples/bin/eslint-examples-jsx.js @@ -15,6 +15,6 @@ console.log('Linting JSX docs code examples...'); lintExamples({ command: 'eslint', args: ['--max-warnings=0', '.'], - extension: 'jsx', + extension: 'js', writeBack: true, }); diff --git a/packages/lint-examples/src/lintExamples.js b/packages/lint-examples/src/lintExamples.js index daa2e8b0d56..5adc0209a57 100755 --- a/packages/lint-examples/src/lintExamples.js +++ b/packages/lint-examples/src/lintExamples.js @@ -30,7 +30,7 @@ const processArgs = process.argv.slice(2); /** * Valid extensions for snack examples */ -const validExtensions = ['jsx', 'tsx']; +const validExtensions = ['js', 'tsx']; /** * Extracts snack examples based on extension to output files, then runs an @@ -54,7 +54,7 @@ async function lintExamples({command, args, extension, writeBack}) { } try { - const mappings = await extractExamples(extension ?? 'jsx'); + const mappings = await extractExamples(extension === 'tsx' ? 'tsx' : 'jsx'); process.exitCode = await runLinter(command, args ?? []); if (writeBack) {