Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion packages/react-icons/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
const closeIcon = <TimesIcon />;
```

For a list of the available icons please refer to the [PatternFly react docs](https://react-staging.patternfly.org/icons)
For a list of the available icons please refer to the [PatternFly react docs](https://pf-react-staging.patternfly.org/icons)

## Styling icons

Expand Down Expand Up @@ -68,3 +68,28 @@ module.exports = {
]
}
```

## Static SVGs

All icons are also available as static SVG files in `@patternfly/react-icons/dist/static`. The static SVGs include all the same attributes as the React components (viewBox, class names, etc.) to ensure visual consistency.

Static SVGs are useful when you need to:
- Use icons in non-React contexts, such as static HTML
- Reference icons via URL or file path

### Usage

You can import or reference static SVG files directly:

```jsx
// In HTML
<img src="/icons/static/times-icon.svg" alt="Close" />

// In CSS
.close-icon {
background-image: url('/icons/static/times-icon.svg');
}

// Direct file path
import timesIcon from '@patternfly/react-icons/dist/static/times-icon.svg';
```
3 changes: 2 additions & 1 deletion packages/react-icons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@
"homepage": "https://github.com/patternfly/patternfly-react#readme",
"scripts": {
"build:single:packages": "node ../../scripts/build-single-packages.mjs --config single-packages.config.json",
"build:esm": "tsc --build tsconfig.json",
"clean": "rimraf dist src/icons src/index.js src/index.d.ts",
"generate": "rimraf dist/esm/icons dist/js/icons && node scripts/writeIcons.mjs"
"generate": "rimraf dist/esm/icons dist/js/icons && yarn build:esm && node scripts/writeIcons.mjs"
},
"devDependencies": {
"@fortawesome/free-brands-svg-icons": "^5.15.4",
Expand Down
57 changes: 55 additions & 2 deletions packages/react-icons/scripts/writeIcons.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { join } from 'path';
import { outputFileSync } from 'fs-extra/esm';
import { outputFileSync, ensureDirSync } from 'fs-extra/esm';
import { generateIcons } from './generateIcons.mjs';
import { createElement } from 'react';
import { renderToString } from 'react-dom/server';

import * as url from 'url';
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));

// Import createIcon from compiled dist (build:esm must run first)
const createIconModule = await import('../dist/esm/createIcon.js');
const createIcon = createIconModule.createIcon;

const outDir = join(__dirname, '../dist');
const staticDir = join(outDir, 'static');

const removeSnake = (s) => s.toUpperCase().replace('-', '').replace('_', '');
const toCamel = (s) => `${s[0].toUpperCase()}${s.substr(1).replace(/([-_][\w])/gi, removeSnake)}`;
Expand Down Expand Up @@ -72,6 +79,50 @@ export default ${jsName};
outputFileSync(join(outDir, 'esm/icons', filename), text);
};

/**
* Generates a static SVG string from icon data using createIcon
* @param {string} iconName The name of the icon
* @param {object} icon The icon data object
* @returns {string} Static SVG markup
*/
function generateStaticSVG(iconName, icon) {
const jsName = `${toCamel(iconName)}Icon`;

// Create icon component using createIcon
const IconComponent = createIcon({
name: jsName,
width: icon.width,
height: icon.height,
svgPath: icon.svgPathData,
xOffset: icon.xOffset || 0,
yOffset: icon.yOffset || 0,
svgClassName: icon.svgClassName
});

// Render the component to string
const svgString = renderToString(createElement(IconComponent));

// Convert React's className to class for static SVG
return svgString.replace(/className=/g, 'class=');
}

/**
* Writes static SVG files to dist/static directory
* @param {object} icons icons from generateIcons
*/
function writeStaticSVGs(icons) {
ensureDirSync(staticDir);

Object.entries(icons).forEach(([iconName, icon]) => {
const svgContent = generateStaticSVG(iconName, icon);
const svgFileName = `${iconName}.svg`;
outputFileSync(join(staticDir, svgFileName), svgContent, 'utf-8');
});

// eslint-disable-next-line no-console
console.log(`Wrote ${Object.keys(icons).length} static SVG files to ${staticDir}`);
}

/**
* Writes CJS and ESM icons to `dist` directory
*
Expand Down Expand Up @@ -114,4 +165,6 @@ ${index
console.log('Wrote', index.length * 3 + 3, 'icon files.');
}

writeIcons(generateIcons());
const icons = generateIcons();
writeIcons(icons);
writeStaticSVGs(icons);
Loading