Skip to content

Commit

Permalink
Merge branch 'next' of https://github.com/mui-org/material-ui into 20…
Browse files Browse the repository at this point in the history
…250_add_targetRef_to_slide_component
  • Loading branch information
benny0642 committed Aug 10, 2021
2 parents b320fd1 + f336e03 commit 7a7c0e4
Show file tree
Hide file tree
Showing 222 changed files with 1,077 additions and 777 deletions.
2 changes: 1 addition & 1 deletion .github/renovate.json
Expand Up @@ -83,7 +83,7 @@
"postUpdateOptions": ["yarnDedupeHighest"],
"prConcurrentLimit": 30,
"prHourlyLimit": 0,
"rangeStrategy": "update-lockfile",
"rangeStrategy": "bump",
"schedule": "on sunday before 6:00am",
"timezone": "UTC"
}
5 changes: 1 addition & 4 deletions docs/next.config.js
Expand Up @@ -95,10 +95,7 @@ module.exports = {
oneOf: [
{
resourceQuery: /@material-ui\/markdown/,
use: [
options.defaultLoaders.babel,
require.resolve('@material-ui/markdown/loader'),
],
use: require.resolve('@material-ui/markdown/loader'),
},
{
// used in some /getting-started/templates
Expand Down
12 changes: 6 additions & 6 deletions docs/package.json
Expand Up @@ -18,9 +18,9 @@
"typescript:transpile:dev": "echo 'Use `yarn docs:typescript'` instead && exit 1"
},
"dependencies": {
"@babel/core": "^7.10.2",
"@babel/plugin-transform-object-assign": "^7.10.1",
"@babel/runtime-corejs2": "^7.10.2",
"@babel/core": "^7.15.0",
"@babel/plugin-transform-object-assign": "^7.14.5",
"@babel/runtime-corejs2": "^7.14.8",
"@date-io/core": "^2.0.0",
"@date-io/date-fns-jalali": "^2.10.8",
"@emotion/cache": "^11.4.0",
Expand Down Expand Up @@ -52,7 +52,7 @@
"@types/react-swipeable-views-utils": "^0.13.0",
"@types/react-virtualized": "^9.21.4",
"@types/react-window": "^1.7.0",
"@types/styled-components": "5.1.11",
"@types/styled-components": "5.1.12",
"accept-language": "^3.0.18",
"address": "^1.0.3",
"ast-types": "^0.14.1",
Expand Down Expand Up @@ -120,8 +120,8 @@
"webpack-bundle-analyzer": "^4.1.0"
},
"devDependencies": {
"@babel/plugin-transform-react-constant-elements": "^7.8.3",
"@babel/preset-typescript": "^7.7.4",
"@babel/plugin-transform-react-constant-elements": "^7.14.5",
"@babel/preset-typescript": "^7.15.0",
"@types/marked": "^2.0.0",
"@types/recharts": "^2.0.0",
"cross-fetch": "^3.0.5",
Expand Down
174 changes: 96 additions & 78 deletions docs/packages/markdown/loader.js
@@ -1,6 +1,10 @@
const { promises: fs, readFileSync } = require('fs');
const { promises: fs } = require('fs');
const path = require('path');
const { notEnglishMarkdownRegExp, prepareMarkdown } = require('./parseMarkdown');
const { prepareMarkdown } = require('./parseMarkdown');

const notEnglishMarkdownRegExp = /-([a-z]{2})\.md$/;
// TODO: pass as argument
const LANGUAGES_IN_PROGRESS = ['en', 'zh', 'ru', 'pt', 'es', 'fr', 'de', 'ja'];

/**
* @param {string} string
Expand All @@ -26,110 +30,124 @@ function moduleIDToJSIdentifier(moduleID) {
}

/**
* @example findTranslatedVersions('/a/b/index.md') === ['index-en.md', 'index-ja.md', 'index.md']
* @param {string} englishFilepath An absolute path to the english version written in markdown (.md)
* @type {import('webpack').loader.Loader}
*/
async function findTranslatedVersions(englishFilepath) {
const filename = path.basename(englishFilepath, '.md');
module.exports = async function demoLoader() {
const englishFilepath = this.resourcePath;

const englishFilename = path.basename(englishFilepath, '.md');

const files = await fs.readdir(path.dirname(englishFilepath));
const translations = await Promise.all(
files
.filter((filename) => {
return (
path.extname(filename) === '.md' &&
path.basename(filename, '.md').startsWith(englishFilename)
);
})
.map(async (filename) => {
const filepath = path.join(path.dirname(englishFilepath), filename);

// Given: index.md
// Match: index-en.md, index-ja.md
// Don't Match: otherindex-en.md, index-eng.md, index-e.md, index.tsx
const translatedVersionRegExp = new RegExp(`^${filename}${notEnglishMarkdownRegExp.source}`);
const matchNotEnglishMarkdown = filename.match(notEnglishMarkdownRegExp);
const userLanguage =
matchNotEnglishMarkdown !== null &&
LANGUAGES_IN_PROGRESS.indexOf(matchNotEnglishMarkdown[1]) !== -1
? matchNotEnglishMarkdown[1]
: 'en';

return files
.filter((filepath) => {
return translatedVersionRegExp.test(filepath);
})
.concat(path.basename(englishFilepath));
}
this.addDependency(filepath);
const markdown = await fs.readFile(filepath, { encoding: 'utf8' });

return {
filename,
markdown,
userLanguage,
};
}),
);

/**
* @type {import('webpack').loader.Loader}
*/
module.exports = async function demoLoader() {
const rawKeys = await findTranslatedVersions(this.resourcePath);

// TODO: Remove requireRaw mock (needs work in prepareMarkdown)
const requireRaw = (moduleID) => {
const filepath = path.join(path.dirname(this.resourcePath), moduleID.replace(/\//g, path.sep));
this.addDependency(filepath);
return readFileSync(filepath, { encoding: 'utf-8' });
};
requireRaw.keys = () => rawKeys;
const pageFilename = this.context
.replace(this.rootContext, '')
// win32 to posix
.replace(/\\/g, '/')
.replace(/^\/src\/pages\//, '');
const { docs } = prepareMarkdown({ pageFilename, requireRaw });
const { docs } = prepareMarkdown({ pageFilename, translations });

const demos = {};
const demoModuleIDs = new Set();
new Set(
docs.en.rendered
.filter((markdownOrComponentConfig) => {
return typeof markdownOrComponentConfig !== 'string' && markdownOrComponentConfig.demo;
})
.map((demoConfig) => {
return demoConfig.demo;
}),
).forEach((demoName) => {
// TODO: const moduleID = demoName;
// The import paths currently use a completely different format.
// They should just use relative imports.
const moduleID = `./${demoName.replace(`pages/${pageFilename}/`, '')}`;
demos[demoName] = {
module: moduleID,
raw: requireRaw(moduleID),
};
demoModuleIDs.add(moduleID);

try {
const moduleTS = moduleID.replace(/\.js$/, '.tsx');
const rawTS = requireRaw(moduleTS);

// In development devs can choose whether they want to work on the TS or JS version.
// But this leads to building both demo version i.e. more build time.
demos[demoName].moduleTS = this.mode === 'production' ? moduleID : moduleTS;
demos[demoName].rawTS = rawTS;
demoModuleIDs.add(demos[demoName].moduleTS);
} catch (error) {
// TS version of the demo doesn't exist. This is fine.
}
});
const demoNames = Array.from(
new Set(
docs.en.rendered
.filter((markdownOrComponentConfig) => {
return typeof markdownOrComponentConfig !== 'string' && markdownOrComponentConfig.demo;
})
.map((demoConfig) => {
return demoConfig.demo;
}),
),
);

await Promise.all(
demoNames.map(async (demoName) => {
// TODO: const moduleID = demoName;
// The import paths currently use a completely different format.
// They should just use relative imports.
const moduleID = `./${demoName.replace(`pages/${pageFilename}/`, '')}`;
const moduleFilepath = path.join(
path.dirname(this.resourcePath),
moduleID.replace(/\//g, path.sep),
);
this.addDependency(moduleFilepath);
demos[demoName] = {
module: moduleID,
raw: await fs.readFile(moduleFilepath, { encoding: 'utf-8' }),
};
demoModuleIDs.add(moduleID);

try {
const moduleTS = moduleID.replace(/\.js$/, '.tsx');
const moduleTSFilepath = path.join(
path.dirname(this.resourcePath),
moduleID.replace(/\//g, path.sep),
);
this.addDependency(moduleTSFilepath);
const rawTS = await fs.readFile(moduleTSFilepath, { encoding: 'utf-8' });

// In development devs can choose whether they want to work on the TS or JS version.
// But this leads to building both demo version i.e. more build time.
demos[demoName].moduleTS = this.mode === 'production' ? moduleID : moduleTS;
demos[demoName].rawTS = rawTS;
demoModuleIDs.add(demos[demoName].moduleTS);
} catch (error) {
// TS version of the demo doesn't exist. This is fine.
}
}),
);

/**
* @param {string} moduleID
*/
function getRequireDemoIdentifier(moduleID) {
function getDemoIdentifier(moduleID) {
return moduleIDToJSIdentifier(moduleID);
}

const transformed = `
${Array.from(demoModuleIDs)
.map((moduleID) => {
return `import ${getRequireDemoIdentifier(moduleID)} from '${moduleID}';`;
return `import ${getDemoIdentifier(moduleID)} from '${moduleID}';`;
})
.join('\n')}
export const docs = ${JSON.stringify(docs, null, 2)};
export const demos = ${JSON.stringify(demos, null, 2)};
export function requireDemo(module) {
return {
${Array.from(demoModuleIDs)
.map((moduleID) => {
// TODO: Remove ES module interop once all demos are loaded via loader
// i.e. replace `{ default: ... }` with `...`
return `'${moduleID}': { default: ${getRequireDemoIdentifier(moduleID)} }`;
})
.join(',\n')}
}[module];
}
requireDemo.keys = () => {
return ${JSON.stringify(demoModuleIDs, null, 2)}
}`;
export const demoComponents = {${Array.from(demoModuleIDs)
.map((moduleID) => {
return `${JSON.stringify(moduleID)}: ${getDemoIdentifier(moduleID)},`;
})
.join('\n')}};
`;

// WARNING: Make sure the returned code is compatible with our .browserslistrc.
return transformed;
};
57 changes: 9 additions & 48 deletions docs/packages/markdown/parseMarkdown.js
Expand Up @@ -3,15 +3,11 @@ const kebabCase = require('lodash/kebabCase');
const textToHash = require('./textToHash');
const prism = require('./prism');

// TODO: pass as argument
const LANGUAGES_IN_PROGRESS = ['en', 'zh', 'ru', 'pt', 'es', 'fr', 'de', 'ja'];

const headerRegExp = /---[\r\n]([\s\S]*)[\r\n]---/;
const titleRegExp = /# (.*)[\r\n]/;
const descriptionRegExp = /<p class="description">(.*?)<\/p>/s;
const headerKeyValueRegExp = /(.*?): (.*)/g;
const emptyRegExp = /^\s*$/;
const notEnglishMarkdownRegExp = /-([a-z]{2})\.md$/;

/**
* Extract information from the top of the markdown.
Expand Down Expand Up @@ -239,11 +235,11 @@ function createRender(context) {

/**
* @param {object} config
* @param {() => string} config.requireRaw - returnvalue of require.context
* @param {Array<{ markdown: string, filename: string, userLanguage: string }>} config.translations - Mapping of locale to its markdown
* @param {string} config.pageFilename - posix filename relative to nextjs pages directory
*/
function prepareMarkdown(config) {
const { pageFilename, requireRaw } = config;
const { pageFilename, translations } = config;

const demos = {};
/**
Expand All @@ -252,27 +248,12 @@ function prepareMarkdown(config) {
const docs = {};
const headingHashes = {};

// Process the English markdown before the other locales.
// English ToC anchor links are used in all languages
let filenames = [];
requireRaw.keys().forEach((filename) => {
if (filename.match(notEnglishMarkdownRegExp)) {
filenames.push(filename);
} else {
filenames = [filename].concat(filenames);
}
});

filenames.forEach((filename) => {
if (filename.indexOf('.md') !== -1) {
const matchNotEnglishMarkdown = filename.match(notEnglishMarkdownRegExp);

const userLanguage =
matchNotEnglishMarkdown && LANGUAGES_IN_PROGRESS.indexOf(matchNotEnglishMarkdown[1]) !== -1
? matchNotEnglishMarkdown[1]
: 'en';

const markdown = requireRaw(filename);
translations
// Process the English markdown before the other locales.
// English ToC anchor links are used in all languages
.sort((a) => (a.userLanguage === 'en' ? -1 : 1))
.forEach((translation) => {
const { filename, markdown, userLanguage } = translation;
const headers = getHeaders(markdown);
const title = headers.title || getTitle(markdown);
const description = headers.description || getDescription(markdown);
Expand Down Expand Up @@ -320,33 +301,13 @@ ${headers.components
title,
headers,
};
} else if (filename.indexOf('.tsx') !== -1) {
const demoName = `pages/${pageFilename}/${filename
.replace(/\.\//g, '')
.replace(/\.tsx/g, '.js')}`;

demos[demoName] = {
...demos[demoName],
moduleTS: filename,
rawTS: requireRaw(filename),
};
} else {
const demoName = `pages/${pageFilename}/${filename.replace(/\.\//g, '')}`;

demos[demoName] = {
...demos[demoName],
module: filename,
raw: requireRaw(filename),
};
}
});
});

return { demos, docs };
}

module.exports = {
createRender,
notEnglishMarkdownRegExp,
getContents,
getDescription,
getHeaders,
Expand Down

0 comments on commit 7a7c0e4

Please sign in to comment.