UNPKG

ember-svg-jar

Version:

Best way to use SVG images in Ember applications

92 lines (71 loc) 2.61 kB
import { assign } from '@ember/polyfills'; import { isNone } from '@ember/utils'; import { htmlSafe } from '@ember/template'; const accessibilityElements = ['title', 'desc']; export function sanitizeAttrs(attrs) { let attrsCopy = Object.assign({}, attrs); Object.keys(attrsCopy).forEach((key) => { let element = document.createElement('div'); element.innerText = attrsCopy[key]; attrsCopy[key] = element.innerHTML; }); return attrsCopy; } export function createAccessibilityElements(attrs) { const sanitizedAttrs = sanitizeAttrs(attrs); const { title, desc } = sanitizedAttrs; if (!title && !desc) { return ''; } return accessibilityElements.reduce((elements, tag) => { if (sanitizedAttrs[tag]) { return elements.concat(`<${tag} id="${tag}">${sanitizedAttrs[tag]}</${tag}>`); } return elements; }, ''); } export function createAriaLabel(attrs) { const { title, desc } = attrs; if (!title && !desc) { return ''; } return `aria-labelledby="${accessibilityElements.filter((tag) => attrs[tag]).join(' ')}"`; } export function formatAttrs(attrs) { return Object.keys(attrs) .filter((attr) => !(accessibilityElements.includes(attr))) .map((key) => !isNone(attrs[key]) && `${key}="${attrs[key]}"`) .filter((attr) => attr) .join(' '); } export function symbolUseFor(assetId, attrs = {}) { return `<svg ${formatAttrs(attrs)}${createAriaLabel(attrs)}><use xlink:href="${assetId}" />${createAccessibilityElements(attrs)}</svg>`; } export function inlineSvgFor(assetId, getInlineAsset, attrs = {}) { let asset = getInlineAsset(assetId); if (!asset) { // eslint-disable-next-line no-console console.warn(`ember-svg-jar: Missing inline SVG for ${assetId}`); return; } let svgAttrs = asset.attrs ? assign({}, asset.attrs, attrs) : attrs; let { size } = attrs; if (size) { svgAttrs.width = parseFloat(svgAttrs.width) * size || svgAttrs.width; svgAttrs.height = parseFloat(svgAttrs.height) * size || svgAttrs.height; delete svgAttrs.size; } return `<svg ${formatAttrs(svgAttrs)}${createAriaLabel(attrs)}>${createAccessibilityElements(attrs)}${asset.content}</svg>`; } export default function makeSvg(assetId, attrs = {}, getInlineAsset) { if (!assetId) { // eslint-disable-next-line no-console console.warn('ember-svg-jar: asset name should not be undefined or null'); return; } let isSymbol = assetId.lastIndexOf('#', 0) === 0; let svg = isSymbol ? symbolUseFor(assetId, attrs) : inlineSvgFor(assetId, getInlineAsset, attrs); return htmlSafe(svg); }