2
0
mirror of https://github.com/iconify/iconify.git synced 2024-10-24 09:32:02 +00:00
iconify/components/ember/src/render.ts

120 lines
2.7 KiB
TypeScript
Raw Normal View History

// @ts-ignore
2022-03-11 16:39:57 +00:00
import { htmlSafe } from '@ember/template';
import type { IconifyIcon } from '@iconify/types';
2022-06-19 16:16:11 +00:00
import { mergeCustomisations } from '@iconify/utils/lib/customisations/merge';
2022-04-30 20:12:34 +00:00
import { flipFromString } from '@iconify/utils/lib/customisations/flip';
import { rotateFromString } from '@iconify/utils/lib/customisations/rotate';
import { iconToSVG } from '@iconify/utils/lib/svg/build';
import { replaceIDs } from '@iconify/utils/lib/svg/id';
import type { IconifyIconCustomisations, IconifyIconProps } from './props';
2022-06-19 16:16:11 +00:00
import { defaultExtendedIconCustomisations } from './props';
/**
* Render result
*/
export interface RenderResult {
width: string | number;
height: string | number;
viewBox: string;
style?: string;
className: string;
body: string;
}
/**
* Render icon
*/
export const render = (
// Icon must be validated before calling this function
icon: Required<IconifyIcon>,
// Partial properties
props: IconifyIconProps,
// Class name
className: string
): RenderResult => {
// Get all customisations
const customisations = mergeCustomisations(
2022-06-19 16:16:11 +00:00
defaultExtendedIconCustomisations,
props as IconifyIconCustomisations
2022-06-19 16:16:11 +00:00
);
// Create empty style
let style = '';
// Get element properties
for (let key in props) {
const value = props[key];
if (value === void 0) {
continue;
}
switch (key) {
// Properties to ignore
case 'icon':
case 'onLoad':
break;
// Boolean attributes
case 'inline':
case 'hFlip':
case 'vFlip':
customisations[key] =
value === true || value === 'true' || value === 1;
break;
// Flip as string: 'horizontal,vertical'
case 'flip':
if (typeof value === 'string') {
flipFromString(customisations, value);
}
break;
// Color: copy to style
case 'color':
style += 'color: ' + value + ';';
break;
// Rotation as string
case 'rotate':
if (typeof value === 'string') {
customisations[key] = rotateFromString(value);
} else if (typeof value === 'number') {
customisations[key] = value;
}
break;
// Ignore other properties
}
}
// Generate icon
const item = iconToSVG(icon, customisations);
// Counter for ids based on "id" property to render icons consistently on server and client
let localCounter = 0;
let id = props.id;
if (typeof id === 'string') {
// Convert '-' to '_' to avoid errors in animations
id = id.replace(/-/g, '_');
}
// Create body
const body = replaceIDs(
item.body,
id ? () => id + 'ID' + localCounter++ : 'iconifyEmber'
);
// Add inline
2022-06-19 16:16:11 +00:00
if (customisations.inline) {
style += 'vertical-align: -0.125em;';
}
return {
...item.attributes,
2022-03-11 16:39:57 +00:00
style: style === '' ? void 0 : htmlSafe(style),
className,
body,
};
};