load.ts 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import { addIcon, type IconifyIcon } from '@vben-core/icons';
  2. let loaded = false;
  3. if (!loaded) {
  4. loadSvgIcons();
  5. loaded = true;
  6. }
  7. function parseSvg(svgData: string): IconifyIcon {
  8. const parser = new DOMParser();
  9. const xmlDoc = parser.parseFromString(svgData, 'image/svg+xml');
  10. const svgElement = xmlDoc.documentElement;
  11. const svgContent = [...svgElement.childNodes]
  12. .filter((node) => node.nodeType === Node.ELEMENT_NODE)
  13. .map((node) => new XMLSerializer().serializeToString(node))
  14. .join('');
  15. const viewBoxValue = svgElement.getAttribute('viewBox') || '';
  16. const [left, top, width, height] = viewBoxValue.split(' ').map((val) => {
  17. const num = Number(val);
  18. return Number.isNaN(num) ? undefined : num;
  19. });
  20. return {
  21. body: svgContent,
  22. height,
  23. left,
  24. top,
  25. width,
  26. };
  27. }
  28. /**
  29. * 自定义的svg图片转化为组件
  30. * @example ./svg/avatar.svg
  31. * <Icon icon="svg:avatar"></Icon>
  32. */
  33. async function loadSvgIcons() {
  34. const svgEagers = import.meta.glob('./icons/**', {
  35. eager: true,
  36. query: '?raw',
  37. });
  38. await Promise.all(
  39. Object.entries(svgEagers).map((svg) => {
  40. const [key, body] = svg as [string, { default: string } | string];
  41. // ./icons/xxxx.svg => xxxxxx
  42. const start = key.lastIndexOf('/') + 1;
  43. const end = key.lastIndexOf('.');
  44. const iconName = key.slice(start, end);
  45. return addIcon(`svg:${iconName}`, {
  46. ...parseSvg(typeof body === 'object' ? body.default : body),
  47. });
  48. }),
  49. );
  50. }