2
0
mirror of https://github.com/iconify/iconify.git synced 2024-12-12 05:37:49 +00:00

feat: add custom loader to svelte component, also add ssr prop to match vue component

This commit is contained in:
Vjacheslav Trushkin 2024-11-03 22:28:37 +02:00
parent d070e3a50a
commit 69b6290f7b
6 changed files with 76 additions and 4 deletions

View File

@ -16,6 +16,8 @@ import {
buildIcon,
loadIcons,
loadIcon,
setCustomIconLoader,
setCustomIconsLoader,
addAPIProvider,
_api
} from './functions';
@ -34,6 +36,8 @@ export {
buildIcon,
loadIcons,
loadIcon,
setCustomIconLoader,
setCustomIconsLoader,
addAPIProvider,
_api
}
@ -79,7 +83,8 @@ export {
// Generate data
$: {
counter;
const iconData = checkIconState($$props.icon, state, mounted, loaded, onLoad);
const isMounted = !!$$props.ssr || mounted;
const iconData = checkIconState($$props.icon, state, isMounted, loaded, onLoad);
data = iconData ? generateIcon(iconData.data, $$props) : null;
if (data && iconData.classes) {
// Add classes

View File

@ -22,6 +22,10 @@ import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
import { defaultIconProps } from '@iconify/utils/lib/icon/defaults';
// API
import type {
IconifyCustomIconLoader,
IconifyCustomIconsLoader,
} from '@iconify/core/lib/api/types';
import type {
IconifyAPIFunctions,
IconifyAPIInternalFunctions,
@ -54,6 +58,10 @@ import type {
IconifyIconLoaderAbort,
} from '@iconify/core/lib/api/icons';
import { loadIcons, loadIcon } from '@iconify/core/lib/api/icons';
import {
setCustomIconLoader,
setCustomIconsLoader,
} from '@iconify/core/lib/api/loaders';
import { sendAPIQuery } from '@iconify/core/lib/api/query';
// Cache
@ -112,6 +120,8 @@ export {
PartialIconifyAPIConfig,
IconifyAPIQueryParams,
IconifyAPICustomQueryParams,
IconifyCustomIconLoader,
IconifyCustomIconsLoader,
};
// Builder functions
@ -360,7 +370,13 @@ const _api: IconifyAPIInternalFunctions = {
export { _api };
// IconifyAPIFunctions
export { addAPIProvider, loadIcons, loadIcon };
export {
addAPIProvider,
loadIcons,
loadIcon,
setCustomIconLoader,
setCustomIconsLoader,
};
// IconifyStorageFunctions
export {

View File

@ -34,6 +34,8 @@ export {
PartialIconifyAPIConfig,
IconifyAPIQueryParams,
IconifyAPICustomQueryParams,
IconifyCustomIconLoader,
IconifyCustomIconsLoader,
} from './functions';
// Builder functions
@ -60,4 +62,11 @@ export {
export { calculateSize, replaceIDs, buildIcon } from './functions';
export { loadIcons, loadIcon, addAPIProvider, _api } from './functions';
export {
addAPIProvider,
loadIcons,
loadIcon,
setCustomIconLoader,
setCustomIconsLoader,
_api,
} from './functions';

View File

@ -21,6 +21,9 @@ export type IconifyIconCustomisations = RawIconifyIconCustomisations & {
// Inline mode
inline?: boolean;
// SSR: render icon instantly without waiting for component to mount
ssr?: boolean;
};
export const defaultExtendedIconCustomisations = {

View File

@ -112,6 +112,7 @@ export function render(
case 'style':
case 'onLoad':
case 'mode':
case 'ssr':
break;
// Boolean attributes

View File

@ -1,6 +1,6 @@
import { describe, test, expect } from 'vitest';
import { render } from '@testing-library/svelte';
import Icon from '../../';
import Icon, { setCustomIconLoader, loadIcon } from '../../';
const iconData = {
body: '<path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"/>',
@ -35,4 +35,42 @@ describe('Creating component', () => {
const style = node.style;
expect(typeof style).toBe('object');
});
test('custom loader', async () => {
const prefix = 'customLoader';
const name = 'TestIcon';
// Set custom loader and load icon data
setCustomIconLoader(() => {
return iconData;
}, prefix);
await loadIcon(`${prefix}:${name}`);
// Create component
const component = render(Icon, {
'icon': `${prefix}:${name}`,
'ssr': true,
'on:load': () => {
// Should be called only for icons loaded from API
throw new Error('onLoad called for object!');
},
});
const node = component.container.querySelector('svg')!;
expect(node).not.toBeNull();
expect(node.parentNode).not.toBeNull();
const html = (node.parentNode as HTMLDivElement).innerHTML;
// Check HTML
expect(html.replace(/<!--(.*?)-->/gm, '')).toBe(
`<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" width="1em" height="1em" viewBox="0 0 24 24" class="iconify iconify--${prefix}"><path d="M4 19h16v2H4zm5-4h11v2H9zm-5-4h16v2H4zm0-8h16v2H4zm5 4h11v2H9z" fill="currentColor"></path></svg>`
);
// Make sure getAttribute() works, used in other tests
expect(node.getAttribute('xmlns')).toBe('http://www.w3.org/2000/svg');
expect(node.getAttribute('aria-hidden')).toBe('true');
// Make sure style exists
const style = node.style;
expect(typeof style).toBe('object');
});
});