Specialized components
UI framework
Icon system
17 min
overview the icon system provides a comprehensive framework for managing and using visual symbols throughout the ir engine ui it transforms raw svg icon definitions into standardized react components that can be easily imported and used in the application by automating the icon generation process and ensuring consistent behavior, the system enables developers to efficiently incorporate visual cues that enhance usability and aesthetics the icons automatically adapt to their context, inheriting colors and scaling appropriately based on the surrounding ui elements core components the icon system consists of several key components that work together to create a streamlined workflow icon definitions icon definitions are stored in a central json file ( icona json ) that serves as the source of truth for the icon library // simplified from icona json { "admin md" { "name" "adminmd", "svg" "\<svg xmlns=\\"http //www w3 org/2000/svg\\" width=\\"20\\" height=\\"20\\" fill=\\"none\\" viewbox=\\"0 0 20 20\\">\<path stroke=\\"#111827\\" stroke linecap=\\"round\\" stroke linejoin=\\"round\\" stroke width=\\"1 75\\" d=\\"m3 125 5 238a9 97 9 97 0 0 0 10 2 5a9 97 9 97 0 0 0 7 002 2 737c 323 984 498 2 035 498 3 126 0 4 66 3 187 8 575 7 5 9 685 4 313 1 11 7 5 5 025 7 5 9 685a10 10 0 0 1 498 3 126z\\"/>\</svg>" }, "save 01 md" { "name" "save01md", "svg" "\<svg viewbox='0 0 20 20'>\<path d=' ' fill='none' stroke='#000000'/>\</svg>" }, // additional icon definitions } each entry contains a unique identifier key (e g , "admin md" ) a name property that defines the react component name an svg property containing the raw svg markup build script the build script ( scripts/build icons ts ) processes the icon definitions and generates react components // simplified from scripts/build icons ts import { transform } from '@svgr/core'; import fs from 'fs/promises'; import iconajson from ' /icona json'; // transform kebab case to pascalcase for component names function transformname(name string) { const parts = name split(/\[^a za z0 9]/gi); return parts map((part) => part charat(0) touppercase() + part slice(1)) join(''); } async function buildicons() { const componentnames = \[]; // process each icon in the json file for (const \[key, iconentry] of object entries(iconajson)) { const componentname = transformname(iconentry name); componentnames push(componentname); // replace hardcoded colors with currentcolor for css styling const correctedsvg = iconentry svg replace(/stroke=\\"#\w{6}\\"/gi, "stroke='currentcolor'") replace(/fill=\\"#\w{6}\\"/gi, "fill='currentcolor'"); // convert svg to react component const reactcomponent = await transform( correctedsvg, { icon true, dimensions true, typescript true, ref true }, { componentname } ); // write component to file if it doesn't exist const filepath = ` /src/icons/files/${componentname} tsx`; try { await fs access(filepath); console log(`${componentname} already exists, skipping `); } catch { await fs writefile(filepath, reactcomponent); console log(`created ${componentname}`); } } // update index file with exports const componentexports = componentnames sort() map((name) => `export { default as ${name} } from ' /files/${name}'`) join('\n'); await fs writefile(' /src/icons/index ts', componentexports + '\n'); console log('updated index ts with all icon exports'); } buildicons() catch(console error); key operations performed by the script reading icon definitions from icona json converting kebab case names to pascalcase for react components replacing hardcoded colors with currentcolor for dynamic styling using @svgr/core to transform svg markup into react components writing each component to its own file in src/icons/files/ generating an index file that exports all icon components generated icon components each icon is transformed into a standardized react component // example of a generated icon component src/icons/files/adminmd tsx import type { svgprops } from 'react'; import as react from 'react'; import { ref, forwardref } from 'react'; const adminmd = (props svgprops\<svgsvgelement>, ref ref\<svgsvgelement>) => ( \<svg xmlns="http //www w3 org/2000/svg" width="1em" height="1em" fill="none" viewbox="0 0 20 20" role="img" ref={ref} { props} \> \<path stroke="currentcolor" strokelinecap="round" strokelinejoin="round" strokewidth={1 75} d="m3 125 5 238a9 97 9 97 0 0 0 10 2 5a9 97 9 97 0 0 0 7 002 2 737c 323 984 498 2 035 498 3 126 0 4 66 3 187 8 575 7 5 9 685 4 313 1 11 7 5 5 025 7 5 9 685a10 10 0 0 1 498 3 126z" /> \</svg> ); const forwardref = forwardref(adminmd); export default forwardref; key features of generated components default dimensions of 1em to scale with text size use of currentcolor to inherit color from css support for all standard svg props ref forwarding for direct dom access accessibility attributes ( role="img" ) central export file all icon components are exported from a central index file // from src/icons/index ts export { default as adminmd } from ' /files/adminmd'; export { default as adminsm } from ' /files/adminsm'; export { default as alertcirclelg } from ' /files/alertcirclelg'; export { default as save01md } from ' /files/save01md'; // additional exports this provides a single import point for all icons, simplifying usage type definitions type definitions ensure proper usage of icon components // from src/icons/types tsx export type svgicontype = react forwardrefexoticcomponent< omit\<react svgprops\<svgsvgelement>, 'ref'> & react refattributes\<svgsvgelement> \>; these types provide typescript validation and ide autocompletion when using icons icon generation workflow the process of transforming raw svg definitions into usable react components follows this workflow sequencediagram participant icondefs as icona json participant buildscript as scripts/build icons ts participant svgr as @svgr/core participant files as src/icons/files/ tsx participant index as src/icons/index ts participant app as application code icondefs >>buildscript provides svg definitions buildscript >>buildscript process each icon entry buildscript >>buildscript replace hardcoded colors with currentcolor buildscript >>svgr pass modified svg for transformation svgr >>buildscript return react component code buildscript >>files write component files buildscript >>index generate export statements app >>index import icons index >>files reference specific icon components files >>app provide icon components for use usage examples basic icon usage icons can be imported and used like any react component import { save01md } from '@ir engine/ui/src/icons'; function savebutton() { return ( \<button classname="flex items center"> \<save01md classname="w 4 h 4 mr 2" /> save \</button> ); } the icon inherits the text color of its parent element and can be sized using css classes icon with custom styling icons can be customized with different colors and sizes import { alertcirclelg } from '@ir engine/ui/src/icons'; function errormessage({ message }) { return ( \<div classname="flex items center text red 500"> \<alertcirclelg classname="w 5 h 5 mr 2" /> \<span>{message}\</span> \</div> ); } in this example, both the icon and text will be red due to the text red 500 class on the parent icon in a button icons are commonly used in buttons to enhance visual communication import { button } from '@ir engine/ui'; import { trashmd } from '@ir engine/ui/src/icons'; function deletebutton({ ondelete }) { return ( \<button variant="danger" onclick={ondelete}> \<trashmd classname="w 4 h 4 mr 2" /> delete \</button> ); } icon as a standalone element icons can also be used as standalone interactive elements import { settingslg } from '@ir engine/ui/src/icons'; function settingstoggle({ onclick }) { return ( \<div classname="p 2 rounded full hover\ bg gray 200 cursor pointer" onclick={onclick} aria label="settings" role="button" \> \<settingslg classname="w 6 h 6 text gray 700" /> \</div> ); } benefits of the icon system the automated icon system provides several key advantages consistency all icons follow the same patterns for sizing, coloring, and behavior maintainability adding new icons requires only updating the source json file performance icons are optimized during the build process developer experience typescript integration provides autocompletion and validation flexibility icons automatically adapt to their context through css inheritance accessibility generated components include appropriate aria attributes next steps with an understanding of how icons are managed and used throughout the ui, the next chapter explores a specific feature module that incorporates many of the ui components we've discussed so far the chat feature next chat feature module docid\ q8y6vh7lrcjq4hcjtnpq5