mirror of
https://github.com/iconify/iconify.git
synced 2025-01-07 15:44:05 +00:00
Web component: export reusable functions
This commit is contained in:
parent
f4efa1853d
commit
9043ec684f
@ -11,6 +11,7 @@ import type {
|
|||||||
import { getInline } from './attributes/inline';
|
import { getInline } from './attributes/inline';
|
||||||
import { getRenderMode } from './attributes/mode';
|
import { getRenderMode } from './attributes/mode';
|
||||||
import type { IconifyIconAttributes } from './attributes/types';
|
import type { IconifyIconAttributes } from './attributes/types';
|
||||||
|
import { exportFunctions, IconifyExportedFunctions } from './functions';
|
||||||
import { renderIcon } from './render/icon';
|
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';
|
||||||
@ -26,6 +27,8 @@ declare interface PartialIconifyIconHTMLElement extends HTMLElement {
|
|||||||
// Add dynamically generated getters and setters
|
// Add dynamically generated getters and setters
|
||||||
export declare interface IconifyIconHTMLElement
|
export declare interface IconifyIconHTMLElement
|
||||||
extends PartialIconifyIconHTMLElement,
|
extends PartialIconifyIconHTMLElement,
|
||||||
|
// Functions added dynamically after class creation
|
||||||
|
IconifyExportedFunctions,
|
||||||
Required<IconifyIconAttributes> {}
|
Required<IconifyIconAttributes> {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,7 +39,9 @@ interface PartialIconifyIconHTMLElementClass {
|
|||||||
prototype: PartialIconifyIconHTMLElement;
|
prototype: PartialIconifyIconHTMLElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IconifyIconHTMLElementClass {
|
export interface IconifyIconHTMLElementClass
|
||||||
|
// Functions added dynamically as static methods and methods on instance
|
||||||
|
extends IconifyExportedFunctions {
|
||||||
new (): IconifyIconHTMLElement;
|
new (): IconifyIconHTMLElement;
|
||||||
prototype: IconifyIconHTMLElement;
|
prototype: IconifyIconHTMLElement;
|
||||||
}
|
}
|
||||||
@ -46,7 +51,7 @@ export interface IconifyIconHTMLElementClass {
|
|||||||
*/
|
*/
|
||||||
export function defineIconifyIcon(
|
export function defineIconifyIcon(
|
||||||
name = 'iconify-icon'
|
name = 'iconify-icon'
|
||||||
): PartialIconifyIconHTMLElementClass | undefined {
|
): IconifyIconHTMLElementClass | undefined {
|
||||||
// Check for custom elements registry and HTMLElement
|
// Check for custom elements registry and HTMLElement
|
||||||
let customElements: CustomElementRegistry;
|
let customElements: CustomElementRegistry;
|
||||||
let ParentClass: typeof HTMLElement;
|
let ParentClass: typeof HTMLElement;
|
||||||
@ -86,7 +91,7 @@ export function defineIconifyIcon(
|
|||||||
/**
|
/**
|
||||||
* Component class
|
* Component class
|
||||||
*/
|
*/
|
||||||
class IconifyIcon extends ParentClass {
|
const IconifyIcon: PartialIconifyIconHTMLElementClass = class extends ParentClass {
|
||||||
// Root
|
// Root
|
||||||
_shadowRoot: ShadowRoot;
|
_shadowRoot: ShadowRoot;
|
||||||
|
|
||||||
@ -300,7 +305,7 @@ export function defineIconifyIcon(
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// Add getters and setters
|
// Add getters and setters
|
||||||
attributes.forEach((attr) => {
|
attributes.forEach((attr) => {
|
||||||
@ -316,8 +321,19 @@ export function defineIconifyIcon(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add exported functions: both as static and instance methods
|
||||||
|
const functions = exportFunctions();
|
||||||
|
for (const key in functions) {
|
||||||
|
IconifyIcon[key] = IconifyIcon.prototype[key] = functions[key];
|
||||||
|
}
|
||||||
|
|
||||||
// Define new component
|
// Define new component
|
||||||
customElements.define(name, IconifyIcon);
|
customElements.define(name, IconifyIcon);
|
||||||
|
|
||||||
return IconifyIcon;
|
return IconifyIcon as IconifyIconHTMLElementClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create exported data: either component instance or functions
|
||||||
|
*/
|
||||||
|
export const IconifyIconComponent = defineIconifyIcon() || exportFunctions();
|
||||||
|
168
packages/icon/src/functions.ts
Normal file
168
packages/icon/src/functions.ts
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
import type { IconifyJSON } from '@iconify/types';
|
||||||
|
|
||||||
|
// Core
|
||||||
|
import type { IconifyStorageFunctions } from '@iconify/core/lib/storage/functions';
|
||||||
|
import {
|
||||||
|
iconExists,
|
||||||
|
getIcon,
|
||||||
|
addIcon,
|
||||||
|
addCollection,
|
||||||
|
} from '@iconify/core/lib/storage/functions';
|
||||||
|
import { listIcons, shareStorage } from '@iconify/core/lib/storage/storage';
|
||||||
|
import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions';
|
||||||
|
import { buildIcon } from '@iconify/core/lib/builder/functions';
|
||||||
|
import { replaceIDs } from '@iconify/utils/lib/svg/id';
|
||||||
|
import { calculateSize } from '@iconify/utils/lib/svg/size';
|
||||||
|
|
||||||
|
// API
|
||||||
|
import type {
|
||||||
|
IconifyAPIFunctions,
|
||||||
|
IconifyAPIInternalFunctions,
|
||||||
|
} from '@iconify/core/lib/api/functions';
|
||||||
|
import { setAPIModule } from '@iconify/core/lib/api/modules';
|
||||||
|
import type { PartialIconifyAPIConfig } from '@iconify/core/lib/api/config';
|
||||||
|
import {
|
||||||
|
addAPIProvider,
|
||||||
|
getAPIConfig,
|
||||||
|
listAPIProviders,
|
||||||
|
} from '@iconify/core/lib/api/config';
|
||||||
|
import {
|
||||||
|
fetchAPIModule,
|
||||||
|
setFetch,
|
||||||
|
getFetch,
|
||||||
|
} from '@iconify/core/lib/api/modules/fetch';
|
||||||
|
import { loadIcons, loadIcon } from '@iconify/core/lib/api/icons';
|
||||||
|
import { sendAPIQuery } from '@iconify/core/lib/api/query';
|
||||||
|
|
||||||
|
// Cache
|
||||||
|
import { cache } from '@iconify/core/lib/cache';
|
||||||
|
import { storeCache, loadCache } from '@iconify/core/lib/browser-storage';
|
||||||
|
import { toggleBrowserCache } from '@iconify/core/lib/browser-storage/functions';
|
||||||
|
import type {
|
||||||
|
IconifyBrowserCacheType,
|
||||||
|
IconifyBrowserCacheFunctions,
|
||||||
|
} from '@iconify/core/lib/browser-storage/functions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for exported functions
|
||||||
|
*/
|
||||||
|
export interface IconifyExportedFunctions
|
||||||
|
extends IconifyStorageFunctions,
|
||||||
|
IconifyBuilderFunctions,
|
||||||
|
IconifyBrowserCacheFunctions,
|
||||||
|
IconifyAPIFunctions {
|
||||||
|
_api: IconifyAPIInternalFunctions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get functions and initialise stuff
|
||||||
|
*/
|
||||||
|
export function exportFunctions(): IconifyExportedFunctions {
|
||||||
|
/**
|
||||||
|
* Initialise stuff
|
||||||
|
*/
|
||||||
|
// Set API module
|
||||||
|
setAPIModule('', fetchAPIModule);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Browser stuff
|
||||||
|
*/
|
||||||
|
interface WindowWithIconifyStuff {
|
||||||
|
IconifyPreload?: IconifyJSON[] | IconifyJSON;
|
||||||
|
IconifyProviders?: Record<string, PartialIconifyAPIConfig>;
|
||||||
|
}
|
||||||
|
let _window: WindowWithIconifyStuff;
|
||||||
|
try {
|
||||||
|
_window = window as WindowWithIconifyStuff;
|
||||||
|
} catch (err) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
if (_window) {
|
||||||
|
// Set cache and load existing cache
|
||||||
|
cache.store = storeCache;
|
||||||
|
loadCache();
|
||||||
|
|
||||||
|
// Load icons from global "IconifyPreload"
|
||||||
|
if (_window.IconifyPreload !== void 0) {
|
||||||
|
const preload = _window.IconifyPreload;
|
||||||
|
const err = 'Invalid IconifyPreload syntax.';
|
||||||
|
if (typeof preload === 'object' && preload !== null) {
|
||||||
|
(preload instanceof Array ? preload : [preload]).forEach(
|
||||||
|
(item) => {
|
||||||
|
try {
|
||||||
|
if (
|
||||||
|
// Check if item is an object and not null/array
|
||||||
|
typeof item !== 'object' ||
|
||||||
|
item === null ||
|
||||||
|
item instanceof Array ||
|
||||||
|
// Check for 'icons' and 'prefix'
|
||||||
|
typeof item.icons !== 'object' ||
|
||||||
|
typeof item.prefix !== 'string' ||
|
||||||
|
// Add icon set
|
||||||
|
!addCollection(item)
|
||||||
|
) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set API from global "IconifyProviders"
|
||||||
|
if (_window.IconifyProviders !== void 0) {
|
||||||
|
const providers = _window.IconifyProviders;
|
||||||
|
if (typeof providers === 'object' && providers !== null) {
|
||||||
|
for (const key in providers) {
|
||||||
|
const err = 'IconifyProviders[' + key + '] is invalid.';
|
||||||
|
try {
|
||||||
|
const value = providers[key];
|
||||||
|
if (
|
||||||
|
typeof value !== 'object' ||
|
||||||
|
!value ||
|
||||||
|
value.resources === void 0
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!addAPIProvider(key, value)) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const _api: IconifyAPIInternalFunctions = {
|
||||||
|
getAPIConfig,
|
||||||
|
setAPIModule,
|
||||||
|
sendAPIQuery,
|
||||||
|
setFetch,
|
||||||
|
getFetch,
|
||||||
|
listAPIProviders,
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
enableCache: (storage: IconifyBrowserCacheType) =>
|
||||||
|
toggleBrowserCache(storage, true),
|
||||||
|
disableCache: (storage: IconifyBrowserCacheType) =>
|
||||||
|
toggleBrowserCache(storage, false),
|
||||||
|
iconExists,
|
||||||
|
getIcon,
|
||||||
|
listIcons,
|
||||||
|
shareStorage,
|
||||||
|
addIcon,
|
||||||
|
addCollection,
|
||||||
|
calculateSize,
|
||||||
|
replaceIDs,
|
||||||
|
buildIcon,
|
||||||
|
loadIcons,
|
||||||
|
loadIcon,
|
||||||
|
addAPIProvider,
|
||||||
|
_api,
|
||||||
|
};
|
||||||
|
}
|
135
packages/icon/src/index.ts
Normal file
135
packages/icon/src/index.ts
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import type { IconifyJSON, IconifyIcon } from '@iconify/types';
|
||||||
|
|
||||||
|
// Core
|
||||||
|
import type { IconifyIconName } from '@iconify/utils/lib/icon/name';
|
||||||
|
import type {
|
||||||
|
IconifyIconSize,
|
||||||
|
IconifyHorizontalIconAlignment,
|
||||||
|
IconifyVerticalIconAlignment,
|
||||||
|
IconifyIconCustomisations,
|
||||||
|
} from '@iconify/utils/lib/customisations';
|
||||||
|
import type { IconifyStorageFunctions } from '@iconify/core/lib/storage/functions';
|
||||||
|
import type { IconifyBuilderFunctions } from '@iconify/core/lib/builder/functions';
|
||||||
|
import type { IconifyIconBuildResult } from '@iconify/utils/lib/svg/build';
|
||||||
|
|
||||||
|
// API
|
||||||
|
import type {
|
||||||
|
IconifyAPIFunctions,
|
||||||
|
IconifyAPIInternalFunctions,
|
||||||
|
IconifyAPIQueryParams,
|
||||||
|
IconifyAPICustomQueryParams,
|
||||||
|
} from '@iconify/core/lib/api/functions';
|
||||||
|
import type {
|
||||||
|
IconifyAPIModule,
|
||||||
|
IconifyAPISendQuery,
|
||||||
|
IconifyAPIPrepareIconsQuery,
|
||||||
|
} from '@iconify/core/lib/api/modules';
|
||||||
|
import type {
|
||||||
|
PartialIconifyAPIConfig,
|
||||||
|
IconifyAPIConfig,
|
||||||
|
GetAPIConfig,
|
||||||
|
} from '@iconify/core/lib/api/config';
|
||||||
|
import type {
|
||||||
|
IconifyIconLoaderCallback,
|
||||||
|
IconifyIconLoaderAbort,
|
||||||
|
} from '@iconify/core/lib/api/icons';
|
||||||
|
|
||||||
|
// Cache
|
||||||
|
import type {
|
||||||
|
IconifyBrowserCacheType,
|
||||||
|
IconifyBrowserCacheFunctions,
|
||||||
|
} from '@iconify/core/lib/browser-storage/functions';
|
||||||
|
|
||||||
|
// Component
|
||||||
|
import type { IconifyIconAttributes } from './attributes/types';
|
||||||
|
import { IconifyIconComponent } from './component';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export used types
|
||||||
|
*/
|
||||||
|
// Function sets
|
||||||
|
export {
|
||||||
|
IconifyStorageFunctions,
|
||||||
|
IconifyBuilderFunctions,
|
||||||
|
IconifyBrowserCacheFunctions,
|
||||||
|
IconifyAPIFunctions,
|
||||||
|
IconifyAPIInternalFunctions,
|
||||||
|
};
|
||||||
|
|
||||||
|
// JSON stuff
|
||||||
|
export { IconifyIcon, IconifyJSON, IconifyIconName };
|
||||||
|
|
||||||
|
// Customisations
|
||||||
|
export {
|
||||||
|
IconifyIconCustomisations,
|
||||||
|
IconifyIconSize,
|
||||||
|
IconifyHorizontalIconAlignment,
|
||||||
|
IconifyVerticalIconAlignment,
|
||||||
|
};
|
||||||
|
|
||||||
|
// API
|
||||||
|
export {
|
||||||
|
IconifyAPIConfig,
|
||||||
|
IconifyIconLoaderCallback,
|
||||||
|
IconifyIconLoaderAbort,
|
||||||
|
IconifyAPIModule,
|
||||||
|
GetAPIConfig,
|
||||||
|
IconifyAPIPrepareIconsQuery,
|
||||||
|
IconifyAPISendQuery,
|
||||||
|
PartialIconifyAPIConfig,
|
||||||
|
IconifyAPIQueryParams,
|
||||||
|
IconifyAPICustomQueryParams,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Builder functions
|
||||||
|
export { IconifyIconBuildResult };
|
||||||
|
|
||||||
|
// Browser cache
|
||||||
|
export { IconifyBrowserCacheType };
|
||||||
|
|
||||||
|
// Component types
|
||||||
|
export { IconifyIconAttributes };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export component
|
||||||
|
*/
|
||||||
|
export { IconifyIconComponent };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export functions
|
||||||
|
*/
|
||||||
|
const {
|
||||||
|
enableCache,
|
||||||
|
disableCache,
|
||||||
|
iconExists,
|
||||||
|
getIcon,
|
||||||
|
listIcons,
|
||||||
|
shareStorage,
|
||||||
|
addIcon,
|
||||||
|
addCollection,
|
||||||
|
calculateSize,
|
||||||
|
replaceIDs,
|
||||||
|
buildIcon,
|
||||||
|
loadIcons,
|
||||||
|
loadIcon,
|
||||||
|
addAPIProvider,
|
||||||
|
_api,
|
||||||
|
} = IconifyIconComponent;
|
||||||
|
|
||||||
|
export {
|
||||||
|
enableCache,
|
||||||
|
disableCache,
|
||||||
|
iconExists,
|
||||||
|
getIcon,
|
||||||
|
listIcons,
|
||||||
|
shareStorage,
|
||||||
|
addIcon,
|
||||||
|
addCollection,
|
||||||
|
calculateSize,
|
||||||
|
replaceIDs,
|
||||||
|
buildIcon,
|
||||||
|
loadIcons,
|
||||||
|
loadIcon,
|
||||||
|
addAPIProvider,
|
||||||
|
_api,
|
||||||
|
};
|
@ -26,7 +26,8 @@ describe('Testing icon component', () => {
|
|||||||
expect(window.customElements.get('iconify-icon')).toBeUndefined();
|
expect(window.customElements.get('iconify-icon')).toBeUndefined();
|
||||||
|
|
||||||
// Define component
|
// Define component
|
||||||
expect(defineIconifyIcon()).toBeDefined();
|
const IconifyIcon = defineIconifyIcon();
|
||||||
|
expect(IconifyIcon).toBeDefined();
|
||||||
expect(window.customElements.get('iconify-icon')).toBeDefined();
|
expect(window.customElements.get('iconify-icon')).toBeDefined();
|
||||||
|
|
||||||
// Create element
|
// Create element
|
||||||
@ -39,6 +40,10 @@ describe('Testing icon component', () => {
|
|||||||
`<style>${expectedBlock}</style>`
|
`<style>${expectedBlock}</style>`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Check for dynamically added methods
|
||||||
|
expect(typeof node.loadIcon).toBe('function');
|
||||||
|
expect(typeof IconifyIcon.loadIcon).toBe('function');
|
||||||
|
|
||||||
// Set icon
|
// Set icon
|
||||||
node.icon = {
|
node.icon = {
|
||||||
body: '<g />',
|
body: '<g />',
|
||||||
|
Loading…
Reference in New Issue
Block a user