mirror of
https://github.com/iconify/iconify.git
synced 2025-01-07 15:44:05 +00:00
Web component: add status property
This commit is contained in:
parent
62a643cac9
commit
2365d9ff1c
@ -16,12 +16,20 @@ import { renderIcon } from './render/icon';
|
|||||||
import { updateStyle } from './render/style';
|
import { updateStyle } from './render/style';
|
||||||
import { IconState, setPendingState } from './state';
|
import { IconState, setPendingState } from './state';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Icon status
|
||||||
|
*/
|
||||||
|
export type IconifyIconStatus = 'rendered' | 'loading' | 'failed';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface
|
* Interface
|
||||||
*/
|
*/
|
||||||
declare interface PartialIconifyIconHTMLElement extends HTMLElement {
|
declare interface PartialIconifyIconHTMLElement extends HTMLElement {
|
||||||
// Restart animation for animated icons
|
// Restart animation for animated icons
|
||||||
restartAnimation: () => void;
|
restartAnimation: () => void;
|
||||||
|
|
||||||
|
// Get status
|
||||||
|
get status(): IconifyIconStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add dynamically generated getters and setters
|
// Add dynamically generated getters and setters
|
||||||
@ -97,6 +105,9 @@ export function defineIconifyIcon(
|
|||||||
// State
|
// State
|
||||||
_state: IconState;
|
_state: IconState;
|
||||||
|
|
||||||
|
// Attributes check queued
|
||||||
|
_checkQueued = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
@ -113,16 +124,15 @@ export function defineIconifyIcon(
|
|||||||
updateStyle(root, inline);
|
updateStyle(root, inline);
|
||||||
|
|
||||||
// Create empty state
|
// Create empty state
|
||||||
const value = this.getAttribute('icon');
|
|
||||||
this._state = setPendingState(
|
this._state = setPendingState(
|
||||||
{
|
{
|
||||||
value,
|
value: '',
|
||||||
},
|
},
|
||||||
inline
|
inline
|
||||||
);
|
);
|
||||||
|
|
||||||
// Update icon
|
// Queue icon render
|
||||||
this._iconChanged(value);
|
this._queueCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,51 +145,19 @@ export function defineIconifyIcon(
|
|||||||
/**
|
/**
|
||||||
* Attribute has changed
|
* Attribute has changed
|
||||||
*/
|
*/
|
||||||
attributeChangedCallback(
|
attributeChangedCallback(name: string) {
|
||||||
name: string,
|
if (name === 'inline') {
|
||||||
oldValue: unknown,
|
// Update immediately: not affected by other attributes
|
||||||
newValue: unknown
|
const newInline = getInline(this);
|
||||||
) {
|
const state = this._state;
|
||||||
const state = this._state;
|
if (newInline !== state.inline) {
|
||||||
switch (name as keyof IconifyIconAttributes) {
|
// Update style if inline mode changed
|
||||||
case 'icon': {
|
state.inline = newInline;
|
||||||
this._iconChanged(newValue);
|
updateStyle(this._shadowRoot, newInline);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'inline': {
|
|
||||||
const newInline = getInline(this);
|
|
||||||
if (newInline !== state.inline) {
|
|
||||||
// Update style if inline mode changed
|
|
||||||
state.inline = newInline;
|
|
||||||
updateStyle(this._shadowRoot, newInline);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'mode': {
|
|
||||||
if (state.rendered) {
|
|
||||||
// Re-render if icon is currently being renrered
|
|
||||||
this._renderIcon(state.icon);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
if (state.rendered) {
|
|
||||||
// Check customisations only if icon has been rendered
|
|
||||||
const newCustomisations = getCustomisations(this);
|
|
||||||
if (
|
|
||||||
haveCustomisationsChanged(
|
|
||||||
newCustomisations,
|
|
||||||
state.customisations
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
// Re-render
|
|
||||||
this._renderIcon(state.icon, newCustomisations);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Queue check for other attributes
|
||||||
|
this._queueCheck();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,6 +214,64 @@ export function defineIconifyIcon(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get status
|
||||||
|
*/
|
||||||
|
get status(): IconifyIconStatus {
|
||||||
|
const state = this._state;
|
||||||
|
return state.rendered
|
||||||
|
? 'rendered'
|
||||||
|
: state.icon.data === null
|
||||||
|
? 'failed'
|
||||||
|
: 'loading';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue attributes re-check
|
||||||
|
*/
|
||||||
|
_queueCheck() {
|
||||||
|
if (!this._checkQueued) {
|
||||||
|
this._checkQueued = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
this._check();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for changes
|
||||||
|
*/
|
||||||
|
_check() {
|
||||||
|
if (!this._checkQueued) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._checkQueued = false;
|
||||||
|
|
||||||
|
const state = this._state;
|
||||||
|
|
||||||
|
// Get icon
|
||||||
|
const newIcon = this.getAttribute('icon');
|
||||||
|
if (newIcon !== state.icon.value) {
|
||||||
|
this._iconChanged(newIcon);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore other attributes if icon is not rendered
|
||||||
|
if (!state.rendered) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for mode and attribute changes
|
||||||
|
const mode = this.getAttribute('mode');
|
||||||
|
const customisations = getCustomisations(this);
|
||||||
|
if (
|
||||||
|
state.attrMode !== mode ||
|
||||||
|
haveCustomisationsChanged(state.customisations, customisations)
|
||||||
|
) {
|
||||||
|
this._renderIcon(state.icon, customisations, mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Icon value has changed
|
* Icon value has changed
|
||||||
*/
|
*/
|
||||||
@ -243,7 +279,7 @@ export function defineIconifyIcon(
|
|||||||
const icon = parseIconValue(newValue, (value, name, data) => {
|
const icon = parseIconValue(newValue, (value, name, data) => {
|
||||||
// Asynchronous callback: re-check values to make sure stuff wasn't changed
|
// Asynchronous callback: re-check values to make sure stuff wasn't changed
|
||||||
const state = this._state;
|
const state = this._state;
|
||||||
if (state.rendered || state.icon.value !== value) {
|
if (state.rendered || this.getAttribute('icon') !== value) {
|
||||||
// Icon data is already available or icon attribute was changed
|
// Icon data is already available or icon attribute was changed
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -257,7 +293,7 @@ export function defineIconifyIcon(
|
|||||||
|
|
||||||
if (icon.data) {
|
if (icon.data) {
|
||||||
// Render icon
|
// Render icon
|
||||||
this._renderIcon(icon as RenderedCurrentIconData);
|
this._gotIconData(icon as RenderedCurrentIconData);
|
||||||
} else {
|
} else {
|
||||||
// Nothing to render: update icon in state
|
// Nothing to render: update icon in state
|
||||||
state.icon = icon;
|
state.icon = icon;
|
||||||
@ -266,7 +302,7 @@ export function defineIconifyIcon(
|
|||||||
|
|
||||||
if (icon.data) {
|
if (icon.data) {
|
||||||
// Icon is ready to render
|
// Icon is ready to render
|
||||||
this._renderIcon(icon as RenderedCurrentIconData);
|
this._gotIconData(icon as RenderedCurrentIconData);
|
||||||
} else {
|
} else {
|
||||||
// Pending icon
|
// Pending icon
|
||||||
this._state = setPendingState(
|
this._state = setPendingState(
|
||||||
@ -277,15 +313,28 @@ export function defineIconifyIcon(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param icon
|
||||||
|
*/
|
||||||
|
_gotIconData(icon: RenderedCurrentIconData) {
|
||||||
|
this._checkQueued = false;
|
||||||
|
this._renderIcon(
|
||||||
|
icon,
|
||||||
|
getCustomisations(this),
|
||||||
|
this.getAttribute('mode')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-render based on icon data
|
* Re-render based on icon data
|
||||||
*/
|
*/
|
||||||
_renderIcon(
|
_renderIcon(
|
||||||
icon: RenderedCurrentIconData,
|
icon: RenderedCurrentIconData,
|
||||||
customisations?: RenderedIconCustomisations
|
customisations: RenderedIconCustomisations,
|
||||||
|
attrMode: string
|
||||||
) {
|
) {
|
||||||
// Get mode
|
// Get mode
|
||||||
const attrMode = this.getAttribute('mode');
|
|
||||||
const renderedMode = getRenderMode(icon.data.body, attrMode);
|
const renderedMode = getRenderMode(icon.data.body, attrMode);
|
||||||
|
|
||||||
// Inline was not changed
|
// Inline was not changed
|
||||||
@ -298,7 +347,7 @@ export function defineIconifyIcon(
|
|||||||
rendered: true,
|
rendered: true,
|
||||||
icon,
|
icon,
|
||||||
inline,
|
inline,
|
||||||
customisations: customisations || getCustomisations(this),
|
customisations,
|
||||||
attrMode,
|
attrMode,
|
||||||
renderedMode,
|
renderedMode,
|
||||||
})
|
})
|
||||||
|
165
packages/icon/tests/component-api-test.ts
Normal file
165
packages/icon/tests/component-api-test.ts
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
import {
|
||||||
|
cleanupGlobals,
|
||||||
|
expectedBlock,
|
||||||
|
expectedInline,
|
||||||
|
setupDOM,
|
||||||
|
nextTick,
|
||||||
|
nextPrefix,
|
||||||
|
fakeAPI,
|
||||||
|
mockAPIData,
|
||||||
|
awaitUntil,
|
||||||
|
} from './helpers';
|
||||||
|
import { defineIconifyIcon, IconifyIconHTMLElement } from '../src/component';
|
||||||
|
import type { IconState } from '../src/state';
|
||||||
|
import type { IconifyMockAPIDelayDoneCallback } from '@iconify/core/lib/api/modules/mock';
|
||||||
|
|
||||||
|
export declare interface DebugIconifyIconHTMLElement
|
||||||
|
extends IconifyIconHTMLElement {
|
||||||
|
// Internal stuff, used for debugging
|
||||||
|
_shadowRoot: ShadowRoot;
|
||||||
|
_state: IconState;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('Testing icon component with API', () => {
|
||||||
|
afterEach(async () => {
|
||||||
|
await nextTick();
|
||||||
|
cleanupGlobals();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Loading icon from API', async () => {
|
||||||
|
// Setup DOM and fake API
|
||||||
|
const doc = setupDOM('').window.document;
|
||||||
|
const provider = nextPrefix();
|
||||||
|
const prefix = nextPrefix();
|
||||||
|
fakeAPI(provider);
|
||||||
|
|
||||||
|
// Define component
|
||||||
|
const IconifyIcon = defineIconifyIcon();
|
||||||
|
expect(IconifyIcon).toBeDefined();
|
||||||
|
expect(window.customElements.get('iconify-icon')).toBeDefined();
|
||||||
|
|
||||||
|
// Create element
|
||||||
|
const node = document.createElement(
|
||||||
|
'iconify-icon'
|
||||||
|
) as DebugIconifyIconHTMLElement;
|
||||||
|
|
||||||
|
// Should be empty
|
||||||
|
expect(node._shadowRoot.innerHTML).toBe(
|
||||||
|
`<style>${expectedBlock}</style>`
|
||||||
|
);
|
||||||
|
expect(node.status).toBe('loading');
|
||||||
|
|
||||||
|
// Mock data
|
||||||
|
const name = 'mock-test';
|
||||||
|
const iconName = `@${provider}:${prefix}:${name}`;
|
||||||
|
|
||||||
|
let sendQuery: IconifyMockAPIDelayDoneCallback | undefined;
|
||||||
|
mockAPIData({
|
||||||
|
type: 'icons',
|
||||||
|
provider,
|
||||||
|
prefix,
|
||||||
|
response: {
|
||||||
|
prefix,
|
||||||
|
icons: {
|
||||||
|
[name]: {
|
||||||
|
body: '<g />',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
delay: (next) => {
|
||||||
|
sendQuery = next;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set icon
|
||||||
|
node.setAttribute('icon', iconName);
|
||||||
|
expect(node.icon).toEqual(iconName);
|
||||||
|
expect(node.getAttribute('icon')).toBe(iconName);
|
||||||
|
|
||||||
|
// Should not have sent query to API yet
|
||||||
|
expect(sendQuery).toBeUndefined();
|
||||||
|
expect(node._shadowRoot.innerHTML).toBe(
|
||||||
|
`<style>${expectedBlock}</style>`
|
||||||
|
);
|
||||||
|
expect(node.status).toBe('loading');
|
||||||
|
|
||||||
|
// Wait until sendQuery is defined and send response
|
||||||
|
await awaitUntil(() => !!sendQuery);
|
||||||
|
sendQuery();
|
||||||
|
|
||||||
|
// Wait until icon exists
|
||||||
|
const iconExists = node.iconExists;
|
||||||
|
await awaitUntil(() => iconExists(iconName));
|
||||||
|
|
||||||
|
// Wait for render
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
// Should render SVG
|
||||||
|
const blankSVG =
|
||||||
|
'<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16"><g></g></svg>';
|
||||||
|
expect(node._shadowRoot.innerHTML).toBe(
|
||||||
|
`<style>${expectedBlock}</style>${blankSVG}`
|
||||||
|
);
|
||||||
|
expect(node.status).toBe('rendered');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Failing to load from API', async () => {
|
||||||
|
// Setup DOM and fake API
|
||||||
|
const doc = setupDOM('').window.document;
|
||||||
|
const provider = nextPrefix();
|
||||||
|
const prefix = nextPrefix();
|
||||||
|
fakeAPI(provider);
|
||||||
|
|
||||||
|
// Define component
|
||||||
|
const IconifyIcon = defineIconifyIcon();
|
||||||
|
expect(IconifyIcon).toBeDefined();
|
||||||
|
expect(window.customElements.get('iconify-icon')).toBeDefined();
|
||||||
|
|
||||||
|
// Create element
|
||||||
|
const node = document.createElement(
|
||||||
|
'iconify-icon'
|
||||||
|
) as DebugIconifyIconHTMLElement;
|
||||||
|
|
||||||
|
// Should be empty
|
||||||
|
expect(node._shadowRoot.innerHTML).toBe(
|
||||||
|
`<style>${expectedBlock}</style>`
|
||||||
|
);
|
||||||
|
expect(node.status).toBe('loading');
|
||||||
|
|
||||||
|
// Mock data
|
||||||
|
const name = 'mock-test';
|
||||||
|
const iconName = `@${provider}:${prefix}:${name}`;
|
||||||
|
|
||||||
|
mockAPIData({
|
||||||
|
type: 'icons',
|
||||||
|
provider,
|
||||||
|
prefix,
|
||||||
|
response: {
|
||||||
|
prefix,
|
||||||
|
icons: {},
|
||||||
|
not_found: [name],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set icon
|
||||||
|
node.setAttribute('icon', iconName);
|
||||||
|
expect(node.icon).toEqual(iconName);
|
||||||
|
expect(node.getAttribute('icon')).toBe(iconName);
|
||||||
|
|
||||||
|
// Should not have sent query to API yet
|
||||||
|
expect(node._shadowRoot.innerHTML).toBe(
|
||||||
|
`<style>${expectedBlock}</style>`
|
||||||
|
);
|
||||||
|
expect(node.status).toBe('loading');
|
||||||
|
|
||||||
|
// Wait until status changes
|
||||||
|
expect(node.status).toBe('loading');
|
||||||
|
await awaitUntil(() => node.status !== 'loading');
|
||||||
|
|
||||||
|
// Should fail to render
|
||||||
|
expect(node._shadowRoot.innerHTML).toBe(
|
||||||
|
`<style>${expectedBlock}</style>`
|
||||||
|
);
|
||||||
|
expect(node.status).toBe('failed');
|
||||||
|
});
|
||||||
|
});
|
@ -3,6 +3,7 @@ import {
|
|||||||
expectedBlock,
|
expectedBlock,
|
||||||
expectedInline,
|
expectedInline,
|
||||||
setupDOM,
|
setupDOM,
|
||||||
|
nextTick,
|
||||||
} from './helpers';
|
} from './helpers';
|
||||||
import { defineIconifyIcon, IconifyIconHTMLElement } from '../src/component';
|
import { defineIconifyIcon, IconifyIconHTMLElement } from '../src/component';
|
||||||
import type { IconState } from '../src/state';
|
import type { IconState } from '../src/state';
|
||||||
@ -15,7 +16,10 @@ export declare interface DebugIconifyIconHTMLElement
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('Testing icon component', () => {
|
describe('Testing icon component', () => {
|
||||||
afterEach(cleanupGlobals);
|
afterEach(async () => {
|
||||||
|
await nextTick();
|
||||||
|
cleanupGlobals();
|
||||||
|
});
|
||||||
|
|
||||||
it('Registering component', () => {
|
it('Registering component', () => {
|
||||||
// Setup DOM
|
// Setup DOM
|
||||||
@ -35,6 +39,7 @@ describe('Testing icon component', () => {
|
|||||||
'iconify-icon'
|
'iconify-icon'
|
||||||
) as DebugIconifyIconHTMLElement;
|
) as DebugIconifyIconHTMLElement;
|
||||||
expect(node instanceof IconifyIcon).toBe(true);
|
expect(node instanceof IconifyIcon).toBe(true);
|
||||||
|
expect(node.status).toBe('loading');
|
||||||
|
|
||||||
// Define component again (should return previous class)
|
// Define component again (should return previous class)
|
||||||
const IconifyIcon2 = defineIconifyIcon();
|
const IconifyIcon2 = defineIconifyIcon();
|
||||||
@ -45,9 +50,10 @@ describe('Testing icon component', () => {
|
|||||||
'iconify-icon'
|
'iconify-icon'
|
||||||
) as DebugIconifyIconHTMLElement;
|
) as DebugIconifyIconHTMLElement;
|
||||||
expect(node2 instanceof IconifyIcon).toBe(true);
|
expect(node2 instanceof IconifyIcon).toBe(true);
|
||||||
|
expect(node2.status).toBe('loading');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Creating component instance, changing properties', () => {
|
it('Creating component instance, changing properties', async () => {
|
||||||
// Setup DOM
|
// Setup DOM
|
||||||
const doc = setupDOM('').window.document;
|
const doc = setupDOM('').window.document;
|
||||||
|
|
||||||
@ -69,6 +75,7 @@ describe('Testing icon component', () => {
|
|||||||
expect(node._shadowRoot.innerHTML).toBe(
|
expect(node._shadowRoot.innerHTML).toBe(
|
||||||
`<style>${expectedBlock}</style>`
|
`<style>${expectedBlock}</style>`
|
||||||
);
|
);
|
||||||
|
expect(node.status).toBe('loading');
|
||||||
|
|
||||||
// Check for dynamically added methods
|
// Check for dynamically added methods
|
||||||
expect(typeof node.loadIcon).toBe('function');
|
expect(typeof node.loadIcon).toBe('function');
|
||||||
@ -87,12 +94,20 @@ describe('Testing icon component', () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Should still be empty: waiting for next tick
|
||||||
|
expect(node._shadowRoot.innerHTML).toBe(
|
||||||
|
`<style>${expectedBlock}</style>`
|
||||||
|
);
|
||||||
|
expect(node.status).toBe('loading');
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
// Should render SVG
|
// Should render SVG
|
||||||
const blankSVG =
|
const blankSVG =
|
||||||
'<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16"><g></g></svg>';
|
'<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16"><g></g></svg>';
|
||||||
expect(node._shadowRoot.innerHTML).toBe(
|
expect(node._shadowRoot.innerHTML).toBe(
|
||||||
`<style>${expectedBlock}</style>${blankSVG}`
|
`<style>${expectedBlock}</style>${blankSVG}`
|
||||||
);
|
);
|
||||||
|
expect(node.status).toBe('rendered');
|
||||||
|
|
||||||
// Check inline attribute
|
// Check inline attribute
|
||||||
expect(node.inline).toBe(false);
|
expect(node.inline).toBe(false);
|
||||||
@ -106,6 +121,7 @@ describe('Testing icon component', () => {
|
|||||||
expect(node._shadowRoot.innerHTML).toBe(
|
expect(node._shadowRoot.innerHTML).toBe(
|
||||||
`<style>${expectedInline}</style>${blankSVG}`
|
`<style>${expectedInline}</style>${blankSVG}`
|
||||||
);
|
);
|
||||||
|
expect(node.status).toBe('rendered');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Testing changes to inline', () => {
|
it('Testing changes to inline', () => {
|
||||||
@ -125,6 +141,7 @@ describe('Testing icon component', () => {
|
|||||||
const node = document.createElement(
|
const node = document.createElement(
|
||||||
'iconify-icon'
|
'iconify-icon'
|
||||||
) as DebugIconifyIconHTMLElement;
|
) as DebugIconifyIconHTMLElement;
|
||||||
|
expect(node.status).toBe('loading');
|
||||||
|
|
||||||
// Should be empty with block style
|
// Should be empty with block style
|
||||||
expect(node._shadowRoot.innerHTML).toBe(
|
expect(node._shadowRoot.innerHTML).toBe(
|
||||||
@ -165,6 +182,9 @@ describe('Testing icon component', () => {
|
|||||||
expect(node.inline).toBe(true);
|
expect(node.inline).toBe(true);
|
||||||
expect(node.hasAttribute('inline')).toBe(true);
|
expect(node.hasAttribute('inline')).toBe(true);
|
||||||
expect(node.getAttribute('inline')).toBeTruthy();
|
expect(node.getAttribute('inline')).toBeTruthy();
|
||||||
|
|
||||||
|
// No icon data, so still loading
|
||||||
|
expect(node.status).toBe('loading');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Restarting animation', async () => {
|
it('Restarting animation', async () => {
|
||||||
@ -183,6 +203,7 @@ describe('Testing icon component', () => {
|
|||||||
const node = document.createElement(
|
const node = document.createElement(
|
||||||
'iconify-icon'
|
'iconify-icon'
|
||||||
) as DebugIconifyIconHTMLElement;
|
) as DebugIconifyIconHTMLElement;
|
||||||
|
expect(node.status).toBe('loading');
|
||||||
|
|
||||||
// Set icon
|
// Set icon
|
||||||
const body =
|
const body =
|
||||||
@ -199,7 +220,11 @@ describe('Testing icon component', () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Wait to render
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
// Should render SPAN, with comment
|
// Should render SPAN, with comment
|
||||||
|
expect(node.status).toBe('rendered');
|
||||||
const renderedIconWithComment =
|
const renderedIconWithComment =
|
||||||
"<span style=\"--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Crect width='10' height='10'%3E%3Canimate attributeName='width' values='10;5;10' dur='10s' repeatCount='indefinite' /%3E%3C/rect%3E%3C!-- --%3E%3C/svg%3E"); width: 1em; height: 1em; background-color: transparent; background-repeat: no-repeat; background-size: 100% 100%;\"></span>";
|
"<span style=\"--svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Crect width='10' height='10'%3E%3Canimate attributeName='width' values='10;5;10' dur='10s' repeatCount='indefinite' /%3E%3C/rect%3E%3C!-- --%3E%3C/svg%3E"); width: 1em; height: 1em; background-color: transparent; background-repeat: no-repeat; background-size: 100% 100%;\"></span>";
|
||||||
const html1 = node._shadowRoot.innerHTML;
|
const html1 = node._shadowRoot.innerHTML;
|
||||||
@ -215,6 +240,7 @@ describe('Testing icon component', () => {
|
|||||||
expect(html2.replace(/-- [0-9]+ --/, '-- --')).toBe(
|
expect(html2.replace(/-- [0-9]+ --/, '-- --')).toBe(
|
||||||
`<style>${expectedBlock}</style>${renderedIconWithComment}`
|
`<style>${expectedBlock}</style>${renderedIconWithComment}`
|
||||||
);
|
);
|
||||||
|
expect(node.status).toBe('rendered');
|
||||||
|
|
||||||
// Small delay to make sure timer is increased to get new number
|
// Small delay to make sure timer is increased to get new number
|
||||||
await new Promise((fulfill) => {
|
await new Promise((fulfill) => {
|
||||||
@ -230,9 +256,10 @@ describe('Testing icon component', () => {
|
|||||||
);
|
);
|
||||||
expect(html3).not.toBe(html1);
|
expect(html3).not.toBe(html1);
|
||||||
expect(html3).not.toBe(html2);
|
expect(html3).not.toBe(html2);
|
||||||
|
expect(node.status).toBe('rendered');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Restarting animation for SVG', () => {
|
it('Restarting animation for SVG', async () => {
|
||||||
// Setup DOM
|
// Setup DOM
|
||||||
const doc = setupDOM('').window.document;
|
const doc = setupDOM('').window.document;
|
||||||
|
|
||||||
@ -248,6 +275,7 @@ describe('Testing icon component', () => {
|
|||||||
const node = document.createElement(
|
const node = document.createElement(
|
||||||
'iconify-icon'
|
'iconify-icon'
|
||||||
) as DebugIconifyIconHTMLElement;
|
) as DebugIconifyIconHTMLElement;
|
||||||
|
expect(node.status).toBe('loading');
|
||||||
|
|
||||||
// Set icon
|
// Set icon
|
||||||
const body =
|
const body =
|
||||||
@ -265,7 +293,11 @@ describe('Testing icon component', () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Wait to render
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
// Should render SVG
|
// Should render SVG
|
||||||
|
expect(node.status).toBe('rendered');
|
||||||
const renderedIcon =
|
const renderedIcon =
|
||||||
'<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16"><rect width="10" height="10"><animate attributeName="width" values="10;5;10" dur="10s" repeatCount="indefinite"></animate></rect></svg>';
|
'<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16"><rect width="10" height="10"><animate attributeName="width" values="10;5;10" dur="10s" repeatCount="indefinite"></animate></rect></svg>';
|
||||||
const html1 = node._shadowRoot.innerHTML;
|
const html1 = node._shadowRoot.innerHTML;
|
||||||
@ -288,5 +320,7 @@ describe('Testing icon component', () => {
|
|||||||
} else {
|
} else {
|
||||||
expect(svg2).not.toBe(svg1);
|
expect(svg2).not.toBe(svg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expect(node.status).toBe('rendered');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user