diff --git a/packages/react-icons/README.md b/packages/react-icons/README.md index eabb4ed8152..82211004774 100644 --- a/packages/react-icons/README.md +++ b/packages/react-icons/README.md @@ -10,7 +10,7 @@ import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon'; const closeIcon = ; ``` -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 @@ -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 +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'; +``` diff --git a/packages/react-icons/package.json b/packages/react-icons/package.json index 2c71f8d8114..7e43022c552 100644 --- a/packages/react-icons/package.json +++ b/packages/react-icons/package.json @@ -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", diff --git a/packages/react-icons/scripts/writeIcons.mjs b/packages/react-icons/scripts/writeIcons.mjs index c468e987080..a4c58a700f4 100644 --- a/packages/react-icons/scripts/writeIcons.mjs +++ b/packages/react-icons/scripts/writeIcons.mjs @@ -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)}`; @@ -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 * @@ -114,4 +165,6 @@ ${index console.log('Wrote', index.length * 3 + 3, 'icon files.'); } -writeIcons(generateIcons()); +const icons = generateIcons(); +writeIcons(icons); +writeStaticSVGs(icons);