Skip to content

Commit

Permalink
feat(icons): add flag icons (#493)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgemoya authored Jan 26, 2021
1 parent b5167f9 commit 0519c8a
Show file tree
Hide file tree
Showing 269 changed files with 42,812 additions and 8 deletions.
7 changes: 7 additions & 0 deletions packages/big-design-icons/flags/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "@bigcommerce/big-design-icons/flags",
"sideEffects": false,
"main": "../dist/cjs/flags/index.js",
"module": "../dist/es/flags/index.js",
"typings": "../dist/flags/index.d.ts"
}
3 changes: 3 additions & 0 deletions packages/big-design-icons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"build:es": "NODE_ENV=production BABEL_ENV=es babel --extensions \".ts,.tsx\" ./src --out-dir ./dist/es",
"build:dt": "tsc --emitDeclarationOnly",
"build:icons": "node scripts/build.js",
"build:flags": "node scripts/build-flags.js",
"download": "node scripts/downloader.js",
"ci": "yarn run lint && yarn run build",
"lint": "yarn run lint:tsc",
Expand All @@ -26,6 +27,7 @@
},
"files": [
"dist",
"flags",
"svgs"
],
"publishConfig": {
Expand Down Expand Up @@ -53,6 +55,7 @@
"@babel/preset-react": "^7.12.1",
"@babel/preset-typescript": "^7.12.1",
"@bigcommerce/configs": "^0.14.0",
"@jorgemoya/flag-icon-css": "3.5.0",
"@svgr/core": "^5.0.1",
"@svgr/plugin-jsx": "^5.0.1",
"@svgr/plugin-prettier": "^5.0.1",
Expand Down
74 changes: 74 additions & 0 deletions packages/big-design-icons/scripts/build-flags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const { default: svgr } = require('@svgr/core');
const { outputFile, readFile } = require('fs-extra');
const glob = require('glob-promise');
const { basename, join } = require('path');
const rimraf = require('rimraf');
const { promisify } = require('util');

const config = require('./svgr-flags.config');

const SOURCE = join(__dirname, '..', '..', '..', 'node_modules', '@jorgemoya/flag-icon-css', 'flags', '4x3', '*.svg');
const DEST_PATH = join(__dirname, '..', 'src', 'flags', 'components');

const componentNames = new Set();
const asyncRimraf = promisify(rimraf);

async function convertToReactComponent(filePath, iconName) {
const svgCode = await readFile(filePath, 'utf8');
const destPath = join(DEST_PATH, `${iconName}.tsx`);

const code = await svgr(
svgCode,
{
...config,
// Need to add the svgo config here to have access to iconName
svgoConfig: {
plugins: [
{
prefixIds: {
prefix: iconName,
},
removeViewBox: false,
},
],
},
},
{ componentName: iconName },
);

return outputFile(destPath, code);
}

async function generateFlags() {
const iconFiles = await glob(SOURCE);

return Promise.all(
iconFiles.map((iconFilePath) => {
const filename = basename(iconFilePath, '.svg');
const name = `${filename.replace('-', '').toUpperCase()}FlagIcon`;

componentNames.add(name);

// eslint-disable-next-line no-console
console.log(`Building: ${name}`);

return convertToReactComponent(iconFilePath, name);
}),
);
}

function cleanDestDirectory() {
return asyncRimraf(DEST_PATH);
}

(async () => {
await cleanDestDirectory();
await generateFlags();

const indexFile = Array.from(componentNames).map((name) => `export * from './${name}';`);

await outputFile(join(DEST_PATH, 'index.ts'), indexFile.join('\n'));

// eslint-disable-next-line no-console
console.log('Done!');
})();
60 changes: 60 additions & 0 deletions packages/big-design-icons/scripts/svgr-flags.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const prettierConfig = require('../../../prettier.config');

module.exports = {
titleProp: true,
ref: true,
ext: 'tsx',
plugins: ['@svgr/plugin-svgo', '@svgr/plugin-jsx', '@svgr/plugin-prettier'],
template({ template }, _, { componentName, jsx }) {
const flagName = componentName.name.replace('FlagIcon', '');

const code = `
// **********************************
// Auto-generated file, do NOT modify
// **********************************
import React, { forwardRef, memo } from 'react';
BREAK
import { PrivateIconProps } from '../../base';
import { useUniqueId } from '../../utils';
import { createStyledFlagIcon, FlagIconProps } from '../base';
BREAK
const FlagIcon: React.FC<FlagIconProps & PrivateIconProps> = ({ svgRef, title = '${flagName} flag', theme, ...props }) => {
const uniqueTitleId = useUniqueId('icon');
const titleId = title ? props.titleId || uniqueTitleId : undefined;
BREAK
return (
JSX
);
};
BREAK
const FlagIconWithForwardedRef = forwardRef<SVGSVGElement, FlagIconProps>((iconProps, ref) => <FlagIcon {...iconProps} svgRef={ref} />);
BREAK
export const COMPONENT_NAME = memo(createStyledFlagIcon(FlagIconWithForwardedRef as React.FC<FlagIconProps>));
BREAK
COMPONENT_NAME.displayName = '${componentName.name}';
`;

const typeScriptTpl = template.smart(code, {
plugins: ['jsx', 'typescript'],
preserveComments: true,
placeholderPattern: false,
placeholderWhitelist: new Set(['BREAK', 'COMPONENT_NAME', 'JSX']),
});

return typeScriptTpl({
COMPONENT_NAME: componentName,
BREAK: '\n',
JSX: jsx,
});
},
prettierConfig: {
...prettierConfig,
parser: 'typescript',
},
};
25 changes: 25 additions & 0 deletions packages/big-design-icons/src/flags/base/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { theme as defaultTheme, Spacing, ThemeInterface } from '@bigcommerce/big-design-theme';
import React, { SVGProps } from 'react';
import styled from 'styled-components';

export interface FlagIconProps extends SVGProps<SVGSVGElement> {
size?: keyof Spacing | number;
theme?: ThemeInterface;
title?: string;
}

export function createStyledFlagIcon(FlagIcon: React.FC<FlagIconProps>) {
const StyledFlagIcon = styled(FlagIcon)`
${({ size, theme }) =>
size && {
width: typeof size === 'number' ? theme.helpers.remCalc(size) : theme.spacing[size],
}}
`;

StyledFlagIcon.defaultProps = {
size: 'xLarge',
theme: defaultTheme,
};

return StyledFlagIcon;
}
Loading

0 comments on commit 0519c8a

Please sign in to comment.