load.ts 1.5 KB

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