mirror of
https://github.com/iconify/iconify.git
synced 2024-11-09 23:00:56 +00:00
chore: add export to utils index
This commit is contained in:
parent
ffd23fb8ec
commit
609537b7bf
@ -1,13 +1,13 @@
|
|||||||
import { promises as fs } from 'fs'
|
import { promises as fs } from 'fs';
|
||||||
import type { IconifyJSON } from '@iconify/types'
|
import type { IconifyJSON } from '@iconify/types';
|
||||||
import type { FullIconifyIcon } from '@iconify/utils'
|
import type { FullIconifyIcon } from '@iconify/utils';
|
||||||
import { defaultCustomisations as DefaultIconCustomizations, iconToSVG, getIconData, tryInstallPkg } from '@iconify/utils';
|
import { defaultCustomisations as DefaultIconCustomizations, iconToSVG, getIconData, tryInstallPkg } from '@iconify/utils';
|
||||||
import createDebugger from 'debug'
|
import createDebugger from 'debug';
|
||||||
import { isPackageExists, resolveModule } from 'local-pkg'
|
import { isPackageExists, resolveModule } from 'local-pkg';
|
||||||
|
|
||||||
const debug = createDebugger('@iconify-core:icon')
|
const debug = createDebugger('@iconify-core:icon');
|
||||||
const debugModern = createDebugger('@iconify-core:modern')
|
const debugModern = createDebugger('@iconify-core:modern');
|
||||||
const debugLegacy = createDebugger('@iconify-core:legacy')
|
const debugLegacy = createDebugger('@iconify-core:legacy');
|
||||||
|
|
||||||
export interface ResolvedIconPath {
|
export interface ResolvedIconPath {
|
||||||
collection: string
|
collection: string
|
||||||
@ -15,54 +15,57 @@ export interface ResolvedIconPath {
|
|||||||
query: Record<string, string | undefined>
|
query: Record<string, string | undefined>
|
||||||
}
|
}
|
||||||
|
|
||||||
const _collections: Record<string, Promise<IconifyJSON | undefined>> = {}
|
const _collections: Record<string, Promise<IconifyJSON | undefined>> = {};
|
||||||
const isLegacyExists = isPackageExists('@iconify/json')
|
const isLegacyExists = isPackageExists('@iconify/json');
|
||||||
|
|
||||||
export async function loadCollection(name: string, autoInstall = false): Promise<IconifyJSON | undefined> {
|
export async function loadCollection(name: string, autoInstall = false): Promise<IconifyJSON | undefined> {
|
||||||
if (!_collections[name])
|
if (!_collections[name]) {
|
||||||
_collections[name] = task()
|
_collections[name] = task();
|
||||||
|
}
|
||||||
|
|
||||||
return _collections[name]
|
return _collections[name];
|
||||||
|
|
||||||
async function task(): Promise<IconifyJSON | undefined> {
|
async function task(): Promise<IconifyJSON | undefined> {
|
||||||
let jsonPath = resolveModule(`@iconify-json/${name}/icons.json`)
|
let jsonPath = resolveModule(`@iconify-json/${name}/icons.json`);
|
||||||
if (jsonPath)
|
if (jsonPath) {
|
||||||
debugModern(name)
|
debugModern(name);
|
||||||
|
}
|
||||||
|
|
||||||
if (!jsonPath && isLegacyExists) {
|
if (!jsonPath && isLegacyExists) {
|
||||||
jsonPath = resolveModule(`@iconify/json/json/${name}.json`)
|
jsonPath = resolveModule(`@iconify/json/json/${name}.json`);
|
||||||
if (jsonPath)
|
if (jsonPath) {
|
||||||
debugLegacy(name)
|
debugLegacy(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!jsonPath && !isLegacyExists && autoInstall) {
|
if (!jsonPath && !isLegacyExists && autoInstall) {
|
||||||
await tryInstallPkg(`@iconify-json/${name}`)
|
await tryInstallPkg(`@iconify-json/${name}`);
|
||||||
jsonPath = resolveModule(`@iconify-json/${name}/icons.json`)
|
jsonPath = resolveModule(`@iconify-json/${name}/icons.json`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jsonPath) {
|
if (jsonPath) {
|
||||||
return JSON.parse(await fs.readFile(jsonPath, 'utf8'))
|
return JSON.parse(await fs.readFile(jsonPath, 'utf8'));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
debugModern(`failed to load ${name}`)
|
debugModern(`failed to load ${name}`);
|
||||||
return undefined
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function searchForIcon(iconSet: IconifyJSON, collection: string, ids: string[], scale = 1): FullIconifyIcon | null {
|
export function searchForIcon(iconSet: IconifyJSON, collection: string, ids: string[], scale = 1): FullIconifyIcon | null {
|
||||||
let iconData: FullIconifyIcon | null
|
let iconData: FullIconifyIcon | null;
|
||||||
for (const id of ids) {
|
for (const id of ids) {
|
||||||
iconData = getIconData(iconSet, id, true)
|
iconData = getIconData(iconSet, id, true);
|
||||||
if (iconData) {
|
if (iconData) {
|
||||||
debug(`${collection}:${id}`)
|
debug(`${collection}:${id}`);
|
||||||
const { attributes, body } = iconToSVG(iconData, {
|
const { attributes, body } = iconToSVG(iconData, {
|
||||||
...DefaultIconCustomizations,
|
...DefaultIconCustomizations,
|
||||||
height: `${scale}em`,
|
height: `${scale}em`,
|
||||||
width: `${scale}em`,
|
width: `${scale}em`,
|
||||||
})
|
});
|
||||||
return `<svg ${Object.entries(attributes).map(i => `${i[0]}="${i[1]}"`).join(' ')}>${body}</svg>`
|
return `<svg ${Object.entries(attributes).map(i => `${i[0]}="${i[1]}"`).join(' ')}>${body}</svg>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -45,3 +45,7 @@ export { colorKeywords } from './colors/keywords';
|
|||||||
export { stringToColor, compareColors, colorToString } from './colors/index';
|
export { stringToColor, compareColors, colorToString } from './colors/index';
|
||||||
|
|
||||||
// SVG Icon loader
|
// SVG Icon loader
|
||||||
|
export type { CustomIconLoader, CustomCollections, InlineCollection } from './loader/types';
|
||||||
|
export { camelize, camelToKebab, pascalize, tryInstallPkg } from './loader/utils';
|
||||||
|
export { FileSystemIconLoader } from './loader/loaders';
|
||||||
|
export { getCustomIcon } from './loader/custom';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import createDebugger from 'debug'
|
import createDebugger from 'debug';
|
||||||
import type { CustomIconLoader, InlineCollection } from '.'
|
import type { CustomIconLoader, InlineCollection } from './types';
|
||||||
|
|
||||||
const debug = createDebugger('@iconify-loader:custom')
|
const debug = createDebugger('@iconify-loader:custom');
|
||||||
|
|
||||||
export async function getCustomIcon(
|
export async function getCustomIcon(
|
||||||
custom: CustomIconLoader | InlineCollection,
|
custom: CustomIconLoader | InlineCollection,
|
||||||
@ -9,23 +9,24 @@ export async function getCustomIcon(
|
|||||||
icon: string,
|
icon: string,
|
||||||
scale = 1
|
scale = 1
|
||||||
): Promise<string | undefined> {
|
): Promise<string | undefined> {
|
||||||
let result: string | undefined | null
|
let result: string | undefined | null;
|
||||||
|
|
||||||
debug(`${collection}:${icon}`)
|
debug(`${collection}:${icon}`);
|
||||||
|
|
||||||
if (typeof custom === 'function') {
|
if (typeof custom === 'function') {
|
||||||
result = await custom(icon)
|
result = await custom(icon);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const inline = custom[icon]
|
const inline = custom[icon];
|
||||||
result = typeof inline === 'function'
|
result = typeof inline === 'function'
|
||||||
? await inline()
|
? await inline()
|
||||||
: inline
|
: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
if (!result.startsWith('<svg '))
|
if (!result.startsWith('<svg ')) {
|
||||||
console.warn(`Custom icon "${icon}" in "${collection}" is not a valid SVG`)
|
console.warn(`Custom icon "${icon}" in "${collection}" is not a valid SVG`);
|
||||||
return result.replace('<svg ', `<svg height="${scale}em" width="${scale}em" `)
|
}
|
||||||
|
return result.replace('<svg ', `<svg height="${scale}em" width="${scale}em" `);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
export type { CustomIconLoader, CustomCollections, InlineCollection } from './types'
|
|
||||||
|
|
||||||
export { camelize, camelToKebab, pascalize } from './utils'
|
|
||||||
export { FileSystemIconLoader } from './loaders'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
import type { Awaitable } from '@antfu/utils'
|
import type { Awaitable } from '@antfu/utils';
|
||||||
import { existsSync, promises as fs } from 'fs';
|
import { existsSync, promises as fs } from 'fs';
|
||||||
import type { CustomIconLoader } from './types';
|
import type { CustomIconLoader } from './types';
|
||||||
import { camelize, pascalize } from './utils';
|
import { camelize, pascalize } from './utils';
|
||||||
@ -9,12 +9,12 @@ export function FileSystemIconLoader(dir: string, transform?: (svg: string) => A
|
|||||||
`${dir}/${name}.svg`,
|
`${dir}/${name}.svg`,
|
||||||
`${dir}/${camelize(name)}.svg`,
|
`${dir}/${camelize(name)}.svg`,
|
||||||
`${dir}/${pascalize(name)}.svg`,
|
`${dir}/${pascalize(name)}.svg`,
|
||||||
]
|
];
|
||||||
for (const path of paths) {
|
for (const path of paths) {
|
||||||
if (existsSync(path)) {
|
if (existsSync(path)) {
|
||||||
const svg = await fs.readFile(path, 'utf-8')
|
const svg = await fs.readFile(path, 'utf-8');
|
||||||
return typeof transform === 'function' ? await transform(svg) : svg
|
return typeof transform === 'function' ? await transform(svg) : svg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { Awaitable } from '@antfu/utils'
|
import type { Awaitable } from '@antfu/utils';
|
||||||
|
|
||||||
export type CustomIconLoader = (name: string) => Awaitable<string | undefined>
|
export type CustomIconLoader = (name: string) => Awaitable<string | undefined>
|
||||||
export type InlineCollection = Record<string, string | (() => Awaitable<string | undefined>)>
|
export type InlineCollection = Record<string, string | (() => Awaitable<string | undefined>)>
|
||||||
|
@ -1,43 +1,44 @@
|
|||||||
import { installPackage } from '@antfu/install-pkg'
|
import { installPackage } from '@antfu/install-pkg';
|
||||||
import { sleep } from '@antfu/utils'
|
import { sleep } from '@antfu/utils';
|
||||||
|
|
||||||
export function camelize(str: string): string {
|
export function camelize(str: string): string {
|
||||||
return str.replace(/-([a-z0-9])/g, g => g[1].toUpperCase())
|
return str.replace(/-([a-z0-9])/g, g => g[1].toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function pascalize(str: string): string {
|
export function pascalize(str: string): string {
|
||||||
const camel = camelize(str)
|
const camel = camelize(str);
|
||||||
return camel[0].toUpperCase() + camel.slice(1)
|
return camel[0].toUpperCase() + camel.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function camelToKebab(key: string): string {
|
export function camelToKebab(key: string): string {
|
||||||
const result = key
|
const result = key
|
||||||
.replace(/:/g, '-')
|
.replace(/:/g, '-')
|
||||||
.replace(/([A-Z])/g, ' $1')
|
.replace(/([A-Z])/g, ' $1')
|
||||||
.trim()
|
.trim();
|
||||||
return result.split(/\s+/g).join('-').toLowerCase()
|
return result.split(/\s+/g).join('-').toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
const warnned = new Set<string>()
|
const warnned = new Set<string>();
|
||||||
|
|
||||||
export function warnOnce(msg: string): void {
|
export function warnOnce(msg: string): void {
|
||||||
if (!warnned.has(msg)) {
|
if (!warnned.has(msg)) {
|
||||||
warnned.add(msg)
|
warnned.add(msg);
|
||||||
console.warn(`[@iconify-loader] ${msg}`)
|
console.warn(`[@iconify-loader] ${msg}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let pending: Promise<void> | undefined
|
let pending: Promise<void> | undefined;
|
||||||
const tasks: Record<string, Promise<void> | undefined> = {}
|
const tasks: Record<string, Promise<void> | undefined> = {};
|
||||||
|
|
||||||
export async function tryInstallPkg(name: string): Promise<void | undefined> {
|
export async function tryInstallPkg(name: string): Promise<void | undefined> {
|
||||||
if (pending)
|
if (pending) {
|
||||||
await pending
|
await pending;
|
||||||
|
}
|
||||||
|
|
||||||
if (!tasks[name]) {
|
if (!tasks[name]) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(`Installing ${name}...`)
|
console.log(`Installing ${name}...`);
|
||||||
tasks[name] = pending = installPackage(name, { dev: true, preferOffline: true })
|
tasks[name] = pending = installPackage(name, { dev: true, preferOffline: true })
|
||||||
.then(() => sleep(300))
|
.then(() => sleep(300))
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
@ -47,9 +48,9 @@ export async function tryInstallPkg(name: string): Promise<void | undefined> {
|
|||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
pending = undefined
|
pending = undefined
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
return tasks[name]!
|
return tasks[name]!;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user