import type { IconData, IconProps } from './types'; export const SVG_NS = 'http://www.w3.org/2000/svg'; /** * Default viewBox shared by all Material Symbols icons. Icons that use a * different viewBox store it in `IconData.vb`. */ export const DEFAULT_VIEWBOX = '0 -960 960 960'; export type SvgStringOpts = IconProps & { xclass?: string }; const serializeAttrs = (attrs?: Record): string => attrs ? Object.entries(attrs) .map(([key, value]) => ` ${key}="${value}"`) .join('') : ''; /** * Build a standalone SVG string from icon data. Replaces the previous * DOMParser-based implementation, so it works in non-DOM environments (SSR, * tests) too. */ export const buildSvgString = (data: IconData, opts: SvgStringOpts = {}): string => { const { variant = 'filled', size, width, height, fill, xclass } = opts; const inner = variant === 'outlined' ? data.o ?? data.f : data.f ?? data.o; if (inner == null) return ''; const w = size ?? width; const h = size ?? height; const rootAttrs = variant === 'outlined' ? data.rao : data.raf; const viewBox = (variant === 'outlined' ? data.vbo : undefined) ?? data.vb ?? DEFAULT_VIEWBOX; let attrs = `xmlns="${SVG_NS}" viewBox="${viewBox}"`; attrs += serializeAttrs(rootAttrs); if (fill) attrs += ` fill="${fill}"`; if (w !== undefined && w !== '') attrs += ` width="${w}"`; if (h !== undefined && h !== '') attrs += ` height="${h}"`; if (xclass) attrs += ` class="${xclass}"`; return `${inner}`; };