From 428477108680ce582b33121a0d2081dc97660f1f Mon Sep 17 00:00:00 2001 From: Bree Hall <40739624+breehall@users.noreply.github.com> Date: Fri, 4 Feb 2022 15:57:41 -0500 Subject: [PATCH] [Docs] Combine All @elastic/eui Imports in the EUI Docs Demo JS Tab (#5533) * Update NPM version * Delete package-lock.json * Update yarn.lock * Update package.json * Update package.json * Replaced the EuiFilterSearch component with the EuiSelectable component for the MultiSelect example for Filter Group in the docs * Remove comments and add a meaningful aria message to EuiSelectable in MultiSelect Filter Group example * Updated the login within _utils.js to combine all EUI imports when preparing source JS for the Demo JS code tab in the EUI Docs * Had to remove changes to the fiter_group_multi that weren't supposed to be in this branch * Better regex to identify only eui imports * Updated the consolidation logic for EUI imports to move each import to its own line * Re-pushing commit responsbile for breaking up EUI imports into their own lines for formatting * Updated the regex pattern of the renderedCode function within _utils.js to take out the removal of the new line at the end of the pattern responsible for combining EUI imports * Updated the template string used to display imports and rendered code to remove additional space that was added to the end of the code block * Added functionality to format non-Eui imports in _utils.js. Also updated the Eui formating functionality to account for and format Eui import statements that only import a single component/function/utility * Update src-docs/src/components/guide_section/_utils.js Co-authored-by: Constance * Handle PR comments: Remove logic to fomrat non-EUI imports Add a helper to check the line length of combined imports to determine if the statement should be wrapped to new lines or if the statement should stay on a single line. * Updated _utils.js to standardize spacing between all imports. Each import (EUI and non-EUI) will have a single new line breaking them up. * Removed a rouge console statement * Removed the helper function for checking the line length of EUI imports and added that logic directly to the main method to prevent code duplication Co-authored-by: Chandler Prall Co-authored-by: Constance --- .../src/components/guide_section/_utils.js | 85 ++++++++++++------- 1 file changed, 55 insertions(+), 30 deletions(-) diff --git a/src-docs/src/components/guide_section/_utils.js b/src-docs/src/components/guide_section/_utils.js index e0b65ef2d04..ddce7322575 100644 --- a/src-docs/src/components/guide_section/_utils.js +++ b/src-docs/src/components/guide_section/_utils.js @@ -1,38 +1,63 @@ +/** + * renderJsSource code is responsible for formatting the JavaScript that goes into the DemoJS within the + * EUI Docs. In addition to formatting the code for the tab, this function also combines EUI imports by + * searching code.default for all EUI imports, extracting the variables, and combining them at the top of + * the formatted code. + */ + import { cleanEuiImports } from '../../services'; export const renderJsSourceCode = (code) => { - let renderedCode = cleanEuiImports(code.default).split('\n'); - const linesWithImport = []; - // eslint-disable-next-line guard-for-in - for (const idx in renderedCode) { - const line = renderedCode[idx]; - if (line.includes('import') && line.includes("from '@elastic/eui';")) { - linesWithImport.push(line); - renderedCode[idx] = ''; + let renderedCode = cleanEuiImports(code.default); + + /* ----- Combine and clean EUI imports ----- */ + let elasticImports = ['']; + + // Find all imports that come from '@elastic/eui' + renderedCode = renderedCode.replace( + // [\r\n] - start of a line + // import\s+\{ - import / whitespace / opening brace + // ([^}]+) - group together anything that isn't a closing brace + // \}\s+from\s+'@elastic\/eui'; - closing brace / whitespace / from / whitespace / '@elastic/eui'; + // [\r\n] - match end of line, so the extra new line is removed via the replace operation + /[\r\n]import\s+\{([^}]+)\}\s+from\s+'@elastic\/eui';/g, + (match, imports) => { + // remove any additional characters from imports + const namedImports = imports.match(/[a-zA-Z0-9]+/g); + elasticImports.push(...namedImports); + return ''; } + ); + + // Remove empty spaces in the array + elasticImports = elasticImports.filter((ele) => ele); + + let formattedEuiImports = ''; + + // determine if imports should be wrapped to new lines based on the import statement length + const combinedImports = elasticImports.join(', '); + const singleLineImports = `import { ${combinedImports} } from '@elastic/eui';`; + + if (singleLineImports.length <= 81) { + formattedEuiImports = singleLineImports; + } else { + const lineSeparatedImports = elasticImports.join(',\n '); + formattedEuiImports = `import {\n ${lineSeparatedImports},\n} from '@elastic/eui';`; } - if (linesWithImport.length > 1) { - linesWithImport[0] = linesWithImport[0].replace( - " } from '@elastic/eui';", - ',' - ); - for (let i = 1; i < linesWithImport.length - 1; i++) { - linesWithImport[i] = linesWithImport[i] - .replace('import {', '') - .replace(" } from '@elastic/eui';", ','); + + // Find any non-EUI imports and join them with new lines between each import for uniformity + const nonEuiImports = []; + + renderedCode = renderedCode.replace( + /import\s+([^]+?)\s+from\s+(\'[A-Za-z0-9 _./-]*\'\;)/g, + (match) => { + nonEuiImports.push(match); + return ''; } - linesWithImport[linesWithImport.length - 1] = linesWithImport[ - linesWithImport.length - 1 - ].replace('import {', ''); - } - const newImport = linesWithImport.join(''); - renderedCode.unshift(newImport); - renderedCode = renderedCode.join('\n'); - let len = renderedCode.replace('\n\n\n', '\n\n').length; - while (len < renderedCode.length) { - renderedCode = renderedCode.replace('\n\n\n', '\n\n'); - len = renderedCode.replace('\n\n\n', '\n\n').length; - } + ); + + const formattedNonEuiImports = nonEuiImports.join('\n'); - return renderedCode; + const fullyFormattedCode = `${formattedEuiImports}\n${formattedNonEuiImports}\n\n${renderedCode.trim()}`; + return fullyFormattedCode; };