import { defaultIconProps } from '@iconify/utils/lib/icon/defaults'; import { cleanupGlobals, setupDOM, waitDOMReady } from './helpers'; import { scanRootNode } from '../src/scanner/find'; import { renderInlineSVG } from '../src/render/svg'; import type { IconifyIcon } from '@iconify/utils/lib/icon/defaults'; import { elementDataProperty, IconifyElement } from '../src/scanner/config'; describe('Testing re-rendering nodes', () => { afterEach(cleanupGlobals); type TestIconCallback = (svg: IconifyElement) => IconifyIcon; const testIcon = async ( placeholder: string, data: IconifyIcon, expected1: string, callback1: TestIconCallback, expected2: string, callback2?: TestIconCallback, expected3?: string ): Promise => { setupDOM(placeholder); await waitDOMReady(); function scan(expected: string): IconifyElement { // Find node const root = document.body; const items = scanRootNode(root); expect(items.length).toBe(1); // Get node and render it const { node, props } = items[0]; const svg = renderInlineSVG(node, props, { ...defaultIconProps, ...data, }); // Find SVG in DOM expect(root.childNodes.length).toBe(1); const expectedSVG = root.childNodes[0]; expect(expectedSVG).toBe(svg); // Get HTML const html = root.innerHTML; expect(html).toBe(expected); return svg; } // Initial scan const svg1 = scan(expected1); // Change element data = callback1(svg1); // Scan again const svg2 = scan(expected2); if (!callback2) { return svg2; } // Change element again data = callback2(svg2); // Scan DOM and return result return scan(expected3); }; it('Changing content', async () => { const svg = await testIcon( '', { body: '', width: 24, height: 24, }, '', (svg) => { const data = svg[elementDataProperty]; expect(data.status).toBe('loaded'); expect(data.addedClasses).toEqual(['iconify--mdi']); expect(data.addedStyles).toEqual([]); // Change icon name and size svg.setAttribute('data-icon', 'mdi-light:home-outline'); svg.setAttribute('data-height', 'auto'); return { body: '', width: 32, height: 32, }; }, '' ); const data = svg[elementDataProperty]; expect(data.status).toBe('loaded'); expect(data.addedClasses).toEqual(['iconify--mdi-light']); expect(data.addedStyles).toEqual([]); }); it('Toggle inline and block using class', async () => { const iconData: IconifyIcon = { body: '', width: 24, height: 24, }; const svg = await testIcon( '', iconData, '', (svg) => { const data = svg[elementDataProperty]; expect(data.status).toBe('loaded'); expect(data.addedClasses).toEqual(['iconify--mdi']); expect(data.addedStyles).toEqual([]); // Set inline by adding class svg.classList.add('iconify-inline'); return iconData; }, '', (svg) => { const data = svg[elementDataProperty]; expect(data.status).toBe('loaded'); expect(data.addedClasses).toEqual(['iconify--mdi']); expect(data.addedStyles).toEqual(['vertical-align']); // Set block by removing class svg.classList.remove('iconify-inline'); return iconData; }, '' ); const data = svg[elementDataProperty]; expect(data.status).toBe('loaded'); expect(data.addedClasses).toEqual(['iconify--mdi']); expect(data.addedStyles).toEqual([]); }); it('Toggle inline and block using attributes', async () => { const iconData: IconifyIcon = { body: '', width: 24, height: 24, }; const svg = await testIcon( '', iconData, '', (svg) => { const data = svg[elementDataProperty]; expect(data.status).toBe('loaded'); expect(data.addedClasses).toEqual(['iconify--mdi']); expect(data.addedStyles).toEqual([]); // Set inline by adding attribute svg.setAttribute('data-inline', 'data-inline'); return iconData; }, '', (svg) => { const data = svg[elementDataProperty]; expect(data.status).toBe('loaded'); expect(data.addedClasses).toEqual(['iconify--mdi']); expect(data.addedStyles).toEqual(['vertical-align']); // Set block by setting empty attribute svg.setAttribute('data-inline', ''); return iconData; }, '' ); const data = svg[elementDataProperty]; expect(data.status).toBe('loaded'); expect(data.addedClasses).toEqual(['iconify--mdi']); expect(data.addedStyles).toEqual([]); }); it('Transformations', async () => { const svg = await testIcon( '', { body: '', width: 24, height: 24, }, '', (svg) => { const data = svg[elementDataProperty]; expect(data.status).toBe('loaded'); expect(data.addedClasses).toEqual(['iconify--mdi']); expect(data.addedStyles).toEqual([]); // Rotate and flip svg.setAttribute('data-rotate', '90deg'); svg.setAttribute('data-flip', 'vertical'); return { body: '', width: 32, height: 32, }; }, '', (svg) => { const data = svg[elementDataProperty]; expect(data.status).toBe('loaded'); expect(data.addedClasses).toEqual(['iconify--mdi']); expect(data.addedStyles).toEqual([]); // Rotate and remove flip svg.setAttribute('data-rotate', '180deg'); svg.removeAttribute('data-flip'); return { body: '', }; }, '' ); const data = svg[elementDataProperty]; expect(data.status).toBe('loaded'); expect(data.addedClasses).toEqual(['iconify--mdi']); expect(data.addedStyles).toEqual([]); }); });