Skip to content

Commit

Permalink
Split EuiIcon into dynamic imports; allow React SVG elements and exte…
Browse files Browse the repository at this point in the history
…rnal urls (#1924)

* Feature/icon breakapart (#1856)

* dynamic import

* Make the icon kinda work

* progress

* generate tsx from svg

* Build and commit icons TSX

* Updated Icon snapshots

* Updated EuiIcon build to again work in dependant projects

* Create a single eui.js build, bundling EuiIcon's dynamic import into the build

* Tests are passing

* Add a loading class to EuiIcon

* Added -isLoaded and using animations for fading

* update snapshots

* Remove background color from isLoaded state

* PR feedback

* Docs for EuiIcon new abilities (#1889)

Add docs for the custom svg abilities in EuiIcon

* DOCS ONLY: Allow multiple snippets (#1908)

* Update IconType and its proptype usage (#1913)

* Expand IconType to include string

* Update EuiIcon IconType to include Element, fix some TS issues, widen the EuiIcon IconType proptype

* Swap Vim example logo out for SVG example logo, which contains a viewBox for IE11 compat

* changelog
  • Loading branch information
chandlerprall authored May 7, 2019
1 parent 3289ac1 commit 47ba51e
Show file tree
Hide file tree
Showing 394 changed files with 4,063 additions and 3,165 deletions.
11 changes: 9 additions & 2 deletions .babelrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module.exports = {
"@babel/react"
],
"plugins": [
"@babel/plugin-syntax-dynamic-import",
"pegjs-inline-precompile",
"./scripts/babel/proptypes-from-ts-props",
"add-module-exports",
Expand All @@ -39,6 +40,12 @@ module.exports = {
]
}
}
]
]
],
],

"env": {
"test": {
"plugins": ["dynamic-import-node"]
}
}
};
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Added support for custom React SVG elements and external SVG URLs to `EuiIcon` ([#1924](https://github.com/elastic/eui/pull/1924))

**Bug fixes**

- Fixed Firefox flash of unstyled select dropdown ([#1927](https://github.com/elastic/eui/pull/1927))

**Breaking changes**

- Split `EuiIcon` icon loading into dynamic imports ([#1924](https://github.com/elastic/eui/pull/1924))

## [`10.4.0`](https://github.com/elastic/eui/tree/v10.4.0)

- Added `display` prop to `EuiTabs` and `EuiTabbedContent` components for ability to use an alternative `condensed` style ([#1904](https://github.com/elastic/eui/pull/1904))
Expand Down
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
"sync-docs": "node ./scripts/docs-sync.js",
"build-docs": "NODE_ENV=production webpack --config=src-docs/webpack.config.js",
"build": "yarn extract-i18n-strings && node ./scripts/compile-clean.js && node ./scripts/compile-eui.js && node ./scripts/compile-scss.js $npm_package_name",
"compile-icons": "node ./scripts/compile-icons.js",
"extract-i18n-strings": "node ./scripts/babel/fetch-i18n-strings",
"lint": "yarn lint-es && yarn lint-ts && yarn lint-sass && yarn lint-framer",
"lint-fix": "yarn lint-es-fix && yarn lint-ts-fix",
"lint-es": "eslint --cache --ignore-pattern \"**/*.snap.js\" \"src/**/*.js\" \"src-docs/**/*.js\"",
"lint-es-fix": "eslint --fix --cache --ignore-pattern \"**/*.snap.js\" \"src/**/*.js\" \"src-docs/**/*.js\"",
"lint-es": "eslint --cache --ignore-pattern \"**/*.snap.js\", --ignore-pattern \"**/assets/**/*.js\" \"src/**/*.js\" \"src-docs/**/*.js\"",
"lint-es-fix": "eslint --fix --cache --ignore-pattern \"**/*.snap.js\", \"**/assets/**/*.js\" \"src/**/*.js\" \"src-docs/**/*.js\"",
"lint-sass": "sass-lint -v --max-warnings 0",
"lint-sass-fix": "sass-lint-auto-fix -c ./.sass-lint-fix.yml",
"lint-ts": "tsc -p ./tsconfig.json --noEmit && tslint -c ./tslint.yaml -p ./tsconfig.json",
Expand Down Expand Up @@ -72,12 +73,15 @@
"@babel/core": "^7.1.2",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/polyfill": "^7.0.0",
"@babel/preset-env": "^7.1.0",
"@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.1.0",
"@elastic/datemath": "^5.0.2",
"@elastic/eslint-config-kibana": "^0.15.0",
"@svgr/core": "^4.1.0",
"@svgr/plugin-svgo": "^4.0.3",
"@types/classnames": "^2.2.6",
"@types/enzyme": "^3.1.13",
"@types/jest": "^24.0.6",
Expand All @@ -92,6 +96,7 @@
"babel-jest": "^24.1.0",
"babel-loader": "^8.0.4",
"babel-plugin-add-module-exports": "^1.0.0",
"babel-plugin-dynamic-import-node": "^2.2.0",
"babel-plugin-inline-react-svg": "^1.0.1",
"babel-plugin-pegjs-inline-precompile": "^0.1.0",
"babel-plugin-react-docgen": "^2.0.0",
Expand Down
3 changes: 2 additions & 1 deletion scripts/babel/proptypes-from-ts-props/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ function stripTypeScript(filename, ast) {
{
filename: filename,
babelrc: false,
presets: ['@babel/typescript']
presets: ['@babel/typescript'],
plugins: ['@babel/plugin-syntax-dynamic-import'],
}
).code;
}
Expand Down
70 changes: 70 additions & 0 deletions scripts/compile-icons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
const glob = require('glob');
const svgr = require('@svgr/core').default;
const path = require('path');
const fs = require('fs');

const rootDir = path.resolve(__dirname, '..');
const srcDir = path.resolve(rootDir, 'src');
const iconsDir = path.resolve(srcDir, 'components', 'icon', 'assets');

function pascalCase(x) {
return x.replace(/^(.)|[^a-zA-Z]([a-zA-Z])/g, (match, char1, char2) => (char1 || char2).toUpperCase());
}

const iconFiles = glob.sync(
'**/*.svg',
{ cwd: iconsDir, realpath: true }
);

function defaultTemplate({
template
}, opts, {
imports,
componentName,
props,
jsx,
exports
}) {
return template.ast`${imports}
const ${componentName} = (${props}) => ${jsx}
${exports}
`;
}

iconFiles.forEach(async filePath => {
const svgSource = fs.readFileSync(filePath);

try {
const jsxSource = (await svgr(
svgSource,
{
plugins: ['@svgr/plugin-svgo', '@svgr/plugin-jsx'],
svgoConfig: {
plugins: [
{ cleanupIDs: false },
{ prefixIds: false },
{ removeViewBox: false },
],
},
svgProps: {
xmlns: 'http://www.w3.org/2000/svg'
},
template: ({ template }, opts, { imports, componentName, props, jsx }) => template.ast`
${imports}
const ${componentName} = (${props}) => ${jsx}
export const icon = ${componentName};
`
},
{
componentName: `EuiIcon${pascalCase(path.basename(filePath, '.svg'))}`
}
));

const outputFilePath = filePath.replace(/\.svg$/, '.js');
fs.writeFileSync(outputFilePath, jsxSource);
} catch (e) {
console.error(`Error processing ${filePath}`);
console.error(e);
process.exit(1);
}
});
3 changes: 2 additions & 1 deletion src-docs/src/components/guide_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ $guideZLevelHighest: $euiZLevel9 + 1000;
.guideDemo__icon {
text-align: center;

svg {
svg,
img {
margin-bottom: $euiSizeS;
}
}
Expand Down
35 changes: 26 additions & 9 deletions src-docs/src/components/guide_section/guide_section.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,28 @@ export class GuideSection extends Component {
return;
}

return [
<Fragment key="snippet">
<EuiSpacer size="m" />
<EuiCodeBlock language="html" fontSize="m" paddingSize="m" isCopyable>
{snippet}
</EuiCodeBlock>
</Fragment>
];
let snippetCode;
if (typeof snippet === 'string') {
snippetCode = (
<Fragment key="snippet">
<EuiSpacer size="m" />
<EuiCodeBlock language="html" fontSize="m" paddingSize="m" isCopyable>
{snippet}
</EuiCodeBlock>
</Fragment>
);
} else {
snippetCode = snippet.map((snip, index) => (
<Fragment key={`snippet${index}`}>
<EuiSpacer size="m" />
<EuiCodeBlock language="html" fontSize="m" paddingSize="m" isCopyable>
{snip}
</EuiCodeBlock>
</Fragment>
));
}

return snippetCode;
}

renderPropsForComponent = (componentName, component) => {
Expand Down Expand Up @@ -413,7 +427,10 @@ GuideSection.propTypes = {
title: PropTypes.string,
id: PropTypes.string,
source: PropTypes.array,
snippet: PropTypes.string,
snippet: PropTypes.oneOfType([
PropTypes.string,
PropTypes.arrayOf(PropTypes.string),
]),
children: PropTypes.any,
toggleTheme: PropTypes.func.isRequired,
theme: PropTypes.string.isRequired,
Expand Down
14 changes: 14 additions & 0 deletions src-docs/src/images/custom.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 31 additions & 9 deletions src-docs/src/views/icon/apps.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
// DON'T USE THIS
// DON'T USE THIS
// DON'T USE THIS
// DON'T USE THIS
// DON'T USE THIS

// This example JS is overly complex for simple icon usage
// and is set up this way for ease of use in our docs.
//
// Check the snippet tab for a more common usage.

import React from 'react';

import {
Expand All @@ -6,6 +17,7 @@ import {
EuiIcon,
EuiPanel,
EuiText,
EuiCopy,
} from '../../../../src/components';

const iconTypes = [
Expand Down Expand Up @@ -62,15 +74,25 @@ export default () => (
key={iconType}
style={{ width: '200px' }}
>
<EuiPanel>
<EuiIcon
type={iconType}
size="xl"
/>
<EuiText size="s">
<p>{iconType}</p>
</EuiText>
</EuiPanel>
<EuiCopy
textToCopy={iconType}
afterMessage={`${iconType} copied`}
>
{(copy) => (
<EuiPanel
onClick={copy}
className="eui-textCenter"
>
<EuiIcon
type={iconType}
size="xl"
/>
<EuiText size="s">
<p>{iconType}</p>
</EuiText>
</EuiPanel>
)}
</EuiCopy>
</EuiFlexItem>
))
}
Expand Down
11 changes: 11 additions & 0 deletions src-docs/src/views/icon/icon_colors.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
// DON'T USE THIS
// DON'T USE THIS
// DON'T USE THIS
// DON'T USE THIS
// DON'T USE THIS

// This example JS is overly complex for simple icon usage
// and is set up this way for ease of use in our docs.
//
// Check the snippet tab for a more common usage.

import React from 'react';

import {
Expand Down
Loading

0 comments on commit 47ba51e

Please sign in to comment.